Partage
  • Partager sur Facebook
  • Partager sur Twitter

Initiation aux classes

Soucis de variable (sans doute)

    4 mai 2011 à 18:29:40

    Bonjour,

    Je m'immerge actuellement dans le monde des classes, déjà le concept est pas simple à comprendre et afin de mieux comprendre, je pratique (enfin j'essaye :( )

    J'ai fais un exercice commun, une gestion de compte en banque rudimentaire avec 2 méthodes deposerArgent et retirerArgent, pour corser un peu, j'ai testé de rajouter la méthode changerNom, qui change le nom de la personne.

    Voici mon code:

    # -*- coding: Utf-8 -*-
    
    # Déclaration de la classe
    class cb(object):
    	"""Classe gérant un compte banquaire rudimentaire"""
    	
    	def __init__(self, argentTotal, nom):
    		self.argentTotal = 1000
    		self.nom =  ""
    		
    	def deposerArgent(self, argentMoins):
    		self.argentTotal -= argentMoins
    		return self.argentTotal
    		
    	def retirerArgent(self, argentPlus):
    		self.argentTotal += argentPlus
    		return argentTotal
    	
    	def changerNom(self, nouveauNom):
    		self.nom == nouveauNom
    		
    # MAIN
    
    userName = input("Votre nom ? ") #userName contient le nom de la personne
    user = cb(1000, userName) # user => objet, on lui passe l'argent dans user.argentTotal et dans user.nom la variable userName)
    print "Votre nom => ", user.nom, " et vous avez ", user.argentTotal, "€"
    


    Milles excuse pour l'abus de commentaire, mais je balise pour bien comprendre ce que chaque ligne fait.

    L'interpréteur me crie dessus ceci:

    Votre nom ? test
    Traceback (most recent call last):
      File "perso.py", line 24, in <module>
        userName = input("Votre nom ? ") #userName contient le nom de la personne
      File "<string>", line 1, in <module>
    NameError: name 'test' is not defined


    A noté que j'ai eu beaucoup de mal à déclarer ma classe correctement, je sais pas si elle doit retourner quelque chose ou pas, et ce "self" me pose pas mal de soucis car j'ai du mal à me rendre compte à quoi il sert.

    Par avance, merci de vos lumières, car là, je patauge ! :)

    P.S: Je me suis dis que c'était peut-être la déclaration de la classe qui aimait pas les variable donc j'ai fais ceci, sans résultat non plus:

    userName = input("Votre nom ? ") #userName contient le nom de la personne
    user = cb(1000, "Paul") # user => objet, on lui passe l'argent dans user.argentTotal et dans user.nom la variable userName)
    user.changerNom(userName)
    print "Votre nom => ", user.nom, " et vous avez ", user.argentTotal, "€"
    
    • Partager sur Facebook
    • Partager sur Twitter
      4 mai 2011 à 18:37:43

      Change juste ton "input()" en un "raw_input()", Ca fonctionnera beaucoup mieux.
      • Partager sur Facebook
      • Partager sur Twitter
      yjltg.
        4 mai 2011 à 19:03:03

        Ha oui, raw_input() pour le texte.

        Ceci, dit, ça ne fonctionne toujours pas

        Votre nom ? TEST
        Votre nom =>    et vous avez  1000 €

        • Partager sur Facebook
        • Partager sur Twitter
          4 mai 2011 à 19:28:16


          edit: Rien. pas les yeux en face des trous.


          Ps : c'est moche d'indenter avec des tabulations.
          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            4 mai 2011 à 23:32:32

            Citation : PsycoPy

            Ligne 20 ! :-°



            Arrrrggh ! o_O Môdieu :euh:

            Merci pour l'info, j'étais vraiment passé à côté... Ceci dit, quand est ce qu'une méthode d'une classe doit renvoyer quelque chose ? C'est un peu comme les fonctions ? On renvoie que si on a besoin ?

            P.S: Le code complet que j'ai modifier (les instructions des classes étaient foireuses) et j'ai tout converti en python3 (enfin je pense):

            # -*- coding: Utf-8 -*-
            
            # Déclaration de la classe
            class cb(object):
            	"""Classe gérant un compte banquaire rudimentaire"""
            	
            	def __init__(self, argentTotal, nom):
            		self.argentTotal = 1000
            		self.nom =  ""
            		
            	def deposerArgent(self, argentMoins):
            		self.argentTotal += argentMoins
            		return self.argentTotal
            		
            	def retirerArgent(self, argentPlus):
            		self.argentTotal -= argentPlus
            		return self.argentTotal
            	
            	def changerNom(self, nouveauNom):
            		self.nom = nouveauNom
            
            		
            # MAIN
            
            userName = input("Votre nom ? ") #userName contient le nom de la personne
            user = cb(1000, "Paul") # user => objet, on lui passe l"argent dans user.argentTotal et dans user.nom la variable userName)
            user.changerNom(userName)
            print ("Votre nom => ", user.nom, " et vous avez ", user.argentTotal, "euros.")
            print ("Que voulez vous faire ?")
            print ("1. Déposer de l\"argent")
            print ("2 Retirer de l\"argent")
            choix = int(input("Votre choix => "))
            if choix == 1:
            	somme = int(input("Quelle somme voulez-vous déposer ?  "))
            	user.deposerArgent(somme)
            	print ("Vous avez maintenant ", user.argentTotal, "euros.")
            if choix == 2:
            	somme = int(input("Quelle somme voulez-vous retirer ? "))
            	if somme > user.argentTotal :
            		print ("Vous ne pouvez pas retirer plus que ce que vous avez !")
            	else:
            		user.retirerArgent(somme)
            		print ("Vous avez maintenant ", user.argentTotal, "euros.")
            
            • Partager sur Facebook
            • Partager sur Twitter
              5 mai 2011 à 1:41:29

              Une méthode n'est pas obligée de renvoyer qlq chose.
              Pour ton code, vire la méthode changerNom, initialise l'attribut self.nom avec le paramètre nom et remplace
              userName = input("Votre nom ? ") 
              user = cb(1000, "Paul") 
              user.changerNom(userName)
              

              par
              userName = input("Votre nom ? ")
              user = cb(1000, userName)
              
              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                6 mai 2011 à 10:03:47

                On pourrait retirer quelques lignes, j'ai regardé rapidement


                # -*- coding: Utf-8 -*-
                
                # Déclaration de la classe
                class cb(object):
                	"""Classe gérant un compte banquaire rudimentaire"""
                	argentTotal = 1000
                	nom =  ''
                
                		
                # MAIN
                user = cb()
                user.nom = input("Votre nom ? ") #userName contient le nom de la personne
                print ("Votre nom => ", user.nom, " et vous avez ", user.argentTotal, "euros.")
                print ("Que voulez vous faire ?")
                print ("1. Déposer de l\'argent")
                print ("2 Retirer de l\'argent")
                choix = int(input("Votre choix => "))
                if choix == 1:
                	somme = int(input("Quelle somme voulez-vous déposer ?  "))
                	user.argentTotal += somme
                	print ("Vous avez maintenant ", user.argentTotal, "euros.")
                if choix == 2:
                	somme = int(input("Quelle somme voulez-vous retirer ? "))
                	if somme > user.argentTotal :
                		print ("Vous ne pouvez pas retirer plus que ce que vous avez !")
                	else:
                		user.argentTotal -= somme
                		print ("Vous avez maintenant ", user.argentTotal, "euros.")
                


                Mais mieux dans ce cas sont les surcharges opérateurs

                # -*- coding: Utf-8 -*-
                
                # Déclaration de la classe
                class cb(object):
                    def __init__(self):
                        self.argentTotal = 1000
                    def __add__(self, n):
                        self.argentTotal += n
                    def __sub__(self, n):
                        if n < self.argentTotal:
                             self.argentTotal -= n
                    def __repr__(self):
                        return repr(self.argentTotal)
                
                		
                # MAIN
                Total = cb()
                nom = input("Votre nom ? ") #userName contient le nom de la personne
                print ("Votre nom => ", nom, " et vous avez ", cb(), "euros.")
                print ("""Que voulez vous faire ?
                1. Déposer de l\'argent
                2. Retirer de l\'argent""")
                choix = int(input("Votre choix => "))
                if choix == 1:
                	somme = int(input("Quelle somme voulez-vous déposer ?  "))
                	Total + somme
                	print ("Vous avez maintenant ", Total, "euros.")
                if choix == 2:
                	somme = int(input("Quelle somme voulez-vous retirer ? "))
                	Total - somme
                	print ("Vous avez maintenant ", Total, "euros.")
                
                • Partager sur Facebook
                • Partager sur Twitter
                  6 mai 2011 à 11:16:21

                  Citation : fred1599

                  def __add__(self, n):
                          self.argentTotal += n
                  


                  Ça me parait curieux, la méthode spéciale __add__ renvoie quelque chose.
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    6 mai 2011 à 11:30:18

                    pas obligatoirement

                    J'ai fais un essai du même style

                    >>> class A(object):
                    ...     def __init__(self):
                    ...         self.n = 12
                    ...     def __add__(self, b):
                    ...         self.n += b
                    ...     def __repr__(self):
                    ...         return repr(self.n)
                    ... 
                    >>> a = A()
                    >>> a + 5
                    >>> a.n
                    17
                    >>> print a + 9
                    None
                    >>> a + 9
                    >>> a
                    35
                    >>> print a
                    35
                    


                    • Partager sur Facebook
                    • Partager sur Twitter
                      6 mai 2011 à 11:57:03

                      Citation : fred1599

                      pas obligatoirement



                      Bien sûr que tu as le droit de le faire mais ce n'est pas du tout la sémantique commune de cette méthode spéciale. J'ai parcouru tous mes fichiers Python de provenance sûre et je n'ai jamais vu __add__ ne pas retourner quelque chose. Et c'est bien normal, cette méthode émule l'addition donc elle renvoie la somme (une nouvelle instance en général).
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Anonyme
                        6 mai 2011 à 12:04:41

                        Oui mais comme la somme ici est représentée par la classe elle même, il suffit de renvoyer l'instance de classe.

                        finalement on pourrait très bien retirer __repr__() et ajouter return repr(self.argentTotal) à la fin de la méthode __add__(), mais je ne vois pas de règles spécifiques pour ce genre de choses

                        Edit:

                        # -*- coding: Utf-8 -*-
                        
                        # Déclaration de la classe
                        class cb(object):
                            def __init__(self):
                                self.argentTotal = 1000
                            def __add__(self, n):
                                self.argentTotal += n
                                return repr(self.argentTotal)
                            def __sub__(self, n):
                                if n < self.argentTotal:
                                     self.argentTotal -= n
                                return repr(self.argentTotal)
                        
                        # MAIN
                        Total = cb()
                        nom = input("Votre nom ? ") #userName contient le nom de la personne
                        print ("Votre nom => ", nom, " et vous avez ", cb(), "euros.")
                        print ("""Que voulez vous faire ?
                        1. Déposer de l\'argent
                        2. Retirer de l\'argent""")
                        choix = int(input("Votre choix => "))
                        if choix == 1:
                        	somme = int(input("Quelle somme voulez-vous déposer ?  "))
                        	print ("Vous avez maintenant ", Total+somme, "euros.")
                        if choix == 2:
                        	somme = int(input("Quelle somme voulez-vous retirer ? "))
                        	print ("Vous avez maintenant ", Total-somme, "euros.")
                        


                        Edit2 : Virer le __repr__() c'est moche, d'ailleurs si il redemande l'argent total de son compte, il faudra bien le remettre. Donc dans ce cas précis, c'était très bien avant.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          6 mai 2011 à 12:24:14

                          Citation : fred1599

                          Oui mais comme la somme ici est représentée par la classe elle même, il suffit de renvoyer l'instance de classe.



                          Pour moi l'utilisation que tu fais de __add__ n'a aucun sens pour un compte bancaire. Disons que pour un banquier ça aurait un sens, il fusionnerait des comptes et donc il ajouterait des comptes en quelque sorte. Mais, pour créditer ou débiter un compte et un seul, dans l'état actuel de mes connaissances, ça n'a pas de sens ni même d'intérêt. L'idée de __add__ est simple, tu veux simuler l'addition de nombres mais pour des trucs qui sont pas des nombres, par exemple, supposons que tu aies une classe Durée (avec des attributs heure, minute, seconde ou encore qui dériverait d'une classe 3-uple), alors par exemple là ça a vraiment un sens d'ajouter deux durées et donc d'implémenter __add__. À la rigueur, ça pourrait avoir un sens d'implémenter __radd__ pour créditer un compte, et encore, faudrait définir une autre classe pour qu'on se rapproche de la situation réelle.
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Anonyme
                            6 mai 2011 à 12:46:23

                            Citation

                            Pour moi l'utilisation que tu fais de __add__ n'a aucun sens pour un compte bancaire. Disons que pour un banquier ça aurait un sens, il fusionnerait des comptes et donc il ajouterait des comptes en quelque sorte. Mais, pour créditer ou débiter un compte et un seul, dans l'état actuel de mes connaissances, ça n'a pas de sens ni même d'intérêt. L'idée de __add__ est simple, tu veux simuler l'addition de nombres mais pour des trucs qui sont pas des nombres, par exemple, supposons que tu aies une classe Durée (avec des attributs heure, minute, seconde ou encore qui dériverait d'une classe 3-uple), alors par exemple là ça a vraiment un sens d'ajouter deux durées et donc d'implémenter __add__. À la rigueur, ça pourrait avoir un sens d'implémenter __radd__ pour créditer un compte, et encore, faudrait définir une autre classe pour qu'on se rapproche de la situation réelle.



                            Je suis totalement d'accord avec toi (pour une fois, ça se fête), cependant on parle d'un entraînement aux classes et le PO (voir 1er post) ajoute des nombres et pas des comptes.

                            Son seul intérêt (je pense) est l'utilisation des classes et l'utilisation des attributs de classe.

                            Après en ce qui concerne un programme plus élaboré, je suis d'accord avec toi que l'objet devrait être un compte et non un nombre.

                            • Partager sur Facebook
                            • Partager sur Twitter

                            Initiation aux classes

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown