Infoforall

Python 08 : TEST LOGIQUE SI ET BOUCLE FOR NUMERIQUE

Nous allons aujourd'hui apprendre à réaliser une interface sans avoir à coder un à un tous les widgets.

Les 16 carrés en tri de couleur

Comment ? Assez simplement : les langages de programmation ont la possibilité de faire des tests logiques SI qui permettent d'exécuter un code sous condition et des boucles POUR qui permettent d'effectuer plusieurs fois les mêmes instructions.

A titre d'exemple, voici une animation qui vous propose deux boutons : GAUCHE permet d'aller à gauche et DROITE permet d'aller ... à droite.

Oui mais que faire si on demande d'aller à droite alors qu'on est déjà au bout du rectangle ? Il faut refuser d'avancer. Le script fait donc bien un choix logique IF en fonction de la position x du cercle au moment où le mouvement doit avoir lieu.

En françaisCodage Python
SI on peut encore aller à droite alorsif (x < xmax) :
    Autoriser le déplacement à droite    Autoriser_droite()
SINON SI on peut encore aller à gauche alorselif (x > xmin) :
    Autoriser le déplacement à gauche    Autoriser_gauche()
Fin du test


X actuelle = 250
X minimale = 150
X maximale = 350
avec un test X > XMIN valant
avec un test X < XMAX valant

En introduction, voilà le codage de différents test de conditions logiques entre deux variables :

Vous pouvez toucher aux curseurs pour voir l'évolution des différentes réponses.

A = 50
B = 50
Symbole du testSignificationExempleResultat du test
==Est égal àA == B?
!=Est différent deA != B?
>Est supérieur àA > B?
>=Est supérieur ou égal àA >= B?
<Est inférieur àA < B?
<=Est inférieur ou égal àA <= B?

Chacun de ces tests ne peut donner normalement que deux résultats : True pour vrai ou False pour faux.

On notera la présence d'une majuscule en Python : True et False. La plupart des langages utilisent simplement true et false.

Deuxième chose importante : la comparaison s'écrit avec deux signes =, pas un seul ! Il va falloir faire attention.

1 - L’instruction conditionnelle SI – SINON

Commençons par voir comment choisir une action en fonction d’une entrée.

01° Voici un programme qui nous permet de lire un nombre rentré au clavier puis de dire s’il est positif, négatif ou nul. Tester le code. A quoi sert la ligne nombre = int(nombre) ?

#!/usr/bin/env python

# -*-coding:Utf-8 -*


# Acquisition des données

nombre = input("Quel est votre nombre ? ")


# Traitement des données

nombre = int(nombre)

if nombre > 0 :

    print("Le nombre est positif")

    print("Ok")

elif nombre < 0 :

    print("Le nombre est négatif")

else :

    print("Le nombre est nul")


# Preparation de l’arret

input("pause")

CLIQUEZ SUR UN BOUTON-REPONSE :

nombre :

Remarque : Le copier-coller Explorateur vers Interpréteur est un peu problématique ici : il crée un espace entre chaque ligne ! Plutôt que de les enlever une à une, vous pouvez aller dans le menu EDITION - Lignes - Enlever les lignes vides. Ca ira plus vite. Pour les tabulations, il faut demander gentiment à Notepad de le faire : EDITION – TRAITEMENT DES ESPACEMENTS – Transformer les espaces en tabulations.

Autre point important : c’est la tabulation (ou 4 espaces) qui permet de savoir qu’une instruction est rattachée au bloc. Il est donc vital de bien tabuler votre code. Dans Notepad++, on peut faire s'afficher les tabulations à l'aide du menu AFFICHAGE - SYMBOLES SPECIAUX - AFFICHER ESPACES ET TABULATIONS

...CORRECTION...

La fonction input renvoie toujours un string.

La fonction int permet donc de convertir le string en entier, si c'est possible.

Comme vous l'avez vu, on ne rentre que dans un des cas disponibles :

Soit :

if nombre > 0 :

    print("Le nombre est positif")

    print("Ok")

Soit :

elif nombre < 0 :

    print("Le nombre est négatif")

Soit :

else :

    print("Le nombre est nul")

Voyons maintenant comment symboliser et expliquer tout ceci.

