USMA1Q — Méthodes Numériques¶

Séance 1 — Fondamentaux de Python¶

Conservatoire National des Arts et Métiers

03 Mars 2026

nicholas-anton.collins-craft@enpc.fr

Plan du cours¶

Jour Sujet
03 mars Fondamentales de la programmation en Python
04 mars Fondamentales de la programmation en Python
11 mars Matrices, précision et la résolution numérique des équations linéaires
18 mars Interpolation, la recherche des racines des fonctions et la résolution numérique des équations non linéaires
25 mars Intégration numérique
02 avril La résolution numérique des équations différentielles ordinaires et partielles
08 avril Examen

Plan de la séance (indicatif)¶

Horaire Sujet
0:00 – 0:20 Mise en route et motivation
0:20 – 1:00 Variables, types et expressions
1:00 – 1:50 Structures de contrôle (if/elif/else)
1:50 – 2:00 ☕ Pause
2:00 – 2:50 Boucles (for, while)
2:50 – 3:45 Mini-projet guidé

1 · Mise en route¶

Vérification de l'installation¶

Ouvrez votre IDE (VS Code, Spyder…) et tapez :

print("Bonjour le monde !")

Si vous voyez Bonjour le monde ! dans le terminal, Python fonctionne.

print() — imprime le texte ou quantité qui apparaît entre les paranthèses dans le terminal

Pourquoi Python pour un ingénieur matériaux ?¶

  • Automatiser le traitement des données de laboratoire
  • Remplacer Excel pour des calculs complexes et reproductibles
  • Simuler des procédés et des comportements mécaniques
  • Visualiser des résultats de façon professionnelle
  • Partager du code : un collègue peut relancer exactement le même calcul

Python est gratuit, multiplateforme, et la bibliothèque scientifique (NumPy, Matplotlib, SciPy…) est immense.

Démonstration — ce que vous saurez faire (très bientôt !)¶

Le script ci-dessous lit un fichier d'essai de traction et trace la courbe contrainte–déformation.

In [ ]:
# ── Démonstration ───
import matplotlib.pyplot as plt

# Données simulées d'un essai de traction
déformation = [0.000, 0.002, 0.005, 0.010, 0.020, 0.050, 0.100, 0.150, 0.200]
contrainte = [  0,   400,  1000,  2000,  3200,  4500,  5000,  4800,  4000]

plt.figure(figsize=(7, 4))
plt.plot(déformation, contrainte, 'b-o', linewidth=2)
plt.xlabel("Déformation ε (sans unité)")
plt.ylabel("Contrainte σ (MPa)")
plt.title("Courbe contrainte–déformation — acier hypothétique")
plt.grid(True)
plt.tight_layout()
plt.show()

2 · Variables, types et expressions¶

Une variable peut-être pensée comme une boîte étiquetée qui contient une valeur.

module_young = 210.0   # GPa — acier
nom_materiau = "Acier inoxydable 316L"
nb_echantillons = 20
spec_passee = True

Python déduit automatiquement le type — pas besoin de le déclarer.

Le = est une commande d'attribution. Il dit que la variable à la gauche prends le valeur donné au droit.

La valeur d'une variable peut changer¶

Une variable n'est pas figée — on peut lui réaffecter une nouvelle valeur à tout moment.

temperature = 20.0
print(temperature)   # → 20.0

temperature = 850.0  # on écrase l'ancienne valeur
print(temperature)   # → 850.0

Une variable peut apparaître des deux côtés du =¶

C'est une des choses les plus importantes à comprendre. Le = n'est pas une équation mathématique — c'est une instruction : "calcule ce qui est à droite, puis stocke le résultat dans la variable à gauche".

compteur = 0
compteur = compteur + 1   # lire l'ancienne valeur (0), ajouter 1, stocker (1)
print(compteur)            # → 1

compteur = compteur + 1   # même chose : 1 + 1 = 2
print(compteur)            # → 2

Opérateurs d'affectation raccourcis¶

Cette opération est si courante que Python fournit des écritures abrégées :

