Les nouvelles technologies pour l’enseignement des mathématiques
Intégration des TICE dans l’enseignement des mathématiques

MathémaTICE, première revue en ligne destinée à promouvoir les TICE à travers l’enseignement des mathématiques.

Calcul formel, programmation par blocs et Python avec SofusPy
Article mis en ligne le 8 juin 2018
dernière modification le 25 octobre 2018

par Patrick Raffinat

Cet article peut être librement diffusé à l’identique dans la limite d’une utilisation non commerciale suivant la license CC-by-nc-nd http://creativecommons.org/licenses/by-nc-nd/3.0/fr/legalcode.

Voir aussi cette brève

A) Introduction

Est-ce vraiment utile de combiner calcul formel et programmation visuelle en mathématiques dans le secondaire ? J’avoue que je n’en sais rien, puisque j’enseigne l’informatique en IUT et, qu’en plus, j’ai beaucoup de mal à décrypter la ligne directrice du Ministère de l’Education Nationale concernant l’enseignement du codage.

Ce que je sais par contre, c’est qu’Alain Busser m’avait incité à me pencher sur le sujet il y a deux ans et que cela avait abouti à un prototype utilisant le tableur formel du logiciel Xcas (voir N°52), avant qu’il ne trouve une solution plus directe dans la dernière version du logiciel Sofus (voir N°59).

Ce que je sais aussi, c’est que les lecteurs de MathémaTICE sont très intéressés par les articles sur Python depuis que le Ministère recommande ce langage au lycée [1] , et qu’il existe une librairie (SymPy) permettant de faire du calcul formel en Python : je vais donc la présenter dans la première partie de cet article, puis l’utiliser dans une nouvelle version du logiciel SofusPy [2].

Pour exécuter un programme visuel formel, SofusPy le traduit en Python, puis transmet cette traduction au serveur « SymPy Live ». C’est donc une moins-value par rapport à Sofus qui peut fonctionner sans connexion à Internet, mais elle est compensée par d’autres atouts, en particulier une plus grande continuité entre la programmation visuelle numérique et la programmation visuelle formelle. Et puis, bien évidemment, un autre intérêt de SofusPy dans le contexte actuel est qu’il peut servir de tremplin pour faciliter l’enseignement de Python dans un cadre mathématique.

B) La librairie SymPy

Introduction

Pour tester la librairie SymPy, j’ai utilisé plusieurs environnements : un environnement en ligne (SymPy Live) et deux environnements installés localement (AmiensPython et EduPython).

Comme on peut le constater ci-dessus, « SymPy Live » effectue à son démarrage plusieurs instructions permettant de faire ensuite directement du calcul formel : une pour importer le module SymPy, une pour indiquer que la variable x est formelle…

Par ailleurs, il est à noter que « SymPy Live » peut faire directement des calculs avec des nombres rationnels (ici 15/6*5 vaut 25/2), alors que j’obtiens des résultats différents avec mes deux installations locales :

  • avec AmiensPython (Python 2), 15/6 vaut 2 (division entière), donc 15/6*5 vaut 10
  • avec EduPython (Python 3), 15/6 vaut 2.5 (division réelle), donc 15/6*5 vaut 12.5

Donc, pour obtenir les mêmes résultats qu’avec SymPy Live, divers aménagements du code Python sont à effectuer :

  1. from sympy import *
  2. x = symbols("x")
  3. expr = 2*x*x - 3*x + 1
  4. print(factor(expr))
  5. print(solve(expr))
  6. print(integrate(expr))
  7. fract = Rational(15,6)*5
  8. print(fract)

Télécharger

Les « print » ne sont pas nécessaires si on utilise les environnements AmiensPython et EduPython en mode console.

Documentation

Pour me former à SymPy, j’ai utilisé plusieurs documents qu’on peut facilement trouver en tapant « SymPy tutoriel » dans un moteur de recherches, en particulier des notes de cours de Sébastien Labbé à l’Université de Liège. Ces notes de cours, d’environ 100 pages, sont disponibles au format pdf ou au format html.

