Skip to content

Prérequis en programmation Python

Démarche

Avant de pouvoir enseigner la programmation au Lycée, il faut : 1. se sentir à l'aise avec le codage de Python de base ; 2. connaître le vocabulaire Python de base et son fonctionnement ; 3. avoir une connaissance claire des mécanismes de base du fonctionnement de Python ; 4. pouvoir faire le pont entre les concepts de programmation à enseigner et leur traduction possibles en Python.

Pour se sentir à l'aise avec le codage de Python de base

Si vous ne vous sentez pas encore à l'aise avec le codage de base, nous ne pouvons que vous conseiller de pratiquer. Pour vous aider, de nombreuses ressources existent souvent sous forme de livres (voir par exemple la liste des manuels dans https://capes-nsi.org/environnement/ pour avoir un large échantillon) ou de ressources en ligne ; par exemple le MOOC Apprendre à coder avec Python sur la plateforme FUN-MOOC qui :

  • fait la part belle à la pratique, en proposant de valider les codes produits par les apprenants,
  • est un cours d'initiation au codage avec Python 3 avec comme publics cibles les Lycéens et leurs enseignants,
  • est sous Creative Commons CC-BY-SA,
  • voit toute la partie programmation impérative de base de Python (en particulier : les instructions, fonctions, séquences, ensembles et dictionnaires).

En fonction de vos besoins, libre à vous de le faire en partie ou totalement, y compris ou non le projet.

Ne sont pas vus dans ce mooc Python : la récursivité, les bases de la programmation orientée objets ainsi que la plupart des algorithmes du programme NSI des Lycées.

Pour connaître le vocabulaire Python de base et son fonctionnement

Même si la démarche de l'enseignant en informatique doit plutôt être celle de celui qui guide et accompagne l'élève plutôt que celui qui sait (maître ignorant plus que omniscient), une fois à l'aise avec la programmation impérative de base en Python, il est bon de connaître le b.a.-ba du vocabulaire Python. Python étant un langage contenant de nombreux concepts allant bien au delà de ce qui doit être enseigné à nos élèves, une sélection peut être faite pour ne pas se noyer.

L'extrait du glossaire Python https://upylab.ulb.ac.be/pub/glossaire_python/Modules/glossaire_extrait.html

reprend les termes importants dans le cadre de l'enseignement de Python dans les Lycées.

Le glossaire provient du glossaire, en version française, donné dans la documentation officielle : https://docs.python.org/fr/3/glossary.html#glossary .

Avoir une connaissance claire des mécanismes de base du fonctionnement de Python

Enseigner la programmation en Python demande à l'enseignant de trouver, au niveau des contenus, un juste milieu entre une approche simple ou approfondie.

Une approche par couche permet à l'élève d'appréhender la matière, de la comprendre, de l'assimiler pour finir par la maîtriser. L'enseignant doit être clair, précis mais sans donner trop de détails qui nuiraient à la compréhension.

La plupart des ouvrages à destination des élèves et enseignants simplifient certaines notions Python. Cela peut devenir un souci quand certains concepts cachés sont utiles pour comprendre d'autres facettes du fonctionnement du langage.

Voici des notions dont vous devez avoir une compréhension claire des mécanismes.

  • Variable
  • Nom
  • Valeur
  • Objet
  • Classe

