Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 17/04/2021, à 21:54

chris7522

[Resolu]boucler sur instance d'une classe contenu dans une liste

Bonjour a toutes et a tous ,
Je souhaiterai qu'a la fin du code , je puisse afficher tous les personnages avec leur reste de vie , pas seulement l'attaquant et l'attaqué . Pour le moment , je n'y arrive pas . Merci de votre aide

  class Personnage:
    def __init__(self,nom):
        self.nom = nom
        self.vie = 5
    def augmente_vie(self,vie_en_plus=1):
        self.vie += vie_en_plus
    def diminue_vie(self,vie_en_moins=2):
        self.vie = max(0,self.vie - vie_en_moins)
    def attaque(self,un_personnage):
        self. augmente_vie()
        un_personnage.diminue_vie()

list_personnage = list()
choix = 'x'
while choix != 'q' and choix != 'Q':
    print(f"Pour entrer un nom....... 1")
    print(f"Pour attaquer............ 2")
    print(f"Pour quitter............. q")
    choix = input("Entrez votre choix  :\n")
    if choix == '1':
        nom = input("Quel est votre nom ?\n")
        nouveau=Personnage(nom)
        list_personnage.append(nouveau)  
    elif choix == '2': 
        for k,personnage in enumerate(list_personnage):
            print(f"{k}---{personnage.nom} a {personnage.vie} vie")
        
        num_attaque = int(input("Entrez numero de l'attaqué :\n"))
        num_attaquant = int(input("Entrez numero de l'attaquant  :\n"))
        attaque = list_personnage[num_attaque]
        attaquant = list_personnage[num_attaquant]
        attaquant.attaque(attaque)
        ...

    

Dernière modification par chris7522 (Le 18/04/2021, à 07:31)

Hors ligne

#2 Le 17/04/2021, à 23:11

Compte supprimé

Re : [Resolu]boucler sur instance d'une classe contenu dans une liste

Bonjour,
crée plutôt une méthode dans ta classe permettant d'ajouter tes personnages (au lieu de multiplier les instances qui sont des objets distincts )

Dernière modification par Compte supprimé (Le 17/04/2021, à 23:12)

#3 Le 18/04/2021, à 07:30

chris7522

Re : [Resolu]boucler sur instance d'une classe contenu dans une liste

J'ai trouvé une solution a mon probleme .
Je te remercie de ton aide .

Hors ligne

#4 Le 20/04/2021, à 12:03

chris7522

Re : [Resolu]boucler sur instance d'une classe contenu dans une liste

Bonjour,
J'ai fait cette version avec les property mais j'ai pas du faire de la bonne facon :

class Personnage:
    def __init__(self,nom):
        self.nom = nom
        self.vie = 5
        
    @property
    def nom(self):
        return self.__nom
    @nom.setter
    def nom(self,nom):
        if isinstance(nom,str)==False:
            raise BaseException("'Nom' must be an str !")
        self.__nom = nom
    
    @property
    def vie(self):
        return self__vie
    @vie.setter
    def vie(self,vie):
        if isinstance(vie,int)==False:
            raise BaseException("'Vie' must be an integer !")
        self.__vie = vie
    
    def augmente_vie(self,vie_en_plus=1):
        self.vie += vie_en_plus
        
    def diminue_vie(self,vie_en_moins=2):
        self.vie = max(0,self.vie - vie_en_moins)
        
    def attaque(self,un_personnage):
        self.augmente_vie()
        un_personnage.diminue_vie()
           

list_personnage = list()
choix = 'x'
print('---------MENU------------')
while choix != 'q' and choix != 'Q':
    print(f"Pour entrer un nom....... 1")
    print(f"Pour attaquer............ 2")
    print(f"Pour tricher ............ 3")
    print(f"Pour quitter............. q")
   
    choix = input("Entrez votre choix  :\n")
    
    if choix == '1':
        nom = input("Quel est votre nom ?\n")
        nouveau=Personnage(nom)
        list_personnage.append(nouveau) 
        print('----------MENU---------------') 
        
    elif choix == '2':
        print('----------JOUEUR---------------') 
        for k,personnage in enumerate(list_personnage):
            print(f"{k}---{personnage.nom} a {personnage.vie} vie")
        num_attaque = int(input("Entrez numero de l'attaqué :\n"))
        num_attaquant = int(input("Entrez numero de l'attaquant  :\n"))
        attaque = list_personnage[num_attaque]
        attaquant = list_personnage[num_attaquant]
        attaquant.attaque(attaque)
        print('---------JOUEUR--------------')
        for personnage in list_personnage:
            print(f"{personnage.nom} a {personnage.vie} vie")
        print('----------MENU---------------')
        
    elif choix == '3':
        bonus = int(input("Entrez le nombre de points que vous voulez en plus :\n"))
        for k,personnage in enumerate(list_personnage):
            print(f"{k}---{personnage.__nom}")
        numero_personnage = int(input("Entrez le numero du personnage a qui vous voulez rajouter des points :\n"))
        personne = list_personnage[numero_personnage]
        personne.augmente_vie(bonus)
        print('---------JOUEUR--------------')
        for personnage in list_personnage:
            print(f"{personnage.__nom} a {personnage.__vie} vie")
       

    

