LANGAGE PYTHON
Cette partie est destinée aux personnes en avance, demander au prof si vous pouvez passer au projet.
- Gérer le temps
Python propose le module time que vous pouvez importer pour connaître l'heure, faire des pauses dans un programme, etc..
L'heure POSIX:
L'heure Posix est une mesure qui représente le temps écoulé depuis le 1 janvier 1970. On peut se servir de cette information pour déterminer le temps écoulé entre deux instants par soustraction de deux lectures successives de l'heure Posix.
La fonction time() du module time renvoie l'heure Posix
La fonction sleep(x) du module time effectue une pose de x secondes
- Tester le programme ci-dessous:
import time
debut, actu = time.time(), time.time()
while actu - debut < 6 :
print ("Le programme s'exécute depuis",int(actu - debut),"secondes.")
# attente d'une seconde
time.sleep(1)
# actualisation du temps avant de reboucler
actu = time.time()
# dés que la boucle while est finie
print ("C'est fini !")
Conclusion: ce programme compte 6s puis affiche c'est fini.
La structure temps
La structure temps est un tuple(1) de nombres entiers qui contient toutes les informations concernant le temps: l'année, le mois, le jour, l'heure, les minutes et les secondes. On peut accéder aux données en connaissant l'indice ou le nom de chaque info dans le tuple:
indice: 0 => nom= tm_year => année
indice: 1 => nom= tm_mon => mois (la valeur est comprise entre 1 à 12)
indice: 2 => nom= tm_mday => jour = ( la valeur est comprise entre 1 et 31)
indice: 3 => nom= tm_hour => heure = ( la valeur est comprise entre 0 et 23)
indice: 4 => nom= tm_min => minutes
indice: 5 => nom= tm_sec => secondes
(1) rappel: un tuple est une liste d'éléments que l'on peut lire mais pas modifier.
On obtient une structure temps avec la fonction localtime(t) qui convertit une heure Posix t:
Exemple:
import time
# t est une variable qui contient l'heure posix
t = time.time()
# tmp est une variable tuple structure temps obtenue à partir de t
tmp = time.localtime(t)
# récupération de l'heure par l'indice dans le tuple
heure = tmp[3]
# autre méthode: récupération de l'heure par son nom dans le tuple
heure2 = tmp.tm_hour
Remarque: la fonction mktime(tmp) convertit la structure temps tmp en heure Posix
Pour faciliter l'affichage de messages on dispose de deux autres fonctions qui permettent de passer d'une structure temps à une chaîne de caractères ou l'inverse:
strftime( fmt, tmp ) : renvoie une chaîne de caractères au format date fmt à partir d'une structure temps tmp. Si le paramètre tmp n'est pas renseigné, l'affichage sera basé sur l'heure locale.
strptime( fmt, tmp ) : transforme la chaîne de caractères fmt en structure temps.
Le format d'une chaîne de caractères date fmt ( voir exemple ci-dessous ) est une chaîne de caractères formatée avec des mots clés:
Le mot clé %d est remplacé dans la chaîne par le jour du mois.
Mot clé %H contient l'heure au format 24h.
Mot clé %j contient le numéro du jour de l'année soit un nombre entier compris entre 1 et 366.
Mot clé %m contient le numéro du mois soit un nombre entier compris entre 1 et 12.
Mot clé %M contient les minutes.
Mot clé %S contient les secondes.
Mot clé %w contient le jour de la semaine ( 0= lundi).
Mot clé %y contient les deux derniers chiffres de l'année.
Mot clé %Y contient l'année sur 4 chiffres.
Exemples:
import time
#la chaîne de caratères formatées
fmt = " nous sommes le %d/%m/%y, il est %H:%M:%S"
#affichage de la chaîne de caractères avec mise à jour par la fonction des infos temps:
print( time.strftime(fmt))
En utilisant toutes les fonctions de conversion décrites précédemment, on obtiendrait le même résultat, exemple:
import time
# t est une variable qui contient l'heure posix
t = time.time()
# tmp est une variable tuple structure temps obtenue à partir de t
tmp = time.localtime(t)
# fmt est une chaîne de caractères formatée date
fmt = " nous sommes le %d/%m/%y, il est %H:%M:%S"
print (time.strftime( fmt, tmp))
Tester le programme précédent
Répéter à intervalle régulier:
Le module Tkinter propose la méthode after(.....) applicable à une fenêtre qui permet de déclencher une fonction après un délai précisé en millisecondes. Cette fonction peut être appelée à intervalle régulier pour obtenir un mouvement, un rafraîchissement d'infos, etc..
On procède ainsi:
nom_fenetre.after( delai_en_ms, fonction_à_appeler)
Tester le programme ci-dessous qui affiche l'heure dans une fenêtre:
#importation des modules
from tkinter import *
import time
#définition d'une fonction affiche()
def affiche():
#formatage de la date et affichage dans le label lbl ( zone d'affichage dans la fenêtre)
f="nous sommes le %d/%m/%y, il est %H:%M:%S"
lbl.config(text=time.strftime(f))
# Ici la fonction affiche se rappelle elle même toutes les 500 ms
# ne pas mettre de parenthèses à la fonction affiche dans la méthode after
fenetre.after(500,affiche)
# Le programme principal:
#création de la fenêtre et configuration de ses propriétés
fenetre = Tk()
fenetre.geometry("300x50")
#création d'une zone d'affichage de texte sur la fenêtre
lbl=Label(fenetre,text="heure")
#positionnement du label dans la fenêtre
lbl.place(x=10,y=10)
'''Appel de la fonction affiche() par le programme principal
ce qui va lancer l'affichage toutes les 500ms'''
affiche()
# abonnement aux messages Windows
fenetre.mainloop()
Exercice 2
Créer un minuteur graphique qui décompte de 60 s à 0.
- Créer des mouvements
Pour gérer des déplacements dans une zone d'affichage (un canvas en python) il faut connaître le système de coordonnées de la zone d'affichage, voici le repérage d'une zone d'affichage de 200 px de large sur 150 px de haut:

Pour déplacer le point A on doit changer ses coordonnées XA, YA en lui affectant une vitesse. On décide un mouvement horizontal vers la gauche, le vecteur vitesse aura une composante nulle selon Y ( VAy=0) et une composante négative selon X par exemple VAx= - 5 pour déplacer de 5 pixels (VAx est négatif parce que l'on doit diminuer la coordonnée XA du point A). Dés que le point atteint ou dépasse le bord, on peut inverser le sens du vecteur vitesse pour gérer un rebond par exemple. En python tout ça est simple à programmer:
VAx, VAY = -5, 0
# mise à jour des coordonnées XA, YA
XA, YA = XA + VAx , YA+ VAY
XA, YA, VAx, VAY sont des variables associées à un nombre entier. Si le point se déplace, il faut répéter la mise à jour des coordonnées avec la méthode after() vue dans les exemples du niveau 2.
Tester le programme ci-dessous d'une balle qui rebondit sur les bords de la fenêtre:
from tkinter import *
#la fonction animation()qui gère le mouvement
def animation():
global VX, VY, BalleX, BalleY
futurX, futurY = BalleX + VX, BalleY + VY
#détection des bords en tenant compte du rayon de la balle
if futurX > 290 or futurX < 10 :
VX = - VX
futurX = BalleX + VX
if futurY > 190 or futurY < 10 :
VY = - VY
futurY = BalleY + VY
# mise à jour du centre de la balle
BalleX, BalleY = futurX, futurY
# balle redessinée aux nouvelles coordonnées
Fond.coords(Balle, BalleX - 10, BalleY - 10, BalleX + 10, BalleY + 10)
# rappel de la fonction au bout de 40ms
fenetre.after(40,animation)
# le programme principal
fenetre=Tk()
fenetre.geometry("300x200")
#la zone d'affichage
Fond=Canvas(fenetre,width=300,height=200,bg="white")
Fond.grid()
# la vitesse initiale
VX, VY = 2, 2
#la position initiale de la balle
BalleX, BalleY = 50, 100
# la balle (une forme ovale)
Balle = Fond.create_oval(40, 90, 60, 110, fill = 'red')
#appel de la fonction animation
animation()
# abonnement aux messages Windows
fenetre.mainloop()
- Gérer le clavier
Chaque fois qu'une touche est enfoncée, on dit qu'un événement est déclenché. La fonction mainloop() surveille les événements.
Appui sur une touche classique
On doit définir une fonction qui s'exécutera dés que l'événement concernant l'appui sur une touche est détecté, on utilise pour ça la méthode bind_all(............) de la fenêtre
La méthode se déclare toujours ainsi:
ma_fenetre.bind_all('<Key>', ma_fonction)
La fonction qui gérera l'événement clavier prendra un paramètre obligatoire qui doit s'appeler evt
def ma_fonction(evt):
.................
Le paramètre evt permet de récupérer la nature de l'événement produit, par exemple evt.char renvoie le caractère correspondant à la touche qui vient d'être enfoncée ( voir exemple ci-dessous).
Voici un programme qui permet de déplacer une balle sur l'écran avec les touches A, S, Q, D:
- Tester le programme, ci dessous:
#importation des fonctions de tkinter
from tkinter import *
# Définition de la fonction touche qui gère l'appui sur les touches du clavier
#*****************************************************************************
def touche(evt):
# on agit sur les variables X et Y du programme principal pour positionner la balle
global X,Y
'''la fonction upper() convertit en lettre capitale a => A,
le nom de la touche est stockée dans la variable t '''
t = evt.char.upper()
# déplacement de 5 px selon touche enfoncée
if t == 'A' :
Y = Y - 5
elif t == 'Q' :
Y = Y + 5
elif t =='S' :
X = X - 5
elif t =='D' :
X = X + 5
# on redessine la balle à ses nouvelles coordonnées
Fond.coords(Balle,X-10, Y-10, X+10, Y+10)
#*******************************************************************************
#Le programme principal
#**************************************************************
fenetre = Tk()
# la zone de dessin
Fond=Canvas(fenetre,width=500,height=500,bg="white")
Fond.grid()
# variables globales X et Y ( position de la balle)
# les coordonnées initiales qu'aura la balle
X, Y = 60, 60
# Création de la balle
Balle = Fond.create_oval(50,50,70,70,fill='red')
# liaison de notre fonction "touche" avec les événements clavier
fenetre.bind_all('<Key>', touche)
# abonnement de la fenêtre aux événements détectés par Windows
fenetre.mainloop()
#**************************************************************
Exercice 3
Modifier le programme précédent pour éviter à la balle de sortir de l'écran, il vous faut interdire le déplacement selon X et Y si les valeurs de X et Y sont celles des bords + le rayon balle.
Créé avec HelpNDoc Personal Edition: Produire facilement des livres électroniques Kindle