Cet extrait illustre la richesse de SymPy en matière de mathématiques symboliques. Je n’en donnerai qu’un petit aperçu dans cet article.

Fonctions mathématiques numériques et fonctions mathématiques symboliques

La librairie « math » propose de nombreuses fonctions mathématiques usuelles : racine carrée (sqrt), exp, sin... La librairie SymPy propose également ces fonctions sous une forme symbolique.

Lorsqu’on utilise ces fonctions symboliques avec des nombres, leur fonctionnement diffère sensiblement de celui des fonctions de la librairie math :

  1. import math
  2. print(1+math.sqrt(3*3))   # 4.0 (calcul reel)
  3. print(1+math.sqrt(3))    # 2.73205080757
  4. from sympy import *
  5. print(1+sqrt(3*3))   # 4 : calcul exact avec simplification
  6. print(1+sqrt(3))   # 1+ sqrt(3) : pas d’evaluation de la racine carree
  7. print(N(1+sqrt(3)))   # 2.73205080757

Télécharger

Après ce préambule, nous allons utiliser deux fonctions symboliques (sqrt et sum) pour définir plusieurs fonctions Python (moyenne, variance et ecartType) :

  1. from sympy import *
  2. def moyenne(t) :
  3.     return sum(t)/len(t)
  4. def variance(t) :
  5.     n = len(t)
  6.     moy = moyenne(t)
  7.     total = 0
  8.     for k in range(n) :
  9.         total = total + (t[k]-moy)**2
  10.     return total/n
  11. def ecartType(t) :
  12.     return sqrt(variance(t))

Télécharger

En voici une première utilisation avec des nombres rationnels :

En voici une seconde utilisation avec des expressions formelles :

C) Programmation visuelle avec SofusPy

Introduction

Pour rendre attractive la programmation visuelle formelle, il me semble indispensable de l’envisager en tant que prolongement de la programmation visuelle classique. C’est pourquoi j’ai cherché à ce qu’un programme créé pour manipuler des réels puisse facilement être adapté à des fractions ou à des expressions formelles, ce que je vais illustrer avec ce programme de calcul présenté dans le N°52 :

Je montrerai ensuite qu’il est possible de l’adapter à des nombres complexes et ... même à des matrices ! Que les enseignants de lycée se rassurent, je ne suis pas en train de préconiser ce type d’exercice au lycée : j’illustre juste les potentialités de SofusPy, sans changer de thématique pour faciliter la lecture de l’article.

Nombres rationnels

Pour introduire une fraction avec SofusPy, il suffit d’utiliser l’opérateur de division :

Ensuite, afin que 15/4 soit interprété comme une fraction et non comme une division, il reste à remplacer la configuration standard par la configuration « calcul formel » :

Voici alors le résultat obtenu à l’exécution :

Le code du programme Python engendré peut être récupéré en cliquant sur le bouton « Editeur » : il peut alors être modifié, puis exécuté dans « SymPy Live ». Mais si l’objectif pédagogique est de récupérer le code pour l’utiliser dans un environnement externe, il faut faire attention : 15/4 sera alors évalué comme une division entière ou une division réelle suivant la version de Python. Il faut donc remplacer 15/4 par Rational(15,4) dans le code Python :

  1. from sympy import *
  2. n = Rational(15,4)
  3. copie = n * n
  4. n = n + 3
  5. n = pow(n,2)
  6. n = n - copie
  7. print(n)

Télécharger

Calcul formel

SofusPy considère que 4 variables (x, y, z et t) sont par défaut formelles, à moins qu’on ne leur attribue une valeur dans le programme :

L’exécution de ce programme montre qu’un simple affichage ne simplifie pas l’expression formelle finale, ce qui justifie l’introduction du bloc « simplifier » :

Complexes

SofusPy considère que la variable « I » (« i » majuscule) correspond par défaut au nombre complexe « i », à moins qu’on ne lui attribue une valeur dans le programme :

L’affichage de la variable « copie » (qui vaut -1) a été ajouté pour prouver que « I » n’est pas une variable formelle (comme « x » l’était précédemment). Voici la trace de l’exécution :

Matrices

SofusPy peut aussi être utilisé pour faire du calcul matriciel, même si l’apport pédagogique de la programmation par blocs est a priori très modéré !

Il est probablement plus réaliste d’envisager la programmation par blocs de SofusPy comme un moyen amusant de familiariser les élèves avec les instructions Python permettant de faire du calcul matriciel. A titre indicatif, voici le code Python engendré par SofusPy pour cet exemple :

  1. from sympy import *
  2. x, y, z, t = symbols('x y z t')
  3. n = Matrix([[x, 1 / t], [t, x * x]])
  4. copie = n * n
  5. n = n + 3 * Matrix([[1, 0], [0, 1]])
  6. n = pow(n,2)
  7. n = n - copie
  8. print(n)
  9. print(simplify(n))

Télécharger

Ce code montre qu’une matrice peut facilement être définie à partir d’une liste de listes, et que les opérateurs usuels (+,*) peuvent lui être appliqués. La fonction « pow » (ou l’opérateur **), qui permet ici d’élever une matrice au carré, peut aussi inverser une matrice en lui affectant l’exposant -1.

Au delà du cas particulier des matrices, il apparaît que les utilisations les plus courantes du calcul formel nécessitent peu d’apprentissage supplémentaire par rapport à celui du « Python de base » : donc, si des enseignants de lycée souhaitent intégrer un peu de calcul formel dans leurs enseignements, cela ne semble pas poser de problème particulier avec Python.

D) Petit extra : les polynômes de Lagrange

Introduction

J’avais prévu d’en rester là pour cet article lorsque j’ai lu un article du N°61 intitulé « Polynômes de Lagrange : récit d’une exploration en terminale S utilisant les outils informatiques ». La programmation n’est que la sixième étape d’une exploration fort intéressante aboutissant à un programme Scilab, dont l’équivalent symbolique en Python est fourni en annexe et reproduit ci-dessous :

  1. from math import*
  2. from sympy import*
  3.  
  4. def Flagrange(X,Y) :
  5.         n=len(X)
  6.         x=symbols("x")
  7.         P=0.
  8.         for i in range(0,n) :
  9.                 L=1
  10.                 for j in range(0,n) :
  11.                         if i==j : continue
  12.                         L=L*(x-X[j])/(X[i]-X[j])
  13.                 P=P+L*Y[i]
  14.         return simplify(P)
  15.  
  16. # polynome dont la courbe passe par les points A(1,6), B(-3,-8) et C(8,-4)
  17. X=[1,-3,8]
  18. Y=[6,-8,-4]
  19. print(Flagrange(X,Y))

Télécharger

C’est clairement un programme non trivial, comme le soulignent les remarques expliquant dans l’article les nombreuses difficultés rencontrées par les élèves :

  • les élèves sont parfois bloqués dans le calcul de la nouvelle valeur de la variable L (ou de la variable P) en fonction de l’ancienne, donc dans l’écriture de l’affectation.
  • il n’est pas naturel pour les élèves de définir une fonction, encore moins de choisir les paramètres X et Y en tant que vecteurs.
  • les élèves ont déclaré la fonction Flagrange , mais ensuite, que font-ils ? Il ne leur est pas toujours évident, ni naturel, de l’appeler en ayant pris soin de définir au préalable les vecteurs X et Y.

A l’arrivée, cela fait tellement d’informations données aux élèves qu’on peut presque se demander si cette sixième étape reste exploratoire ! Je me suis alors posé deux questions en tant qu’en enseignant d’informatique (en IUT) :

  • serait-il possible de rendre le problème plus accessible, notamment avec l’extension formelle de SofusPy ?
  • quels renseignements initiaux peut-on donner aux élèves pour espérer qu’ils puissent se débrouiller seuls ensuite, renseignements ne devant évidemment pas trop leur « mâcher le travail » ?