Lorsque je passe au choix 2 , j'ai :

Traceback (most recent call last):
  File "personnage.py", line 55, in <module>
    print(f"{k}---{personnage.nom} a {personnage.vie} vie")
  File "personnage.py", line 17, in vie
    return self__vie
NameError: name 'self__vie' is not defined

Je ne dois pas mettre d'underscore devant les attributs de ma méthode __init__ puisque que ça passe par la méthode @property , non ?
Merci de votre aide .

Dernière modification par chris7522 (Le 20/04/2021, à 13:36)

Hors ligne

#5 Le 20/04/2021, à 20:51

Compte supprimé

Re : [Resolu]boucler sur instance d'une classe contenu dans une liste

Bonjour,

Ton exception est plutôt explicite:

NameError: name 'self__vie' is not defined

self__vie n'existe pas dans ton code contrairement à self.__vie ...

Sinon les conventions pour dire qu'un attribut est privé, c'est un underscore et non pas deux :
self.__vie --> self._vie
remarque: input de renvoit toujours une string donc isinstance(nom,str) sera toujours faux.
Tu pourrais faire:

class Personnage:
    def __init__(self, nom):
        self.nom = nom
    @property
    def nom(self):
        return self._nom
    @nom.setter
    def nom(self,nom):
        if nom.isalpha() == False:
            raise SyntaxError("'Nom' doit être une suite de lettre !")
        self._nom = nom
        return self.nom


p = Personnage("moi")
print(p.nom)
p = Personnage(445)
print(p.nom)

On peut aussi écrire un property comme il suit :

class Personnage:
    def __init__(self,nom):
        self.nom = nom
    def _get_nom(self):
        return self._nom
    def _set_nom(self, nom):
        if nom.isalpha() == False:
            raise SyntaxError("'Nom' doit être une suite de lettre !")
        self._nom = nom.title()
        return self.nom
    nom = property(_get_nom, _set_nom)

p = Personnage("moi")
print(p.nom)

#6 Le 21/04/2021, à 09:24

chris7522

Re : [Resolu]boucler sur instance d'une classe contenu dans une liste

Merci de ton aide une nouvelle fois .
Plusieurs petites choses pas super claire :

@nom.setter
    def nom(self,nom):
        if nom.isalpha() == False:
            raise SyntaxError("'Nom' doit être une suite de lettre !")
        self._nom = nom
        return self.nom

Mon attribut 'nom' est il vraiment inaccessible de l'extérieur de la classe lorsqu'il est précédé d'un underscore ?
Le ' return self.nom  ' est il nécéssaire a la fin de ma méthode ?
Parmis les deux possibilités que tu as présenté pour "encapsuler" , il y en a t il une a privilégier ? Laquelle va t on rencontrer le plus souvent ?
Merci

Hors ligne

#7 Le 21/04/2021, à 13:42

Compte supprimé

Re : [Resolu]boucler sur instance d'une classe contenu dans une liste

chris7522 a écrit :

Mon attribut 'nom' est il vraiment inaccessible de l'extérieur de la classe lorsqu’il est précédé d'un underscore ?

Non cela veut simplement dire qu'il est destiné à un usage interne.

chris7522 a écrit :

Le ' return self.nom  ' est il nécéssaire a la fin de ma méthode ?

à priori non

chris7522 a écrit :

Parmis les deux possibilités que tu as présenté pour "encapsuler" , il y en a t il une a privilégier ? Laquelle va t on rencontrer le plus souvent ?

Je pense(j'imagine) que c'est affaire de goût. J'ignore laquelle on va rencontrer le plus souvent. Je n'ai utilisé les property que dans le cadre de quelques exercises. Ce que je note c'est que le mooc enseigne uniquement la deusième forme. Du coup, c'est celle que j'utilise.
C'est une question à poser à un prof (professeur / professionnel).
Perso, ma pratique est de l'ordre du loisir... D'ailleurs je ne suis pas à l'abris de dire des bétises, et j'espère que dans le cas où j'en dise une, elle serait rectifiée par les lecteurs pratiquants. (ce qui n'est sur le net malheureusement pas toujours le cas)

#8 Le 22/04/2021, à 04:56

chris7522

Re : [Resolu]boucler sur instance d'une classe contenu dans une liste

Merci pour tes réponses big_smile

Hors ligne