Description en français : l'action logique qu’on peut traduire en texte par

SI la première condition est vraie alors
    Fait les actions 1
SINON SI la deuxième condition est vraie alors
    Fait les actions 2
SINON
    Fait les actions 3
Fin du test

Représentation graphique : la même action logique sous forme graphique :

Le Si

On voit que la condition est un losange qui possède deux sorties uniquement.

Les instructions sont des rectangles.

Description en code Python : l'action logique se traduit en code par

En françaisCodage Python
SI la première condition est vraie alorsif condition_1 :
    Fait les actions 1    Instructions_1
SINON SI la deuxième condition est vraie alorselif (condition_2) :
    Fait les actions 2    Instructions_2
SINONelse :
    Fait les actions 3    Instructions_3
Fin du testRien sinon le retour à l'indentation de base

On remarquera d’abord qu’on met double point [ : ] après la condition de if, else if (elif en Python) ou else.

Cela permet à l’interpréteur de savoir quand commence la condition à tester (après le if, elif ou else) et quand la condition est définie (au : justement).

02° Compléter le code suivant : il doit demander si oui ou non vous êtes un humain. Il doit répondre "Bonjour humain !" si la réponse est "oui", et "Bonjour robot !" sinon.

#!/usr/bin/env python

# -*-coding:Utf-8 -*


# Acquisition des données

testHumain = input("Etes-vous humain (oui/non) ?")


# Traitement des données

if testHumain == "oui" :

    print("Bonjour humain !")


# Preparation de l’arret

input("pause")

...CORRECTION...

#!/usr/bin/env python

# -*-coding:Utf-8 -*


# Acquisition des données

testHumain = input("Etes-vous humain (oui/non) ?")


# Traitement des données

if testHumain == "oui" :

    print("Bonjour humain !")

else :

    print("Bonjour robot !")


# Preparation de l’arret

input("pause")

03° Tester avec une mauvaise réponse, comme chien ou chat par exemple. Conclusion ?

Voilà : le programme fait ce que vous lui avez demandé, pas ce que vous vouliez.

04° Modifier le programme pour qu'il affiche :

...CORRECTION...

#!/usr/bin/env python

# -*-coding:Utf-8 -*


# Acquisition des données

testHumain = input("Etes-vous humain (oui/non) ?")


# Traitement des données

if testHumain == "oui" :

    print("Bonjour humain !")

elif testHumain == "non" :

    print("Bonjour robot !")

else :

    print("Erreur de saisie")


# Preparation de l’arret

input("pause")

On peut exécuter plusieurs instructions dans le if ou le elif(else if). Python attend simplement le elif ou else suivant et comprend en attendant qu’il s’agit d’un bloc à exécuter si la condition est validée. On peut même imbriquer un bloc if dans un if.

05° Rajouter une demande supplémentaire lorsqu'on rentre dans le cas "humain" : on doit demander "Etes vous un homme ? (oui/non)". Dans ce cas (et uniquement dans ce cas) :

...CORRECTION...

#!/usr/bin/env python

# -*-coding:Utf-8 -*


testHumain = input("Etes-vous humain (oui/non) ?")


if testHumain == "oui" :

    testHomme = input("Etes-vous un homme (oui/non) ?")

    if testHomme == "oui" :

        print("Bonjour monsieur !")

    elif testHumain == "non" :

        print("Bonjour madame !")

    else :

        print("Bonjour humain.")

elif testHumain == "non" :

    print("Bonjour robot !")

else :

    print("Erreur de saisie")


# Preparation de l’arret

input("pause")

Si on analyse le code en terme de blocs imbriqués l'un dans l'autre, on obtient ceci :

if testHumain == "oui" :

    testHomme = input("Etes-vous un homme (oui/non) ?")

if testHomme == "oui" :

    print("Bonjour monsieur !")

elif testHomme == "non" :

    print("Bonjour madame !")

else :

    print("Bonjour humain.")

elif testHumain == "non" :

    print("Bonjour robot !")

else :

    print("Erreur de saisie")

Il reste à tester des conditions doubles. Rappel : une condition renvoie un booléen qui est true (True en Python, avec un T majuscule) ou false (False en Python, avec un F majuscule).

Voici comment :