Programmation avec SofusPy : version 1

Ce programme est l’équivalent visuel du code Python fourni dans l’article sur les polynômes de Lagrange. En voici la trace de l’exécution :

Programmation avec SofusPy : version 2

Quels renseignements initiaux peut-on donner aux élèves pour espérer qu’ils puissent se débrouiller seuls ensuite, renseignements ne devant évidemment pas trop leur « mâcher le travail » ? Il m’est impossible d’y répondre puisque je ne connais pas le niveau algorithmique des lycéens à qui on le fournirait. Néanmoins, je suggère de leur fournir cette fonction qui correspond à la boucle interne calculant les produits :

SofusPy en fournit la traduction suivante en Python (bouton « Editeur ») :

  1. from sympy import *
  2. x, y, z, t = symbols('x y z t')
  3.  
  4. def coefficient(XX, i):
  5.         n = len(XX)
  6.         L = 1
  7.         for j in range(0,n ):
  8.                 if i != j:
  9.                         L = L * (x - XX[j])
  10.                         L = L / (XX[i] - XX[j])
  11.         return L
  12.  
  13. print(coefficient([1, -3, 8], 0))
  14. print(expand(coefficient([1, -3, 8], 0)))
  15. print(factor(coefficient([1, -3, 8], 0)))

Télécharger

Avant de passer à l’étape finale de la programmation, je suggère d’inciter les élèves à utiliser des moyens plus rudimentaires afin de trouver le polynôme de Lagrange dont la courbe passe par les points A(1,6), B(-3,-8) et C(8,-4). Il s’agit d’un exemple étudié (sans programmation) lors de l’exploration, dont on peut retrouver les résultats ainsi :

On peut espérer que des élèves de terminale S soient capables de terminer la programmation par eux-mêmes : sommer n termes, c’est similaire à multiplier n termes, sans compter qu’ils ont probablement déjà utilisé cette technique qu’on retrouve dans de nombreux algorithmes mathématiques. Peut-être le feront-ils sans introduire une nouvelle fonction, ce qui ne me gênerait pas outre mesure :

  1. XX = [1, -3, 8]
  2. YY = [6, -8, -4]
  3. n = len(XX)
  4. P = 0
  5. for i in range(0,n ):
  6.         P = P + YY[i] * coefficient(XX, i)
  7. print(P)
  8. print(expand(P))

Télécharger

L’essentiel est à mes yeux qu’ils parviennent à résoudre le problème de façon autonome. Et s’ils y parviennent sans introduire une nouvelle fonction, rien n’empêche de le leur demander ensuite. Voici une solution possible :

  1. def lagrange(XX, YY):
  2.         n = len(XX)
  3.         P = 0
  4.         for i in range(0,n ):
  5.                 P = P + YY[i] * coefficient(XX, i)
  6.         return expand(P)
  7.  
  8. print(lagrange([1, -3, 8], [6, -8, -4]))

Télécharger

Je suis parti de l’hypothèse que des lycéens opteraient pour une résolution en Python (à leur initiative ou à celle de leur enseignant), mais il est éventuellement envisageable de passer par la programmation par blocs :

E) Conclusion

SofusPy permet d’envisager la programmation visuelle formelle en tant que prolongement de la programmation visuelle « classique ». Est-ce suffisant pour la rendre attractive dans l’enseignement secondaire ? Aux enseignants concernés d’en décider…

Quoi qu’il advienne, cet article m’aura permis d’illustrer les possibilités de Python en matière de calcul formel, possibilités bien plus importantes que je ne le supposais au départ. Et j’espère qu’il donnera envie aux lecteurs d’en savoir plus, voire d’en tirer profit dans leurs enseignements.