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
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
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.
Blond, bouclé, toujours le sourire aux lèvres...