On peut tester plusieurs conditions à la fois à l’aide des codages suivants :

TEST LOGIQUEEn FrançaisEn Python
andcode ETA and B : Renvoie True si les deux conditions A et B sont True.
orcode OUA or B : Renvoie True si l'une deux conditions au moins est True.
notcode NONnot(A) : Renvoie True si A == False et renvoie False si A == True.

06° Trouver l'affichage obtenu pour une note de 13, de 19 et de 8 à partir du programme ci-dessous.

#!/usr/bin/env python

# -*- coding: utf-8 -*-


a = 17

if a>0 :

    if (a>10 and a<16) :

        print("C'est pas mal comme note.")

        print("Mais avoir plus, c'est mieux !")

    elif a>= 16 :

        print("C'est bien !")

    else :

        print("C'est pas bien !")

else :

    print("Le prof a dû se tromper, votre note est négative. Ou alors ...")

...CORRECTION...

La note de 13 donne "C'est pas mal comme note.".

La note de 19 donne "C'est bien !".

La note de 8 donne "C'est pas bien !".


En analysant la structure des tabulations :

if a>0 :

    if (a>10 and a<16) :

        print("C'est pas mal comme note.")

        print("Mais avoir plus, c'est mieux !")

    elif a>= 16 :

        print("C'est bien !")

    else :

        print("C'est pas bien !")

else :

    print("Le prof a dû se tromper, votre note est négative. Ou alors ...")

La question suivante vous permettra de revoir le tuple dont les caractéres d'ouverture et de fermeture sont les parenthèses.

Le tuple permet d'envoyer un ensemble de données qu'on pourra ensuite récupérer dans différentes variables.

Ici, on crée une variable couleurs qui fait référence au tuple (250,150,200). On parvient ainsi à stocker les 3 intensités R G et B dans une seule variable :

couleurs = (250,150,200)

Pour récupérer ces trois valeurs, il suffit alors d'affecter le contenu du tuple dans trois variables :

r,g,b = couleurs

07° Compléter le code suivant qui doit :

#!/usr/bin/env python

# -*- coding: utf-8 -*-


# Déclaration du tuple (r,g,b) et récupération des valeurs r,g,b

couleurs = (250,150,200)

r,g,b = couleurs


COMPLETER LE CODE ICI


print("La nouvelle valeur de rouge est ",r)

Une correction possible :

...CORRECTION...

#!/usr/bin/env python

# -*- coding: utf-8 -*-


# Déclaration du tuple (r,g,b) et récupération des valeurs r,g,b

couleurs = (250,150,200)

r,g,b = couleurs


# Tests pour savoir si on rajoute 50 ou non

if r>g and r>b :

    r = r+50

    print("L'intensité rouge est la plus grande : elle est plus grande que la verte ET que la bleue.")

elif r>g or r>b :

    print("L'intensité rouge est plus grande qu'au moins une des deux autres.")

    print("Attention, cela peut vouloir dire normalement qu'elle est plus grande que la verte et plus grande que la bleue.")

    print("Par contre, ce cas est traité dans le IF juste au dessus. Si on arrive ici, c'est bien que le rouge n'est supérieur qu'à l'un des deux autres composants.")


# Tests pour gérer les valeurs max et min

if r>255 :

    r = 255

elif r<0 :

    r = 0


print("La nouvelle valeur de rouge est ",r)

Si on analyse le test ET / AND :

a b a and b
VRAI VRAI VRAI
FAUX VRAI FAUX
VRAI FAUX FAUX
FAUX FAUX FAUX

Si on analyse le test OU / OR :

a b a or b
VRAI VRAI VRAI
FAUX VRAI VRAI
VRAI FAUX VRAI
FAUX FAUX FAUX

2 - la boucle itérative POUR (FOR) par itérateur chiffré

On peut utiliser un FOR pour faire une boucle revenant à réaliser les mêmes instructions X fois.

Comment fonctionne une boucle for ? Le cas le plus simple est facile à comprendre : on prend une variable i qui commence à la valeur zéro. On l'augmente de 1 à chaque tour tant qu'elle ne dépasse pas strictement une valeur de seuil iMAX telle que i < iMAX.

Si vous n'êtes pas familier avec le concept, utilisez le script ci-dessous :

