Dans cette activité Python pour la Physique-Chimie, nous allons voir comment parvenir à réaliser des courbes de ce type qui nécessite de faire un choix vis à vis de l'avancement maximmum. Cela nous permettra de tracer des courbes de ce type :
A titre d'exemple, voici une animation qui vous propose deux boutons : GAUCHE permet d'aller à gauche et DROITE permet d'aller ... à droite.
Oui mais que faire si on demande d'aller à droite alors qu'on est déjà au bout du rectangle ? Il faut refuser d'avancer. Le script fait donc bien un choix logique IF en fonction de la position x du cercle au moment où le mouvement doit avoir lieu.
En français | Codage Python |
---|---|
SI on peut encore aller à droite alors | if (x < xmax) : |
Autoriser le déplacement à droite | Autoriser_droite() |
SINON SI on peut encore aller à gauche alors | elif (x > xmin) : |
Autoriser le déplacement à gauche | Autoriser_gauche() |
Fin du test |
En introduction, voilà le codage de différents test de conditions logiques entre deux variables :
Vous pouvez toucher aux curseurs pour voir l'évolution des différentes réponses.
Symbole du test | Signification | Exemple | Resultat du test |
---|---|---|---|
== | Est égal à | A == B | ? |
!= | Est différent de | A != B | ? |
> | Est supérieur à | A > B | ? |
>= | Est supérieur ou égal à | A >= B | ? |
< | Est inférieur à | A < B | ? |
<= | Est inférieur ou égal à | A <= B | ? |
Chacun de ces tests ne peut donner normalement que deux résultats : True pour vrai ou False pour faux.
On notera la présence d'une majuscule en Python : True et False. La plupart des langages utilisent simplement true et false.
Deuxième chose importante : la comparaison s'écrit avec deux signes =, pas un seul ! Il va falloir faire attention.
Remarque : si vous travaillez via un site vous permettant d'utiliser mapplotlib, il faudrait rajouter la ligne permettant de sauvegarder les courbes dans un fichier-image :
plt.savefig("essai.png")
Commençons par voir comment choisir une action en fonction d’une entrée.
01° Voici un programme qui nous permet de lire un nombre rentré au clavier puis de dire s’il est positif, négatif ou nul. Tester le code. A quoi sert la ligne nombre = int(nombre)
?
#!/usr/bin/env python
# -*-coding:Utf-8 -*
# Acquisition des données
nombre = input("Quel est votre nombre ? ")
# Traitement des données
nombre = int(nombre)
if nombre > 0 :
print("Le nombre est positif")
print("Ok")
elif nombre < 0 :
print("Le nombre est négatif")
else :
print("Le nombre est nul")
# Preparation de l’arret
input("pause")
CLIQUEZ SUR UN BOUTON-REPONSE :
nombre :
Point important : c’est la tabulation (ou 4 espaces) qui permet de savoir qu’une instruction est rattachée au bloc. Il est donc vital de bien tabuler votre code. Dans Notepad++, on peut faire s'afficher les tabulations à l'aide du menu AFFICHAGE - SYMBOLES SPECIAUX - AFFICHER ESPACES ET TABULATIONS
...CORRECTION...
La fonction input renvoie toujours un string.
La fonction int permet donc de convertir le string en entier, si c'est possible.
Comme vous l'avez vu, on ne rentre que dans un des cas disponibles :
Soit :
if nombre > 0 :
print("Le nombre est positif")
print("Ok")
Soit :
elif nombre < 0 :
print("Le nombre est négatif")
Soit :
else :
print("Le nombre est nul")
Voyons maintenant comment symboliser et expliquer tout ceci.
Description en français : l'action logique qu’on peut traduire en texte par
SI la première condition est vraie alors |
Fait les actions 1 |
SINON SI la deuxième condition est vraie alors |
Fait les actions 2 |
SINON |
Fait les actions 3 |
Fin du test |
Représentation graphique : la même action logique sous forme graphique :
On voit que la condition est un losange qui possède deux sorties uniquement.
Les instructions sont des rectangles.
Description en code Python : l'action logique se traduit en code par
En français | Codage Python |
---|---|
SI la première condition est vraie alors | if condition_1 : |
Fait les actions 1 | Instructions_1 |
SINON SI la deuxième condition est vraie alors | elif (condition_2) : |
Fait les actions 2 | Instructions_2 |
SINON | else : |
Fait les actions 3 | Instructions_3 |
Fin du test | Rien sinon le retour à l'indentation de base |
On remarquera d’abord qu’on met double point [ : ] après la condition de if, else if (elif en Python) ou else.
Cela permet à l’interpréteur de savoir quand commence la condition à tester (après le if, elif ou else) et quand la condition est définie (au : justement).
02° Compléter le code suivant : il doit demander si oui ou non vous êtes un humain. Il doit répondre "Bonjour humain !"
si la réponse est "oui"
, et "Bonjour robot !"
sinon.
#!/usr/bin/env python
# -*-coding:Utf-8 -*
# Acquisition des données
testHumain = input("Etes-vous humain (oui/non) ?")
# Traitement des données
if testHumain == "oui" :
print("Bonjour humain !")
# Preparation de l’arret
input("pause")
...CORRECTION...
#!/usr/bin/env python
# -*-coding:Utf-8 -*
# Acquisition des données
testHumain = input("Etes-vous humain (oui/non) ?")
# Traitement des données
if testHumain == "oui" :
print("Bonjour humain !")
else :
print("Bonjour robot !")
# Preparation de l’arret
input("pause")
03° Tester avec une mauvaise réponse, comme chien ou chat par exemple. Conclusion ?
Voilà : le programme fait ce que vous lui avez demandé, pas ce que vous vouliez.
04° Modifier le programme pour qu'il affiche :
...CORRECTION...
#!/usr/bin/env python
# -*-coding:Utf-8 -*
# Acquisition des données
testHumain = input("Etes-vous humain (oui/non) ?")
# Traitement des données
if testHumain == "oui" :
print("Bonjour humain !")
elif testHumain == "non" :
print("Bonjour robot !")
else :
print("Erreur de saisie")
# Preparation de l’arret
input("pause")
On peut exécuter plusieurs instructions dans le if ou le elif(else if). Python attend simplement le elif ou else suivant et comprend en attendant qu’il s’agit d’un bloc à exécuter si la condition est validée. On peut même imbriquer un bloc if dans un if.
05° Rajouter une demande supplémentaire lorsqu'on rentre dans le cas "humain" : on doit demander "Etes vous un homme ? (oui/non)". Dans ce cas (et uniquement dans ce cas) :
...CORRECTION...
#!/usr/bin/env python
# -*-coding:Utf-8 -*
testHumain = input("Etes-vous humain (oui/non) ?")
if testHumain == "oui" :
testHomme = input("Etes-vous un homme (oui/non) ?")
if testHomme == "oui" :
print("Bonjour monsieur !")
elif testHumain == "non" :
print("Bonjour madame !")
else :
print("Bonjour humain.")
elif testHumain == "non" :
print("Bonjour robot !")
else :
print("Erreur de saisie")
# Preparation de l’arret
input("pause")
Si on analyse le code en terme de blocs imbriqués l'un dans l'autre, on obtient ceci :
if testHumain == "oui" :
testHomme = input("Etes-vous un homme (oui/non) ?")
if testHomme == "oui" :
print("Bonjour monsieur !")
elif testHomme == "non" :
print("Bonjour madame !")
else :
print("Bonjour humain.")
elif testHumain == "non" :
print("Bonjour robot !")
else :
print("Erreur de saisie")
Il reste à tester des conditions doubles. Rappel : une condition renvoie un booléen qui est true (True en Python, avec un T majuscule) ou false (False en Python, avec un F majuscule).
Voici comment :
On peut tester plusieurs conditions à la fois à l’aide des codages suivants :
TEST LOGIQUE | En Français | En Python |
---|---|---|
and | code ET | A and B : Renvoie True si les deux conditions A et B sont True. |
or | code OU | A or B : Renvoie True si l'une deux conditions au moins est True. |
not | code NON | not(A) : Renvoie True si A == False et renvoie False si A == True. |
06° Trouver l'affichage obtenu pour une note de 13, de 19 et de 8 à partir du programme ci-dessous.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
a = 17
if a>0 :
if (a>10 and a<16) :
print("C'est pas mal comme note.")
print("Mais avoir plus, c'est mieux !")
elif a>= 16 :
print("C'est bien !")
else :
print("C'est pas bien !")
else :
print("Le prof a dû se tromper, votre note est négative. Ou alors ...")
...CORRECTION...
La note de 13 donne "C'est pas mal comme note.".
La note de 19 donne "C'est bien !".
La note de 8 donne "C'est pas bien !".
En analysant la structure des tabulations :
if a>0 :
if (a>10 and a<16) :
print("C'est pas mal comme note.")
print("Mais avoir plus, c'est mieux !")
elif a>= 16 :
print("C'est bien !")
else :
print("C'est pas bien !")
else :
print("Le prof a dû se tromper, votre note est négative. Ou alors ...")
La question suivante vous permettra de découvrir une nouvelle structure de données : le tuple dont les caractéres d'ouverture et de fermeture sont les parenthèses.
Le tuple permet d'envoyer un ensemble de données qu'on pourra ensuite récupérer dans différentes variables.
Ici, on crée une variable couleurs qui fait référence au tuple (250,150,200)
. On parvient ainsi à stocker les 3 intensités R G et B dans une seule variable :
couleurs = (250,150,200)
Pour récupérer ces trois valeurs, il suffit alors d'affecter le contenu du tuple dans trois variables :
r,g,b = couleurs
Ici r contient alors 250, g contient 150 et b contient 200.
07° Compléter le code suivant qui doit :
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Déclaration du tuple (r,g,b) et récupération des valeurs r,g,b
couleurs = (250,150,200)
r,g,b = couleurs
COMPLETER LE CODE ICI
print("La nouvelle valeur de rouge est ",r)
Une correction possible :
...CORRECTION...
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Déclaration du tuple (r,g,b) et récupération des valeurs r,g,b
couleurs = (250,150,200)
r,g,b = couleurs
# Tests pour savoir si on rajoute 50 ou non
if r>g and r>b :
r = r+50
print("L'intensité rouge est la plus grande : elle est plus grande que la verte ET que la bleue.")
elif r>g or r>b :
print("L'intensité rouge est plus grande qu'au moins une des deux autres.")
print("Attention, cela peut vouloir dire normalement qu'elle est plus grande que la verte et plus grande que la bleue.")
print("Par contre, ce cas est traité dans le IF juste au dessus. Si on arrive ici, c'est bien que le rouge n'est supérieur qu'à l'un des deux autres composants.")
# Tests pour gérer les valeurs max et min
if r>255 :
r = 255
elif r<0 :
r = 0
print("La nouvelle valeur de rouge est ",r)
Si on analyse le test ET / AND :
a | b | a and b |
---|---|---|
VRAI | VRAI | VRAI |
FAUX | VRAI | FAUX |
VRAI | FAUX | FAUX |
FAUX | FAUX | FAUX |
Si on analyse le test OU / OR :
a | b | a or b |
---|---|---|
VRAI | VRAI | VRAI |
FAUX | VRAI | VRAI |
VRAI | FAUX | VRAI |
FAUX | FAUX | FAUX |
Si vous voulez plus de précision sur les tests and, or ..., vous pouvez trouver des précision sur ces deux fiches :
Il est temps pour vous de passer à un mini-projet lié au tableau d'avancement.
On considère la combustion complète du butane :
1 C4H10 + 13/2 O2 → 4 CO2 + 5 H20
Reprenons le référenciel :
Capacité numérique dans | Description |
---|---|
Déterminer la composition de l’état final d’un système et l’avancement final d’une réaction | Déterminer la composition de l’état final d’un système siège d’une transformation chimique totale à l’aide d’un langage de programmation. |
Nous allons vouloir prévoir le réactif limitant et l'état final. C'est une tâche complexe que nous allons donc réduire en un ensemble de probèmes plus simples.
08° Réaliser un programme qui enregistre les coefficients stochioémtriques dans des variables nommmées
...CORRECTION...
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Déclaration des coefficients stochiométriques
cs_C4H10 = 2
cs_O2 = 13
csCO2 = 8
cs_H2O = 10
09° Demander via deux inputs les quantités de matière initiales no_C4H10 et no_O2 des réactifs. Il faudra également initialiser no_CO2 et no_H20.
10° Calculer les deux avancements possibles et les stocker dans des variables x_max_C4H10 et x_max_O2.
11° Tester les valeurs avec un IF et placer dans x_max le plus petit des deux avancements précédents.
...CORRECTION...
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Déclaration des coefficients stochiométriques
cs_C4H10 = 2
cs_O2 = 13
cs_CO2 = 8
cs_H2O = 10
# Initialisation des quantités de matières initiales (en mol)
no_C4H10 = float(input("Que vaut la quantité de matière initiale de butane ? : "))
no_O2 = float(input("Que vaut la quantité de matière initiale de dioxygène ? : "))
no_CO2 = 0
no_H2O = 0
# Calcul de l'avancement maximum
x_max_C4H10 = no_C4H10 / cs_C4H10
x_max_O2 = no_O2 / cs_O2
if x_max_C4H10 < x_max_O2 :
x_max = x_max_C4H10
else :
x_max = x_max_O2
12° Créer une liste x qui contient 2 valeurs : 0 et x_max.
13° Créer une liste n_C4H10 qui contiendra les valeurs des quantités de matière de butane.
14° Créer une liste n_O2 qui contiendra les valeurs des quantités de matière de dioxygène.
15° Créer une liste n_CO2 qui contiendra les valeurs des quantités de matière de dioxyde de carbone.
16° Créer une liste n_H2O qui contiendra les valeurs des quantités de matière d'eau.
...CORRECTION...
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Déclaration des coefficients stochiométriques
cs_C4H10 = 2
cs_O2 = 13
cs_CO2 = 8
cs_H2O = 10
# Initialisation des quantités de matières initiales (en mol)
no_C4H10 = float(input("Que vaut la quantité de matière initiale de butane ? : "))
no_O2 = float(input("Que vaut la quantité de matière initiale de dioxygène ? : "))
no_CO2 = 0
no_H2O = 0
# Calcul de l'avancement maximum
x_max_C4H10 = no_C4H10 / cs_C4H10
x_max_O2 = no_O2 / cs_O2
if x_max_C4H10 < x_max_O2 :
x_max = x_max_C4H10
else :
x_max = x_max_O2
# Création des listes
x = [ 0, x_max ]
n_C4H10 = [ (no_C4H10-cs_C4H10*valeur) for valeur in x]
n_O2 = [ (no_O2 - cs_O2*valeur) for valeur in x]
n_CO2 = [ (no_CO2 + cs_CO2*valeur) for valeur in x]
n_H2O = [ (no_H2O + cs_H2O*valeur) for valeur in x]
17° Créer le graphique qui permettra d'observer ces 4 quantités de matières.
Voici le résultat en fournissant 5 mol pour le butane et 16 mol pour le dioxygène.
...CORRECTION...
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
# Déclaration des coefficients stochiométriques
cs_C4H10 = 2
cs_O2 = 13
cs_CO2 = 8
cs_H2O = 10
# Initialisation des quantités de matières initiales (en mol)
no_C4H10 = float(input("Que vaut la quantité de matière initiale de butane ? : "))
no_O2 = float(input("Que vaut la quantité de matière initiale de dioxygène ? : "))
no_CO2 = 0
no_H2O = 0
# Calcul de l'avancement maximum
x_max_C4H10 = no_C4H10 / cs_C4H10
x_max_O2 = no_O2 / cs_O2
if x_max_C4H10 < x_max_O2 :
x_max = x_max_C4H10
else :
x_max = x_max_O2
# Création des listes
x = [ 0, x_max ]
n_C4H10 = [ (no_C4H10-cs_C4H10*valeur) for valeur in x]
n_O2 = [ (no_O2 - cs_O2*valeur) for valeur in x]
n_CO2 = [ (no_CO2 + cs_CO2*valeur) for valeur in x]
n_H2O = [ (no_H2O + cs_H2O*valeur) for valeur in x]
# Création des courbes
plt.plot(x, n_C4H10, label="C4H10")
plt.plot(x, n_O2, label="O2")
plt.plot(x, n_CO2, label="CO2")
plt.plot(x, n_H2O, label="H2O")
# Réglages axes et grille
liste_des_n_max = [ max(n_C4H10), max(n_O2), max(n_CO2), max(n_H2O) ]
n_max = max(liste_des_n_max)
plt.xlabel("Avancement (mol)")
plt.ylabel("Quantité de matière (mol)")
plt.title("Evolution de la réaction de combustion")
plt.legend(loc='upper center')
plt.axis([0,x_max,0,n_max])
plt.grid()
# Création de l'image
nom_du_fichier = "courbes_avancement_"+str(no_C4H10)+str(no_O2)
plt.savefig(nom_du_fichier+".png")
# Affichage de l'interface
plt.show()
18° Que font les deux lignes suivantes ? A quoi servent-elles dans le cadre de ce programme ?
liste_des_n_max = [ max(n_C4H10), max(n_O2), max(n_CO2), max(n_H2O) ]
n_max = max(liste_des_n_max)
...CORRECTION...
La fonction max est une fonction native de Python : elle peut retourner la plus grande valeur contenue dans une liste.
La première ligne crée donc une liste contenant les plus grandes valeurs calculées de quantités de matières pour les 4 espèces.
La deuxième ligne permet de ne garder que la plus grande des quantités de matière et de la mémoriser via la variable n_max.
Une fois cette quantité de matière enregistrée, on la réutilise pour définir l'axe des ordonnées.
plt.axis([0,x_max,0,n_max])
19° Puisque la fonction min existe également, avait-on vraiment besoin d'utiliser un test SI ici ?
...CORRECTION...
Non, nous avons recrée une sorte de fonction max. Nous aurions pu remplacer :
if x_max_C4H10 < x_max_O2 :
x_max = x_max_C4H10
else :
x_max = x_max_O2
par :
x_max = min( [x_max_O2,x_max_C4H10] )
ou même, encore plus simplement :
x_max = min(x_max_O2,x_max_C4H10)
Une dernière chose : les couleurs sont pour l'instant choisies par le programme lui-même. Heureusement, on peut imposer les notres. Il suffit de rajouter color lors de la création d'une courbe avec plot.
plt.plot(x, n_O2, label="O2", color='red')
20° Modifier le programme pour afficher les couleurs suivantes par exemple (ici, on a pris 10 moles de butane et 100 moles de dioxygène :
...CORRECTION...
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
# Déclaration des coefficients stochiométriques
cs_C4H10 = 2
cs_O2 = 13
cs_CO2 = 8
cs_H2O = 10
# Initialisation des quantités de matières initiales (en mol)
no_C4H10 = float(input("Que vaut la quantité de matière initiale de butane ? : "))
no_O2 = float(input("Que vaut la quantité de matière initiale de dioxygène ? : "))
no_CO2 = 0
no_H2O = 0
# Calcul de l'avancement maximum
x_max_C4H10 = no_C4H10 / cs_C4H10
x_max_O2 = no_O2 / cs_O2
x_max = min(x_max_O2,x_max_C4H10)
# Création des listes
x = [ 0, x_max ]
n_C4H10 = [ (no_C4H10-cs_C4H10*valeur) for valeur in x]
n_O2 = [ (no_O2 - cs_O2*valeur) for valeur in x]
n_CO2 = [ (no_CO2 + cs_CO2*valeur) for valeur in x]
n_H2O = [ (no_H2O + cs_H2O*valeur) for valeur in x]
# Création des courbes
plt.plot(x, n_C4H10, label="C4H10", color='orange')
plt.plot(x, n_O2, label="O2", color='red')
plt.plot(x, n_CO2, label="CO2", color='black')
plt.plot(x, n_H2O, label="H2O", color='blue')
# Réglages axes et grille
liste_des_n_max = [ max(n_C4H10), max(n_O2), max(n_CO2), max(n_H2O) ]
n_max = max(liste_des_n_max)
plt.xlabel("Avancement (mol)")
plt.ylabel("Quantité de matière (mol)")
plt.title("Evolution de la réaction de combustion")
plt.legend(loc='upper center')
plt.axis([0,x_max,0,n_max])
plt.grid()
# Création de l'image
nom_du_fichier = "courbes_avancement_"+str(no_C4H10)+str(no_O2)
plt.savefig(nom_du_fichier+".png")
# Affichage de l'interface
plt.show()
Dans la prochaine activtié, nous verrons comment créer des fonctions et ainsi avoir par exemple des zones où on pourra taper les conditions initiales plutôt que de les imposer dans le code.