Programmation Impérative Fonctions, etc

publicité
Semaine Prochaine et TP
TP de rattrapage
Programmation Impérative
Fonctions, etc
lundi 8h, H104
pour ceux qui n'ont pas atteint 10 (obligatoire)
un TP « classique »
Séance de TP suivante
mercredi
continuer le TP5 (chomp)
rendu final avant le TP6
NB: les TP suivants seront de moins en moins guidés
6 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Retours sur les examens
Programmation Impérative 7 : Plan
Notes par email
Infos
Statistiques
Fonctions en Python
moyenne : 10.85
écart type : 2.93
médiane : 10.37
Fonctions et Programmes
Fonctions Comme Outils d'Abstraction
But de calibration
avoir une idée de ce qui est attendu
rien n'est perdu/gagné
le suivant ne sera pas plus simple
Technique de la Fonction Principale
Technique de la Simulation
Fonctions Récursives et Pile d'Appels
7 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
8 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Fonctions en Python
Les bibliothèques fournissent des fonctions
Il est possible d'écrire ses propres fonctions
éviter de se répéter, éviter le copier/coller
Qu'est ce qu'une fonction
un nom et une liste de noms de paramètres
un corps (suite d'instructions)
possiblement une valeur retournée (avec return )
Définie suivant le modèle
1
2
3
4
5
def «nom» ( «liste-param» ):
"documentation de la fonction,
«instr» # dans le corps de la
«instr» # dans le corps de la
…
# dans le corps de la
optionnelle"
fonction
fonction
fonction
Définir une fonction ne l'exécute pas
1
2
3
4
5
6
def meteo(temperature):
if temperature > 0:
print("Il fait bon")
else:
print("Il fait froid")
Qu'affiche le programme suivant ? ⇒ RIEN
Le corps de la fonction n'est exécuté que lorsqu'on l'appelle
1
2
3
4
5
6
7
8
def meteo(temperature):
if temperature > 0:
print("Il fait bon")
else:
print("Il fait froid")
meteo(4)
meteo(-10)
def , ( , ) , : et l'indentation sont obligatoires
Dans «liste-param», les noms de variables séparés par des ,
9 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
10 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Définition et appel de fonction
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def norme(x, y):
d = x**2 + y**2
return d ** 0.5
# Appel 1
print(norme(3, 4))
# Appel 2
print(norme(40, 30))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Programmation Impérative 7 : Plan
# Juste se rappeler
# ... que norme existe
a1_x
a1_y
a1_d
a1 =
Infos
Fonctions en Python
= 3
= 4
= a1_x**2 + a1_y**2
a1_d ** 0.5
Fonctions et Programmes
Fonctions Comme Outils d'Abstraction
print(a1)
a2_x
a2_y
a2_d
a2 =
Technique de la Fonction Principale
Technique de la Simulation
= 40
= 30
= a2_x**2 + a2_y**2
a2_d ** 0.5
Fonctions Récursives et Pile d'Appels
print(a2)
NB
chaque appel de fonction a ses propres variables x et y
chaque appel de fonction a sa propre variable d
return donne la valeur par laquelle sera remplacée l’appel
11 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
12 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Différence Entre Programme et Fonction
Programmation Impérative 7 : Plan
Programme
Infos
un fichier .py entier
exécuté depuis bash, avec python lefichier.py p1 p2 p3 …
des paramètres dont la valeur est tapée dans le terminal
des paramètres accessibles avec la liste sys.argv
des paramètres forcément chaînes de caractères
interrompu par exit()
Fonctions en Python
Fonctions et Programmes
Fonctions Comme Outils d'Abstraction
Technique de la Fonction Principale
Fonction
Technique de la Simulation
définie dans une partie d'un fichier .py
appelée n'importe où en python, avec la_fonction(p1,p2,p3)
des paramètres dont la valeur est calculée à l'appel de la fonction
des paramètres qui sont des valeurs/objets python
des paramètres accessibles avec leurs noms
des paramètres de n'importe quel type
interrompue par return
une valeur de retour (ou None )
Fonctions Récursives et Pile d'Appels
13 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
14 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Programme Sans Fonctions
1
2
3
4
5
planetes = [ # x, y,
masse,
nom
[0, 0,
5.9736E24, "terre"],
[3.844E5, 0, 7.3477E22, "lune"]
G = 6.6742E-11 * 1E-6 # N km2 kg-2
ZERO = [0, 0]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
]
bob = [0, 6378.137] # km
bobm = 100 # kg
for pl in planetes:
dx = pl[0] - bob[0]
dy = pl[1] - bob[1]
d = (dx * dx + dy * dy)**0.5
print("Bob est a", d, "km du centre de", pl[3])
somme_forces = ZERO
for pl in planetes:
dx = pl[0] - bob[0]
dy = pl[1] - bob[1]
d = (dx * dx + dy * dy)**0.5
u = [dx / d, dy / d] # vecteur unitaire
df = [G * bobm * pl[2] / d / d * u[0],
G * bobm * pl[2] / d / d * u[1]]
somme_forces = [somme_forces[0] + df[0],
somme_forces[1] + df[1]]
print("Somme des forces sur Bob :", somme_forces, "newtons")
16 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Fonctions : Répétitions Contrôlées
1
2
3
4
5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
planetes = [ # x, y,
masse,
nom
[0, 0,
5.9736E24, "terre"],
[3.844E5, 0, 7.3477E22, "lune"]
G = 6.6742E-11 * 1E-6 # N km2 kg-2
ZERO = [0, 0]
]
def info_bob(bob, bobm):
for pl in planetes:
dx = pl[0] - bob[0]
dy = pl[1] - bob[1]
d = (dx * dx + dy * dy)**0.5
print("Bob est a", d, "km du centre de", pl[3])
somme_forces = ZERO
for pl in planetes:
dx = pl[0] - bob[0]
dy = pl[1] - bob[1]
d = (dx * dx + dy * dy)**0.5
u = [dx / d, dy / d] # vecteur unitaire
df = [G * bobm * pl[2] / d / d * u[0],
G * bobm * pl[2] / d / d * u[1]]
somme_forces = [somme_forces[0] + df[0],
somme_forces[1] + df[1]]
print("Somme des forces sur Bob :", somme_forces, "newtons")
info_bob([0, 6378.137], 100)
info_bob([6378.137, 0], 100)
17 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Fonctions : Ne Pas Se Répéter
1
2
3
4
5
planetes = [ # x, y,
masse,
nom
[0, 0,
5.9736E24, "terre"],
[3.844E5, 0, 7.3477E22, "lune"]
G = 6.6742E-11 * 1E-6 # N km2 kg-2
ZERO = [0, 0]
]
def dist(a, b):
dx = b[0] - a[0]
dy = b[1] - a[1]
return ( dx**2 + dy**2 )**0.5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def info_bob(bob, bobm):
for pl in planetes:
d = dist(pl, bob)
print("Bob est a", d, "km du centre de", pl[3])
somme_forces = ZERO
for pl in planetes:
d = dist(pl, bob)
u = [ (pl[0] - bob[0]) / d, (pl[1] - bob[1]) / d]
df = [G * bobm * pl[2] / d / d * u[0],
G * bobm * pl[2] / d / d * u[1]]
somme_forces = [somme_forces[0] + df[0],
somme_forces[1] + df[1]]
print("Somme des forces sur Bob :", somme_forces, "newtons")
info_bob([0, 6378.137], 100)
Fonctions : Meilleures Abstractions
1
2
3
4
5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
planetes = [ # x, y,
masse,
nom
[0, 0,
5.9736E24, "terre"],
[3.844E5, 0, 7.3477E22, "lune"]
G = 6.6742E-11 * 1E-6 # N km2 kg-2
ZERO = [0, 0]
def vec_addmul(a, m, b): # retourne a + m*b (en 2d)
return [ a[0]+m*b[0], a[1]+m*b[1] ]
def dist(a, b):
d = vec_addmul(b, -1, a)
return ( d[0]**2 + d[1]**2 )**0.5
Infos
Fonctions en Python
Fonctions et Programmes
Fonctions Comme Outils d'Abstraction
Technique de la Fonction Principale
Technique de la Simulation
Fonctions Récursives et Pile d'Appels
# b - a
def info_bob(bob, bobm):
for pl in planetes:
d = dist(pl, bob)
print("Bob est a", d, "km du centre de", pl[3])
somme_forces = ZERO
for pl in planetes:
d = dist(pl, bob)
u = vec_addmul(bob, -1, pl)
# pl - bob
u = vec_addmul(ZERO, 1/d, u)
# u / d
df = vec_addmul(ZERO, G * bobm * pl[2] / d / d, u)
somme_forces = vec_addmul(somme_forces, 1, df)
print("Somme des forces sur Bob :", somme_forces, "newtons")
info_bob([0, 6378.137], 100)
18 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Programmation Impérative 7 : Plan
]
19 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Portée et Visibilité des Variables
1 a = 1
2 b = 2
3 c = 3
4 def fun(b, d):
5
print(a) #
6
c = 10
#
global
7
print(c) #
8
e = 3.14 #
9
10 fun(1, 1)
#
11 print(c)
#
# b cache le b global
lecture seulement -> lit le a global
affectation -> nouvelle, qui cache le c
10
variable locale
1 10
3
Variable globale
définie (affectées) dans la partie principale du programme
(sans indentation, ou dans un if, for, while)
visible de partout dans le programme
Variable locale
définie dans une fonction (ou en paramètre d'une fonction)
visible uniquement dans la fonction, changée à chaque appel
cache possiblement une variable globale du même nom
20 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Technique de la fonction « principale »
But : n'avoir aucune variable globale
pas de risque de partager des variables sans le savoir
moins de risque d'erreur
programme plus sûr
Technique
définir une fonction « principale »
(dont le nom est au choix mais est souvent principale ou main )
se limiter dans son fichier python à
des définitions de fonctions
un appel à la fonction « principale »
1
2
3
4
5
6
7
8
9
10
def puissance(a, b):
print("notons que a vaut", a)
return a**b
Ne pas utiliser trop de variables globales !
21 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Programmation Impérative 7 : Plan
Infos
Fonctions en Python
Fonctions et Programmes
Fonctions Comme Outils d'Abstraction
Technique de la Fonction Principale
Technique de la Simulation
Fonctions Récursives et Pile d'Appels
def principale():
v = puissance(2*21, 4)
v2 = puissance(v, 2)
print(v, v2)
principale()
22 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
23 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Une « simulation » ?
Technique de la simulation
Étape 1 : initialisation de l'état
Imitation du comportement d'un système au cours du temps
Étape 2 :, en boucle
Exemples
physique : pendule, gravité, fusée au décollage, …
chimie : cinétique, dosage, évaporation, molécules 3d, …
jeux : chomp, snake, tetris, angry birds, …
Principes de bases
le système a un état
le temps ou les événements externes changent l'état
on peut représenter l'état du système
Questions à se poser
à quels événements réagit le système ?
que faut-il pour afficher l'état du système ?
que faut-il pour réagir aux événements/temps ?
⇒ de quoi est fait l'état du système ?
1
2
3
4
5
6
7
8
9
10
11
13
14
15
16
17
18
19
20
21
22
23
affichage de l'état
attente et gestion d'événements (externes et temps)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Imports des modules nécessaires
...
# Définitions de fonctions utilitaires
...
def main():
# Technique de la fonction principale
# initialisation de l'état du système
...
while not «condition-de-fin»:
# affichage de l'état du système
...
# attente d'un événement (ou du temps)
...
# mise à jour de l'état du système
...
main()
# Appel de la fonction principale
24 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
25 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Simulation : mouvement linéaire
Simulation : avec rebond
# Imports des modules nécessaires
from qtido import *
# Définitions de fonctions utilitaires
def main(): # Technique de la fonction principale
f = creer(800, 600)
# initialisation de l'état du système
pos = [400, 300]
while not est_fermee(f):
# affichage de l'état du système
effacer(f)
disque(f, pos[0], pos[1], 20)
# attente d'un événement (ou du temps)
attendre_pendant(f, 10)
# mise à jour de l'état du système
pos = [ pos[0]+3, pos[1]-1 ]
main()
# Appel de la fonction principale
Comment gérer le rebond à droite ?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Imports des modules nécessaires
from qtido import *
# Définitions de fonctions utilitaires
def main(): # Technique de la fonction principale
f = creer(800, 600)
# initialisation de l'état du système
pos = [400, 300]
vit = [3, 1]
while not est_fermee(f):
# affichage de l'état du système
effacer(f)
disque(f, pos[0], pos[1], 20)
# attente d'un événement (ou du temps)
attendre_pendant(f, 10)
# mise à jour de l'état du système
if pos[0] > 790: # on a touché à droite
# changer de direction
vit = [ -vit[0], vit[1] ]
# déplacer pos dans la bonne direction
pos = [ pos[0]+vit[0], pos[1]-vit[1] ]
main()
# Appel de la fonction principale
26 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
27 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Simulation : et le chomp ?
Programmation Impérative 7 : Plan
État du système
quelles cases sont mangées
un tableau à deux dimensions (liste de liste), 1 si mangé
Infos
Fonctions en Python
Fonctions et Programmes
Initialisation
rien de mangé, creer_liste_de_listes(...)
Affichage
effacer la fenêtre
tracer chaque carreau non mangé en marron
Attente d'événements
attente d'un click souris ⇒ manger des cases
ignorer tout le reste
Fonctions Comme Outils d'Abstraction
Technique de la Fonction Principale
Technique de la Simulation
Fonctions Récursives et Pile d'Appels
Imports
qtido , random , …
Fonctions utilitaires
coordonnees_click , dessiner_carre , …
28 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
29 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Pile d'Appels de Fonctions
Qu'affiche ce programme ?
1
2
3
4
5
6
7
8
9
10
11
12
x=42
def mystere(x, p):
print(x)
if x <= 1:
res = 1
else:
res = x * mystere(x-1, p+1)
print(p*" ", res)
return res
x = mystere(4, 0)
print(x)
Pile d'appels
Points Clés
Définition de nos propres fonctions
Principe de l'appel d'une fonction
chaque appel de fonction a ses propres variables x et y
chaque appel de fonction a sa propre variable d
return donne la valeur par laquelle sera remplacée l’appel
Différences entre fonction et programme
Technique de la fonction principale
Technique de la simulation
chaque appel de fonction a ses propres variables
copie des valeurs passées en argument
stockage dans une pile en cas d'appels récursifs
30 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
31 / 31 − Rémi Emonet − Programmation Impérative Fonctions, etc
Téléchargement