402 : Python bases - boucles - fonctions

Boucle

Pour laisser l'utilisateur saisir la valeur d'une variable, il faut utiliser la fonctions input

input retourne une chaîne de caractère (string) qu'il faut convertir en numérique flottant (float)

1
mess = "Saisir une valeur numérique"
2
valeurS = float(input(message))
3
print(valeurS)

Testez plusieurs fois ce code en entrant du texte : toto par exemple, puis 2.5, puis 4.

Si l'utilisateur ne saisit pas une valeur cohérente avec les traitements à suivre, il faut soit, redémarrer le programme, soit prévoir dans le code une boucle tant que la valeur saisie n'est pas satisfaisante.

1
# boucler la demande de to et tu tant que l'un des deux est nul
2
err = True
3
while err:
4
    to = float(input ("to ? (0 pour inconnu) : "))
5
    tb = float(input ("tb ? (0 pour inconnu) : "))
6
    err = (to==0) and (tb==0)
7
print (tu,to)

On notera ici que l'on ne teste pas la saisie de données qui vont provoquer une erreur d'exécution (type de données incompatible, division par zéro, etc ...)

On demandera simplement à l'utilisateur de saisir une donnée numérique différente de 0 pour sortir de la boucle. Saisir la chaîne toto provoquera un arrêt brutal du programme.

Problème posé.

Construire un programme qui effectue les tâches suivantes :

  • demander à l'utilisateur la valeur de N0

  • boucler tant que Nt est différent de 0

  • calculer et afficher Rt dans la boucle

Question

« étape 1 » : On teste le traitement principal dans un fichier nommé 402_01_v1.py

Dans l'exercice précédent, on sait calculer R(t) à partir de données dites constantes. On peut garder ce code (le recopier sans modifier le premier programme qui avait son propre objectif). On pourrait enlever des lignes inutiles, mais ici, c'est une bonne base pour ce que l'on a à faire.

Testez le pour être sûr qu'il fonctionne.

1
# 402_01_v1. py --> repris du code 401-1.py
2
N0 = 1000
3
Nt = 490
4
Rt = Nt/N0
5
print(Rt)
6
mess = "La fiabilité est de " + str(Rt*100) + " %"
7
print(mess)

Dans un premier temps, on va garder les lignes N0=1000 et Nt = 490, et se concentrer sur la boucle. Mettre en place la condition de sortie de la boucle avec la variable err qui peut être testée juste après l'affectation de Nt=490.

On est sûr que l'on doit avoir err à false car  Nt est bien différent de 0

Indice

On testera err avec la comparaison de Nt avec la valeur 0

On affiche la valeur de la variable booléenne err

Solution

1
# code 401-1
2
N0 = 1000
3
err = True
4
Nt = 490
5
err = (Nt == 0)
6
print(err)
7
'''
8
Rt = Nt/N0
9
print(Rt)
10
mess = "La fiabilité est de " + str(Rt*100) + " %"
11
print(mess)
12
'''

REMARQUE : du code est mis en commentaires pour ne pas exécuter le calcul de R(t) si on teste Nt=0. On n'a que l'affichage de la variable err

Question

« étape 2 » : saisie par l'utilisateur de Nt (402_01_v2.py)

on demande la valeur de Nt à l'utilisateur avec la fonction python input

Solution

1
N0 = 1000
2
Nt = int(input("Survivants à un instant t quelconque ? : "))
3
err = (Nt == 0)
4
print(err)
5

Testez plusieurs fois avec des valeurs de 0 1000 et -100 par exemple

Question

« étape 3 » : la boucle avec sortie si pas d'erreur (402_01_v3.py)

On initialise err = True avant le début de la boucle, on teste la boucle while avec la variable err qui est forcément à vrai de sorte que l'on est assurée que la boucle soit exécutée au moins une fois.

Même si votre code est juste, testez Nt avec 0 et 20 pour vérifier que la boucle fonctionne bien.

Lisez le code corrigé.

Solution

1
N0 = int(input("N à t=0 ? :"))
2
err = True
3
while err:
4
    print("début itération")
5
    Nt = int(input("Survivants à un instant t quelconque ? : "))
6
    err = (Nt == 0)
7
    print(err)
8
print ("Fin de boucle")
9
10

Question

« étape 4 » : la boucle avec sortie si pas d'erreur (402_01_v4.py)

Si nous avons une erreur, il ne faut pas calculer Rt, sinon le programme sera interrompu. Exécutez le calcul de Rt seulement si err est à false dans la boucle. Affichez Rt

Solution

1
# Mettre un # devant l'une des deux lignes selon ce que l'on souhaite faire
2
3
# N0 = int(input("N à t=0 ? :")) # pour la version finale
4
N0=1000                          # pour les tests
5
6
err = True
7
while err:
8
    print("début itération")
9
    Nt = int(input("Survivants à un instant t quelconque ? : "))
10
    err = (Nt == 0)
11
    if not err:
12
        Rt=Nt/N0
13
        print(Rt)
14
print ("Fin de boucle")
15
16

Tant que l'on teste, on n'est pas obligé de demander N0 à l'utilisateur et on peut laisser N0=1000. Mettre une des deux lignes en commentaire est intéressant

Question

« étape 5 » : une boucle avec calcul répétitif de la fiabilité et sortie quand l'utilisateur va saisir 0 (402_01_v5.py)

On va maintenant sortie de la boucle quand Nt sera égal à zéro.

On continue la boucle en calculant Rt seulement quand Nt>0 et Nt<=N0, car une fiabilité négative est impossible.

Vous pouvez là aussi y aller en deux sous-étapes. D'abord, sortir de la boucle quand Nt sera nul, puis ensuite laisser la boucle défiler si il y une erreur sur la saisie de Nt.