Valeur initiale (initialisation) :

On continue tant que i < Valeur de test:

Je vais maintenant vous présenter l’utilisation basique de la fonction range (xmax). On notera toujours la présence du double point et de la tabulation pour montrer clairement où se situent les actions à répéter :

#!/usr/bin/env python

# -*- coding: utf-8 -*-


print("Debut du programme")

for x in range(5) :

    print (x)


input("pause")

CLIQUEZ SUR LE BOUTON-ANIMATION :

x :

08° Quelles sont les différentes valeurs prises par x ? Va-t-on réellement jusqu’à 5 ou s’arrête-t-on juste avant ?

Et oui. On ne compte que jusqu'à 4, on s'arrête avant 5.

Pourquoi ?

Nous verrons plus loin la raison exacte mais si on regarde ce qui est affiché ...

Debut du programme

0

1

2

3

4

... on voit qu'on compte jusqu'à 4 mais qu'on a bien 5 nombres : 0 - 1 - 2 - 3 - 4.

La boucle s'exécute donc tant que x est strictement inférieur à 5.

Regardons comme utiliser ceci dans un cas plutôt simple : on veut faire bouger le point en suivant le trajet. Vous pouvez utiliser les curseurs pour définir :

for i in range(IMAX) :

    va_a_gauche()


for j in range(JMAX) :

    va_en_bas()

A droite : IMAX = 0
En bas : JMAX = 0

...CORRECTION...

Il faut régler IMAX sur 4 pour avoir 4 étapes : 0-1-2-3.

Il faut régler JMAX sur 7 pour avoir 7 étapes : 0-1-2-3-4-5-6.

Il faut donc se souvenir qu'on commence ici avec le compteur à 0 car on note var i = 0.

09° Afficher les chiffres de 0 à 20 avec une boucle.

...CORRECTION...

for x in range(20) :

    print (x)


input("pause")

10° Regarder le code ci-dessous et prévoir ce qu’il va afficher à l’écran. Vérifier en lançant le code.

for i in range(3) :

    print("Cas ",i)

    print (i," x2 =",i*2,"\n")

input("pause")

Voilà ce que devrait afficher l'ordinateur :

Cas 0

0 x2 = 0


Cas 1

1 x2 = 2


Cas 2

2 x2 = 4


pause

Il exécute donc la boucle pour i=0, i=1 et i=2. En gros, tant que i est strictement inférieur à 3.

11° Réaliser un programme ne comprenant qu’une seule boucle FOR qui affiche (pour chaque valeur de x variant de 0 à 6) le carré de x et la puissance trois de x.

Remarque : En Python, la puissance se note ** : Ainsi 6 puissance 2 se note 6**2.

Si on veut que le compteur ne commence pas à 0, il suffit de la préciser dans la fonction : range(2,6) va donc prendre les valeurs 2, 3, 4 et 5.

12° Réaliser un programme qui affiche un à un les nombres compris entre 32 et 127.

Nous avons vu que les images ne sont que des successions de nombres stockés dans le fichier image.

C'est la même chose pour les caractères : l'ordinateur ne stocke pas un caractère mais un nombre : chr(x) permet de connaître le caractère associé au nombre entier x.

13° Réaliser un programme qui affiche un à un les caractères associés aux nombres compris entre 32 et 127 sous la forme :

        Le caractère XXX correspond au code X

Il faudra utiliser une boucle FOR et la fonction chr.

...CORRECTION...

for x in range(32,128) :

    print("Le caractère ",chr(x)," correspond au code ",x)

Le caractère 127 est-il imprimable ? Allez donc vous renseigner sur Internet le caractère 127 du code ASCII.

14° Essayer les caractères de 0 à 31. A-t-on des caractères imprimables ? Que se passe-t-il pour le 10 ?

On peut encore rajouter un paramètre à range : range (5,10,2) va compter de 2 en 2 à partir de 5 et jusqu’10 non inclus : 5, 7 et 9 donc.

Si le pas est négatif, on compte en sens inverse : range (9,1,-1) donne : 9 8 7 6 5 4 3 2, mais pas 1 puisque la condition n'est alors plus vérifiée.

