Programmer en Python au lycée

Lycée

Tu viens d’entrer en seconde et tu t’es offert pour l’occasion une magnifique calculatrice programmable en Python. Tu as bien fait, les petits programmes en Python sont au programme du bac. Mais la programmation ne s’improvise pas. Pour l’instant tu te contentes de recopier les lignes de codes données par le professeur, et tu n’arrives pas à écrire tes propres scripts. Dans cet article tu vas revoir les bases et essayeras de te lancer tout seul.

Les variables

En maths, la variable habituelle est notée x. Elle est utilisée par exemple pour dresser le tableau de valeurs d’une fonction.

tbaleau de valeurs
pour chaque valeur de x, on calcule 2 x + 3

Voici comment tu peux programmer Python pour remplir la première colonne :

x = 0
print(x ,”a pour image”, 2 * x + 3)

Si tu lances le programme, tu vas voir s’afficher le message :

0 a pour image 3

Comment ça marche ?

  • la première ligne du programme indique à Python la valeur de la variable x, donc ici zéro ;
  • la deuxième ligne demande à Python d’afficher (print en anglais) la valeur de la variable x — donc 0 — puis le texte “a pour image” et enfin la valeur du calcul 2*0+3, c’est-à-dire 3 ;
  • remarque 1 : l’astérique * est le symbole de la multiplication pour Python ; l’oublier conduit à une erreur ;
  • remarque 2 : les guillemets permettent à Python de différencier les variables – qu’il doit calculer — et les textes — qu’il doit laisser tels quels ;
  • remarque 3 : les virgules servent à séparer les variables et les textes, mais ne sont pas affichées à l’écran. Python les remplace par des espaces.

À ton avis, que se passe-t-il si on modifie le programme de la façon suivante ?

x = 0
print(“x a pour image”, 2 * x + 3)

Réponse : Python affichera

x a pour image 3

Et pour la deuxième colonne du tableau ?

La solution de facilité serait :

x = 0
print(x ,”a pour image”, 2 * x + 3)
x = 1
print(x ,”a pour image”, 2 * x + 3)

Ce qui donnerait :

0 a pour image 3
1 a pour image 5

Et pour les colonnes suivantes :

