Python 2.7 FEUILLE n° 24 Quatorze sur les Thread avec Turtle juin 2019
COURS :
• POO ou Programmation Orientée Objet
Dans la POO ce qui est manipulé ( concrètement ou abstraitement ) ce sont des objets.
• • Un objet ( ou instance ) étant résumé par une entité structurée hiérarchisée
qui regroupe ses caractéristiques ( propriétés ).
Il est associé à un type qui permet de définir sa structure.
• • • exemple : La chaîne " DUPONT " est un objet modélisé par les proprités
suivantes choisies dans cet ordre:
Date de naissance
Ville de naissance
Adresse
Profession
On aurait pu, pour nos besoins, envisager d'autres propriétés que celles citées.
• • • Pour manipuler un objet il faut disposer de Méthodes et de règles de codage.
• • • Les listes , les dictionnaires , les chaînes , les fonctions mathématiques
sont envisagés comme des objets.
Un objet n'est donc pas forcément quelque chose de physique.
Toutes les données stockées et utilisées en Python 2.7 sont des objets.
C'est dire l'importance des objets.
• • • Chaque objet a :
une identité ( pour le localiser dans la mémoire ),
un type ( pour les modalités de stockage et sa représentation ),
une valeur ( ce qui y est stocké ).
Exemple: print id( "DUPONT " ) = 40580512
print type ( "DUPONT " ) = < class 'str ' >
print "DUPONT " = 'DUPONT
• • •instancier veut dire créer
instancier un objet veut dire créer un objet.
• • Notion de class.
C'est un ensemble de variables, attributs , fonctions, objets, méthodes.
C'est donc très vaste.
• • • Pour définir une classe nommée Voiture on écrit simplement
class Voiture :
( pas de double parenthèse nécessaire.)
On met ensuite, par convention systématiquement, une demande d'affichage
d'une chaîne du style :
print " Instanciation de classe ===== \n "
Pour initialiser cette class, il faut considérer ses attributs ( un ou plusieurs )
et les initialiser.
La Méthode consiste à écrire, si l' on considère le tarif et le délai, comme attributs :
def _init_(self): # la varible est notée self systématiquement
self.tarif=10000 # 10000 euros
self.delai=4 # 4 mois
On peut, à présent, instancier cette classe, c-à-d, créer un objet comme Renault
dans cette class .
On écrit :
renault= Voiture()
Pour cet objet on précise ses propriétés .
On peut avant définir différentes fonctions
etc ......
• • Notion de thread dans les tracés:
On les utilise pour la programmation en parallèle, en multi tâches.
Deux souris ( ou tortues), voire plus, accomplissent des tâches presque
en même en même temps. L'ordinateur gère les piles d'instructions
pour optimiser le déroulement, en parallèle, des déplacements des souris.
# La définition d'un thread est assez "alambiquée"....
<< Un thread est un flux de contrôle qui partage la mémoire de l'ordinateur
avec d'autres threads >>
C'est un peu comme, qu'est-ce que c'est une voiture ?
<< C'est un véhicule qui partage, dans le temps, la route avec d'autres véhicules >>
Il vaut mieux retenir l'effet produit.
Les threads semblent s"exécuter simultanément bien qu'ils se relayent ,
par petits bouts , en général, sur un seul processeur / noyau de processeur ( cpu core ).
Il existe des ordinateurs à double cœurs pour améliorer le problème.
# Il faut savoir que les threads se maîtrisent difficilement et sont difficiles
à tester, peu fiables et encore plus difficiles à déboger.
Quand un thread se bloque en cours d'exécution, c-à-d souvent, la seule solution,
en général, est de fermer le programme puis de le relancer.
Souvent ça remarche. Attendre ne sert à rien.
" Quand un train déraille,sans dégats, il faut le remettre sur les rails."
Il n'est pas rare d'avoir ," pour un oui ou pour un non ", des messages du style :
ValueError: could not convert string to float: itemconfigure
ou encore
ValueError: could not convert string to float: after
ou encore
TclError: bad screen distance "coords"
# En fait, c'est comme un problème de boite de vitesse.
Il faut que l'embrayage amène les deux pignons ( engrenages ) à la même
vitesse de rotations pour qu'ils s'emboitent facilement sinon les dents
s'entrechoquent ce qui fait du bruit et peut abimer les pignons de la boite.
C'est ce qui arrive quand le conducteur n'appuye pas assez sur la pédale
d'embrayage avant de passer la vitesse.
# On peut imaginer la situation d'un père de deux petit bébés A et B
qu'il fait manger . Il a une seule cuillère.
Il la charge , la met dans la bouche de A qui commence à mastiquer.
Il la retire, la recharge , la met dans la bouche de B qui se met à mastiquer.
Il la retire et la recharge pendant que A déglutit et bave.
Il la remet dans la bouche de A et la retire pendant que B déglutit et bave.
Ainsi de suite. Il doit synchroniser le processus.
Cela peut très bien se passer ou déraper...
Peut-on dire que, réellement, que A et B mangent en même temps ?
Non, pas vraiment, même si on le dit. Il faudrait ,en fait, deux cuillères
comme deux cœurs.
La série des actions pour A et la séries des actions pour B
sont imbriquées, dans le temps, pour arriver à les nourrir
dans un temps optimisé.
Donc c'est un thread.
# Il y a deux catégories de threads, ceux de bas niveau et ceux de haut niveau.
Ceux de bas niveau se bloquent souvent.
Ceux de haut niveau sont très compliqués à implémenter et à tester.
-----------------------------------------------------------------------------------------------------------
EXERCICE 1:
Donner en Python 2.7 , avec deux threads ,un script qui permet simultanément d'avoir deux cercles
de tailles rayons et de couleurs différentes.
--------------------------------------------------------------------------------------------------------
REPONSE :
On peut envisager :
import turtle as t # on importe le module turtle comme t ( Donc on le nommera t )
from threading import Thread # importation du module thread
import thread
import time
def Ecran(): # initialisation de l'écran
global cadre
cadre=Tkinter.Tk()
fond=Tkinter.Canvas(cadre,width=600,height=600) # fenêtre 600 x 600
fond.pack()
sc=t.TurtleScreen(fond) # écran dans la fenêtre
sc.bgcolor("white")
return sc
def cercle(cx,cy,pas,couleur): # (cx, cy) coord du point de départ, stp= longueur du pas
global sc # L'écran de la tortue fait par TurtleScreen()
# global pour pouvoir y accéder de l'extérieur
n=32
tr=t.RawTurtle(sc) # création de tr tortue
tr.width(5)
tr.color(couleur)
tr.up()
tr.goto(cx,cy) # tortue mise en position initiale
tr.down()
tr.speed(0) # vitesse maxi
angle=360.0/n
for i in range(4*n): # avancer d'un pas puis tourner de angle pour avoir un cercle
tr.forward(pas)
tr.left(angle)
sc= Ecran()
def Edit_thread(nom,a):
return Thread(name=nom,target=cercle,args=a)
def commande(): # Les deux pas sont 15 et 30 pour des cercles différents
t1=Edit_thread("dodo",(-130,30,15,"red")) # création du thread t1 de la souris dodo
t2=Edit_thread("fafa",(60,-235,30,"green")) # création du thread t2 de la souris fafa
t1.start() # demande de démarrage de t1
t2.start() # demande de démarrage de t2
commande()
On obtient après la touche F5 et Entrée
Le deux cercles ne sont pas de même rayon, pas de la même couleur, pas de même centre.
Mais ils sont réalisés en parallèle à l'aide de deux threads.
---------------------------------------------------------------------------------------------------------------------------
EXERCICE 2:
Donner en Python 2.7 , avec deux threads, un script qui permet simultanément d'avoir
deux rectangles de tailles et de couleurs différentes.
--------------------------------------------------------------------------------------------------------
REPONSE:
On peut considérer : ( On reprend l'essentiel du script précédent )
import Tkinter
import turtle as t # on importe le module turtle comme t ( Donc on le nommera t )
from threading import Thread
import thread
import time
def Ecran(): # initialisation de l'écran
global cadre
cadre=Tkinter.Tk()
fond=Tkinter.Canvas(cadre,width=600,height=600) # fenêtre 600x600 demandée
fond.pack() # activation de la demande de fenêtre
sc=t.TurtleScreen(fond) # écran ou screen dans la fenêtre
sc.bgcolor("white") # couleur de l'intérieur de l'écran
return sc
def rect(cx,cy,larg,long,couleur): # (cx, cy) coord du point de départ de la construction du rectangle
global sc ,b # L'écran de la tortue fait par TurtleScreen()
# variables globales pour pouvoir y accéder de l'extérieur de la fonction
b=90
tr=t.RawTurtle(sc) # création de tr tortue tr=turtle.RawTurtle(sc)
tr.width(5)
tr.color(couleur)
tr.up()
tr.goto(cx,cy) # tortue tr en position initiale sans marquer
tr.down()
tr.speed(0) # vitesse maxi pour tr
for k in range(2):
tr.forward(larg)
tr.left(b)
tr.forward(long)
tr.left(b)
sc= Ecran()
def Edit_thread(nom,a):
return Thread(name=nom,target=rect,args=a)
def commande():
t1=Edit_thread("dodo",(-130,40,60,30,"red")) # thread dodo pour la souris t1
t2=Edit_thread("fafa",(60,-100,30,100,"green")) # thread fafa pour la souris t2
t1.start() # demande de démarrage de t1
t2.start() # demande de démarrage de t2
commande()
Le lancement est directe avec la touche F5 puis Entrée
On obtient, en simultaté, la construction des deux rectangles demandés.
----------------------------------------------------------------------------------------------------------------------------------
EXERCICE 3:
Modifier le script , Python 2.7, pour avoir les deux rectangles avec des couleurs
différentes à l'intérieur.
-----------------------------------------------------------------------------------------------------------------------
REPONSE :
On peut proposer simplement de rajouter trois lignes
et d'introduire deux couleurs, couleur1 pour le bord et couleur2 pour le garnissage:
import Tkinter
import turtle as t # on importe le module turtle comme t ( Donc on le nommera t )
from threading import Thread
import thread
import time
def Ecran(): # initialisation de l'écran
global cadre
cadre=Tkinter.Tk()
fond=Tkinter.Canvas(cadre,width=600,height=600) # fenêtre 600 x600 demandée
fond.pack() # activation
sc=t.TurtleScreen(fond) # écran ou screen dans la fenêtre
sc.bgcolor("white") # couleur à l'intérieur de l'écran
return sc
def rect(cx,cy,larg,long,couleur1,couleur2): # (cx, cy) coord du point de départ
global sc ,b # L'écran de la tortue fait par TurtleScreen()
# global pour pouvoir y accéder de l'extérieur
b=90
tr=t.RawTurtle(sc) # création de la tortue tr
tr.width(5)
tr.color(couleur1) # tr écrit de couleur1
tr.up()
tr.goto(cx,cy) # tortue tr en position initiale au point de coords ( cx , cy )
tr.down()
tr.speed(0) # vitesse maxi pour tr
tr.fillcolor(couleur2)
tr.begin_fill()
for k in range(2):
tr.forward(larg)
tr.left(b)
tr.forward(long)
tr.left(b)
tr.end_fill()
sc= Ecran()
def Edit_thread(nom,a):
return Thread(name=nom,target=rect,args=a)
def commande():
t1=Edit_thread("dodo",(-130,40,60,30,"red","yellow")) # création d'un thread dodo
t2=Edit_thread("fafa",(60,-100,30,100,"green","blue"))
t1.start() # demande de démarrage de t1
t2.start() # demande de démarrage de t2
commande()
Avec la touche F5 puis Entrée on obtient en simultané les rectangles pleins:
-----------------------------------------------------------------------------------------------------------------------------------------
EXERCICE 4:
De même donner un script en Python 2.7 qui donne deux triangles équilatéraux
différents.
------------------------------------------------------------------------------------------------------------
REPONSE:
On peut proposer:
import Tkinter
import turtle as t # on importe le module turtle comme t ( Donc on le nommera t )
from threading import Thread
import thread
import time
def Ecran(): # initialisation de l'écran
global cadre
cadre=Tkinter.Tk()
fond=Tkinter.Canvas(cadre,width=600,height=600) # fenêtre 600 x 600 demandée
fond.pack()
sc=t.TurtleScreen(fond) # écran ou screen dans la fenêtre
sc.bgcolor("white") # couleur de l'intérieur de l'écran
return sc
def triangle(cx,cy,long,couleur): # (cx, cy) coord du point de départ
global sc # L'écran de la tortue fait par TurtleScreen()
# global pour pouvoir y accéder de l'extérieur
tr=t.RawTurtle(sc) # création de la tortue tr
tr.width(5)
tr.color(couleur)
tr.up()
tr.goto(cx,cy) # tortuet r mise en position initiale
tr.down()
tr.speed(0) # vitesse maxi de tr
angle=120
for i in range(3): # avancer puis tourner
tr.forward(long)
tr.left(angle)
sc= Ecran()
def Edit_thread(nom,a):
return Thread(name=nom,target=triangle,args=a)
def commande():
t1=Edit_thread("dodo",(-100,30,50,"red"))
t2=Edit_thread("fafa",(50,-70,100,"green"))
t1.start() # demande de démarrage de t1
t2.start() # demande de démarrage de t2
commande()
Avec la touche F5 puis Entrée on obtient en simultané :
-------------------------------------------------------------------------------------------------------------
EXERCICE 5:
Que donne en Python 2.7 le script suivant ?
import Tkinter
import turtle as t
from threading import Thread
import thread
import time
from random import*
def Ecran():
global cadre
cadre=Tkinter.Tk()
fond=Tkinter.Canvas(cadre,width=600,height=600)
fond.pack()
sc=t.TurtleScreen(fond)
sc.bgcolor("white")
return sc
def triangle(cx,cy,long,couleur1,couleur2):
global sc
tr=t.RawTurtle(sc)
tr.width(5)
tr.color(couleur1)
tr.up()
tr.goto(cx,cy)
tr.down()
tr.speed(0)
angle=120
tr.ht() # cacher à la fin la tortue tr
tr.fillcolor(couleur2)
tr.begin_fill()
for i in range(3):
tr.forward(long)
tr.left(angle)
tr.end_fill()
sc= Ecran()
def Edit_thread(nom,a):
return Thread(name=nom,target=triangle,args=a)
def commande():
for i in range(10):
p,q,v=randint(-180,50),randint(-180,50),randint(-180,50)
m,g,s=randint(-110,100),randint(-110,100),randint(-110,100)
L1=["green","red","brown","blue","orange","yellow","violet"]
L2=["green","yellow","violet"]
couleur1=choice(L1)
couleur2=choice(L2)
t1=Edit_thread("dodo",(p,m,150,couleur1,couleur2))
t2=Edit_thread("fafa",(q,g,150,couleur1,couleur2))
t3=Edit_thread("fifi",(v,s,150,couleur1,couleur2))
t1.start()
t2.start()
t3.start()
commande()
-----------------------------------------------------------------------------------------------------------
REPONSE :
L'ordinateur, à dix reprises, à l'aide de trois souris ( ou tortues ) , fait tracer
trois triangles simultanés de couleurs et positions aléatoires encadrées,
de cotés de longueur 150.
Avec la touche F5 puis Entrée on obtient par exemple:
"Quand l'ordinateur devient un artiste ! " : 15 000 $
------------------------------------------------------------------------------------------------------------------------------------
EXERCICE 6:
Donner un script en Python 2.7 avec trois threads qui constuisent les trois tours d'un château.
---------------------------------------------------------------------------------------------------------------------------
REPONSE :
On peut proposer le script qui reprend des parties des script précédents:
import Tkinter
import turtle as t
from threading import Thread
import thread
import time
def Ecran():
global cadre
cadre=Tkinter.Tk()
fond=Tkinter.Canvas(cadre,width=600,height=600)
fond.pack()
sc=t.TurtleScreen(fond)
sc.bgcolor("white")
return sc
def tour(cx,cy,dx,dy,larg,long1,long2,long3,couleur1,couleur2,couleur3,pas): # 12 paramètres
global sc ,b ,e
e=round(360.0/32,2)
b=90
tr=t.RawTurtle(sc)
tr.width(5)
tr.color(couleur1)
tr.up()
tr.goto(cx,cy)
tr.down()
tr.speed(0)
tr.fillcolor(couleur2)
tr.begin_fill()
for k in range(2):
tr.forward(larg)
tr.right(b)
tr.forward(long1)
tr.right(b)
tr.end_fill()
for k in range(2):
tr.forward(larg)
tr.right(b)
tr.forward(long3)
tr.right(b)
angle=120
tr.fillcolor(couleur3)
tr.begin_fill()
for i in range(3):
tr.forward(long2)
tr.left(angle)
tr.end_fill()
tr.up()
tr.goto(dx,dy)
tr.down()
tr.fillcolor("red")
tr.begin_fill()
for i in range(42):
tr.forward(pas)
tr.left(e)
tr.end_fill()
tr.up()
tr.goto(cx,cy)
tr.down()
sc= Ecran()
def Edit_thread(nom,a):
return Thread(name=nom,target=tour,args=a)
def commande():
t1=Edit_thread("dodo",(-150,120,-90,50,120,30,120,200,"green","brown","grey",2))
t2=Edit_thread("fafa",(95,120,175,55,150,30,150,220,"green","brown","grey",2))
t3=Edit_thread("lulu",(-25,-50,35,-110,120,30,120,200,"green","brown","grey",2))
t1.start()
t2.start()
t3.start()
commande()
C'est-à-dire:
On obtient avec la latouche F5 puis Entrée la construction simultanée des trois
tours suivantes.
" Vous êtes ici chez vous "
--------------------------------------------------------------------------------------------------------------------------------------------