15° Créer un programme qui affiche automatiquement une lettre sur 2 de A (code 65) à Z (code 90) puis qui affiche les lettres de Z à A. Utiliser les boucles FOR associées au code ASCII.

...CORRECTION de A à Z...

for x in range(65,91,2) :

    print(chr(x))

...CORRECTION de Z à A...

for x in range(90,64,-2) :

    print(chr(x))

Il existe également une possibilité pour lire une chaîne de caractères string caractère par caractère en utilisant un FOR numérique : une chaîne de caractères n’est rien d’autre qu’une sorte de tableau ordonné de caractères.

Le string monTexte = "Bonjour, je suis ici." peut se voir comme le tableau suivant :

Case 00 : contient : B
Case 01 : contient : o
Case 02 : contient : n
Case 03 : contient : j
Case 04 : contient : o
Case 05 : contient : u
Case 06 : contient : r
Case 07 : contient : ,
Case 08 : contient :  
Case 09 : contient : j
Case 10 : contient : e
Case 11 : contient :  
Case 12 : contient : s
Case 13 : contient : u
Case 14 : contient : i
Case 15 : contient : s
Case 16 : contient :  
Case 17 : contient : i
Case 18 : contient : c
Case 19 : contient : i
Case 20 : contient : .

Attention: comme d’habitude en informatique, le premier élément est l’élément 0.

On peut accéder aux différents caractères stockées dans la chaîne de caractéres à l'aide d'une boucle FOR NUMERIQUE. On dit que le String est un objet :

  • itérable car il contient une succession d'éléments (des caractères)
  • séquentiel car on peut y accéder en suivant un certain ordre.

Si on veut connaître la taille d’un string monTexte (son nombre de cases), on peut utiliser la fonction len pour length (longueur en anglais) : len(monTexte) renvoie un integer qui vaut … 21. Le tableau va jusqu’à 20 mais la première case est la case 0. D’où 20+1=21. On notera que l’espace est bien stocké dans une case : on stocke bien l’information « laisser un espace » dans la chaîne de caractères.

Nous pouvons accéder à l’élément n°X d’une chaîne de caractères monTexte en utilisant la syntaxe suivante : monTexte[X] où X est un integer, monTexte est une chaîne de caractères définie préalablement. On notera l’utilisation des crochets [ ].

A titre d'exemple, voilà un programme qui permet de définir une chaîne de caractères monTexte, de stocker dans nLongueur le nombre de caractères de la chaîne et qui demande quel numéro de caractère nCase afficher. On affiche alors le caractère numéro nCase.

Votre chaîne de caractères:

Position désirée :

La chaîne possède - caractères.

Le caractère voulu est

En Python :

#!/usr/bin/env python

# -*-coding:Utf-8 -*


monTexte = "Bonjour, je suis ici."

nLongueur = len(monTexte) # n pour indiquer visuellement que c'est un nombre


print(monTexte)

print("Nombre de caractères au total : ", nLongueur)


nCase = int(input("Donner le numéro du caractère voulu :")) # n pour indiquer que c'est un nombre, int pour transformer l'entrée clavier en nombre integer justement

print(monTexte[nCase])


input("pause")

16° Rajouter un test IF au code ci-dessus : on ne doit pas accepter de traiter un numéro de case inférieur à 0 ou supérieur à son plus grand numéro. Attention : la fonction len donne la longueur de la chaîne. Si elle renvoie 45, c’est qu’on peut lire les caractères du numéro 0 au numéro 44. Le caractère 45 n’existe pas !

17° Créer maintenant un code qui affiche le texte caractère par caractère jusqu’à la case demandée. Vous devrez pour l’exercice utiliser un FOR associé à un itérateur chiffré pour lire le contenu d’une case avec monTexte[0], monTexte[1] …

...CORRECTION ...

for x in range(0,nCase+1) :

    print(monTexte[x])

3 - Exemple avec Tkinter

Voyons ce qu'on peut en faire avec Tkinter. Je voudrais générer une application de 500 px sur 500 px.

Dans cette application, je veux créer un certain nombre de carrés bleus de 100 px de côté, separés entre eux par 20 px.

Les carrés seront des widgets Label contenant l'image Tk carreBleuTk suivante :

carreBleu = Img.new("RGB", (40,40), (0,0,255))