Abrégé Équivalent complet Signification
x += 3 x = x + 3 ajouter 3 à x
x -= 3 x = x - 3 soustraire 3 de x
x *= 2 x = x * 2 doubler x
x /= 2 x = x / 2 diviser x par 2
total = 0
total += 450   # total vaut maintenant 450
total += 380   # total vaut maintenant 830
print(total)   # → 830

Affecter la valeur d'une variable à une autre¶

On peut copier la valeur d'une variable dans une nouvelle variable avec =.

module_acier = 210.0   # GPa
E = module_acier       # E reçoit une copie de la valeur 210.0
print(E)               # → 210.0

Attention — ce n'est qu'une copie de la valeur¶

Modifier E ensuite ne change pas module_acier, et vice-versa :

module_acier = 210.0
E = module_acier       # copie : E vaut 210.0

E = 70.0               # on réaffecte E (aluminium)
print(E)               # → 70.0
print(module_acier)    # → 210.0  (inchangé !)

La ligne E = module_acier ne crée pas un lien permanent entre les deux variables. Elle dit simplement : "prends la valeur que contient module_acier en ce moment, et mets-la dans E". Après cela, les deux variables sont indépendantes.

À noter : ceci est vrai pour les nombres (int, float) et les chaînes de caractères. Pour les autres types de variables (voir listes), le comportement est différent — nous y reviendrons.

Exemple concret¶

longueur_initiale = 50.0    # mm
longueur_finale   = longueur_initiale   # copie

longueur_finale = longueur_finale + 13.5   # allongement après traction
print("L0 =", longueur_initiale)  # → 50.0  (inchangé)
print("Lf =", longueur_finale)    # → 63.5

Les types fondamentaux¶

Type Python Ce qu'il représente Exemple
int — entier Nombre entier 20, -3, 0
float — flottant Nombre réel (en pratique un décimal) 210.0, 3.14e-3
str — chaîne de caractères Texte "MPa", 'verre'
bool — booléen Vrai ou faux True (vrai), False (faux)
type(210)      # → <class 'int'>
type(210.0)    # → <class 'float'>
type("GPa")    # → <class 'str'>
type(True)     # → <class 'bool'>

int vs float — attention !¶

# Division entière vs division réelle
7 / 2    # → 3.5   (float)
7 // 2   # → 3     (int)  ← division entière (plancher)

En ingénierie, on travaille presque toujours avec des float.
Utiliser 210 là où 210.0 est attendu peut introduire des erreurs silencieuses.

# Bonne pratique : écrire le point décimal explicitement
E_acier = 210.0   # GPa

Les listes¶

Une liste (list) contient plusieurs valeurs dans un ordre défini.

durete = [245, 251, 238, 260, 249]   # mesures HB

Attention! Le premier élément d'une liste en Python est indexé par le nombre 0 !

print(durete[0])   # → 245  (premier élément, indice 0)

Le dernier élément d'une liste peut-être indexé par le nombre -1 (et -2 pour l'avant-dernier etc)

print(durete[-1])  # → 249  (dernier élément)

La commande len (où on mets la liste on veut savoir entre les parenthèses après)

print(len(durete)) # → 5    (nombre d'éléments)

Les listes peuvent mélanger les types, mais en pratique on ne le fait pas.

Elles s'agrandissent dynamiquement : durete.append(255) mets 255 comme dernier élément.

Une liste peut contenir d'autres listes¶

Les éléments d'une liste peuvent eux-mêmes être des listes. C'est la façon naturelle de représenter des tableaux de données en Python "pur".

lot_a = [242, 248, 235, 255, 251]
lot_b = [239, 253, 241, 257, 245]

lots = [lot_a, lot_b]   # liste de deux listes

print(lots[0])      # → [242, 248, 235, 255, 251]  (premier lot)
print(lots[1][2])   # → 241  (3e élément du second lot)

On accède à un élément avec deux indices : lots[i][j] — d'abord le numéro du lot, ensuite le numéro de la mesure dans ce lot.

⚠️ Affecter une liste à une autre — attention !¶

Pour les nombres et les chaînes, b = a copie la valeur — les deux variables sont ensuite indépendantes. Pour les listes, ce n'est pas le cas.

mesures_a = [245, 251, 238]
mesures_b = mesures_a       # PAS une copie — même liste en mémoire !

mesures_b.append(260)

print(mesures_a)   # → [245, 251, 238, 260]  ← modifié aussi !
print(mesures_b)   # → [245, 251, 238, 260]

mesures_b = mesures_a crée un second nom pour la même liste en mémoire. Toute modification via l'un des deux noms est visible par l'autre.

Pour faire une vraie copie indépendante, utilisez list() :¶

mesures_a = [245, 251, 238]
mesures_b = list(mesures_a)   # copie indépendante

mesures_b.append(260)

print(mesures_a)   # → [245, 251, 238]       (inchangé)
print(mesures_b)   # → [245, 251, 238, 260]

Ce comportement est commun à tous les types mutables en Python (listes, dictionnaires…). Les types immuables (int, float, str, bool) n'ont pas ce problème.

À vous de faire les exercises 1.1 et 1.2 dans le fichier session1_exercices.ipynb !¶

Il est trouvable à l'addresse suivant : https://github.com/nickcollins-craft/USMA1Q-Methodes-Numeriques/

2. Opérations arithmétiques¶

Opérateur Signification Exemple Résultat
+ - * / Opérations de base 500 / 1000 0.5
** Puissance (exponentiation) 2 ** 10 1024
// Division entière (plancher) 7 // 2 3
% Modulo (reste de division) 7 % 2 1
# Conversion MPa → GPa
sigma_mpa = 450.0
sigma_gpa = sigma_mpa / 1000.0   # → 0.45

# Surface d'un disque (rayon en mm)
r = 12.5
aire = 3.14159 * r ** 2          # → 490.87 mm²

À noter que l'espace entre opérateurs ne fait rien (donc a * b + c / d est équivalent à a*b+c/d). Il peut faciliter la lisibilité du code (et votre propre compréhension) d'écrire avec une utilisation judicieuse des éspaces (moi j'écrire comme a*b + c/d) et/ou des parenthèses pour bien grouper les termes.

Opérateurs spéciaux : **, //, %¶

** — Puissance¶

Choisi pour des raisons historiques (Fortran, Ada…).
^ est réservé au OU-exclusif binaire en Python.

2 ** 8    # → 256
1.5 ** 3  # → 3.375

// — Division entière (plancher)¶

Utile pour : numérotation de cycles, partitionnement de données.

echantillon = 17 // 5   # → 3  (3 groupes complets de 5)

% — Modulo (reste)¶

Utile pour : tester la parité, les cycles périodiques.

17 % 5    # → 2  (il reste 2 après 3 groupes de 5)
est_pair = (n % 2 == 0)

Les commentaires (#)¶

Un commentaire commence par # — Python ignore tout ce qui suit. Le commentaire peut commencer une ligne, ou être mis au fin de la ligne. La convention est de garder une espace après le #, et si le commentaire est au fin, d'avoir deux espaces avant le #

# Calcul du taux d'allongement
L0 = 50.0  # longueur initiale en mm
Lf = 63.5  # longueur finale en mm
A = (Lf - L0) / L0 * 100  # allongement en %
# résultat attendu : 27 %

Pourquoi commenter ?

  • Vous relirez ce code dans 6 mois — vous aurez oublié
  • Un collègue doit comprendre votre raisonnement
  • Les commentaires expliquent le pourquoi, pas seulement le quoi

Règle d'or : chaque bloc logique mérite au moins un commentaire.

À vous de faire les éxercices 2.1 et 2.2 !¶

3 · Structures de contrôle¶

if (si) / elif (sinon si) / else (sinon)¶

E = 70.0   # GPa — module de Young

if E < 10:
    print("Polymère")
elif E < 100:
    print("Aluminium ou matériau intermédiaire")
elif E < 300:
    print("Acier ou céramique dense")
else:
    print("Matériau exceptionnel")

⚠️ L'indentation est obligatoire en Python.
Utilisez 4 espaces (ou Tab). Un mauvais alignement = erreur, et la programme ne tournera pas.

Opérateurs de comparaison¶

Opérateur Sens Exemple
== égal à E == 210
!= n'est pas égal à materiau != "polymère"
< > strictement inférieur / supérieur sigma > 500
<= >= inférieur ou égal / supérieur ou égal T <= 1200

Attention : = assigne une valeur — == compare.

x = 5      # assigne 5 à x
x == 5     # → True  (compare x avec 5)

Opérateurs logiques : and (et), or (ou), not (non)¶

L'opérateur and exige que les booléens des deux côtés sont vrais. L'opérateur or exige qu'au moins un des deux booléens est vrai (c'est un or dit inclusif). L'opérateur not exige que le booléen qui le suit est faux.

T = 850      # °C
pression = 1.2   # bar

# Les deux conditions doivent être vraies
if T > 800 and pression >= 1.0:
    print("Conditions de frittage atteintes")

# Au moins une condition suffit
if T > 1000 or pression > 5.0:
    print("Risque de surchauffe")

# Négation
if not spec_passee:
    print("Échantillon hors spécification")

À vous de faire les éxercices 3.1, 3.2 et 3.3 !¶

☕ Pause — 10 minutes¶

4 · Boucles¶

Boucle while — tant que¶

Répète un bloc tant qu'une condition est vraie.

temperature = 20.0   # °C

while temperature < 900.0:
    temperature = temperature + 50.0   # on chauffe par pas de 50 °C
    print(f"T = {temperature} °C")

print("Température de palier atteinte.")

Utilisez while quand vous ne savez pas à l'avance combien d'itérations seront nécessaires. Mais fait attention, si la condition qui gouverne la boucle n'est jamais rempli, la boucle va jamais finir à tourner.

Boucle for et range() (suite d'entiers) — pour chaque¶

Parcourt une séquence un élément à la fois.

mesures = [245, 251, 238, 260, 249]

for valeur in mesures:
    print(valeur)

range(n) génère les entiers de 0 à n-1 :

for i in range(5):
    print(i)   # 0, 1, 2, 3, 4

Complexité : une boucle sur n éléments fait n opérations.
Si vous doublez les données, vous doublez le temps.
Une boucle dans une boucle → n² opérations. Attention !

Patron accumulateur¶

mesures = [245, 251, 238, 260, 249]

# Calcul de la somme
total = 0
for v in mesures:
    total += v          # total = total + v

moyenne = total / len(mesures)
print("Moyenne =", moyenne, "HB")

# Calcul du maximum
maximum = mesures[0]
for v in mesures:
    if v > maximum:
        maximum = v
print("Maximum =", maximum, "HB")

À vous de faire les éxercices 4.1–4.4 !¶

5 · Mini-projet guidé¶

Scénario¶

Vous recevez 20 mesures de dureté Brinell d'un lot de pièces forgées. La spécification impose une dureté moyenne ≥ 240 HB et un écart-type ≤ 15 HB.

Votre script doit :

  1. Stocker les 20 valeurs dans une liste
  2. Calculer la moyenne, le maximum et l'écart-type
  3. Afficher si le lot est conforme ou non conforme
  4. Rédiger une analyse d'ingénierie : le procédé industriel est-il acceptable ?
In [ ]:
# Données — 20 mesures de dureté Brinell (HB)
durete_lot_A = [
    242, 248, 235, 255, 251,
    238, 246, 260, 244, 250
]
durete_lot_B = [
    239, 253, 241, 257, 245,
    252, 237, 249, 243, 258
]  # Notons qu'on peut écrire les listes sur plusieurs lignes pour plus de lisibilité

Points clés de la séance¶

Concept Ce qu'il faut retenir
Types int, float, str, bool — Python les détecte automatiquement
Listes Séquences d'éléments, indexées à partir de 0
Opérateurs ** puissance, // plancher, % reste
if/elif/else L'indentation délimite les blocs — 4 espaces
for / while for pour un nombre connu d'itérations, while sinon
Commentaires # Documenter le pourquoi, pas seulement le quoi