Partage
  • Partager sur Facebook
  • Partager sur Twitter

Dilemme itéré du prisonnier

Programmation orientée objet

    23 janvier 2020 à 23:38:25

    Bonjour,

    Dans le cadre d'un td sur le dilemme du prisonnier, je dois remplir une classe permettant d'élaborer les différentes stratégies. 

    Je me retrouve avec un message d'erreur dont je ne comprends pas l'origine. Après avoir tout essayé et redémarrer mon ordinateur je fais donc appel à la communauté afin de bien vouloir m'éclairer.

    Ci joint la partie utile de mon code. Le test effectué et le message d'erreur renvoyé. Le problème porte sur la méthode surname.

    Je suis novice, merci de regarder ce code avec bienveillance. Toutes remarques constructives quand à rendre mon code plus propre sont bien entendu bienvenues! 

    Partie utile du code :

    # Importation de fonctions externes:
    
    import numpy as np
    import random
    
    #_______________________________________________________
    # Définition locale de fonctions:
    
    class Model:
        def __init__(self, rewards:dict, values:dict):
    
            """
                à partir des récompenses (rewards) et des valeurs (values)
    	    construit 
    	    self.rewards : les récompenses et les actions les causant
    	    self.values : les valeurs
    	    self.actions : les actions valides
    	    self.reward_names : les noms des récompenses
    	    self.get_actions(rew:str) -> str : les actions associées aux récompenses
    	"""
            self.__recompenses = set(''.join([x for x in rewards.values()]))
            self.__actions = set(''.join([x for x in rewards.keys()]))
            if len(rewards) != len(self.__actions)**2:
                raise Exception("Actions inconsistency")
            if len(self.__recompenses) != len(values):
                raise Exception("Rewards inconsitency")
            self.__rewards = rewards
            self.__values = values
            self.__rewact = {}
            for k,v in rewards.items():
                for (i,x) in enumerate(v):
                    _old = self.__rewact.get(x, set())
                    if i == 0: _old.add(k)
                    else: _old.add(k[::-1])
                    self.__rewact[x] = _old
    
            for k in self.__rewact:
                if len(self.__rewact[k]) != 1:
                    self.__rewact[k] = list(self.__rewact[k])
                else:
                    self.__rewact[k] = self.__rewact[k].pop()
    
        @property
        def rewards(self): return self.__rewards
        @property
        def values(self): return self.__values
        @property
        def actions(self):
            return ''.join(sorted(list(self.__actions), reverse=True))
        @property
        def reward_names(self):
            return ''.join(sorted(list(self.__recompenses)))
    
        def get_actions(self, rew):
            """ for a given reward send the actions involved 
                1st is mine, 2nd is adversary
            """
            return self.__rewact.get(rew,'')
    
    default = { 'DD': 'PP', 'DC': 'TS', 'CD': 'ST', 'CC': 'RR' }
    default_val = { 'T': 7, 'R': 5, 'P': 2, 'S': 0}
    m1 = Model( default.copy(), default_val.copy() )
    for x in "DC":
        default[x+'R'] = default['R'+x] = "AA"
    default["RR"] = "AA"
    default_val['A'] = 3    
    m2 = Model( default, default_val ) 
    
    class Strategie:
        
        ID = 0
            
        def __init__(self, styl:int=1, maxsz:int=0, model:Model=m1):
            """ constructeur 
    	    styl in {-1, 0, 1} le style correspondant au premier coup joué
    	    maxsz : la taille maximum occupée par la mémoire
    	    model : le modèle dans lequel on joue
    	"""
            # NE PAS MODIFIER LES 2 LIGNES SUIVANTES
            self.__idnum = self.ID
            Strategie.ID += 1
            # ICI les variables locales communes à initialiser
            # avec styl, maxsz, actions ou encore surname et color
            
            self.__style=styl
            self.__size=maxsz
            self.__model=model
            self.color=self.__idnum
            
            self.__actions=model.actions
            
            
            # ENSUITE reset
            self.reset()
    
        def reset(self) -> None:
            """ raz des variables """
            self.__memsz=0
            self.__memory=""
            self.__count=0
    
        # NE PAS MODIFIER CES 4 LIGNES
        @property
        def idnum(self) -> int:
            return self.__idnum
        @property
        def name(self) -> str:
            return "Strat_{0.idnum:03d}".format(self)
    
        # A PARTIR D'ICI IL FAUT FAIRE QQUE CHOSE
        @property
        def size(self) -> int:
            """ renvoie la taille max de la mémoire
            - infinie: -1
            - sinon un entier >= 0
            """
            return self.__size
            raise Exception("something to do")
    
        @property
        def memsz(self) -> int:
            """ renvoie la taille mémoire occupée """
            return self.__memsz
            raise Exception("something to do")
    
        @property
        def memory(self) -> str:
            """ renvoie la mémoire des dernières récompenses """
            return self.__memory
            raise Exception("something to do")
    
        @property
        def actions(self) -> str:
            """ renvoie les actions autorisées DC ou DCA ordre quelconque """
            return self.__actions
            raise Exception("something to do")
    
        @property
        def count(self) -> int:
            """ le nombre de récompenses depuis reset """
            return self.__count
            raise Exception("something to do")
    
        @property
        def style(self) -> str:
            """ renvoie D, C ou a """
            return self.__style
            raise Exception("something to do")
            
        @property
        def surname(self) -> str:
            """ renvoie le petit nom de la stratégie """
            return name
                
            raise Exception("something to do")


    Test effectué :

    x = Strategie()
    print("Déclaration d'une nouvelle strategie x    :    \n\n",x)
    print("_____________________________________________\n\n")
    
    print("Test des @property:\n")
    
    print("x.surname  =  'Michel-Austin' doit renvoyer None. Check  :   ",x.surname)
    print("x.surname  =  ",x.surname)

    Contenu du shell reçu une fois le programme et le programme de test lancé :

    Déclaration d'une nouvelle strategie x    :    
    
     <td1.Strategie object at 0x037370F0>
    ________________________________________________________
    
    
    Test des @property:
    
    Traceback (most recent call last):
      File "C:\Users\anon\Desktop\dossier\INTELLIGENCE-ARTIFICIELLE\jalon1\test_td1.py", line 42, in <module>
        print("x.surname    =    ",x.surname)
      File "C:\Users\anon\Desktop\dossier\INTELLIGENCE-ARTIFICIELLE\jalon1\td1.py", line 167, in surname
        return name
    NameError: name 'name' is not defined

    Merci de m'accorder du temps. 

    Bonne nuit à tous :)



    • Partager sur Facebook
    • Partager sur Twitter
      24 janvier 2020 à 3:47:17

      La variable name n'est pas définie. Je sais, je ne fais que répéter le message d'erreur en français, mais je ne sais pas trop quoi dire d'autre pour expliquer, je ne vois pas dans ton code où est la déclaration de cette variable.

      Le redémarrage, c'est une perte de temps, quand un débutant a un bug, 99.9% du temps c'est le code du programme qui est à corriger, pas un bug dans le langage ni dans les autres logiciels. D'ailleurs c'est à peu près pareil pour les développeurs expérimentés.

      Tu peux aussi supprimer les raise ... qui sont après les return dans ton code. L'exécution de la fonction s'arrête au return, donc tout ce qui est après est inutile.

      -
      Edité par LoupSolitaire 24 janvier 2020 à 3:47:45

      • Partager sur Facebook
      • Partager sur Twitter

      Blond, bouclé, toujours le sourire aux lèvres...

      Dilemme itéré du prisonnier

      × 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