Une variable est un nom auquel on associe une valeur via l'affectation, appelée également assignation, une valeur étant un objet d'un certain type (plus précisément d'une certaine classe)

  • Affectation ou assignation simple : l'assignation définit une variable : elle peut :
  • donner un nom v à un objet nouvellement créé grâce à l'évaluation d'une valeur : v = valeur
  • ajouter un nouveau nom à un objet déjà nommé : a = bb est une variable déjà définie ; a et b sont donc des alias.
  • Passage de paramètres : dont le mécanisme est celui de l'assignation de l'argument au paramètre correspondant, les portées pouvant être différentes puisque le paramètre correspond à une variable locale à l'instance de la fonction appelée.
  • Diagramme d'état (voir pythontutor.com http://pythontutor.com/visualize.html#) qui montre l'état de la pile et du tas d'exécution (runtime stack and heap) tout au long de l'exécution du code ; les trames (frames) montrent les différents espaces de noms sur la pile d'exécution et les objets étant sur le tas d'exécution.

Les diagrammes d'états illustrent parfaitement le fonctionnement d'un code Python. Cela permet, par exemple, - de montrer pourquoi une liste reçue en paramètre peut être modifiée et, - la différence entre :

def ma_fonction(m):
    m[0] = 3

ma_liste = [2, 5, 7]
ma_fonction(ma_liste)
print(ma_liste)
[3, 5, 7]

qui modifie la composante 0 de ma_liste et

def ma_fonction(m):
    m = [3] + m[1:]

ma_liste = [2, 5, 7]
ma_fonction(ma_liste)
print(ma_liste) 
[2, 5, 7]

qui crée dans ma_fonction une nouvelle liste qui va porter le même nom m que la liste reçue en paramètre, cette dernière n'étant pas modifiée.

Concepts de programmation à enseigner et leur traduction possibles en Python.

Objets immuables versus muables

Objets simples

Le fait que les variables simples (int, float, bool) correspondent à des objets immuables ne pose généralement pas de problème. Par exemple :

a = b = 36
b = b + 1 
print(a, b)
36 37

peut être vu comme deux variables différentes a et b, initialisées à une certaine valeur mais qui évoluent différemment. Il peut être fait abstraction du fait que la première instruction crée un objet int valant 36 et que a et b sont des alias de cet objet, puisque ce n'est plus le cas dès la seconde instruction. De façon générale, puisque l'objet est immuable, on ne pourra le modifier en gardant les alias.

Séquences

Les choses sont évidemment différentes avec les objets muables, comme le rappelle l'exemple suivant :

a = b = [36]
b[0] = b[0] + 1
print(a, b)
[37] [37]

Plus généralement, il est important de bien montrer la différence entre les séquences immuables (n-uplets et chaînes de caractères) et les séquences muables (listes, ensembles, dictionnaires). Il faut en particulier faire attention aux méthodes qui les manipulent (voir par exemple l'aide mémoire https://upylab.ulb.ac.be/pub/aide-memoire-Python.pdf). Pour chaque méthode d'une classe de séquence, il est important de voir si la méthode : - modifie l'objet (ce qui est évidemment impossible pour les objets immuables) - renvoie un résultat (voir par exemple la différence entre les méthodes sort()et sorted())

Tableau, table, vecteur, matrice, cube et toutes ces sortes de choses

Les algorithmiques simples (par exemple, recherche, tris, ...) manipulent des structures de données non simples à une ou plusieurs dimensions.

Tableaux à une dimension ou vecteurs et leur traduction en Python de base (sans nouvelles classes)

Par ordre de difficulté croissante, l'étudiant débute sur les tableaux à une dimension contenant des valeurs simples, par exemple des entiers.

vecteur = [i**2 for i in range(10)] # tableau des 10 premiers carrés de nombres naturels

dont le premier élément est vecteur[0], qui peuvent être étendus en tableaux à une dimension dont les éléments peuvent contenir plusieurs informations, par exemple sous forme de n-uplet d'informations :

tableau = [('Isabelle', 36), ('Sophie', 42), ('Thierry', 55), ('Gabriel', 44)]
print(tableau[1][0])
Sophie

Tableaux à 2 ou plus de dimensions

La notion de matrice, par exemple de valeurs entières ou flotantes, est utilisée en mathématiques. Par exemple :

avec une liste

voir MOOC "Apprendre à coder avec Python" section 5.9 (manipulons les matrices https://www.fun-mooc.fr/courses/course-v1:ulb+44013+session04/courseware)

carre = [[2, 7, 6], [9, 5, 1], [4, 3, 8]] 
print(carre[0][0])
print(carre[2][2])
2
8

donne une matrice 3 x 3 dont les deux indices vont de 0 à 2 compris.

Notons que le code suivant crée dans mat une matrice 3 x 3 nulle sous forme d'une liste avec 3 sous-listes, tandis que dans pas_mat, la structure créée n'est pas une matrice, comme on peut le voir grâce à PythonTutor ou en affichant le résultat après avoir fait pas_mat[1][1] = 666 :

mat = [[0]*3 for _ in range(3)]
pas_mat = [[0]*3]*3 # ceci n'est pas une matrice nulle !
pas_mat[1][1] = 666
print(pas_mat) # Affiche [[0, 666, 0], [0, 666, 0], [0, 666, 0]] 

Comme pour les tableaux à une dimension, chaque composante d'une matrice peut être non simple.

Pour des tableaux à 3 ou plus de dimensions, on parle de cube.

avec un dictionnaire

Une matrice ou un cube peut également être implémenté avec un dictionnaire Python dont les indices sont des couple (ou n-uplets) de valeurs entières.

carre_dic = {(1,1): 2, (1,2): 7, (1,3): 6, 
             (2,1): 9, (2,2): 5, (2,3): 1, 
             (3,1): 4, (3,2): 3, (3,3): 8}
print(carre_dic[2,2])
5

Ici, nous avons rompu avec la convention Python de débuter l'indiçage à 0

Implémenter un arbre sans définir de nouvelles classes

Un arbre peut être implémenté avec des listes :

arbre_abstrait = [3, '+', [5, '*', 7]]

peut, par exemple, représenter sous forme d'arbre binaire, une expression arithmétique ; la racine à la valeur '+', le fils gauche 3et le fils droit est le sous-arbre de racine '*', de fils gauche 5et de fils droit 7. (On simplifie les feuilles sous la forme d'une valeur simple, ici de type int.)

voir MOOC "Apprendre à coder avec Python" section 5.9 (manipulons les matrices https://www.fun-mooc.fr/courses/course-v1:ulb+44013+session05/courseware)

Notons que les arbres vont de pair avec la pratique de la récursivité (non abordée dans le MOOC "Apprendre à coder avec Python). La fonction evalue évalue une telle expression arithmétique où les opérateurs possibles sont '+' (addition), '-' (soustraction), '*' (multiplication), '/' (division) et '^' (exponentiation).

def evalue(v):
   """eval(v) récursive où v est l'arbre syntaxique abstrait de l'expression arithmétique"""
   if type(v) is not list:
       res= v
   elif v[1]=='+':
       res = evalue(v[0]) + evalue(v[2])
   elif v[1]=='-':
       res = evalue(v[0]) - evalue(v[2])
   elif v[1] == '*':
       res = evalue(v[0]) * evalue(v[2])
   elif v[1]=='/':
       res = evalue(v[0]) / evalue(v[2])
   elif v[1] == '^':
       res = evalue(v[0]) ** evalue(v[2])
   else:
       res = None # error
   return res

arbre_abstrait = [3, '+', [5, '*', 7]]
print(evalue(arbre_abstrait))
38

Implémenter un graphe sans définir de nouvelles classes

Un graphe orienté peut être implémenté avec un dictionnaire Python où la clé de chaque entrée identifie un sommet du graphe et la valeur associée est l'ensemble (des clés correspondant à) de ses voisins.

graphe = {'Isabelle' : {'Thierry', 'Gabriel'}, 
          'Sophie' : {'Isabelle'}, 
          'Thierry' : {'Gabriel', 'Isabelle'}, 
          'Gabriel' : set()}
print(graphe['Isabelle']) # amis d'Isabelle
{'Gabriel', 'Thierry'}

L'exercice suivant demande la construction d'un tel graphe :

https://www.fun-mooc.fr/courses/course-v1:ulb+44013+session04/courseware/333595ac156e41ac8b9d6ceadc901cf7/6434a1bd0117493e99b90912de97619b/