Les deux révisions précédentesRévision précédenteProchaine révision | Révision précédente |
issue53:tutopython [2011/11/16 11:20] – auntiee | issue53:tutopython [2011/11/17 16:00] (Version actuelle) – majordom |
---|
Les files d'attente FIFO sont celles que nous voyons dans la vie quotidienne. Tous les exemples que j'ai énumérés ci-dessus sont des files d'attente FIFO. La première personne dans la ligne est traitée d'abord, s'en va, puis tout le monde se déplace d'une place dans la ligne. Dans un tampon FIFO, il n'y a pas de limite (sauf celle de la raison) au nombre d'éléments qu'il peut contenir. Ils s'empilent simplement dans l'ordre. Lorsqu'un élément est traité, il est sorti de la file, et tous les autres se rapprochent d'une position du début de la file d'attente. | Les files d'attente FIFO sont celles que nous voyons dans la vie quotidienne. Tous les exemples que j'ai énumérés ci-dessus sont des files d'attente FIFO. La première personne dans la ligne est traitée d'abord, s'en va, puis tout le monde se déplace d'une place dans la ligne. Dans un tampon FIFO, il n'y a pas de limite (sauf celle de la raison) au nombre d'éléments qu'il peut contenir. Ils s'empilent simplement dans l'ordre. Lorsqu'un élément est traité, il est sorti de la file, et tous les autres se rapprochent d'une position du début de la file d'attente. |
| |
Les files d'attente LIFO sont moins fréquentes dans la vie, mais il existe encore des exemples réels. Celui qui vient tout de suite à l'esprit est l'exemple d'une pile d'assiettes dans votre placard de cuisine. Lorsque les assiettes sont lavées et séchées, elles s'empilent dans le placard. La dernière arrivée sur la pile est la première qui sera réutilisée. Tout le reste attend, peut-être pendant des jours, pour être utilisé. C'est une bonne chose que la file d'attente pour un billet de cinéma soit FIFO, n'est ce pas ? Comme pour la file d'attente FIFO, en restant dans des tailles raisonnables, il n'y a pas de limite à la taille d'une file d'attente LIFO. Le premier élément entré dans la pile doit attendre que tous les éléments arrivés après lui soient retirés de la mémoire tampon (assiettes retirées de la pile) jusqu'à ce qu'il soit le seul restant. | Les files d'attente LIFO sont moins fréquentes dans la vie, mais il existe encore des exemples réels. Celui qui vient tout de suite à l'esprit est l'exemple d'une pile d'assiettes dans votre placard de cuisine. Lorsque les assiettes sont lavées et séchées, elles s'empilent dans le placard. La dernière arrivée sur la pile est la première qui sera réutilisée. Tout le reste attend, peut-être pendant des jours, pour être utilisé. C'est une bonne chose que la file d'attente pour un billet de cinéma soit FIFO, n'est-ce pas ? Comme pour la file d'attente FIFO, en restant dans des tailles raisonnables, il n'y a pas de limite à la taille d'une file d'attente LIFO. Le premier élément entré dans la pile doit attendre que tous les éléments arrivés après lui soient retirés de la mémoire tampon (assiettes retirées de la pile) jusqu'à ce qu'il soit le seul restant. |
| |
**Priority queues are a bit harder for many people to imagine right off the bat. Think of a company that has one printer. Everyone uses that one printer. The print jobs are handled by department priority. Payroll has a higher priority (and thankfully so) than say, you, a programmer. You have a higher priority (and thankfully so) than the receptionist. So in short, the data that has a higher priority gets handled, and gets out of the queue, before data that has a lower priority. | **Priority queues are a bit harder for many people to imagine right off the bat. Think of a company that has one printer. Everyone uses that one printer. The print jobs are handled by department priority. Payroll has a higher priority (and thankfully so) than say, you, a programmer. You have a higher priority (and thankfully so) than the receptionist. So in short, the data that has a higher priority gets handled, and gets out of the queue, before data that has a lower priority. |
[1,2,3,4,5,6,7,8,9,10]** | [1,2,3,4,5,6,7,8,9,10]** |
| |
Les files d'attente prioritaires sont un peu plus difficiles à comprendre du premier coup pour beaucoup de gens. Pensez à une entreprise qui possède une seule imprimante. Tout le monde utilise cette imprimante unique. Les travaux d'impression sont traitées par ordre de priorité des départements. La paie a une priorité plus élevée (et heureusement) que, par exemple, vous, un programmeur. Vous avez une priorité plus élevée (et heureusement) que la réceptionniste. En bref, donc, les données qui ont une priorité plus élevée sont traitées et sortent de la file d'attente avant les données qui ont une priorité inférieure. | Les files d'attente prioritaires sont un peu plus difficiles à comprendre du premier coup pour beaucoup de gens. Pensez à une entreprise qui possède une seule imprimante. Tout le monde utilise cette imprimante unique. Les travaux d'impression sont traités par ordre de priorité des départements. La paie a une priorité plus élevée (et heureusement) que, par exemple, vous, un programmeur. Vous avez une priorité plus élevée (et heureusement) que la réceptionniste. En bref, donc, les données qui ont une priorité plus élevée sont traitées et sortent de la file d'attente avant les données qui ont une priorité inférieure. |
| |
FIFO | FIFO |
[4,5,6,7,8,9,10] | [4,5,6,7,8,9,10] |
| |
Je suis sûr que vous voyez l'idée. Python fournit une simple bibliothèque, assez étonnamment appelée « Queue » [Ndt : qui signifie file d'attente], qui fonctionne bien pour des files d'attente de petite et moyenne taille, jusqu'à environ 500 éléments. Voici un exemple simple de démonstration. | Je suis sûr que vous voyez l'idée. Python fournit une simple bibliothèque, assez étonnamment appelée « Queue » [Ndt : qui signifie file d'attente], qui fonctionne bien pour des files d'attente de petite et moyenne taille, jusqu'à environ 500 éléments. Voici un exemple simple de démonstration : |
| |
**import Queue | **import Queue |
Ici, la file d'attente est paramétrée à un maximum de 12 éléments. Lorsque nous ajoutons des éléments dans la file d'attente, nous commençons avec 0 et arrivons à 11. Mais lorsque nous atteignons le nombre 12, le tampon est déjà plein. Puisque nous vérifions si la mémoire tampon est pleine avant d'essayer d'ajouter un élément, le dernier élément est tout simplement rejeté. | Ici, la file d'attente est paramétrée à un maximum de 12 éléments. Lorsque nous ajoutons des éléments dans la file d'attente, nous commençons avec 0 et arrivons à 11. Mais lorsque nous atteignons le nombre 12, le tampon est déjà plein. Puisque nous vérifions si la mémoire tampon est pleine avant d'essayer d'ajouter un élément, le dernier élément est tout simplement rejeté. |
| |
Il existe d'autres options, mais elles peuvent causer d'autres effets secondaires, et nous aborderons la question dans un prochain article. Ainsi, la plupart du temps, la voie à suivre est soit d'utiliser une file d'attente sans aucune limite ou bien de s'assurer que l'on prévoit plus d'espace dans la file d'attente que ce dont on aura besoin. | Il existe d'autres options, mais elles peuvent causer d'autres effets secondaires, et nous aborderons la question dans un prochain article. Ainsi, la plupart du temps, la voie à suivre est soit d'utiliser une file d'attente sans aucune limite, soit de s'assurer que l'on prévoit plus d'espace dans la file d'attente que ce dont on aura besoin. |
| |
LIFO | LIFO |
Basse | Basse |
| |
Dans nos deux premiers exemples, nous avons simplement affiché les données qui sortent de notre file d'attente. C'est très bien pour ces exemples, mais dans le monde réel de la programmation, vous aurez probablement besoin de faire quelque chose avec cette information dès qu'elle sort de la file d'attente, sinon elle sera perdue. Lorsque nous utilisons « print fifo.get', nous envoyons les données vers le terminal puis elle sont détruites. Il faut juste garder ça à l'esprit. | Dans nos deux premiers exemples, nous avons simplement affiché les données qui sortent de notre file d'attente. C'est très bien pour ces exemples, mais dans le monde réel de la programmation, vous aurez probablement besoin de faire quelque chose avec cette information dès qu'elle sort de la file d'attente, sinon elle sera perdue. Lorsque nous utilisons « print fifo.get », nous envoyons les données vers le terminal puis elle sont détruites. Il faut juste garder ça à l'esprit. |
| |
**Now let's use some of what we've already learned about tkinter to create a queue demo program. This demo will have two frames. The first will contain (to the user) three buttons. One for a FIFO queue, one for a LIFO queue, and one for a PRIORITY queue. The second frame will contain an entry widget, two buttons, one for adding to the queue, and one for pulling from the queue, and three labels, one showing when the queue is empty, one showing when the queue is full, and one to display what has been pulled from the queue. We'll also be writing some code to automatically center the window within the screen. Here's the beginning of the code. | **Now let's use some of what we've already learned about tkinter to create a queue demo program. This demo will have two frames. The first will contain (to the user) three buttons. One for a FIFO queue, one for a LIFO queue, and one for a PRIORITY queue. The second frame will contain an entry widget, two buttons, one for adding to the queue, and one for pulling from the queue, and three labels, one showing when the queue is empty, one showing when the queue is full, and one to display what has been pulled from the queue. We'll also be writing some code to automatically center the window within the screen. Here's the beginning of the code. |
</nowiki>** | </nowiki>** |
| |
Ici, nous avons nos importations et le début de notre classe. Comme précédemment, nous créons la routine __init__ avec les routines DefinirVariables, ConstruireWidgets, et PlacerWidgets. Nous avons aussi une routine appelée AfficherStatut qui... affichera l'état de notre file d'attente. | Ici, nous avons nos importations et le début de notre classe. Comme précédemment, nous créons la routine __init__ avec les routines DefinirVariables, ConstruireWidgets et PlacerWidgets. Nous avons aussi une routine appelée AfficherStatut qui... affichera l'état de notre file d'attente. |
| |
def DefinirVariables(self): | def DefinirVariables(self): |
self.TypeDeFile = '' | self.TypeDeFile = '' |
self.DerniereFile = '' FIXME | |
self.StatutPlein = StringVar() | self.StatutPlein = StringVar() |
self.StatutVide = StringVar() | self.StatutVide = StringVar() |
return frame** | return frame** |
| |
Ensuite nous mettons en place le second cadre, le widget de saisie et les deux boutons. La seule chose ici qui sort de l'ordinaire est le rappel pour le widget de saisie. Ici nous associons la routine self.AjouterALaFile à la touche « Return » (Entrée). De cette façon, l'utilisateur n'a pas à utiliser la souris pour ajouter les données. Il peut simplement entrer les données dans la zone de saisie et appuyez sur Entrée. | Ensuite nous mettons en place le second cadre, le widget de saisie et les deux boutons. La seule chose ici qui sort de l'ordinaire est le rappel pour le widget de saisie. Ici nous associons la routine self.AjouterALaFile à la touche « Return » (Entrée). De cette façon, l'utilisateur n'a pas à utiliser la souris pour ajouter les données. Il peut simplement entrer les données dans la zone de saisie et appuyer sur Entrée. |
| |
self.lblEmpty = Label(self.f2, | self.lblEmpty = Label(self.f2, |
</nowiki>** | </nowiki>** |
| |
Voici les trois dernières définitions de widgets. Tous trois sont des étiquettes. Nous réglons l'attribut textvariable des variables que nous avons défini plus tôt. Si vous vous souvenez, lorsque cette variable change, le texte de l'étiquette changera aussi. Nous faisons aussi quelque chose d'un peu différent sur l'étiquette lblData. Nous allons utiliser une police différente pour faire ressortir l'affichage des données extraites de la file d'attente. Rappelez-vous que nous devons retourner l'objet fenetre de sorte qu'il puisse être utilisé dans la routine PlacerWidgets. | Voici les trois dernières définitions de widgets. Toutes les trois sont des étiquettes. Nous réglons l'attribut textvariable des variables que nous avons définies plus tôt. Si vous vous souvenez, lorsque cette variable change, le texte de l'étiquette changera aussi. Nous faisons aussi quelque chose d'un peu différent sur l'étiquette lblData. Nous allons utiliser une police différente pour faire ressortir l'affichage des données extraites de la file d'attente. Rappelez-vous que nous devons retourner l'objet fenêtre de sorte qu'il puisse être utilisé dans la routine PlacerWidgets. |
| |
def PlacerWidgets(self, principale): | def PlacerWidgets(self, principale): |
commapos = temp.find(',') | commapos = temp.find(',') |
if commapos == -1: | if commapos == -1: |
print "ERROR" FIXME | print "ERREUR" |
tkMessageBox.showerror('Demo File', | tkMessageBox.showerror('Demo File', |
'Un element Priority doit etre au format\r(priorite,valeur)') | 'Un element Priority doit etre au format\r(priorite,valeur)') |
root.mainloop()** | root.mainloop()** |
| |
Nous arrivons à la fin de notre application. Voici la routine de centrage de fenêtre. Nous récupérons d'abord la largeur et la hauteur de l'écran. Nous récupérons ensuite la largeur et la hauteur de la fenêtre racine à l'aide des routines winfo_reqwidth() et winfo_reqheight() intégrées à tkinter. Ces routines, lorsqu'elles sont appelées au bon moment, retourneront la largeur et la hauteur de la fenêtre racine en tenant compte du placement des widgets. Si vous l'appelez trop tôt, vous obtiendrez des valeurs mais pas celles dont vous avez vraiment besoin. Nous soustrayons ensuite la largeur de la fenêtre de la largeur de l'écran, et divisons cela par 2, puis nous faisons la même chose pour la hauteur. Nous utilisons alors ces informations dans l'appel de la fonction geometry. La plupart du temps, cela fonctionne à merveille. Toutefois, il pourrait y avoir des moments où vous aurez besoin de définir la largeur et la hauteur à la main. | Nous arrivons à la fin de notre application. Voici la routine de centrage de fenêtre. Nous récupérons d'abord la largeur et la hauteur de l'écran. Nous récupérons ensuite la largeur et la hauteur de la fenêtre racine à l'aide des routines winfo_reqwidth() et winfo_reqheight() intégrées à tkinter. Ces routines, lorsqu'elles sont appelées au bon moment, retourneront la largeur et la hauteur de la fenêtre racine en tenant compte du placement des widgets. Si vous l'appelez trop tôt, vous obtiendrez des valeurs, mais pas celles dont vous avez vraiment besoin. Nous soustrayons ensuite la largeur de la fenêtre de la largeur de l'écran, et divisons cela par 2, puis nous faisons la même chose pour la hauteur. Nous utilisons alors ces informations dans l'appel de la fonction geometry. La plupart du temps, cela fonctionne à merveille. Toutefois, il pourrait y avoir des moments où vous aurez besoin de définir la largeur et la hauteur à la main. |
| |
root = Tk() | root = Tk() |
Well, that's it for this time. Have fun with your queues. The QueueTest code can be found at http://pastebin.com/5BBUiDce.** | Well, that's it for this time. Have fun with your queues. The QueueTest code can be found at http://pastebin.com/5BBUiDce.** |
| |
Enfin, nous instancions la fenêtre racine, définissons le titre de base, et instancions la class TestFiles. Nous appelons ensuite root.after, qui attend un nombre x de millisecondes (dans ce cas 3) après que la fenêtre racine soit instanciée, puis appelle la routine Centrer. De cette façon, la fenêtre racine a été complètement paramétrée et est prête à s'afficher, donc nous pouvons obtenir sa largeur et sa hauteur. Vous pourriez avoir à ajuster légèrement le temps de retard. Certaines machines sont beaucoup plus rapides que d'autres. 3 fonctionne très bien sur ma machine, votre réglage peut varier. Enfin nous appelons la boucle principale de la fenêtre racine pour exécuter l'application. | Enfin, nous instancions la fenêtre racine, définissons le titre de base et instancions la class TestFiles. Nous appelons ensuite root.after, qui attend un nombre x de millisecondes (dans ce cas 3), après que la fenêtre racine soit instanciée, puis appelle la routine Centrer. De cette façon, la fenêtre racine a été complètement paramétrée et est prête à s'afficher, donc nous pouvons obtenir sa largeur et sa hauteur. Vous pourriez avoir à ajuster légèrement le temps de retard. Certaines machines sont beaucoup plus rapides que d'autres. 3 fonctionne très bien sur ma machine, votre réglage peut varier. Enfin nous appelons la boucle principale de la fenêtre racine pour exécuter l'application. |
| |
Pendant que vous jouez avec les files d'attente, notez que si vous mettez des données dans une file d'attente (disons la file d'attente FIFO), puis passez à une autre file d'attente (disons la file d'attente LIFO), les données qui ont été placées dans la file FIFO sont toujours là et vous attendent. Vous pouvez complètement ou partiellement remplir tous les trois files d'attente, puis commencer à jouer avec. | Pendant que vous jouez avec les files d'attente, notez que si vous mettez des données dans une file d'attente (disons la file d'attente FIFO), puis passez à une autre file d'attente (disons la file d'attente LIFO), les données qui ont été placées dans la file FIFO sont toujours là et vous attendent. Vous pouvez complètement ou partiellement remplir les trois files d'attente, puis commencer à jouer avec. |
| |
Eh bien, c'est tout pour cette fois-ci. Amusez-vous avec vos files d'attente. Le code de TestFiles peut être trouvé ici : http://pastebin.com/5yjcf8R7 | Eh bien, c'est tout pour cette fois-ci. Amusez-vous avec vos files d'attente. Le code de TestFiles peut être trouvé ici : http://pastebin.com/MKLTmSES |
| |