Afficher avec Python

Identification

Infoforall

2 - Expressions numériques


Cette activité vous présente une première utilisation de Python de façon à effectuer quelques calculs.

Nous allons voir que l'interpréteur Python évalue les ordres qu'on lui transmet en respectant des règles précises.

Nous répondrons notamment à ce problème : comment parvenir à trouver que la case 9 est sur la colonne 1 et la ligne 2 ?

Logiciel nécessaire pour l'activité : Python 3 : Thonny, IDLE ou un site sur lequel on peut faire interpréter du Python

Evaluation : 8 questions

 questions 04-07-11-12-15-16-19

 questions 20

Exercices supplémentaires 🏠 : oui

Documents de cours PDF : .PDF

Sources latex : .TEX, entete.tex et licence.tex

Résumé : Version HTML ou imprimable ou ou PDF (couleur ou gris)

1 - Expression comportant un opérateur

1.1 Expression - Valeur - Opérateur

Une expression caractérise une séquence de valeurs associées à des opérateurs.

L'interpréteur Python évalue l'expression et fournit sa valeur associée. Cette action se nomme une évaluation.

Cas simple :

>>> 4 + 5 9
  • 4 et 5 sont des valeurs.
  • + est un opérateur.
  • 4 + 5 est une expression.
  • 9 est la valeur de l'évaluation.

Les opérations arithmétiques classiques sont représentées de cette façon en Python :

  • + symbolise l'addition
  • - symbolise la soustraction
  • * symbolise la multiplication
  • / symbolise la division
  • ** symbolise la puissance
1.2 DEFINITION : Priorité d'évaluation

L'évaluation d'une expression est séquentielle et progressive  : l'interpréteur Python effectue certaines opérations en priorité.

Voici les règles de priorité que respecte l'interpréteur :

  1. les parenthèses d'abord
  2. ensuite, l'opérateur de puissance **
  3. puis, les opérateurs * /
  4. enfin, les opérateurs + -
  5. En cas d'égalité de priorité : le plus à gauche d'abord.

Exemple

10 + (5 + 3) * 2

10 + 8 * 2

10 + 16

26

Pour vérifier, il suffit de demander poliment à Python de faire le calcul :

>>> 10 + (5 + 3) * 2 26

Exemple 2

5 + 10 / 2 * 3

5 + 5.0 * 3

5 + 15.0

20.0

1.3 Quotient et reste d'une division euclidienne avec // et %

On désigne parfois ces divisions euclidiennes sous le terme de "divisions entières".

A - Rappels sur les divisions euclidiennes

Il s'agit de diviser un nombre a par un nombre b, en trouvant :

  • Le quotient, c'est à dire le nombre de paquets égaux qu'on peut faire en divisant a par b.
  • Le reste, c'est à dire le nombre d'éléments restants après création des paquets.
  • Exemple avec la division euclidienne de 10 par 5 :
  •      10 │ 5
            ├────
    reste 02
    

    Le quotient vaut 2 et le reste vaut 0.

    On remarquera qu'on peut également le justifier en écrivant 10 = 2*5 + 0

B - Opérateur Python //

En Python, la syntaxe permettant d'obtenir le quotient de la division entière de 10 par 5 est 10 // 5.

Cela revient à demander à Python "Python, quel est le quotient de la division euclidienne de 10 par 5 ?"

Moins formellement, "Python, combien de paquets de 5 objets peut-on faire avec 10 objets ?"

>>> 10 // 5 2
C - Opérateur Python %

En Python, la syntaxe permettant d'obtenir le reste de la division entière de 10 par 5 est 10 % 5.

Cela revient à demander à Python "Python, quel est le reste de la division euclidienne de 10 par 5 ?"

Moins formellement, "Python, combien va-t-il me rester d'objets en faisant des paquets de 5 objets ?"

>>> 10 % 5 0
D - Quelques autres exemples
  1. Division entière de 11 par 5
  2. Voici la division posée :

         11 │ 5
            ├────
    reste 12
    

    On peut également le justifier en écrivant 11 = 2*5 + 1

    Et voici pour Python :

    >>> 11 // 5 2 >>> 11 % 5 1
  3. Division entière de 13 par 5
  4. Voici la division posée :

         13 │ 5
            ├────
    reste 32
    

    On peut également le justifier en écrivant 13 = 2*5 + 3

    Et voici pour Python :

    >>> 13 // 5 2 >>> 13 % 5 3
  5. Division entière de 14 par 3
  6. Voici la division posée :

         14 │ 3
            ├────
    reste 24
    

    On peut également le justifier en écrivant 14 = 4*3 + 2

    Et voici pour Python :

    >>> 14 // 3 4 >>> 14 % 3 2
