La solution naïve

Imaginons que notre algoblob ne soit pas tout seul. Ils sont plusieurs ... La solution naïve, ce serait de nommer les variables en ajoutant un nom ou un numéro devant chaque variable

abscisse1 = 10
abscisse2 = 20
abscisse3 = 50

Il est assez évident de voir qu'une telle solution n'est pas viable. Il faudrait changer le nombre de variables à chaque fois que l'on ajoute ou l'on enlève un algoblob, sans compter les copier coller pour les déplacements.... Il y a mieux : nous allons utiliser des listes

Vous vous souvenez ? Nous avions vu comment utiliser des listes pour voir la vie en couleur avec nos algoblobs. Nous avions utilisé une liste de couleurs. Et si nous utilisions des listes pour stocker les caractéristiques de nos algoblobs ? Une liste contiendra les abscisses, une liste contiendra les ordonnées, etc. Mais pour pouvoir travailler, il nous faudra parcourir nos listes.

Parcourir une liste

Ce qui est intéressant avec une liste, c'est que l'on peut parcourir une liste pour effectuer des opérations sur chaque élément de la liste. Faire des actions répétitives est au cœur de l'informatique.

la boucle for

Pour effectuer une action répétitive sur une liste, on utilise la boucle for. La syntaxe est assez simple.

maListe=['carotte','patates','chou','navet','haricot']
for legume in maListe :
    print(legume)
    
Essayer le code dans le bloc python ci dessous
maListe=['carotte','patates','chou','navet','haricot'] for legume in maListe : print(legume)

Lorsque l'on effectue la boucle for, la variable legume va prendre successivement toutes les valeurs des éléments de la liste et effectuer les instructions qui sont dans le bloc de code indenté en dessous.

Vous n'aimez peut être pas le navet ? Reprenez le programme au dessus et modifiez afin que, au lieu d'afficher juste le nom du légume, il affiche j'aime bien ce légume : ..., sauf pour le navet ou vous devez afficher Je n'aime pas ce légume : .... Bien entendu, il faudra utiliser une condition.

maListe=['carotte','patates','chou','navet','haricot'] for legume in maListe : print(legume)

Plus fort... nous allons utiliser une seconde liste. Celle des légumes que vous n'aimez pas. Il est possible de poser une condition sur l'appartenance à une liste ou pas. Le mot clef in a en effet deux usages :

reprenez le programme au dessus. Étendez la liste des légumes de base. Créer une seconde liste que vous appelerez "listePasBon" et dans laquelle vous mettrez les légumes que vous n'aimez pas. Modifiez ensuite le programme pour qu'il affiche la liste de tous les légumes en précisant pour chacun si vous aimez ou non ce légume (et pas seulement le navet)

Seconde façon d'utiliser la boucle for

Il y a une seconde façon d'utiliser la boucle for. On peut utiliser une liste particulière, qui est créé par l'appel à la fonction range. Cette fonction va faire une liste particulière qui est une liste d'entier (en fait, c'est plus compliqué, c'est un itérateur, mais on va faire comme ci ...). Pour parcourir notre liste, on va pouvoir utiliser les indices comme dans le code ci dessous. Notez que range(n) donne n nombres entier, en commençant à 0 et en finissant à n-1 (donc range(10) va de 0 à 9)

On va aussi se servir de la fonction len qui retourne la longueur d'une liste (abbréviation de length).

  1. Éxécutez le programme.
  2. On pourrait aussi afficher la position dans la première boucle, mais en ajoutant une variable que l'on modifie au fur et à mesure Essayez de le faire
maListe=['carotte','patates','chou','navet','haricot'] # Version 1 for legume in maListe : print(legume) print("--") print("Seconde version") print("--") # Version 2 for i in range(len(maListe)) : print(i+1, end=". ") print(maListe[i])
Mais pourquoi faire