Solution

1
# N0 = int(input("N à t=0 ? :"))
2
N0 = 1000
3
continuerboucle = True
4
while continuerboucle:
5
    Nt = int(input("Survivants à un instant t quelconque ? : "))
6
    continuerboucle = (Nt!=0)
7
    if continuerboucle:
8
        err = (Nt <= 0 or Nt > N0)
9
        if not err:
10
            Rt=Nt/N0
11
            print(Rt)
12
print ("Fin")

Une variable de type compteur : (402_01c_ex.py)

Il est intéressant dans une boucle de connaître savoir ce qui se passe au niveau du nombre d'itérations. Observons le code ci-dessous.

1
# boucler la demande de to et tu tant que l'un des deux est nul
2
err = True
3
i = 0
4
while err:
5
    i = i + 1
6
    print("itération n°"+str(i))
7
    to = float(input ("to ? (0 pour inconnu) : "))
8
    tb = float(input ("tb ? (0 pour inconnu) : "))
9
    err = (to==0) and (tb==0)
10
print (tu,to)

Avec la variable i initialisé à 0 avant le début de la boucle, on va à chaque fois qu'une nouvelle itération est démarrée, ajouter 1 à la variable i.

Dans les exercices qui vont suivre, lorsque l'on va introduire les listes , les tableaux, les dictionnaires, il faudra accéder à un et un seul élément, et c'est avec une variable itérative qu'il sera possible de gérer un ensemble de TTF dans le cadre d'observations de durées de vie, mais aussi de traiter une défaillance avec son rang i, une période de rang i, etc ...

Ici, on affiche le nombre d'itération au fur et à mesure, mais on peut se contenter d'afficher la variable en sortie de boucle.

Question

Reprise du code 402-01_v5.py.

Avec la variable i, comptez le nombre d'itérations du programme.

Avec la variable iNbR, on veut compter uniquement les itérations pour lesquelles le calcul de la fiabilité a pu se faire.

Solution

1
# N0 = int(input("N à t=0 ? :"))
2
N0 = 1000
3
continuerboucle = True
4
i=0
5
iNbR=0
6
while continuerboucle:
7
    i=i+1
8
    print("itération n°"+str(i))
9
    Nt = int(input("Survivants à un instant t quelconque ? : "))
10
    continuerboucle = (Nt!=0)
11
    if continuerboucle:
12
        err =  (Nt < 0 or Nt > N0)
13
        print(err)
14
        if not err:
15
            iNbR=iNbR+1
16
            print("Calcul de fiabilité n° "+ str(iNbR))
17
            Rt=Nt/N0
18
            print(Rt)
19
print ("Fin")

Question

Construire une variante 1 du programme précédent qui permette à l'utilisateur de calculer uniquement 3 fois la fiabilité et que la boucle s'arrête.

Faire de même avec une boucle for : chercher comment utiliser la boucle for

Les Fonctions

Vous avez l'habitude d'utiliser des fonctions tableur qui retournent une valeur lorsque vous transmettez à cette fonction des arguments

On remarque que lorsque l'on doit interagir avec l'utilisateur et qu'il faut contrôler la cohérence des données, le code peut vite devenir long et si il faut en plus dupliquer ce code à chaque valeur à saisir, le code va vite y perdre en lisibilité ainsi qu'en testabilité.

Analyser et essayer de comprendre le code de la fonction finput[1]: n'hésitez pas demander des explications complémentaires

Tester cette fonction :

  • le code de la fonction doit être présent dans un fichier mod1.py.

  • créer un autre fichier 402-test-finput.py dans le même dossier que mod1.py.

Dans le fichier 402-test-finput.py, copier les lignes ci-dessous

1
from mod1 import finput
2
tu = finput("tu","95")
3
to = finput("to","100",False)

Question

Appliquez dans les codes précédents la fonction finput pour saisir N0 et Nt

Question

Construire une fonction fR qui calcule R(t)

Solution

1
def fR(Nt,N):
2
    R=Nt/N
3
    return R
4
5
N0=1000
6
Nt1=500
7
Nt2=700
8
Rt1=fR(Nt1,N0)
9
Rt2=fR(Nt2,N0)
10
print(str(Rt1)+ "-" + str(Rt2)
11

Question

Construire une fonction fLambda qui calcule λ [ t , t + dt ] = dN [ t ] N [ t ] . dt = N [ t ] N [ t + dt ] N [ t ] . dt %lambda[t,t+dt]={func dN[t]} over {{N[ t]}.dt}={N[ t]-N[t+dt]} over {{N[ t]}.dt}

Les arguments seront

  • dN pour dN(t)

  • Ndeb pour N(t)

  • dt pour dt

Solution

1
def fLambda(Ndeb,dN,dt):
2
    lbd = dN/Ndeb/dt
3
    return lbd

Question

Construire une fonction fLambda qui calcule λ [ t , t + dt ] = dN [ t ] N [ t ] . dt = N [ t ] N [ t + dt ] N [ t ] . dt %lambda[t,t+dt]={func dN[t]} over {{N[ t]}.dt}={N[ t]-N[t+dt]} over {{N[ t]}.dt}

Les arguments seront

  • Ndeb pour N(t)

  • Nfin pour N(t+dt)

  • tdeb pour t

  • tfin pour t+dt

On pourra utiliser des variables intermédiaires dt et dN pour calculer lambda=dN/Ndeb/dt

Solution

1
def fLambda(Ndeb,Nfin,tdeb,tfin):
2
    dt = tfin-tdeb
3
    dN = Ndeb-Nfin
4
    lbd = dN/Ndeb/dt
5
    return lbd