E - Priorité

L'opérateur // et l'opérateur % possèdent la même priorité que la multiplication ou la division.

Lorsque les deux sont présents, c'est donc l'ordre d'apparition qui tient lui de priorité. Attention, ils ne sont pas interchangeables.

>>> 1407 % 5 // 2 1 >>> 1407 // 2 % 5 3

Pourquoi ? Voici la décomposition des deux évaluations précédentes.

Déroulé de la première évaluation : 1407 % 5 // 2

1407 % 5 // 2

2 // 2

1

Déroulé de la première évaluation : 1407 // 2 % 5

1407 // 2 % 5

703 % 5

3

Vous avez vu plusieurs lignes de calcul possédant des espacements. Ceux-ci ne sont pas positionnés au hasard :

Ecrire un code clair 1 : les espaces dans les expressions

Lorsqu'une expression ne contient que des opérateurs ayant la même priorité, on laisse un espace entre les différentes termes :

Expressions correctement écrites : >>> 25 % 10 >>> 25 + 10 - 5 Expressions posant des problèmes de lecture : >>> 25%10 >>> 25+10+5

Lorsqu'une expression ne contient que des opérateurs ayant des priorités différentes, on ne place pas d'espace sur les opérateurs prioritaires :

Expressions correctement écrites : >>> 10 + 25*5 >>> 25/10 - 5 Expressions posant des problèmes de lecture : >>> 10+25*5 >>> 10 + 25 * 5 >>> 25/10-5 >>> 25 / 10 - 5

S'il faut des parenthèses, on ne rajoute pas d'espace au début ou à la fin de l'expression située dans les parenthèses.

L'expression dans la parenthèse est prioritaire sur la multiplication. Cette fois, on ne placera donc pas d'espace entre le + mais on en place autour du * :

Expressions correctement écrites : >>>(25 + 5) * 5 >>> (4 + 5) * (12 + 55) Expressions posant des problèmes de lecture : >>> (25+5)*5 >>> ( 25 + 5 ) * 5 >>> ( 25+5 ) * 5

Et pour les cas plus complexes ? On fait appel à son bon sens !

⚙ 01 (exercice)° Tapez ceci dans la console interactive puis répondre aux questions.

>>> 5 * 10 ??? >>> 15 - 4 ???

Questions

  1. Quelles sont les valeurs utilisées dans la deuxième expression ?
  2. Quelle est l'évaluation produite par la deuxième expression ?
  3. Quel est le symbole de l'opérateur de la deuxième expression ?
  4. Quelle est la signification de ce symbole en Python manifestement (sa sémantique) ?

...CORRECTION 1...

  1. Quelles sont les valeurs utilisées dans la deuxième expression ?
  2. Les valeurs de la première expression sont 15 et 4

  3. Quelle est l'évaluation produite par la deuxième expression ?
  4. "Evaluer" veut dire fournir la valeur attribuée à l'expression. Ici 15-4 donne simplement 9

  5. Quel est le symbole de l'opérateur de la deuxième expression ?
  6. Le seul opérateur de la deuxième expression est -.

  7. Quelle est la signification de ce symbole en Python manifestement (sa sémantique) ?
  8. Cet opérateur permet de demander à Python de réaliser la soustraction de ces deux valeurs.

⚙ 02-A (exercice)° Donner, de tête, la valeur que va fournir Python en évaluant ces expressions. Vérifier ensuite en évaluant dans la console.

>>> 9*9 + 2 ? >>> 2 + 9*9 ?

...CORRECTION 2A...

Pour comprendre ce calcul, il faut se souvenir que l'opérateur multiplication * est prioritaire sur l'opérateur addition +.

L'ordinateur va ainsi évaluer votre calcul progressivement, étape par étape :

>>> 9*9 + 2 >>> (9*9) + 2 >>> 81 + 2 83

Ca ne change rien pour le second du coup, les priorités sont les mêmes :

>>> 2 + 9*9 >>> 2 + (9*9) >>> 2 + 81 83

⚙ 02-B (exercice)° Donner, de tête, la valeur que va fournir Python en évaluant ces expressions. Vérifier ensuite en évaluant dans la console.

>>> 12 - 2*0.2 ? >>> 3*0.1 + 12 ?

...CORRECTION 2B...

Même principe : l'opérateur multiplication * est prioritaire sur l'opérateur soustraction -.

L'ordinateur va ainsi évaluer votre calcul progressivement, étape par étape :

>>> 12 - 2*0.2 >>> 12 - (2*0.2) >>> 12 - 0.4 11.6