carreBleuTk = ImageTk.PhotoImage(carreBleu)

Pour l'instant, vous ne connaissez pas de structure de données permettant de stocker les références des Label sans les associer à une variable. Nous allons donc simplement les créer sans nous soucier de pouvoir les modifier ensuite. Nous utiliserons une seule ligne, sans stocker la référence de votre Label :

Label(fen_princ, image = carreBleuTk).place(x = 50, y = 100)

plutôt que :

monCarre = Label(fen_princ, image = carreBleuTk).place(x = 50, y = 100)

monCarre.place(x = 50, y = 100)

Le nombre de carrés sera stocké dans une variable nbrCarres.

La largeur des carrés sera stockée dans une variable largeur.

La séparation entre les carrés sera stockée dans une variable marge.

Voici l'interface Tkinter de base :

#!/usr/bin/env python

# -*-coding:Utf-8 -*

from tkinter import *

from PIL import Image as Img

from PIL import ImageTk


# - - - - - - - - - - - - - - - - - -

# Définition des variables globales

# - - - - - - - - - - - - - - - - - -

nbrCarres = 3

largeur = 100

marge = 20


# - - - - - - - - - - - - - - - - - -

# Création de la fenêtre et des objets associés la fenêtre

# - - - - - - - - - - - - - - - - - -


fen_princ = Tk()

fen_princ.geometry("500x500")


# Création d'une image de base

carreBleu = Img.new("RGB", (40,40), (0,0,255))

carreBleuTk = ImageTk.PhotoImage(carreBleu)


for i in range(nbrCarres) :

    c_horizontale = marge + i * (marge+largeur)

    c_verticale = marge

    Label(fen_princ, image = carreBleuTk).place(x = c_horizontale, y = c_verticale)


# - - - - - - - - - - - - - - - - - -

# Bouclage de la fenêtre fen_princ

# - - - - - - - - - - - - - - - - - -


fen_princ.mainloop()

18° Analyser le programme, le lancer puis le modifier pour que les carrés créés avec carreBleu = Img.new...soient bien des carrés ayant la bonne largeur (100 pixels). Pensez à utiliser la variable largeur justement.

Le code est incomplet : si on demande 6 carrés, il trace n'importe quoi.

En regardant la boucle, on peut voir :

Valeur de l'index i Valeur de c_horizontale Valeur de c_verticale
0 20+0*(20+100) = 20 20
1 20+1*(20+100) = 140 20
2 20+2*(20+100) = 260 20
3 20+3*(20+100) = 380 20
4 20+4*(20+100) = 500 20
5 20+5*(20+100) = 620 20

On ne change donc jamais de lignes et on finit par sortir de l'écran...

Pour palier à cela, nous allons utiliser l'opérateur % qui fournit le modulo d'une division (le reste de la division entière):

De cette façon, la coordonnée en x ne pourra jamais dépasser 500.

Et comment savoir qu'on veut placer le carré en ligne 0, 1, 2 ? Pour savoir cela, nous allons utiliser l'opérateur // qui renvoit la valeur entière de la division :

for i in range(nbrCarres) :

    c_horizontale = marge + i * (marge+largeur)

    ligne = c_horizontale//500

    c_verticale = marge + ligne * (marge+largeur)

    c_horizontale = c_horizontale%500

    Label(fen_princ, image = carreBleuTk).place(x = c_horizontale, y = c_verticale)

19° Tester le code avec 12 carrés. C'est presque ça, mais pas vraiment ! Trouver la valeur remplacant le 500 pour obtenir un affichage correct dans notre cas.

Avec 16 cubes, cela donne :

Les 16 carrés

C'est bien mais c'est bleu...

Rajoutons des carrés rouge et jaune :

carreBleu = Img.new("RGB", (largeur,largeur), (0,0,255))

carreBleuTk = ImageTk.PhotoImage(carreBleu)


carreRouge = Img.new("RGB", (largeur,largeur), (255,0,0))

carreRougeTk = ImageTk.PhotoImage(carreRouge)


carreJaune = Img.new("RGB", (largeur,largeur), (220,220,0))

carreJauneTk = ImageTk.PhotoImage(carreJaune)

