Les blocs “Consigne” synthétisent les étapes à faire pour mener à bien le TP.
Les TP de l’UE Projets Numériques sont construits de manière incrémentale : chaque TP s’appuie sur le travail fait lors des TP précédents. À des fins d’organisation de code, il est recommandé, lors avant chaque nouveau TP, de :
Créer un nouveau fichier Python correspondant au nouveau TP, par exemple tp5.py
Ajouter les fonctions que vous avez implémentées au TP précédent dans un fichier my_functions.py
import sys; sys.path.append('.'); from my_functions import * dans le fichier du nouveau TP
Démarrer le sujet du nouveau TP
Avertissement
De nombreux exemples sont donnés dans les sujets de TP pour illustrer des notions de code. Ne copiez-collez pas ces exemples sans réfléchir. Les fonctions (par exemple la fonction write_xyz) données telles quelles dans le sujet peuvent être copiées sans soucis.
Puisque chaque TP s’appuie sur les TP précédents, il est important de terminer chaque TP, même si les TP 1 à 4 ne sont pas évalués, car aucune correction ne sera donnée. En cas de blocage, il est donc essentiel de demander de l’aide, à vos collègues ou au responsable (moi).
Utilisation de modèles génératifs (type ChatGPT)
L’un des objectifs l’UE Projets Numériques est d’apprendre à traduire des idées mathématiques en code. Les algorithmes qu’il faut implémenter sont relativement simples et suffisamment documentés pour que ChatGPT (ou un autre modèle génératif) soit capable de générer un code fonctionnel. Cela veut aussi dire que ces algorithmes sont tout à fait à la portée d’étudiants de L3 ! Si vous voulez utiliser un modèle génératif, essayez de vous en servir comme d’une aide à l’apprentissage, et non comme un outil qui ferait le travail à votre place.
Note
Dans tous les cas, n’hésitez pas à poser des questions en cas de doute.
Python
Tous les travaux pratiques et le projet se feront en Python. Avant de commencer les TPs d’implémentation, vérifions que l’installation Python à disposition (dans les salles de TP ou sur une machine personnelle) est suffisante :
Consigne
Ouvrir “Anaconda Navigator” puis “Spyder” depuis Anaconda.
Vérifiez que les librairies numpy et matplotlib sont bien présentes (import numpy; import matplotlib.pyplot)
Pour la rédaction du rapport, il est recommandé d’utiliser LaTeX, le Wikibook LaTeX est une excellente ressource, et Overleaf une bonne solution d’édition, qui évite d’installer LaTeX et permet facilement la collaboration.
Afin de se refamiliariser avec Python, il est fortement recommandé de faire les exercices corrigés de code du chapitre sur l’intégration numérique des équations différentielles ordinaires.
Important
Dans Spyder, n’utilisez jamais la fonctionnalité de “cellule” ou de “notebook” (le bouton “Exécuter la cellule”). C’est une grosse source d’erreurs difficiles à tracer. À la place, toujours exécuter un script avec le bouton “Exécuter le fichier” ou le raccourci “F5”.
Installation de paquets Python
Sur les ordinateurs de TP, il est possible d’installer des paquets Python avec la commande :
Il est possible qu’il faille redémarrer le noyau IPython pour pouvoir import matscipy: dans Spyder, Console > Redémarrer le noyau, ou avec le raccourci Ctrl+..
Quelques erreurs communes en Python et Numpy
Création vs. mise-à-jour de la valeur d’une variable
N =10velocities = np.zeros([2, N])velocities[:] =1print(f"`velocities[:] = 1` donne :\n{velocities}\n")velocities =2print(f"`velocities = 2` donne :\n{velocities}")
1
On crée des vitesses 2D pour chaque particule
2
On assigne une valeur à chaque composante du vecteur velocities
3
On crée une nouvelle variable qui vient effacer la première
Le code velocities[:] = 1 permet d’assigner la valeur 1 à toutes les valeurs du tableau velocities, qui est un “Numpy array”. En revanche, quand on écrit velocities = 2, on crée en réalité une nouvelle variable qui vient détruire l’ancienne variable. velocities est donc maintenant un entier qui vaut 2.
Valeur de retour d’une fonction
def forward_euler1(position, velocity, dt):return position + velocity * dtdef forward_euler2(position, velocity, dt): position += velocity * dt
La première fonction retourne la position après une itération d’Euler explicite. On doit donc l’utiliser comme ceci, en assignant la valeur de retour de la fonction :
Notez que si on utilise forward_euler2 comme forward_euler1, on change complètement la variable position, qui devient None :
position = forward_euler2(position, velocity, dt)print(position, type(position))
None <class 'NoneType'>
Cela peut facilement causer des erreurs dans le reste du code, par exemple :
position +=1.0
---------------------------------------------------------------------------TypeError Traceback (most recent call last)
CellIn[7], line 1----> 1position+=1.0TypeError: unsupported operand type(s) for +=: 'NoneType' and 'float'
Expliciter les types de variables en Python
Depuis la version 3.5 de Python, il est possible d’annoter le type d’une variable. Contrairement à un langage comme le C, le type indiqué en Python est purement indicatif : il ne contraint en rien l’exécution du programme si le type indiqué ne correspond pas au type effectif de la variable. L’annotation se fait comme suit :
L’intérêt d’annoter les types est de pouvoir préciser les types qu’une fonction attend pour ses arguments, par exemple :
def exponentielle(x: float):return np.exp(x)
On peut également préciser des types issus de Numpy. Il faut dans ce cas importer le module numpy.typing, par exemple, si une fonction attend un tableau de flottants :