Les priorités sont les mêmes mais comme on commence à gauche par *, mettre les parenthèses ou pas ne changent rien au résultat final sur ce cas particulier :

>>> 3*0.1 + 12 >>> (3*0.1) + 12 >>> 0.3 + 12 12.3

⚙ 03 (exercice)° Evaluer de tête ces deux expressions. Donnent-elles le même résultat ?

>>> 3 + 2*3 + 2 ? >>> (3+2) * (3+2) ?

...CORRECTION...

L'ordinateur évalue ainsi la première expression :

>>> 3 + 2*3 + 2 >>> 3 + (2*3) + 2 >>> 3 + 6 + 2 >>> (3 + 6) + 2 >>> 9 + 2 11

Pour la deuxième expression, on respecte juste les parenthèses :

>>> (3+2) * (3+2) >>> 5 * (3+2) >>> 5 * 5 25

✎ 04 (rédaction)° Pour chaque cas, poser la division puis expliquer la réponse fournie par Python : reste ou quotient ? Vérifier votre réponse en tapant l'expression dans la console.

>>> 12 // 5 ? >>> 12 % 5 ? >>> 12 // 9 ? >>> 12 % 9 ? >>> 7 // 2 ? >>> 7 % 2 ? >>> 380 % 360 ?

⚙ 05 (exercice)° Vous voulez acheter des paquets de gâteaux. Un paquet coûte 12 euros. Vous avez 100 euros sur vous :

  1. Ecrire le calcul à demander à l'interpréteur pour savoir combien de paquets vous pouvez acheter avec 100 euros.
  2. Ecrire le calcul à demander à l'interpréteur pour savoir combien d'euros il va vous rester après cet achat.

...Correction...

On trouve le résultat avec deux lignes.

"Python, combien de paquets puis-je acheté ?"

>>> 100 // 12 8

"Python, combien va-il me rester ?"

>>> 100 % 12 4

On peut donc acheter 8 paquets et il nous restera 4 euros.

Cela revient à dire que 100 = 8*12 + 4.

⚙ 06 (question)° Taper les expressions suivantes qui illustrent l'opérateur ** : la puissance.

>>> 3**2 9 >>> 4**2 16 >>> 5**2 25 >>> 10**2 100 >>> 10**3 1000

Question :

Comment peut-on écrire 10**6 uniquement en utilisant des multiplications ?

...Correction...

10**6 = 10 * 10 * 10 * 10 * 10 * 10

✎ 07 (rédaction)° Utiliser la console pour calculer les résultats des puissances de 2 suivantes (sans noter les résultats pour le moment) :

>>> 2**2 ? >>> 2**3 ? >>> 2**4 ? >>> 2**5 ? >>> 2**6 ? >>> 2**7 ?

Compléter ensuite sur votre copie le tableau suivant que vous devez impérativement connaitre parfaitement désormais :

Avec exposant : 27 26 26 25 24 23 22 21 20 Valeur obtenue : 128 64 ? ? ? ? ? ? ?

Remarque

On peut donc calculer 27 de deux façons, l'une étant plus facile que l'autre :

>>> 2**7 ? >>> 2*2*2*2*2*2*2 ?

✎ 08 (rédaction)° On considère l'expression suivante : 5**2*5**2.

Question

  1. Réaliser sur papier l'évaluation de cette expression en expliquant clairement les étapes successives.
  2. Vérifier votre résultat sur la console Python.
  3. Ecrire l'expression de façon plus claire en utilisant des espaces de façon pertinente.

...correction...

>>> 5**2*5**2 >>> (5**2)*(5**2) >>> 25*25 625

La puissance étant prioritaire, nous aurions dû écrire l'expression sous cette forme plus claire :

>>> 5**2 * 5**2

On notera bien que 2**5 veut dire 25, ce qui correspond à 2*2*2*2*2 et pas 2*5.

De la même façon,

  • 10**1 veut dire 101, ce qui correspond à 10
  • 10**2 veut dire 102, ce qui correspond à 10*10
  • 10**3 veut dire 103, ce qui correspond à 10*10*10
  • 10**4 veut dire 104, ce qui correspond à 10*10*10*10

2 - Application à la résolution de problèmes

A quoi peut bien servir ce que nous venons de voir aujourd'hui, notamment la division euclidienne et le modulo ?

La programmation consiste en partie à faire une traduction : comment faire comprendre à l'interpréteur Python ce qu'on veut faire en utilisant son langage.

2.1 - Trouver le chiffre des centaines ou des dizaines...

Imaginons un ensemble de taxis identifiés par un nombre entre 0000 et 9999. Un témoin sait qu'un suspect a pris un taxi dont la dizaine est 4. Pour identifier informatiquementles taxis potentiels, il faut savoir poser la question sous cette forme à l'interpréteur Python : "Quel est le chiffre de la dizaine du taxi ?"