x = 0
print(x ,”a pour image”, 2 * x + 3)
x = 1
print(x ,”a pour image”, 2 * x + 3)
x = 2
print(x ,”a pour image”, 2 * x + 3)
x = 3
print(x ,”a pour image”, 2 * x + 3

pour le résultat :

0 a pour image 3
1 a pour image 5
2 a pour image 7
3 a pour image 9

Comment peux-tu modifier une variable ?

L’instruction x = 1 ne t’a sans doute pas choqué, pourtant elle est très surprenante.

Quand Python rencontre la variable x, par exemple dans 2 * x + 3, on a vu qu’il remplaçait x par 0 et calculait 2 * 0 + 3 = 3.

Alors dans l’égalité x = 1, remplacer x par 0 donnerait 0 = 1. Étrange, non ?

Retiens que le symbole “=” de Python n’a rien à voir avec celui des maths. On pourrait le traduire par “la nouvelle valeur est”.

Et donc “x = 1” se lit “la nouvelle valeur de x est 1”.

Alors rien n’interdit d’écrire désormais x = x + 1 pour que x passe de 0 à 1, puis de 1 à 2, de 2 à 3, de 3 à 4 etc.
Explications :

  • Tu peux traduire cette instruction par “la nouvelle valeur de x est x+1”
  • Python commence par regarder ce qui est à droite du “=” , donc x + 1 ;
  • ensuite il remplace x par 0 puis fait le calcul : 0 + 1 = 1 ;
  • et pour finir il conclut par “la nouvelle valeur de x est 1”.

Le programme s’écrit désormais :

x = 0
print(x ,”a pour image”, 2 * x + 3)
x = x + 1
print(x ,”a pour image”, 2 * x + 3)
x = x + 1
print(x ,”a pour image”, 2 * x + 3)
x = x + 1
print(x ,”a pour image”, 2 * x + 3)

Quels sont les avantages et inconvénients de ce nouveau programme ?

  • tu peux ajouter au tableau de valeurs autant de colonnes que tu veux par des simples copier-coller ;
  • si tu décides que la première valeur de x est -2 au lieu de 0, tu ne dois changer que la première ligne du programme ;
  • faire des copier-coller sur l’ordinateur c’est facile, mais sur ta calculatrice ?

Programmer une boucle, comme dans Scratch

Au collège tu as sans doute appris à tracer un carré avec le logiciel Scratch. Le programme ressemblait à ceci :

répéter 4 fois :
– avance de 50 pas
– tourne à gauche de 90 degrés

Cette boucle permet de demander au logiciel de faire quatre fois la même chose, sans être obligé d’écrire quatre fois les mêmes lignes de code.

Tu peux utiliser une boucle Python pour le tableau de valeurs précédent :

for x in range(0, 7) :
__print(x ,”a pour image”, 2 * x + 3)

avec pour résultat :

0 a pour image 3
1 a pour image 5
2 a pour image 7
3 a pour image 9
4 a pour image 11
5 a pour image 13
6 a pour image 15

Comment ça marche ?

  • “for x in range(0, 7)” se traduit par “pour x allant de 0 inclus à 7 exclu avec un pas de 1” ;
  • en pratique, Python va donner à x les valeurs 0, 1, 2, 3, 4, 5 et 6 ;
  • puis, pour chacune des valeurs de x, calculer et afficher le résultat du calcul ;
  • les deux points “:” à la fin de la première ligne sont obligatoires ; ils indiquent à Python que ce qui suit est dans la boucle ;
  • Python ajoute automatiquement des espaces en début de ligne pour les instructions qui sont dans la boucle ; ils sont représentés ici par des tirets ;
  • pour sortir de la boucle, il suffit d’effacer les espaces en début de ligne.

Compare :

for x in range(0, 7) :
__print(x ,”a pour image”, 2 * x + 3)
__print(“tableau de valeurs terminé”)

et

for x in range(0, 7) :
__print(x ,”a pour image”, 2 * x + 3)
print(“tableau de valeurs terminé”)

Le premier script donne :

0 a pour image 3
tableau de valeurs terminé
1 a pour image 5
tableau de valeurs terminé
2 a pour image 7
tableau de valeurs terminé
3 a pour image 9
tableau de valeurs terminé
4 a pour image 11
tableau de valeurs terminé
5 a pour image 13
tableau de valeurs terminé
6 a pour image 15
tableau de valeurs terminé

alors que le second donne :

0 a pour image 3
1 a pour image 5
2 a pour image 7
3 a pour image 9
4 a pour image 11
5 a pour image 13
6 a pour image 15
tableau de valeurs terminé

Un autre type de boucle : “tant que”

Un des inconvénients de la boucle précédente est qu’il n’est pas possible de donner un tableau de valeurs avec un pas non entier.

Il est possible d’aller de 2 en 2 en complétant la commande range :

for x in range(0, 7, 2) :
__print(x ,”a pour image”, 2 * x + 3)
print(“tableau de valeurs terminé”)

“for x in range(0, 7, 2)” se lit “pour x allant de 0 inclus à 7 exclu avec un pas de 2”. Le résultat est le suivant :

0 a pour image 3
2 a pour image 7
4 a pour image 11
6 a pour image 15
tableau de valeurs terminé

Mais si on te demande un tableau de valeurs avec un pas de 0,5 le programme suivant ne fonctionne pas :

for x in range(0, 7, 0.5) :
__print(x ,”a pour image”, 2 * x + 3)
print(“tableau de valeurs terminé”)

La boucle while (tant que) est plus souple car elle autorise les nombres non entiers ; mais elle est plus délicate à utiliser.

x = 0
while x <= 6 :
__print(x ,”a pour image”, 2 * x + 3)
__x = x + 0.5
print(“tableau de valeurs terminé”)

pour un résultat :

0 a pour image 3
0.5 a pour image 4.0
1.0 a pour image 5.0
1.5 a pour image 6.0
2.0 a pour image 7.0
2.5 a pour image 8.0
3.0 a pour image 9.0
3.5 a pour image 10.0
4.0 a pour image 11.0
4.5 a pour image 12.0
5.0 a pour image 13.0
5.5 a pour image 14.0
6.0 a pour image 15.0
tableau de valeurs terminé

Comment ça marche ?

La boucle while se décompose en trois parties :

  • “while x <= 6 :” se lit “tant que x est inférieur ou égal à 6” ;
    • les quatre inégalités habituelles sont acceptées :
      • <= inférieur ou égal
      • >= supérieur ou égal
      • < strictement inférieur
      • > strictement supérieur
  • la deuxième partie contient les instructions qui doivent être exécutées à chaque fois : calculer l’image de x et afficher le résultat
    • print(x ,”a pour image”, 2 * x + 3)
  • enfin la troisième partie indique comment la valeur de la variable x évolue : ici on a choisi un pas de 0,5
    • x = x + 0.5

 !!! N’oublie surtout pas la troisième partie, sinon la boucle tournera indéfiniment, puisque la variable x n’atteindra jamais la valeur 6 !!!

Tests : si, sinon

Ici tu ne vas pas afficher les valeurs des images de la variable x, mais seulement indiquer leurs signes : “strictement positif”, “strictement négatif”, “nul”

Le problème mathématique à résoudre est le suivant :

  • La fonction \(f\) est définie sur l’intervalle \([0\;;\;6]\) par \(f(x)=x^2-7x+10\) ;
  • donne le signe de \(f(x)\) pour \(x\) entier compris entre 0 et 6.

Dans un tableau cela donnerait :

tableau de valeurs et de signes
on calcule f(0), qui vaut 10 donc est positif ; et ainsi de suite avec 1, 2, etc.

Une première version du programme pourrait être :

for x in range(0,7) :
__img = x**2 – 7 * x + 10
__print(x, “a pour image”, img)

qui afficherait :

0 a pour image 10
1 a pour image 4
2 a pour image 0
3 a pour image -2
4 a pour image -2
5 a pour image 0
6 a pour image 4

Comment ça marche ?

  • Une précaution s’impose : comme l’image f(x) va être utilisée plusieurs fois, il vaut mieux que tu stockes sa valeur dans une nouvelle variable, sinon Python sera obligé de la recalculer à chaque fois que tu en auras besoin ;
  • en maths on utilise généralement les notations f(x) ou y ; la première n’est pas possible avec Python, mais tu peux choisir la deuxième ; ou n’importe quel autre nom ; j’ai choisi img pour que ce soit plus parlant et pas trop long ;
  • remarque : la fonction carré n’est pas représentée par ^2 comme on le trouve parfois ; Python utilise la notation ** pour les puissances, donc x**2 pour x au carré.

Et le signe dans tout ça ?

Une fois que Python a calculé la valeur de l’image, il va pouvoir la tester pour indiquer son signe.

Un nouveau programme :

for x in range(0,7) :
__img = x**2 -7 * x + 10
__if img > 0 :
____print(“l’image de”, x, “est strictement positive”)

pour le résultat suivant :

l’image de 0 est strictement positive
l’image de 1 est strictement positive
l’image de 6 est strictement positive

Comment ça marche ?

  • “if img > 0 :” se lit “si la variable img est strictement positive, alors” ;
  • comme pour les boucles, la ligne de test se termine obligatoirement par “:” ;
  • Python comprend alors qu’un test est en cours, et décale à nouveau les instructions qui suivent de quelques espaces vers la droite

Deuxième amélioration du programme

for x in range(0,7) :
__img = x**2 -7 * x + 10
__if img > 0 :
____print(“l’image de”, x, “est strictement positive”)
__else :
____print(“l’image de”, x, “est strictement négative”)

pour le résultat :

l’image de 0 est strictement positive
l’image de 1 est strictement positive
l’image de 2 est strictement négative
l’image de 3 est strictement négative
l’image de 4 est strictement négative
l’image de 5 est strictement négative
l’image de 6 est strictement positive

Comment ça marche ?

  • “else :” se lit “sinon” ;
  • même principe que pour les boucles et le test if, la ligne se termine par “:” et un décalage est automatiquement créé sur la ligne suivante ;
  • remarque que else et if doivent être positionnés l’un au-dessous de l’autre ; si besoin efface les espaces créés automatiquement.

Troisième amélioration

Il y a une erreur dans le précédent programme. L’image de 2 n’est pas strictement négative, puisqu’elle vaut 0.

Nouvel essai :

for x in range(0,7) :
__img = x**2 -7 * x + 10
__if img > 0 :
____print(“l’image de”, x, “est strictement positive”)
__elif img < 0 :
____print(“l’image de”, x, “est strictement négative”)
__else :
____print(“l’image de”, x, “est nulle”)

avec pour résultat :

l’image de 0 est strictement positive
l’image de 1 est strictement positive
l’image de 2 est nulle
l’image de 3 est strictement négative
l’image de 4 est strictement négative
l’image de 5 est nulle
l’image de 6 est strictement positive

Ouf ! Tu as obtenu les mêmes résultats que dans le tableau un peu plus haut  🙂

Comment ça marche ?

  • elif est une contraction de else if
  • le programme se lit de la façon suivante :
    • si l’image est strictement positive, alors affiche…
    • sinon, si l’image est strictement négative, alors affiche…
    • sinon affiche…
  • en résumé :
    • un test commence toujours par l’instruction “if” ;
    • si besoin, le test se termine par une instruction “else” ;
    • si plus de deux cas sont à traiter (par exemple positif, négatif, nul), tu peux insérer des instructions “elif” autant que tu veux.

Exercice : la suite de Syracuse

Cette suite de nombres est générée de la façon suivante :

  • Choisis un nombre entier supérieur ou égal à 1 ;
  • si ce nombre est pair, divise-le par 2 ;
  • mais s’il est impair, multiplie-le par 3 et ajoute 1 ;
  • recommence à partir du nouvel entier obtenu.

Exemple :

Je choisis 1. C’est un nombre impair donc je calcule 1 fois 3 plus 1 égale 4.
4 est pair donc je le divise par 2 pour obtenir 2.
2 est pair donc je le divise par 2 et j’obtiens 1.
Si je continue j’obtiendrai à nouveau 4, puis 2, puis 1, puis 4, puis…

À toi d’essayer :

Vérifie qu’en partant de 3 on arrive au nombre 1 en sept coups.

Dans cet exercice tu vas programmer ta calculatrice pour qu’elle t’affiche la suite obtenue à partir de l’entier de départ que tu auras choisi.

Une division ? Des divisions !

Si je te demande “9 divisé par 2”, tu vas certainement me répondre “4,5” ou “4 et demi”. Bien.
Mais si je te l’avais demandé il y a six ou sept ans tu m’aurais répondu “si on distribue 9 objets à 2 personnes, chacune en reçoit 4 et il en reste 1”

Si je demande à Python, il va me donner soit la première réponse, soit la deuxième, selon la façon dont je pose la question.
Ouvre un nouvre script sur ta calculatrice et tape :

print(9/2)
print(9//2)
print(9%2)

Lance le script. Qu’obtiens-tu ? Étonnant, non ?

Comment ça marche ?

  • L’opérateur / est celui des calculatrices, il permet d’obtenir la valeur décimale, éventuellement arrondie, de la division ;
  • l’opérateur // donne la partie entière de la division : si je distibue 9 objets à 2 personnes, chacune en recevra 4 ;
  • quant à %, rien à voir avec les pourcentages ☺️ ; cet opérateur donne le reste de la division : 9 divisé par 2 égale 4 et il reste 1

Pour cet exercice, retiens seulement que l’opération “%2” permet de savoir si un nombre est pair (le résultat de l’opération est 0) ou impair (le résultat est 1).

Entraine-toi

Écris un petit script qui affiche tous les entiers de 0 à 9 et qui précise s’ils sont pairs ou impairs.
Tu as besoin d’une boucle for… et d’un test if… else…

Résultat attendu

0 est pair
1 est impair
2 est pair
3 est impair
4 est pair
5 est impair
6 est pair
7 est impair
8 est pair
9 est impair

Solution (rappel : les traits représentent les espaces ajoutés automatiquement par Python, tu n’as pas à les écrire)
La variable utilisée est n, mais peu importe si tu as choisi x ou tout autre lettre.

for n in range(0, 10) :
__if n%2 > 0 :
____print(n, “est impair”)
__else :
____print(n, “est pair”)

Python permet également de vérifier si deux nombres sont égaux. L’opérateur utilisé est == (double égal).
Une autre solution serait donc :

for n in range(0, 10) :
__if n%2 == 0 :
____print(n, “est pair”)
__else :
____print(n, “est impair”)

Retour à Syracuse

Écris un script qui part de l’entier 3 et qui affiche la suite générée par le processus indiqué plus haut (diviser par 2 ou multiplier par 3 puis ajouter 1).
Tu as besoins d’une boucle while… pour que la suite s’arrête dès que le nombre 1 est obtenu. Tu as également besoin des tests if… else…

Résultat attendu

10
5
16
8
4
2
1

Solution

n = 3
while n > 1 :
__if  n%2 == 0 :
____n = n // 2
__else :
____n = n * 3 + 1
__print(n)

Python permet également de vérifier si deux nombres sont différents. L’opérateur utilisé est != (le point d’exclamation représente la négation).
Autre solution :

n = 3
while n != 1 :
__if  n%2 == 0 :
____n = n // 2
__else :
____n = n * 3 + 1
__print(n)

Remarque : peut-être as-tu obtenu les nombres 5.0 16.0 8.0… au lieu de 5 16 et 8 ? Pyhon transforme automatiquement les nombres entiers en nombres décimaux si tu utilises l’opérateur de division “/”. Dans tes scripts ne concernant que des nombres entiers, prends l’habitude d’utiliser l’opérateur de division entière “//”.

Pour aller plus loin

Je voudrais que le nombre choisi comme point de départ de la suite soit affiché à l’écran. Mais également que le nombre de termes de la suite apparaisse en conclusion. Peux-tu t’en charger ? Tu auras besoin d’un compteur qui augmente de 1 à chaque nouveau nombre obtenu.

Résultat attendu

3
10
5
16
8
4
2
1
La suite contient 8 nombres.

Solution

n = 3
compteur = 1
print(n)
while n != 1 :
__if n%2 == 0 :
____n = n // 2
__else :
____n = n * 3 + 1
__compteur = compteur + 1
__print(n)
print(“La suite contient”, compteur, “nombres.”)

Remarque importante : l’instruction “while n != 1 :” est très dangereuse et vivement déconseillée en général.
Pourquoi ? Parce que rien n’indique que l’entier n va prendre la valeur 1, même au bout d’un grand nombre d’étapes. Tu risques donc de lancer un script qui ne va jamais s’arrêter !

Par exemple, remplace n = 3 par n = 27. Qu’observes-tu ?

Pour l’anecdote, personne n’a jamais réussi à trouver un nombre de départ qui ne permette pas d’arriver à 1. Seras-tu le premier ?
Plus d’informations sur la conjecture de Syracuse sur Wikipédia.

Bonus : une version interactive

Le script demande la valeur de départ à l’utilisateur. À la fin il demande à l’utilisateur si celui-ci veut refaire un essai. Réponds 1 pour continuer.

encore = “1”
while encore == “1” :
__n = int(input(“n = “))
__compteur = 1
__print(n)
__while n != 1 :
____if n%2 == 0 :
______n = n // 2
____else :
______n = n * 3 + 1
____compteur = compteur + 1
____print(n)
__print(“La suite contient”, compteur, “nombres.”)
__encore = input(“Encore ? (1 = oui) : “)

Un dernier point avant de se quitter : les fonctions

Une fonction Python peut faire la même chose qu’une fonction mathématique.

Par exemple la fonction f définie par f(x) = 2x+3 peut être programmée de la façon suivante :

def f(x) :
__return 2*x+3

Comment ça marche ?

  • Les mots-clefs à utiliser ici sont def et return ;
  • comme d’habitude, la première ligne se termine par : et Python insèrera des espaces  au début des lignes suivantes ;
  • une fois la fonction définie, on peut l’utiliser dans le script.

Exemple :

def f(x) :
__return 2*x+3
print(“L’image de 5 est”, f(5))

Créer une fonction PPCM

Le plus petit multiple commun à 6 et 9 est 18. Cela t’a sans doute servi au collège pour additionner deux fractions : \({5\over6}+{2\over9}={15\over18}+{4\over18}={19\over18}\).

La méthode la plus rapide pour trouver le PPCM est de connaitre tes tables de multiplication. Celle de 6 commence par 6-12-18-24-30… et celle de 9 par 9-18-27… Inutile d’aller plus loin, on a trouvé un multiple commun : 18.

Avec Python, je te propose de prendre les multiples de 6 les uns après les autres, de vérifier si chacun est divisible par 9, et de t’arrêter dès que c’est le cas.
Tu auras donc besoin d’une variable m et d’une boucle while.

Résultat attendu

18 est un multiple de 6 et de 9

Solution

m = 6
while m%9 > 0 :
__m = m + 6
print(m, “est un multiple de 6 et de 9”)

Comment ça marche ?

  • La variable m prend la valeur 6, puis le script lui ajoute 6 un certain nombre de fois ;
  • de cette façon m parcourt la table de multiplication de 6 ;
  • la boucle continue tant que la division par 9 ne tombe pas juste (rappel : m%9 donne le reste de la division de m par 9).

Retour à la fonction PPCM

Ce qui est valable avec 6 et 9 l’est tout autant avec deux entiers strictement positifs quelconques a et b.
Je te propose donc de transformer le petit script ci-dessus en fonction :

def ppcm(a, b) :
__m = a
__while m%b > 0 :
____m = m + a
__return m

Cette fonction peut ensuite être utilisée dans la suite du script.

def ppcm(a, b) :
__m = a
__while m%b > 0 :
____m = m + a
__return m
print(“le PPCM de 6 et 9 est”, ppcm(6, 9), “et celui de 60 et 48 est”, ppcm(60, 48))

Voila, tu sais tout (ou presque) sur les bases de Python

Certaines activités de Klérigo créent des scripts Python. Des articles du blog y seront consacrées.
Si tu es abonné, tu peux t’entrainer avec ces activités sur la page Lycée en choisissant la catégorie “Algorithmes et programmation”.

algorithme du balayage