IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Programmation orientée objet


Sujet :

Python

  1. #1
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Juillet 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juillet 2012
    Messages : 7
    Par défaut Programmation orientée objet
    Bonjour

    Je travaille avec Python3, avec linux ubuntu 12.10

    J'essaie de créer un programme qui simule un robot qui doit rechercher une cible.
    J'ai déclaré un objet bloc, qui me servira à dessiner un robot (en bleu) et une cible (en rouge).

    Lorsqu'on lance le programme, 2 boutons apparaissent dans une fenêtre : départ et stop.
    La fonction depart() crée et affiche le robot et la cible, mais je n'arrive pas à déplacer le robot : pour l'instant ses mouvements sont réduits à une petite boucle for.
    J'ai placé une pause entre 2 mouvements, mais on ne voit rien bouger.

    Quelqu'un peut-il maider ?
    Fichiers attachés Fichiers attachés

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 718
    Par défaut
    Salut,
    Allez jeter un œil sur les posts existants dans le forum tkinter.
    Celui ci
    montre les trucs a utiliser pour faire bouger les items d'un canvas.

    - W
    PS: Pour découvrir Tkinter, inutile de se compliquer la vie avec des "class" surtout si c'est pour avoir des variables globales dans tous les coins.
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre émérite
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Par défaut
    Bonsoir,
    (@ Wiztricks: pour le PS, oui, mais cela semble précisément être le but de l'exercice, non?)

    @ronnie_sun:
    J'ai un peu de mal à suivre (mais bon, il est tard!! :-))…
    - Que représente pour vous la variable "self" de la classe Bloc?

    Indice1 (Tkinter 8.5 reference: a GUI for Python):
    8.6. Methods on Canvas widgets
    All Canvas objects support these methods:

    .coords(tagOrId, x0, y0, x1, y1, ..., xn, yn)
    If you pass only the tagOrId argument, returns a tuple of the coordinates of the lowest or only object specified by that argument. The number of coordinates depends on the type of object. In most cases it will be a 4-tuple (x1, y1, x2, y2) describing the bounding box of the object.
    You can move an object by passing in new coordinates.
    Indice2: Insertion de "print(cnv1.coords(self))" juste avant la ligne "cnv1.coords(…":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    >>> ================================ RESTART ================================
    >>> 
    []
    []
    []
    []
    []
    []
    []
    []
    []
    []
    >>>
    Réponse au problème (mais il vaut mieux s'intéresser aux questions précédentes et y répondre!!):
    - La variable self à l'intérieur de la classe bloc référence une instance de la classe Bloc.
    - Vous essayer de déplacer un objet appartenant à cnv1. Cet objet que vous tentez de déplacer est une instance de la classe Bloc… qui n'appartient pas à cnv1. D'où le résultat de la fonction print() rajoutée.
    - Il suffit donc, lors de la création de l'instance de Bloc, de récupérer une référence à l'objet "rectangle" créé à l'intérieur de cnv1. Et bien sûr, d'utiliser cette référence pour en modifier les coordonnées par la suite…
    Soit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    #---------------------------------------------------------
    # Robot POO
    # 19/10/2013
    #---------------------------------------------------------
    from tkinter import *
    from math import *
    from random import *
    from time import *
    
    #---------------------------------------------------------
    #Lancement :
    def depart():
    	robot=Bloc(cnv1,randint(1,100),randint(1,100),10,'blue')
    	cible=Bloc(cnv1,30,40,10,'red')
    	
    	for i in range(10):
    		pause(0.5)
    		robot.mvt(5,5)
    
    def pause(t):
    	#pause de t secondes
    	fnt1.update()
    	sleep(t)
    	
     
    #---------------------------------------------------------
    #Objets :
    class Bloc(object):
    	"""Petit bloc carré """
    	def __init__(self,cnv,x,y,taille,couleur):
    		self.cnv=cnv		#réf au canevas
    		self.x=x
    		self.y=y
    		self.taille=taille
    		self.couleur=couleur
    		self.carre = cnv.create_rectangle(x,y,x+taille,y+taille,fill=couleur)
    			
    	def mvt(self,dx,dy):
    		self.x=randint(1,100)
    		self.y=randint(1,100)
    #		print(cnv1.coords(self)) # Que réprésente self ici?
    		cnv1.coords(self.carre,self.x,self.y,self.x+10,self.y+10)
    		
    #---------------------------------------------------------
    #Zone graphique :
    #Fenêtre principale :
    fnt1 = Tk()
    
    #Canevas :
    cnv1 = Canvas(fnt1, width=300, height=200, bg='grey')
    cnv1.pack(side=LEFT)
    
    #Boutons :
    bt_depart=Button(fnt1, text="départ",command=depart)
    bt_depart.pack(side=TOP)
    bt_fin=Button(fnt1, text="stop",command=fnt1.destroy)
    bt_fin.pack(side=TOP)
    bt_rob_x=Label(fnt1,text="x_rob")
    bt_rob_x.pack(side=TOP)
    
    #Boucle principale :
    fnt1.mainloop()
    Clodion

    PS: il me semble que les définitions de self.x/y sont un peu problématiques, non?
    PS2: ainsi que le dit wiztricks, quitte à faire de la POO pourquoi ne pas essayer d'aller un peu plus loin ?

  4. #4
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Juillet 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juillet 2012
    Messages : 7
    Par défaut
    Bonjour

    Merci beaucoup pour vos réponses.
    Effectivement, maintenant ça marche !
    Tout à fait d'accord pour aller plus loin avec la POO, mais avant j'avais besoin de voir graphiquement le résultat de ma programmation.

    Bien cordialement.

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 718
    Par défaut
    Citation Envoyé par Clodion Voir le message
    (@ Wiztricks: pour le PS, oui, mais cela semble précisément être le but de l'exercice, non?)
    Peut être mais les soucis du PO viennent d'abord de ses méconnaissances cote GUI graphique.
    Il y a tout un chapitre du Swinnen qui traite de Tkinter et aborde les animations.
    Apprendre les bases avant de vouloir se compliquer la vie en essayant d'organiser son code avec des notions POO est incontournable.
    Pire, la POO avec Tkinter est assez particulière (comme avec tout GUI).
    Dit autrement, sans POO, ca donne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    26
    27
    28
    29
    30
    31
    import tkinter as tk
    from tkinter.constants import *
    import random
     
    ident = robot = cible = None
     
    def update(delay=20):
        global ident
        canvas.move(robot, 5, 5)
        ident = app.after(delay, update)
     
    def start():
        global robot, cible
        x, y = random.randint(1, 100), random.randint(1, 100)
        robot = canvas.create_rectangle(x, y, x+10, y+10, fill='blue')
        x, y = 30, 40
        cible = canvas.create_rectangle(x, y, x+10, y+10, fill='red')
        update()
     
    def stop():
        app.after_cancel(ident)
        app.quit()
     
    if __name__ == '__main__':
        app = tk.Tk()
        canvas = tk.Canvas( width=300, height=200, bg='grey')
        canvas.pack(side=LEFT)
        tk.Button(text='start', command=start).pack(side=TOP)
        tk.Button(text='stop', command=stop).pack(side=TOP)
        tk.Label(text='x_rob').pack(side=TOP)
        app.mainloop()
    On peut s'amuser a ajouter de la POO apres. Mais il y a du boulot.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Juillet 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juillet 2012
    Messages : 7
    Par défaut
    Sans la POO j'ai déjà bien avancé : voir la pièce jointe, si vous avez le temps.
    Je pense que le moment est venu (pour moi) de franchir le pas.

    Mais je suis tout à fait prêt à suivre vos conseils !

    Bien cordialement.
    Fichiers attachés Fichiers attachés

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 718
    Par défaut
    salut,
    La POO ca commence par reduire les variables globales, i.e. eviter les
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    from tkinter import *           #fenêtres graphiques
    from math import *              #fonctions mathématiques
    from random import *            #nombres aléatoires
    from time import *
    ou encore des choses comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    xmin,ymin=1,1           #coordonnées minimales
    xmax,ymax=50,20         #coordonnées maximales
    patch=10                #taille des sprites
    max_pas=1000	            #nb de pas maximal du robot
    pas=0					#compteur de pas du robot
    cible_atteinte=FALSE    #indicateur de cible atteinte
    robot=0                 #image du robot
    xr,yr,xr0,yr0=0,0,0,0   #coordonnées du robot, et copies
    capr=0                  #cap du robot
    vxr,vyr=0,0             #vitesse du robot
    xc,yc,xc0,yc0=0,0,0,0   #coordonnées du robot, et copies
    capc=0                  #cap du robot
    vxc,vyc=0,0             #vitesse du robot
    delai=0.1				#délai entre 2 mouvements du robot
    max_trajets=3			#nb maximum de trajets pour le robot
     
    dxr,dyr = 4,4			#dimensions trace du robot
    Avant de sortir le mot "class", vous pourriez la jouer "a l'ancienne": un objet est un contexte (un dict) et des fonctions associees.
    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def creer_robot():
        global robot,xr,yr,xr0,yr0,capr,vxr,vyr,trace_robot
        xr=randint(xmin+1,xmax-1)
        yr=randint(ymin+1,ymax-1)
        robot=cnv1.create_rectangle(xr*patch,yr*patch,(xr+1)*patch,(yr+1)*patch,fill='blue')
        trace_robot=cnv1.create_rectangle(xr*patch+dxr,yr*patch+dxr,(xr+1)*patch-dxr,(yr+1)*patch-dxr,fill='blue')
        xr0,yr0=xr,yr
        capr=randint(0,359)
        vxr,vyr=sin(capr),-cos(capr)
    => creer_robot() retourne un dict qui sera l'etat du robot.

    Preferez le globish:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    def robot_create(canvas,...):
    sera un meilleur precurseur d'une classe Robot que "creer_robot"
    Puisque l'etat du robot est un dict, un truc comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def accelerer_robot():
    	global vxr,vyr
    	vxr *= 1.2
    	vyr *= 1.2
    deviendrait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def robot_accelerate(robot):
    	#global vxr,vyr le but est de virer les "variables globales"
    	robot['vxr'] *= 1.2
    	robot['vyr'] *= 1.2
    Pour faciliter la "transition" vous pourriez, utiliser le dict d'une "class".
    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Robot:
          vxr = 0
          vyr = 0
    def robot_create(robot, canvas):
          ...
         robot.iid = canvas.create...
         capr=randint(0,359)
         robot.vxr, robot.vyr=sin(capr),-cos(capr)
     
    def robot_accelerate(robot):
    	robot.vxr *= 1.2
    	robot.vyr *= 1.2
    Le but étant de pousser dans un /dict/ dédie a robot les choses qui sont liée au robot et de visibiliser les objets externes dont il dépend (le canvas).
    Cela fait, il suffit de faire des fonctions commençant par "robot" des méthodes de la "class" robot:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Robot:
          ...
          __init__ = robot_create
          accelerate = robot_accelerate
          ...
    Puis de remplacer les appels a robot_* par robot.*

    Ca vous permettrait de modifier l'existant par étape en faisant pousser les objets sans tout casser.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Juillet 2012
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Juillet 2012
    Messages : 7
    Par défaut
    Merci beaucoup pour ce coaching.
    Je vais me mettre au travail.

    Question sans doute naïve : "dict" signifie bien "dictionnaire" ?
    Je n'ai pas encore manipulé ce type de structure en Python, mais je vois à peu près à quoi cela correspond.

    Bien cordialement.

  9. #9
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 718
    Par défaut
    Citation Envoyé par ronnie_sun Voir le message
    Question sans doute naïve : "dict" signifie bien "dictionnaire" ?
    Oui: Python est plein de dict:
    • les variables globales sont dans un dict - globals() -,
    • les variables locales (dans un fonction) sont dans un dict - locals(),
    • les attributs d'une classe sont dans un dict Robot.__dict__
    • Et ceux d'une instance aussi

    le dict définit un espace de "noms": robot.xr va chercher l'objet associee au nom "xr" dans l'espace de nom associe a "robot".

    C'est ce qui rend utile de remplacer "from tkinter import *" - ca recopie tous les noms du module tkinter dans le globals() courant - par "import tkinter as tk" - seul tk a ete ajoute a globals() -.

    Plutôt qu’écrire app = Tk() on se force a ecrire app= tk.Tk() i.e. la chose /Tk/ dans l'espace de nom /tk/. tk pourrait etre classe ou instance la syntaxe ne change pas et la sémantique sera toujours appeler l'objet associe au nom "Tk" dans l'espace de noms tk.

    Un des avantages de la POO est de vous permettre de partitionner l'espace de noms en espaces de noms plus petits.
    L’inconvénient est que tout pousser dans des boites suppose de définir des relations entre ces boites: parfois c'est simple mais comme c'est a priori un "graphe" ca peut devenir assez vite le boxon.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Problème de programmation orientée objet
    Par dan65 dans le forum WinDev
    Réponses: 8
    Dernier message: 17/09/2006, 01h04
  2. Réponses: 2
    Dernier message: 30/03/2006, 14h48
  3. [C#] Comment correctement programmer orienté objet ?
    Par ChristopheOce dans le forum C#
    Réponses: 5
    Dernier message: 06/02/2006, 13h22
  4. [POO] apprendre la programmation orientée objet
    Par Invité dans le forum Langage
    Réponses: 5
    Dernier message: 10/12/2005, 11h33
  5. [DEBUTANT] Conseil sur la programmation orienté objet
    Par etiennegaloup dans le forum Langage
    Réponses: 7
    Dernier message: 27/05/2005, 12h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo