Infoforall

Python-Physique 03 : Test SI

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 :

avancement en couleur

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çaisCodage Python
SI on peut encore aller à droite alorsif (x < xmax) :
    Autoriser le déplacement à droite    Autoriser_droite()
SINON SI on peut encore aller à gauche alorselif (x > xmin) :
    Autoriser le déplacement à gauche    Autoriser_gauche()
Fin du test


X actuelle = 250
X minimale = 150
X maximale = 350
avec un test X > XMIN valant
avec un test X < XMAX valant

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.

A = 50
B = 50
Symbole du testSignificationExempleResultat du test
==Est égal àA == B?
!=Est différent deA != 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")

1 - L’instruction conditionnelle SI – SINON

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 :

Le Si

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çaisCodage Python
SI la première condition est vraie alorsif condition_1 :
    Fait les actions 1    Instructions_1
SINON SI la deuxième condition est vraie alorselif (condition_2) :
    Fait les actions 2    Instructions_2
SINONelse :
    Fait les actions 3    Instructions_3
Fin du testRien 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 LOGIQUEEn FrançaisEn Python
andcode ETA and B : Renvoie True si les deux conditions A et B sont True.
orcode OUA or B : Renvoie True si l'une deux conditions au moins est True.
notcode NONnot(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

2 - Mini-projet

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.

avancement

...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 :

avancement en couleur

...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.