Préparez-vous : cette leçon est plutôt longue. Nous allons voir comment définir de nouvelles commandes de robot. Nous verrons aussi une troisième règle utile pour l'écriture de programmes :
Si vous y réfléchissez attentivement, vous pourrez trouver que faire
faire à Reeborg trois rotations à gauche à la suite donne le même
résultat que s'il faisait une seule rotation à droite. Essayez de
comprendre, en dessinant sur une feuille de papier, ce que le programme
suivant ferait faire à Reeborg. sans utiliser votre ordinateur :
turn_left()
move()
turn_left()
turn_left()
turn_left()
move()
move()
turn_left()
turn_left()
turn_left()
move()
turn_left()
turn_left()
turn_left()
move()
move()
turn_left()
turn_left()
turn_off()
Écrivez et enregistrez le programme ci-dessus, et voyez si ce que Reeborg fait est ce à quoi vous vous attendiez.
Changez le programme que vous venez d'enregistrer pour qu'il fasse
tourner Reeborg dans le sens des aiguilles d'une montre autour d'un
carré comme dans l'image ci-dessous :
Nous avons déjà vu comment Reeborg peut tourner à droite en combinant trois rotations à gauche à la suite. Si nous voulons faire une série de rotations à droite, il devient plutôt ennuyeux d'écrire et lire le code obtenu. C'est parce que nous nous répétons ; en d'autres mots, la même suite d'instructions apparaît à différents endroits dans le programme. Pour éviter de telles duplications, la possibilité de programmer Reeborg en Python est très utile.
En Python, on peut donner un nom simple à une série d'instructions. Par exemple, nous pouvons définir la commande qui permet de faire tourner à droite (en anglais turn right) Reeborg comme ceci :
Au moins cinq points importants sont à noter :
Cela fait pas mal d'informations présentées en une fois. C'est probablement le bon moment pour vérifier si vous avez bien compris comment utiliser ce mot-clé.
Écrivez un programme qui 1) définit cette nouvelle commande pour tourner à droite et 2) l'utilise pour faire tracer à Reeborg un carré dans le sens des aiguilles d'une montre comme précédemment. Remarquez que le programme final est plus court que l'original et qu'il est plus facile de comprendre le chemin que suit Reeborg.
Définissez l'instruction pas_en_arriere() pour que le programme suivant :
# pas_en_arriere() défini ci-dessus
move()
pas_en_arriere()
turn_off()
fasse avancer Reeborg d'un pas en avant puis revenir à sa position de départ face à la même direction qu'au début, comme dans l'image suivante :
Conseil : Soyez sûr de ne pas oublier d'indenter les commandes qui font partie de votre nouvelle définition.
[NdT Attention : Comme pour les synonymes que nous avons vus dans une leçon précédente et comme pour les noms de variables que nous verrons par la suite, les noms de fonctions doivent utiliser l'alphabet anglais et donc ne peuvent pas contenir de lettres accentuées. C'est pourquoi le nom de la fonction pas_en_arriere()ne comporte pas d'accent (eh non ! ce n'était pas un oubli...).]
Définissez l'instruction demi_tour() pour que les nouvelles commandes suivantes puissent fonctionner comme prévu :
def demi_tour():
demi_tour()
move()
demi_tour()
def turn_right():
demi_tour()
turn_left()
Dans le chapitre précédent, un des derniers exercices que vous aviez à faire était d'écrire un programme pour que Reeborg livre un journal. Voici un rappel en image de ce que Reeborg devait faire :
Votre solution à cet exercice ressemblait probablement à ceci :
move()
# monter une marche
turn_left()
move()
turn_left()
turn_left()
turn_left()
move()
move()
# monter une marche
turn_left()
move()
turn_left()
turn_left()
turn_left()
move()
move()
# monter une marche
turn_left()
move()
turn_left()
turn_left()
turn_left()
move()
move()
# monter une marche
turn_left()
move()
turn_left()
turn_left()
turn_left()
move()
move()
# poser le journal et faire demi-tour
put_beeper()
turn_left()
turn_left()
# descendre une marche
move()
move()
turn_left()
move()
turn_left()
turn_left()
turn_left()
# descendre une marche
move()
move()
turn_left()
move()
turn_left()
turn_left()
turn_left()
# descendre une marche
move()
move()
turn_left()
move()
turn_left()
turn_left()
turn_left()
# descendre une marche
move()
move()
turn_left()
move()
turn_left()
turn_left()
turn_left()
# avancer et s'arrêter
move()
turn_off()
C'est beaucoup de frappe au clavier... et il y a beaucoup de répétitions. Quand vous arriviez à la fin du programme, vous ne pouviez plus voir son début à l'écran. Vous avez peut-être remarqué que j'ai ajouté quelques commentaires qui m'ont aidé à repérer où je suis dans le travail à faire. Ces commentaires sont plus proches de ce qu'on pense quand on pose le plan d'une solution :
monter_quatre_marches()
put_beeper()
demi_tour()
descendre_quatre_marches()
Ce n'est pas une solution tout à fait complète [par exemple, il manque une instruction turn_off()], mais cela en est assez proche et c'est beaucoup plus facile à lire que ce que nous avions avant, en supposant que ces nouvelles instructions soient définies. Voici quelques unes des définitions dont on a besoin :
def demi_tour():
turn_left()
turn_left()
def turn_right():
turn_left()
turn_left()
turn_left()
def monter_une_marche():
turn_left()
move()
turn_right()
move()
move()
def monter_quatre_marches():
monter_une_marche()
monter_une_marche()
monter_une_marche()
monter_une_marche()
Ajoutez les définitions manquantes pour que le programme final ressemble à ce que j'ai appelé la version Pythonique. Vous aurez besoin d'ajouter quelques instructions simples en plus, dont un turn_off() à la fin. Rappelez-vous d'enregistrer votre programme en utilisant un nom différent de celui de votre solution d'origine.
Prenez le temps de comparer votre solution d'origine au programme de livraison de journal ainsi qu'à ce dernier programme. Lequel est le plus facile à lire ?
Des noms bien choisis peuvent vraiment aider à comprendre ce que fait un programme. De même, des noms mal choisis peuvent le rendre vraiment difficile à comprendre [Voir la Règle N°4]. Essayez de comprendre le sens du programme suivant sans utiliser l'ordinateur pour l'exécuter.
def a():
turn_left()
turn_left()
def b():
turn_left()
a()
def c():
move()
move()
def d():
c()
b()
def e():
d()
d()
d()
d()
turn_left()
e()
b()
turn_off()
Vous pourrez trouver utile de donner des noms plus significatifs aux commandes a(), b(), c(), d() et e().