Rajoutons un test SI : nous voudrions que les carrés soient alternativement bleu, vert, rouge.

Pour cela, il suffit de prendre la variable i de la boucle FOR et d'en faire le modulo 3 :

20° A l'aide de la description précédente des valeurs obtenues par un modulo 3 et en utilisant les 3 images Tk colorées précédentes, réaliser une interface qui rajoute des carrés alternativement bleu, rouge et jaune.

Les 16 carrés en tri de couleur

Et si vous bloquez, voici une correction possible :

...CORRECTION...

#!/usr/bin/env python

# -*-coding:Utf-8 -*

from tkinter import *

from PIL import Image as Img

from PIL import ImageTk


# - - - - - - - - - - - - - - - - - -

# Définition des variables globales

# - - - - - - - - - - - - - - - - - -

nbrCarres = 3

largeur = 100

marge = 20


# - - - - - - - - - - - - - - - - - -

# Création de la fenêtre et des objets associés la fenêtre

# - - - - - - - - - - - - - - - - - -


fen_princ = Tk()

fen_princ.geometry("500x500")


# Création des images de base

carreBleu = Img.new("RGB", (largeur,largeur), (0,0,255))

carreBleuTk = ImageTk.PhotoImage(carreBleu)


carreRouge = Img.new("RGB", (largeur,largeur), (255,0,0))

carreRougeTk = ImageTk.PhotoImage(carreRouge)


carreJaune = Img.new("RGB", (largeur,largeur), (220,220,0))

carreJauneTk = ImageTk.PhotoImage(carreJaune)


for i in range(nbrCarres) :

    c_horizontale = marge + i * (marge+largeur)

    ligne = c_horizontale//480

    c_verticale = marge + ligne * (marge+largeur)

    c_horizontale = c_horizontale%480

    if (i%3==0) :

        choix = carreBleuTk

    elif (i%3==1) :

        choix = carreRougeTk

    else :

        choix = carreJauneTk

    Label(fen_princ, image = choix).place(x = c_horizontale, y = c_verticale)


# - - - - - - - - - - - - - - - - - -

# Bouclage de la fenêtre fen_princ

# - - - - - - - - - - - - - - - - - -


fen_princ.mainloop()

Voilà. Il nous reste à voir le TANT QUE et le FOR nominatif dans une prochaine activité.

4 - FAQ

Question : comment sortir d'une boucle for avant la fin ?

On utilise l'instruction break. Exemple : on lance une boucle avec un compteur évoluant de 0 à 20 mais on sort définitivement de la boucle lorsque le compteur vaut 5 :

for compteur in range(21) :

    print(compteur)

    if (compteur == 5) :

        break

Sur la console, on voit bien qu'on ne revient pas dans la boucle pour le cas 6 et plus :

0

1

2

3

4

5

Question : Je voudrais compter de 0 à 6 mais sans passer par 5, c'est possible ?

On utilise l'instruction continue. On lance une boucle avec un compteur évoluant de 0 à 6 mais sans agir pour 5 en forçant un retour au début de la boucle :

for compteur in range(7) :

    if (compteur == 5) :

        continue

    print(compteur)

Comme vous le voyez, je n'ai même pas besoin de mettre un else après le if. L'exécution du programme va répartir au début de la boucle dès qu'elle rencontrera continue.

Sur la console, on voit bien qu'on a sauté l'exécution du print pour le 5 :

0

1

2

3

4

6

Question : Je voudrais lire un à un les valeurs des pixels d'une image, c'est possible ?

from PIL import Image as Img # On importe la classe Img

monImage = Img.open("linux.jpg") # On crée un objet-image à partir d'un fichier-image

nLargeur = monImage.width # On va chercher la largeur de l'image

nHauteur = monImage.height # On va chercher la hauteur de l'image

for y in range(nHauteur) : # Pour y variant de 0 jusqu'à nHauteur exclus

    for x in range(nLargeur) : # Pour x variant de 0 jusqu'à nLargeur exclus

        r,g,b = monImage.getpixel((x,y)) # Place dans r,g et b les RGB du pixel (x,y) de monImage

Attention, ce code n'est valide que si l'image possède 3 couches. Ca ne fonctionnera pas avec une image en nuance de gris ou avec une image RGBA.