Imaginons par exemple que vous vouliez trouver le chiffre de la dizaine dans 2004. C'est 0 bien entendu. Ok. Mais comment demander à Python de nous répondre 0 sur ce cas ?

Il n'existe pas d'opérateurs basiques pour faire cela... Il va falloir composer avec ce qu'on sait demander à Python pour l'instant : + - * / // % **...

2.1 - Extraire le chiffre de l'unité, de la dizaine et de la centaine

Description du problème
  • Entrée du problème : un nombre ENTIER M positif ( exemple d'entrée : M =  1234 )
  • Nombre M = 1 2 3 4
    La case code 1000
    millier
    100
    centaine
    10
    dizaine
    1
    unité
  • Sortie du problème : en fonction du chiffré demandé :
    • le chiffre de la centaine c (avec l'exemple c =  2 ) ;
    • le chiffre de la dizaine d (avec l'exemple d =  3 ) ;
    • le chiffre de l'unité u (avec l'exemple u =  4 ) .
Chiffre de l'unité

Il suffit de faire une division euclidienne par 10 et de récupérer le reste.

Exemples :

>>> 1234 % 10 4 >>> 489 % 10 9
Chiffre des dizaines

Il suffit de diviser le nombre par 10. Le chiffre de la dizaine se retrouve alors à la position de l'unité.

Pour récupérer ce chiffre, il suffit donc de faire une deuxième division euclidienne par 10 et de récupérer le reste.

Exemples :

# En deux étapes >>> 1234 // 10 123 >>> 123 % 10 3 # En une étape avec parenthèses >>> (1234 // 10) % 10 3

Puisque les opérateurs // et % ont la même priorité, on peut donc juste écrire 

# En une étape >>> 1234 // 10 % 10 3
Chiffre des centaines

Il suffit de diviser le nombre par 100. Le chiffre de la centaine se retrouve alors à la position de l'unité.

Il suffit de faire une deuxième division euclidienne par 10 et de récupérer le reste.

Exemples :

# En deux étapes >>> 1234 // 100 12 >>> 12 % 10 2 # En une étape >>> 1234 // 100 % 10 2

⚙ 09 (exercice)° Compléter le code pour que la variable dizaine référence la dizaine de l'année stockée dans la variable a (quelque soit le contenu de a, ne placez pas juste 1 !).

Exemple

>>> a = 2018 >>> dizaine = a... (à compléter) >>> dizaine 1

...CORRECTION...

>>> a = 2018 >>> dizaine = a // 10 % 10 >>> dizaine 1

⚙ 10 (exercice)° Compléter le code pour que la variable centaine référence la centaine de l'année stockée dans la variable a (quelque soit le contenu de a).

Exemple

>>> a = 2018 >>> centaine = a... (à compléter) >>> centaine 0

...CORRECTION...

>>> a = 2018 >>> centaine = a // 100 % 10 >>> centaine 0

✎ 11 (rédaction)° Voici un court programme.

  1. Exécuter d'abord mentalement le programme.
  2. Ecrire ensuite les lignes suivies par l'interpréteur en écrivant clairement les contenus finaux des deux variables test1 et test2.
  3. Finir en exécutant réellement le programme (avec la flèche verte) et en vérifant (via la console interactive) le contenu des deux variables.
1 2 3 4 5 6 7
def centaine(n): """Renvoie le chiffre des centaines du nombre reçu""" return n // 100 % 10 test1 = centaine(2470) test2 = centaine(78126)

Vérification via la console :

>>> test1 4 >>> test2 1

...CORRECTION...

L1 (déclaration de fonction)

L6 (appel en envoyant 2470) - L1 - L3 (envoi de 4) - L6(réception de 4 et test1 référence donc 4)

L7 (appel en envoyant 78126) - L1 - L3 (envoi de 1) - L7(réception de 1 et test2 référence donc 1) - fin

✎ 12 (rédaction)° On s'intéresse à un jeu de dés qui consiste à lancer 3 dés et à compter les points obtenus d'une certain façon que vous allez devoir découvrir. Pour représenter les valeurs obtenus sur un jet de dés, on utilise un simple nombre composé de 3 chiffres allant de 1 à 6 : 426 voudrait ainsi dire que le dé de gauche à donner 4, celui du milieu 2 et celui de gdroite 6.

  1. Exécuter mentalement le programme.
  2. Ecrire ensuite les lignes suivies par l'interpréteur en écrivant clairement les contenus finaux des deux variables jet1 et jet2.
  3. Exécuter réellement le programme (avec la flèche verte) et vérifier (via la console interactive) le contenu des deux variables.
  4. Expliquer briévement en français comment on compte les points sur ce jeu.
1 2 3 4 5 6 7 8 9 10 11 12 13
def points(n): """Calculer les points attribués à un jet de dés""" gauche = n // 100 % 10 milieu = n // 10 % 10 droite = n % 10 somme = gauche + milieu + droite if gauche == droite: somme = somme * 2 return somme jet1 = points_du_jet(623) jet2 = points_du_jet(434)

...CORRECTION...

L1 (déclaration de fonction)

L12 (appel en envoyant 623) - L1 - L4 (stockage de 6) - L5 (stockage de 2) - L6 (stockage de 3) - L7 (somme référence 11) - L8 (condition fausse) - L10 (envoi de 11) - L12 (réception de 11 et jet1 référence donc 11)

L13 (appel en envoyant 414) - L1 - L4 (stockage de 4) - L5 (stockage de 1) - L6 (stockage de 4) - L7 (somme référence 9) - L8 (condition vrai) - L9 (somme référence 18) - L10 (envoi de 18) - L12 (réception de 18 et jet2 référence donc 18) - fin

2.2 Position d'une case sur un plateau

2.2 - Position d'une case sur un plateau de jeu

2.2.A - Description du plateau

Imaginons qu'on dispose d'un plateau de jeu de 4 cases sur 4 cases. Les cases sont numérotées de 0 à 15, comme indiqué ci-dessous :

La ligne du haut porte le numéro 0, la ligne du dessous le numéro 1...

La colonne de gauche porte le numéro 0 puis les autres 1, 2 et 3.

2.2.B - Numéro de ligne

Comment trouver le numéro de ligne d'une case dont on connaît le numéro ?

Il y a 4 cases par ligne.0-1-2-3 pour la ligne 0, 4-5-6-7 pour la ligne 1, 8-9-10-11 pour la ligne 2. ...,

Il suffit de récupérer le quotient de la division euclidienne du numéro de la case par 4.

>>> 3 // 4 0 >>> 4 // 4 1 >>> 7 // 4 1 >>> 8 // 4 2
2.2.C - Numéro de colonne

Comment trouver le numéro de colonne d'une case dont on connaît le numéro ?

Il y a 4 cases par ligne et les cases commencent à 0.

On part d'une case de la première ligne puis on rajoute des multiples de 4 : la colonne 0 est constituée des cases 0-4-8-12, la colonne 1 par 1-5-9-13, la colonne 2 par 2-6-10-14...

Il suffit de récupérer le reste de la division euclidienne du numéro de la case par 4.

>>> 3 % 4 3 >>> 4 % 4 0 >>> 7 % 4 3 >>> 8 % 4 0

⚙ 13 (exercice)° Quel calcul faire pour obtenir le numéro de colonne de la case n°9 ?

...Correction...

9 % 4

⚙ 14 (exercice)° Quel calcul faire pour obtenir le numéro de ligne de la case n°9 ?

...Correction...

9 // 4

✎ 15 (rédaction)° Comment trouver la colonne de la case 117 d'un plateau de jeu comportant 34 cases par ligne ?

✎ 16 (rédaction, difficile)° On considère un plateau comportant 42 cases par ligne. Un monstre est dans la case 1432 et un héros dans la case 1417. Les deux sont-ils adjacents, c'est à dire sur deux cases situées directement l'une à côté de l'autre dans le plateau ?

3 - Interface graphique : interface Homme-Machine

Vous allez découvrir une première interface graphique construite en utilisant Python et dans la partie suivante nous verrons à quoi peuvent servir les opérateurs quotient et reste sur ce type de programmes.

J'en présente deux au choix :

  1. Pyxel : un module d'interface graphique qui permet de créer "facilement" de petits jeux vidéos de type retro (gros pixels, musiques des années 80...)
  2. Tkinter : un module intégré de base à Python qui permet de créer des interfaces graphiques plus sérieuses.

A vous de choisir.

Choisir votre module graphique pour la suite :
3 Principe d'un programme pyxel

Logo Pyxel
Logo Pyxel

Le principe de fonctionnement d'un programme utilisant le module pyxel est basé sur une séquence qui inclut une boucle infinie.

Principe de fonctionnement

    1 - La fonction init() crée la fenêtre graphique.

    2 - La fonction run() active l'alternance infinie ci dessous :

    3 - TANT QUE le programme est actif :

      On mémorise les actions de l'utilisateur

      SI la dernière activation date de 1/30e de seconde

        On active la fonction controleur() qui mettra les données à jour en fonction des événements détéctés.

        On active la fonction vue() qui effacera l'écran avec cls() puis générera le nouvel affichage.

      Fin du SI

    Fin TANT QUE

La structure usuelle du code Python pour ce module
1 2 3 4 5 6 7 8 9 10 11 12 13
import pyxel def controleur(): """Récupère l'événement et le gère les données (30 fois par seconde)""" ... # A modifier def vue(): """création des objets (30 fois par seconde)""" pyxel.cls(0) # vide la fenetre ... # A modifier pyxel.init(128, 128, title="Mon premier jeu") pyxel.run(controleur, vue)
Système d'axes

Le point (0,0) est le bord haut gauche.

L'abscisse va bien vers la gauche.

Par contre, l'ordonnée est orientée vers le bas, attention.

Les axes dans Pyxel

✔ 17 (action, pyxel)° Vérifier si le module pyxel est installé :

>>> import pyxel

Si cela ne fonctionne pas :

Installer la bibliothèque pyxel dans Thonny :

  • Allez dans l'onglet "Outils"
  • Cherchez "Gérer les paquets"
  • Lancez la recherche sur pyxel puis activer l'installation
  • Attendez que l'installation soit totalement effectuée
  • Validez l'installation en utilisant le bouton Fermer

Si le module n'est pas installé et que vous ne parvenez pas à le rajouter sur votre ordinateur, pas de panique. Vous pouvez utiliser des solutions en ligne comme pyxel studio mais c'est bien plus lent qu'avec une installation directe.

⚙ 18 (exercice, pyxel)° Une fois le module installé,

  1. placer en mémoire et lancer le programme suivant;
  2. Vérifier que vous parvenez à faire bouger le vaisseau à l'aide des touches flèches gauche et droite du clavier.
  3. L'analyse total du programme sera réalisée dans quelques activités. Pour l'instant, vous n'allez avoir besoin que de survoler quelques unes des lignes.

  4. Lignes 32-35 : qu'envoie-t-on à la fonction calculer_x() lorsqu'on appuie sur la flèche DROITE ?
  5. Ligne 13 : comment se nomment les deux variables qui vont recevoir ces deux valeurs dans calculer_x() lors de l'appel ?
  6. Lignes 13-21 : Pourquoi le vaisseau ne peut-il pas sortir totalement de l'écran ?
  7. Modifier la fonction calculer_x() pour que le vaisseau soit bien bloqué dès que son coin droit touche l'écran à droite : pour l'instant, il sort un peu trop...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
import pyxel # Importation des données et fonctions du module pyxel # NE PAS LIRE CETTE PARTIE : elle n'est pas expliquée aujourd'hui data = {'x': 100, 'y': 50} # Dictionnaire stockant les données du modèle def lire_colonne(): return data['x'] # on renvoie la valeur associée à la clé "y" def lire_ligne(): return data['y'] # on renvoie la valeur associée à la clé "y" def ecrire_colonne(x): data['x'] = x # on modifie la valeur associée à la clé "x" # Définitions des fonctions : PARTIE A LIRE def calculer_x(x, dx): """Renvoie la nouvelle valeur qu'on veut attribuer à x""" x = x + dx if x > 128: x = 127 if x < 0: x = 0 return x def controleur(): """Récupère l'événement et le gère les données (30 fois par seconde)""" if pyxel.btn(pyxel.KEY_LEFT): # Si il y a un appui sur la flèche gauche x = lire_colonne() # on lit la valeur de x depuis le modèle x = calculer_x(x, -1) # on calcule la nouvelle valeur de x ecrire_colonne(x) # on enregistre cette valeur dans le modele if pyxel.btn(pyxel.KEY_RIGHT): # Si il y a un appui sur la flèche droite x = lire_colonne() # on lit la valeur de x depuis le modèle x = calculer_x(x, 1) # on calcule la nouvelle valeur de x ecrire_colonne(x) # on enregistre cette valeur dans le modele def vue(): """création des objets (30 fois par seconde)""" pyxel.cls(0) # vide la fenetre x = lire_colonne() # on lit la valeur de x depuis le modèle y = lire_ligne() # on lit la valeur de y depuis le modèle pyxel.rect(x, y, 8, 8, 1) # carré 8x8 en couleur 1 et placé en (x,y) # Le programme en lui-même ecrire_colonne(100) # on place le vaisseau sur le pixel 100 dans le modèle pyxel.init(128, 128, title="Mon premier jeu") pyxel.run(controleur, vue)

...Correction...

  1. On regarde les lignes 32-34
  2. 32 33 34
    if pyxel.btn(pyxel.KEY_RIGHT): # Si il y a un appui sur la flèche droite x = lire_colonne() # on lit la valeur de x depuis le modèle x = calculer_x(x, 1) # on calcule la nouvelle valeur de x

    Si on appuie sur DROITE, on envoie x et 1.

  3. On ne sort pas de l'écran à cause des lignes 17-20 : si x devient trop grand, on le fixe à 127, s'il devient trop petit, on le fixe à 0 :
  4. 17 18 19 22
    if x > 128: x = 127 if x < 0: x = 0
  5. Il suffit de remplacer la limite fixée à 127 sur les lignes 19-20 à une valeur plus faible, 120 par exemple.
3.4 Principe d'un programme tkinter

Le principe de fonctionnement d'un programme utilisant le module tkinter est basé sur la séquence suivante qui inclut une boucle infinie :

    1 - La fonction Tk() crée la fenêtre graphique.

    2 - La méthode bind() permet de faire le lien entre un événement et une fonction de contrôle controle_...() de l'événement

    3 - La méthode mainloop() lance la surveillance en boucle des événements

    4 - TANT QUE le programme est actif :

      SI l'utilisateur appuie sur une touche, on active la fonction controle_...() correspondante qui va

        D'abord déterminer comment faire appel aux fonctions maj_...() pour modifier les modèles

        Ensuite demander à modifier l'affichage (la vue) en faisant appel à vue() qui va

        faire appel à delete() pour effacer l'écran

        faire appel à des fonctions afficher_...() pour afficher des formes à l'écran

      Fin du SI

    Fin TANT QUE

On peut résumer cela en 

  • Séquence de réglage : bind() puis mainloop()
  • Dès qu'un événement survient : controle_...() puis vue()

✔ 17 (action, tkinter)° Vérifier si le module tkinter est installé :

>>> import tkinter

Si cela ne fonctionne pas :

Installer la bibliothèque pyxel dans Thonny :

  • Allez dans l'onglet "Outils"
  • Cherchez "Gérer les paquets"
  • Lancez la recherche sur tkinter puis activer l'installation
  • Attendez que l'installation soit totalement effectuée
  • Validez l'installation en utilisant le bouton Fermer

⚙ 18 (exercice, tkinter)° Une fois le module installé,

  1. placer en mémoire et lancer le programme suivant;
  2. Vérifier que vous parvenez à faire bouger le vaisseau à l'aide des touches flèches gauche et droite du clavier.
  3. L'analyse total du programme sera réalisée dans quelques activités. Pour l'instant, vous n'allez avoir besoin que de survoler quelques unes des lignes.

  4. Lignes 32-35 : qu'envoie-t-on à la fonction calculer_x() lorsqu'on appuie sur la flèche DROITE ?
  5. Ligne 14 : comment se nomment les deux variables qui vont recevoir ces deux valeurs dans calculer_x() lors de l'appel ?
  6. Lignes 14-22 : Pourquoi le vaisseau ne peut-il pas sortir totalement de l'écran ?
  7. Modifier la fonction calculer_x() pour que le vaisseau soit bien bloqué dès que son coin droit touche l'écran à droite : pour l'instant, il sort un peu trop...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
from tkinter import Tk # pour créer la fenetre de jeu from tkinter import Canvas # pour créer la zone de dessin # NE PAS LIRE CETTE PARTIE : elle n'est pas expliquée aujourd'hui data = {'x': 100, 'y': 50} # Dictionnaire stockant les données du modèle def lire_colonne(): return data['x'] # on renvoie la valeur associée à la clé "y" def lire_ligne(): return data['y'] # on renvoie la valeur associée à la clé "y" def ecrire_colonne(x): data['x'] = x # on modifie la valeur associée à la clé "x" # Définitions des fonctions : PARTIE A LIRE def calculer_x(x, dx): """Renvoie la nouvelle valeur qu'on veut attribuer à x""" x = x + dx if x > 500: x = 499 if x < 0: x = 0 return x def controleur(evenement): """Fonction qui récupère l'action, modifie le modèle puis appelle la vue""" touche = evenement.keysym # touche utilisée (Left, Right, Up, Left) if touche == "Left": # Si l'utilisateur appuie sur FLECHE LEFT x = lire_colonne() # on lit la valeur de x depuis le modèle x = calculer_x(x, -1) # on calcule la nouvelle valeur de x ecrire_colonne(x) # on enregistre cette valeur dans le modele if touche == "Right": x = lire_colonne() # on lit la valeur de x depuis le modèle x = calculer_x(x, 1) # on calcule la nouvelle valeur de x ecrire_colonne(x) # on enregistre cette valeur dans le modele vue() def vue(): """Efface puis dessine la nouvelle vue""" plateau.delete("all") # Efface les dessins dans le canvas x = lire_colonne() # on lit la valeur de x depuis le modèle y = lire_ligne() # on lit la valeur de y depuis le modèle plateau.create_rectangle(x, y, x+20, y+20, fill="blue", width=0) # Le programme en lui-même fenetre = Tk() # Référence de la fenètre graphique fenetre.title("Mon premier jeu") fenetre.geometry("600x600") plateau = Canvas(fenetre) # Référence de la zone du plateau de jeu plateau.configure(width=500) plateau.configure(height=500) plateau.configure(bg="ivory") plateau.place(x=50, y=50) vue() # Dessine le vaisseau à la position initiale fenetre.bind("<Any-KeyPress>", controleur) # Lie le clavier à la fonction fournie fenetre.mainloop() # Lance la surveillance des événements

...Correction...

  1. On regarde les lignes 35-37
  2. 35 36 37
    if touche == "Right": x = lire_colonne() # on lit la valeur de x depuis le modèle x = calculer_x(x, 1) # on calcule la nouvelle valeur de x

    Si on appuie sur DROITE, on envoie x et 1.

  3. On ne sort pas de l'écran à cause des lignes 18-21 : si x devient trop grand, on le fixe à 499, s'il devient trop petit, on le fixe à 0 :
  4. 18 19 20 21
    if x > 500: x = 499 if x < 0: x = 0
  5. Il suffit de remplacer la limite fixée à 499 sur les lignes 18-19 à une valeur plus faible, 490 par exemple.

4 - Résolution à l'aide d'une simple division euclidienne

Choisir votre module graphique pour la suite :

✎ 19 (rédaction, pyxel)° Notre fenêtre d'application graphique comporte un écran de 128 sur 128 pixels.

Question

Modifier la fonction calculer_x() pour que le vaisseau apparaisse à droite lorsqu'on va trop loin à gauche et à gauche lorsqu'on va trop loin à droite.

Vous proposerez une solution qui utilisera des if pour modifier x

...avec un if...

11 12 13 14 15 16 17 18 19 20 21 22 23
... def calculer_x(x, dx): """Renvoie la nouvelle valeur qu'on veut attribuer à x""" x = x + dx if x > 124: x = 0 if x < 0: x = 121 return x ...

✎ 20 (rédaction, pyxel)° Modifier la fonction : on ne veut plus de if mais juste une division euclidienne.

...avec %...

12 13 14 15 16 17 18 19 20 21
... def calculer_x(x, dx): """Renvoie la nouvelle valeur qu'on veut attribuer à x""" x = x + dx x = x % 128 return x ...

✎ 19 (rédaction, tkinter)° Notre fenêtre d'application graphique comporte un écran de 500 sur 500.

Question

Modifier la fonction calculer_x() pour que le vaisseau apparaisse à droite lorsqu'on va trop loin à gauche et à gauche lorsqu'on va trop loin à droite.

Vous proposerez une solution qui utilisera des if pour modifier x

...avec un if...

12 13 14 15 16 17 18 19 20 21 22 23 24
... def calculer_x(x, dx): """Renvoie la nouvelle valeur qu'on veut attribuer à x""" x = x + dx if x > 481: x = 0 if x < 0: x = 480 return x ...

✎ 20 (rédaction, tkinter)° Modifier la fonction : on ne veut plus de if mais juste une division euclidienne.

...avec %...

12 13 14 15 16 17 18 19 20 21
... def calculer_x(x, dx): """Renvoie la nouvelle valeur qu'on veut attribuer à x""" x = x + dx x = x % 500 return x ...

🏠 Exercices supplémentaires° Réaliser ces exercices en rédigeant correctement vos réponses.

Exercices supplémentaires

5 - FAQ (Frequently Asked Questions)

J'ai vu une erreur sur le site, comment la signaler ?

Utilisez le bouton CONTACT en bas de chaque page.

Notez l'URL de l'activité ou son nom et copiez le texte qui pose problème, si besoin avec une description de ce qu'il faut changer si vous pensez que c'est nécessaire.

Merci !

Voici pour ce premier contact avec la console de Python.

Pour la plupart des activités, vous trouverez un récapitulatif des notions à connaître. Il ne s'agit d'un ensemble de questions auxquelles il faudra savoir répondre si vous voulez une bonne note.

Le résumé de l'activité regroupe lui l'ensemble des points de cours, les encarts verts .

LIEN VERS LES RECAPITULATIFS

LIEN VERS LES RESUMES

Activité publiée le 28 08 2019
Dernière modification : 15 07 2023
Auteur : ows. h.