Vous allez me dire que ... ce n'est pas très intéressant de pouvoir ajouter juste un numéro devant un élément de la liste. Mais il faut penser dans l'autre sens. Il faut penser à la création des éléments d'une liste. Par exemple, si nous voulons créer une liste qui contient les carrés des nombres de 1 à 12, cela sera assez facile

maListe = []
for i in range(12) :
    nombre = i+1 # i va de 0 à 11
    maListe.append( nombre * nombre )

Au passage, on pourrait s'éviter le décalage en utilisant la fonction range avec un départ (inclus) et une arrivée (exclue) :

maListe = []
for nombre in range(1,13) :
    maListe.append( nombre * nombre )

Et là, on se rend compte de l'intérêt de cette démarche : on va pouvoir remplir une liste de façon automatisée.

Notez bien qu'il serait aussi possible d'utiliser une boucle while avec un compteur. On ne le fait généralement pas car cela nécessite de rajouter une variable que l'on controle, là où la boucle for combiné au range effectuera ces opérations pour nous.

Ils se multiplient !

Ils se multiplient

Et c'est bien ce que nous voulons faire : nous voulons que nos algoblobs se multiplient. Qu'il n'y en ait plus un seul, mais plusieurs ! Disons une douzaine par exemple. On va reprendre le code que l'on avait avant, mais au lieu d'avoir des variables, nous allons avoir des listes de variables et nous allons les parcourir.

  1. Dans votre éditeur Python, reprenez le dernier fichier que nous avions où l'algoblob se déplaçait. Il est reproduit ci dessous, vous pouvez le copier si besoin
  2. au lieu des variables abscisse, ordonnee,vitesseX,vitesseY, créer 4 tableaux vides correspondant à ces 4 éléments caractéristiques
  3. Faites une boucle pour remplir ces 4 tableaux avec pour chacun 12 éléments, qui correspondront aux 4 caractéristiques (x,y,vx,vy) de nos 12 blobs.
    • La vitesse sera aléatoire comme actuellement
    • l'abscisse sera aléatoire en utilisant uniform(0,largeur)
    • l'ordonnee sera aléatoire en utilisant uniform(0,hauteur)
  4. modifier ensuite toute la partie qui est en dessous de background(0) pour que les instructions soient toutes dans une boucle qui va parcourir les 12 valeurs des 4 tableaux pour afficher et faire se déplacer nos 12 blobs.
  5. Éxécutez le programme et savourez ce foisonnement d'algoblob. Non seulement ils sont vivants, mais vous les avez multipliés !
  6. Bonus : vous pouvez aussi transformer le rayon en tableau et avoir des rayons aléatoires.
from  p5 import *
from random import uniform

largeur,hauteur = 500, 500
abscisse, ordonnee, rayon = 250, 250, 20
vitesseX, vitesseY = uniform(-5,5), uniform(-5,5)
if vitesseX == 0 and vitesseY == 0:
    vitesseX = 1

def setup():
    size(largeur,hauteur)

def draw():
    global abscisse, ordonnee, vitesseX, vitesseY
    background(0)
    circle(abscisse,ordonnee,rayon)
    abscisse = abscisse + vitesseX
    ordonnee = ordonnee + vitesseY
    if abscisse > largeur :
        abscisse = largeur
        vitesseX = - vitesseX
    if abscisse < 0 :
        abscisse = 0
        vitesseX = -vitesseX
    if ordonnee > hauteur :
        ordonnee = hauteur
        vitesseY = -vitesseY
    if ordonnee < 0 :
        ordonnee = 0 
        vitesseY = - vitesseY

run()

Voilà, nos algoblobs sont nombreux et ils évoluent librement ... dans l'espace qui leur est alloué. Et la suite ? Ce n'est quand même pas très pratique ces tableaux qui trainent dans un peu tous les sens. On va essayer de regrouper les données en utilisant une autre structure composée : les dictionnaire. Les informations sur chaque algoblob seront stockées dans un dictionnaire, et notre liste des algoblobs sera juste une liste de dictionnaires.