issue168:python
Différences
Ci-dessous, les différences entre deux révisions de la page.
Prochaine révision | Révision précédente | ||
issue168:python [2021/05/02 12:16] – créée auntiee | issue168:python [2021/05/07 12:15] (Version actuelle) – auntiee | ||
---|---|---|---|
Ligne 1: | Ligne 1: | ||
- | As many of you know or have at least heard, Python 3.10 is well on its way. According to python.org (https:// | + | **As many of you know or have at least heard, Python 3.10 is well on its way. According to python.org (https:// |
Here is the release schedule as of April 2021: | Here is the release schedule as of April 2021: | ||
Ligne 10: | Ligne 10: | ||
• 3.10.0 candidate 1: Monday, 2021-08-02 | • 3.10.0 candidate 1: Monday, 2021-08-02 | ||
• 3.10.0 candidate 2: Monday, 2021-09-06 (if necessary) | • 3.10.0 candidate 2: Monday, 2021-09-06 (if necessary) | ||
- | • 3.10.0 final: Monday, 2021-10-04 | + | • 3.10.0 final: Monday, 2021-10-04** |
- | Just because we have over 5 months before the actual release is due, that doesn’t mean that you can’t start getting prepared and excited about the upcoming new version. Some of the changes that are supposed to be coming are: | + | Comme beaucoup d' |
+ | |||
+ | Voici le calendrier de publication à partir d' | ||
+ | ••3.10.0 alpha 7 : mardi 06-04-2021. | ||
+ | Attendu : | ||
+ | ••3.10.0 beta 1 : lundi 03-05-2021 (pas de nouvelles fonctionnalités au-delà de ce point). | ||
+ | ••3.10.0 beta 2 : Mardi 25-05-2021. | ||
+ | ••3.10.0 beta 3 : jeudi 17-06-2021. | ||
+ | ••3.10.0 beta 4 : samedi 10-07-2021. | ||
+ | ••3.10.0 candidate 1 : lundi 02-08-2021. | ||
+ | ••3.10.0 candidate 2 : lundi 06-09-2021 (si nécessaire). | ||
+ | ••3.10.0 final : Lundi 04-10-2021. | ||
+ | |||
+ | |||
+ | **Just because we have over 5 months before the actual release is due, that doesn’t mean that you can’t start getting prepared and excited about the upcoming new version. Some of the changes that are supposed to be coming are: | ||
• PEP 604 – Allow writing union types as X | Y | • PEP 604 – Allow writing union types as X | Y | ||
• PEP 612 – Parameter Specification Variables | • PEP 612 – Parameter Specification Variables | ||
Ligne 23: | Ligne 37: | ||
And I’ve saved the best for last - | And I’ve saved the best for last - | ||
- | • PEP 634, PEP 635 Structural Pattern Matching | + | • PEP 634, PEP 635 Structural Pattern Matching** |
- | Each of the new features that are listed above have the PEP (Python Enhancement Proposals) numbers with them so you can easily do a web search for the ones you are interested in exploring. For the rest of the article, I will be discussing the new Pattern Matching feature. If you want to try out any of these things, hopefully you have pyenv installed. That way you can simply do a pyenv install 3.10-dev to play with version 3.10. There are other ways to try out 3.10, but honestly pyenv is the way to go! If you would rather check out another way, try looking at https:// | + | Ce n'est pas parce qu'il reste plus de 5 mois avant la sortie de la nouvelle version que vous ne pouvez pas commencer à vous préparer et à vous enthousiasmer pour la version à venir. Certains des changements qui sont censés arriver sont : |
+ | ••PEP 604 - Permettre l' | ||
+ | ••PEP 612 - Variables de spécification de paramètres. | ||
+ | ••PEP 626 - Numéros de ligne précis pour le débogage et autres outils. | ||
+ | ••PEP 597 - Ajout d'un EncodingWarning optionnel. | ||
+ | ••PEP 618 - Ajout d'un contrôle de longueur optionnel pour zip. | ||
+ | ••PEP 644 - Nécessite OpenSSL 1.1.1 ou plus récent. | ||
+ | ••PEP 632 - Dépréciation du module distutils. | ||
+ | ••PEP 613 - Alias de types explicites. | ||
- | Pattern Matching | + | Et j'ai gardé le meilleur pour la fin - |
+ | ••PEP 634, PEP 635 Correspondance de motifs structurels. | ||
+ | |||
+ | |||
+ | **Each of the new features that are listed above have the PEP (Python Enhancement Proposals) numbers with them so you can easily do a web search for the ones you are interested in exploring. For the rest of the article, I will be discussing the new Pattern Matching feature. If you want to try out any of these things, hopefully you have pyenv installed. That way you can simply do a pyenv install 3.10-dev to play with version 3.10. There are other ways to try out 3.10, but honestly pyenv is the way to go! If you would rather check out another way, try looking at https:// | ||
+ | |||
+ | Chacune des nouvelles fonctionnalités énumérées ci-dessus est associée à un numéro PEP (Python Enhancement Proposals - Propositions d' | ||
+ | |||
+ | |||
+ | **Pattern Matching | ||
You might be wondering why I’m making such a point to talk about this single item. Well, a small history lesson is in order here. | You might be wondering why I’m making such a point to talk about this single item. Well, a small history lesson is in order here. | ||
Ligne 33: | Ligne 64: | ||
For many years, programmers have been asking for Python to support Select Case (VB) or Switch Case (C#) type statements. They have been saying that it makes code much easier to read. An example of such a statement in Visual Basic would be something like this (below). | For many years, programmers have been asking for Python to support Select Case (VB) or Switch Case (C#) type statements. They have been saying that it makes code much easier to read. An example of such a statement in Visual Basic would be something like this (below). | ||
- | Each time the subject has come up, those who make decisions about Python have said that there is no need for that. The standard if | elif | else structure works just fine (below). | + | Each time the subject has come up, those who make decisions about Python have said that there is no need for that. The standard if | elif | else structure works just fine (below).** |
- | While the Visual Basic structure might look a bit more efficient, both are (in my humble opinion) equally easy to read. That having been said, I came from a Visual Basic background and I have to admit that when I was first learning Python, I too wondered why such a simple solution like the Select Case type testing wasn’t supported. However, I got over it and learned the Python way. | + | Correspondance de motifs |
- | Python 3.10 introduces something called Structural Pattern Matching. At first glance, it is the same thing as the Select Case for VB and Switch Case for C#. Here’s the same code as above, but done with the Pattern Matching. (Top right. By the way, this won’t work without being in Python 3.10.) | + | Vous vous demandez peut-être pourquoi je tiens tant à parler de ce seul élément. Eh bien, une petite leçon d' |
- | When it runs, it returns: | + | Depuis de nombreuses années, les programmeurs demandent que Python supporte les instructions de type Select Case (VB) ou Switch Case (C#). Ils disent que cela rend le code beaucoup plus facile à lire. Un exemple d'une telle déclaration en Visual Basic serait quelque chose comme ceci (ci-dessous). |
+ | |||
+ | Chaque fois que le sujet a été abordé, ceux qui prennent les décisions concernant Python ont dit que ce n' | ||
+ | |||
+ | |||
+ | **While the Visual Basic structure might look a bit more efficient, both are (in my humble opinion) equally easy to read. That having been said, I came from a Visual Basic background and I have to admit that when I was first learning Python, I too wondered why such a simple solution like the Select Case type testing wasn’t supported. However, I got over it and learned the Python way. | ||
+ | |||
+ | Python 3.10 introduces something called Structural Pattern Matching. At first glance, it is the same thing as the Select Case for VB and Switch Case for C#. Here’s the same code as above, but done with the Pattern Matching. (Top right. By the way, this won’t work without being in Python 3.10.)** | ||
+ | |||
+ | Bien que la structure de Visual Basic puisse sembler un peu plus efficace, les deux sont (à mon humble avis) tout aussi faciles à lire. Ceci étant dit, je viens d'un environnement Visual Basic et je dois admettre que lorsque j'ai commencé à apprendre Python, je me suis également demandé pourquoi une solution aussi simple que le test de type Select Case n' | ||
+ | |||
+ | Python 3.10 introduit quelque chose appelé Structural Pattern Matching (Correspondance de motifs structurelle). À première vue, c'est la même chose que le Select Case pour VB et le Switch Case pour C#. Voici le même code que ci-dessus, mais réalisé avec le Pattern Matching. (En haut à droite. Au fait, ceci ne fonctionnera pas sans être en Python 3.10). | ||
+ | |||
+ | |||
+ | **When it runs, it returns: | ||
0 Not between 1 and 10, inclusive | 0 Not between 1 and 10, inclusive | ||
Ligne 54: | Ligne 99: | ||
11 Not between 1 and 10, inclusive | 11 Not between 1 and 10, inclusive | ||
- | Honestly, in this example, it doesn’t look that much better than the Python if | elif version. That’s because while you can do simple things, there is no pattern to match in that case, really. | + | Honestly, in this example, it doesn’t look that much better than the Python if | elif version. That’s because while you can do simple things, there is no pattern to match in that case, really.** |
- | On the other hand, let’s look at an example of how to make this new functionality really shine. We’ll throw together a really limited and simple text adventure game. Surely you remember those, unless you are younger than 30 years old or so. | + | Lorsqu' |
- | The typical text adventure drops the player in the middle of a forest (usually after a night of enjoying copious amounts of adult beverages), or into a dark room inside of a castle. Since Ronnie is Scotish and both sides of my family tree shares that same root, I’ll pick the first option for our adventure. We’ll make our player a male human (since we all know that female humans are smarter than to enjoy copious amounts of adult beverages, right?). | + | 0 pas entre 1 et 10, inclus |
+ | 1 est entre 1 et 5, inclus | ||
+ | 2 est entre 1 et 5, inclus | ||
+ | 3 est entre 1 et 5, inclus | ||
+ | 4 est entre 1 et 5, inclus | ||
+ | 5 est entre 1 et 5, inclus | ||
+ | 6 est entre 6 et 8, inclus | ||
+ | 7 est entre 6 et 8, inclus | ||
+ | 8 est entre 6 et 8, inclus | ||
+ | 9 est égal à 9 ou 10 | ||
+ | 10 est égal à 9 ou 10 | ||
+ | 11 pas entre 1 et 10, inclus | ||
- | Now, our player is in a forest with a bit of a headache. There are only four directions that he can move; North, West, South and East. We will assume that the paths available to him won’t normally run him into a tree. I mean, he already has a hangover – let’s not make it any worse. Scattered throughout his journey, he will stumble over things like a sword, an axe, some gold, some silver, some diamonds, flint and steel to start a fire, and so on. I won’t be nice enough to let him find some aspirin, just because he should suffer some for his evening’s indulgences. He also will possibly run into a monster or two. | + | Honnêtement, dans cet exemple, cela ne semble pas tellement mieux que la version if | elif de Python. En effet, même si vous pouvez faire des choses simples, il n' |
- | Now that we’ve defined his world somewhat, let’s start looking at writing some code. We’ll need to create a couple of lists to handle the objects in the game that the player can deal with and to “hold” the items he’s picked up (above). | ||
- | Our main loop (below) will be fairly simple. As long as the game_running variable is True, then we will continue to loop. At the top of the loop, we ask the user what they want to do and get their response. We send that to the function work_command. | + | **On the other hand, let’s look at an example of how to make this new functionality really shine. We’ll throw together a really limited and simple text adventure game. Surely you remember those, unless you are younger than 30 years old or so. |
+ | |||
+ | The typical text adventure drops the player in the middle of a forest (usually after a night of enjoying copious amounts of adult beverages), or into a dark room inside of a castle. Since Ronnie is Scotish and both sides of my family tree shares that same root, I’ll pick the first option for our adventure. We’ll make our player a male human (since we all know that female humans are smarter than to enjoy copious amounts of adult beverages, right? | ||
+ | |||
+ | D' | ||
+ | |||
+ | Le jeu d' | ||
+ | |||
+ | |||
+ | **Now, our player is in a forest with a bit of a headache. There are only four directions that he can move; North, West, South and East. We will assume that the paths available to him won’t normally run him into a tree. I mean, he already has a hangover – let’s not make it any worse. Scattered throughout his journey, he will stumble over things like a sword, an axe, some gold, some silver, some diamonds, flint and steel to start a fire, and so on. I won’t be nice enough to let him find some aspirin, just because he should suffer some for his evening’s indulgences. He also will possibly run into a monster or two. | ||
+ | |||
+ | Now that we’ve defined his world somewhat, let’s start looking at writing some code. We’ll need to create a couple of lists to handle the objects in the game that the player can deal with and to “hold” the items he’s picked up (above).** | ||
+ | |||
+ | Maintenant, notre joueur se trouve dans une forêt et a un peu mal à la tête. Il ne peut se déplacer que dans quatre directions : nord, ouest, sud et est. Nous supposerons que les chemins qui s' | ||
+ | |||
+ | Maintenant que nous avons plus ou moins défini son monde, nous allons commencer à écrire du code. Nous devrons créer quelques listes pour gérer les objets du jeu que le joueur peut manipuler et pour « contenir » les objets qu'il a ramassés (ci-dessus). | ||
+ | |||
+ | |||
+ | **Our main loop (below) will be fairly simple. As long as the game_running variable is True, then we will continue to loop. At the top of the loop, we ask the user what they want to do and get their response. We send that to the function work_command. | ||
Inside the work_command function, we will use the new match case function. We’ll start pretty simply (top right). | Inside the work_command function, we will use the new match case function. We’ll start pretty simply (top right). | ||
- | I’ve defined the global variables here that I think might be used. When we start the match case section, we set the match statement to look at the command that has been split apart with the .split() command. This way, the case statements can look for commands like “quit” as well as “go North” and even things more complicated like “get Axe”. Let’s add another case for moving towards the North. | + | I’ve defined the global variables here that I think might be used. When we start the match case section, we set the match statement to look at the command that has been split apart with the .split() command. This way, the case statements can look for commands like “quit” as well as “go North” and even things more complicated like “get Axe”. Let’s add another case for moving towards the North.** |
+ | |||
+ | Notre boucle principale (ci-dessous) sera assez simple. Tant que la variable game_running est True, nous continuons la boucle. Au début de la boucle, nous demandons à l' | ||
+ | |||
+ | Dans la fonction work_command, | ||
+ | |||
+ | J'ai défini ici les variables globales que je pense pouvoir être utilisées. Lorsque nous démarrons la section match case, nous configurons l' | ||
- | case[" | + | **case[" |
| | ||
Ligne 78: | Ligne 158: | ||
So in this case (no pun intended), if the user enters the command “North” or “go North”, it will fall into the above case. This allows us to handle multiple options. | So in this case (no pun intended), if the user enters the command “North” or “go North”, it will fall into the above case. This allows us to handle multiple options. | ||
- | However, we can even get more complex. In the next version, we can mix the “go” command with an set of directions that will allow us to encapsulate the go command with a direction, use the pattern of ‘North’ | ‘South’ | ‘East’ | ‘West’, assign that to the variable direction, and test that to handle any of the four options. | + | However, we can even get more complex. In the next version, we can mix the “go” command with an set of directions that will allow us to encapsulate the go command with a direction, use the pattern of ‘North’ | ‘South’ | ‘East’ | ‘West’, assign that to the variable direction, and test that to handle any of the four options.** |
- | Then at the bottom of the test for the four directions, we can make a test, just in case the player decided to get cute, and enter something like “go Up”. The *wth wildcard will catch anything that isn’t part of our four directions. | + | case[" |
+ | |||
+ | | ||
+ | |||
+ | | ||
+ | |||
+ | Donc, dans ce cas (sans jeu de mots), si l' | ||
+ | |||
+ | Cependant, nous pouvons même devenir plus complexes. Dans la prochaine version, nous pourrons combiner la commande « go » avec un ensemble de directions qui nous permettra d' | ||
+ | |||
+ | |||
+ | **Then at the bottom of the test for the four directions, we can make a test, just in case the player decided to get cute, and enter something like “go Up”. The *wth wildcard will catch anything that isn’t part of our four directions. | ||
We also can handle things like this (next page, top left). | We also can handle things like this (next page, top left). | ||
- | In this instance, the user can type “get Axe” or “pick up Sword” or even “pick shovel up”. So when the program hits this part of the code, the object is then added to the players “bag o’ infinite stuff” by the append command. When the player wants to see the contents of his bag, he just enters “inventory” which displays the contents of the list. | + | In this instance, the user can type “get Axe” or “pick up Sword” or even “pick shovel up”. So when the program hits this part of the code, the object is then added to the players “bag o’ infinite stuff” by the append command. When the player wants to see the contents of his bag, he just enters “inventory” which displays the contents of the list.** |
+ | Ensuite, en bas du test pour les quatre directions, nous pouvons faire un test, juste au cas où le joueur déciderait de faire le malin et entrerait quelque chose comme « Monter ». Le caractère générique *wth attrapera tout ce qui ne fait pas partie de nos quatre directions. | ||
+ | Nous pouvons également gérer des choses comme ceci (page suivante, en haut à gauche). | ||
- | Pick up Axe | + | Dans ce cas, l' |
+ | |||
+ | |||
+ | |||
+ | **Pick up Axe | ||
~~~~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
You currently have 1 objects in your bag: | You currently have 1 objects in your bag: | ||
Ligne 96: | Ligne 193: | ||
I have to be honest with you, the examples that I have provided here only scratch the surface of the Structural Pattern Matching feature and are very simplistic. For more information and examples, you can check out the following web sites… | I have to be honest with you, the examples that I have provided here only scratch the surface of the Structural Pattern Matching feature and are very simplistic. For more information and examples, you can check out the following web sites… | ||
+ | |||
+ | https:// | ||
+ | |||
+ | https:// | ||
+ | |||
+ | Ramasser hache | ||
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
+ | Vous avez actuellement 1 objet dans votre sac : | ||
+ | sac d' | ||
+ | hache | ||
+ | ~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
+ | |||
+ | Je dois être honnête avec vous, les exemples que j'ai fournis ici ne font qu' | ||
https:// | https:// | ||
Ligne 101: | Ligne 211: | ||
https:// | https:// | ||
- | As things get a bit further along with the beta version, I’m sure you will see a large amount of web information about all of the version 3.10 features – especially the Pattern Matching feature. | + | |
+ | **As things get a bit further along with the beta version, I’m sure you will see a large amount of web information about all of the version 3.10 features – especially the Pattern Matching feature. | ||
I’ll put the Python code that I provided in the article on my github repository at https:// | I’ll put the Python code that I provided in the article on my github repository at https:// | ||
- | Until next time, as always; stay safe, healthy, positive and creative! | + | Until next time, as always; stay safe, healthy, positive and creative!** |
+ | |||
+ | Au fur et à mesure que les choses avancent dans la version bêta, je suis sûr que vous verrez une grande quantité d' | ||
+ | |||
+ | Je mettrai le code Python que j'ai fourni dans l' | ||
+ | |||
+ | Jusqu' | ||
+ | |||
+ | |||
+ | //Encart de la page 25 en bas à droite :// | ||
+ | **Select Case number | ||
+ | Case 1 To 5 | ||
+ | Debug.WriteLine(" | ||
+ | ' The following is the only Case clause that evaluates to True. | ||
+ | Case 6, 7, 8 | ||
+ | Debug.WriteLine(" | ||
+ | Case 9 To 10 | ||
+ | Debug.WriteLine(" | ||
+ | Case Else | ||
+ | Debug.WriteLine(" | ||
+ | End Select** | ||
+ | |||
+ | Select Case number | ||
+ | Case 1 To 5 | ||
+ | Debug.WriteLine(" | ||
+ | ' Le suivant est le seul Case évalué à True (Vrai). | ||
+ | Case 6, 7, 8 | ||
+ | Debug.WriteLine(" | ||
+ | Case 9 To 10 | ||
+ | Debug.WriteLine(" | ||
+ | Case Else | ||
+ | Debug.WriteLine(" | ||
+ | End Select | ||
+ | |||
+ | //Encart de la page 26 en haut : // | ||
+ | **def check_number(number): | ||
+ | match number: | ||
+ | case 1 | 2 | 3 | 4 | 5: | ||
+ | print(f" | ||
+ | case 6 | 7 | 8: | ||
+ | print(f" | ||
+ | case 9 | 10: | ||
+ | print(f" | ||
+ | case _: # if none of the above matches. Sort of ‘else’ | ||
+ | print(f" | ||
+ | for i in range(0, 12): # get numbers between 0 and 11 | ||
+ | check_number(i)** | ||
+ | |||
+ | def check_number(number): | ||
+ | match number: | ||
+ | case 1 | 2 | 3 | 4 | 5: | ||
+ | print(f" | ||
+ | case 6 | 7 | 8: | ||
+ | print(f" | ||
+ | case 9 | 10: | ||
+ | print(f" | ||
+ | case _: # si aucune correspondance au-dessus. Un peu comme ‘else’ | ||
+ | print(f" | ||
+ | for i in range(0, 12): # obtenir les chiffres de 0 à 11 | ||
+ | check_number(i) | ||
+ | |||
+ | // €ncart page 26 en bas : // | ||
+ | |||
+ | **if 1 <= number <= 5: | ||
+ | print(" | ||
+ | elif 6 <= number <= 8: | ||
+ | print(" | ||
+ | elif number == 9 or number == 10: | ||
+ | print(" | ||
+ | else: | ||
+ | print(" | ||
+ | |||
+ | if 1 <= number <= 5: | ||
+ | print(" | ||
+ | elif 6 <= number <= 8: | ||
+ | print(" | ||
+ | elif number == 9 or number == 10: | ||
+ | print(" | ||
+ | else: | ||
+ | print(" | ||
+ | |||
+ | |||
+ | // Encart de la page 27 en haut à gauche : // | ||
+ | |||
+ | **global game_objects, | ||
+ | < | ||
+ | ' | ||
+ | possessions = ['bag of stuff' | ||
+ | |||
+ | global game_objects, | ||
+ | < | ||
+ | ' | ||
+ | possessions = ['Sac d' | ||
+ | |||
+ | |||
+ | // Encart de la page 27 en haut à droite : // | ||
+ | **def work_command(command): | ||
+ | global directions, items, monsters, possessions, | ||
+ | game_running | ||
+ | global north_count, | ||
+ | match command.split(): | ||
+ | case[" | ||
+ | print(" | ||
+ | quit_game()** | ||
+ | |||
+ | def work_command(command): | ||
+ | global directions, items, monsters, possessions, | ||
+ | game_running | ||
+ | global north_count, | ||
+ | match command.split(): | ||
+ | case[" | ||
+ | print(" | ||
+ | quit_game() | ||
+ | |||
+ | |||
+ | // Encart de la page 27 au milieu à droite : // | ||
+ | **def work_command(command): | ||
+ | match command.split(): | ||
+ | case ' | ||
+ | direction: | ||
+ | match direction: | ||
+ | case ' | ||
+ | print(' | ||
+ | case ' | ||
+ | print(' | ||
+ | case ' | ||
+ | print(' | ||
+ | case ' | ||
+ | print(' | ||
+ | case ' | ||
+ | print(f' | ||
+ | |||
+ | def work_command(command): | ||
+ | match command.split(): | ||
+ | case ' | ||
+ | direction: | ||
+ | match direction: | ||
+ | case ' | ||
+ | print(' | ||
+ | case ' | ||
+ | print(' | ||
+ | case ' | ||
+ | print(' | ||
+ | case ' | ||
+ | print(' | ||
+ | case ' | ||
+ | print(f' | ||
+ | |||
+ | |||
+ | // Encart de la page 27 en bas à gauche : // | ||
+ | **game_running = True | ||
+ | while game_running: | ||
+ | response = input(' | ||
+ | work_command(response)** | ||
+ | |||
+ | game_running = True | ||
+ | while game_running: | ||
+ | response = input(' | ||
+ | work_command(response) | ||
+ | |||
+ | |||
+ | // Encart de la page 28 : // | ||
+ | **case[" | ||
+ | if obj in game_objects: | ||
+ | print(f" | ||
+ | possessions.append(obj) | ||
+ | else: | ||
+ | print(f' | ||
+ | case[" | ||
+ | print(' | ||
+ | message = f'You currently have {len(possessions)-1} object(s) in your bag:' | ||
+ | print(message) | ||
+ | for pos in possessions: | ||
+ | print(f' | ||
+ | {pos}' | ||
+ | print(" | ||
+ | case[" | ||
+ | if obj in game_objects: | ||
+ | print(f" | ||
+ | possessions.append(obj) | ||
+ | else: | ||
+ | print(f' | ||
+ | case[" | ||
+ | print(' | ||
+ | message = f'vous possédez actuellement {len(possessions)-1} objet(s) dans votre sac :' | ||
+ | print(message) | ||
+ | for pos in possessions: | ||
+ | print(f' | ||
+ | {pos}' | ||
+ | print(" |
issue168/python.1619950616.txt.gz · Dernière modification : 2021/05/02 12:16 de auntiee