先前定义的 class 方法上的名称错误和应该存在的索引上的 IndexError
Name Error on a class method previously defined and IndexError on an Index that should exist
所以,我在 npc.name 上收到一个 NameError(我想它会出现在我试图重新定义的所有后续 class 方法链接变量中),而且,我有较早出现的 IndexError。
我会更详细地解释,但首先是我的代码。
这是我的完整代码,注意:
# import pickle
import pickle
npcs_pickle_file = 'NPCatt.pk'
npc_count = 200
class NPC:
def __init__(self, name="", occupation="", weakness="", need="", desire="", enemy="",
rumor="", secret="", passion="", redeeming_quality="",damning_quality="", happy="",
occ_desire="", occ_complication="", pc_opinion="", accomplishment="", magical_gear="",
political_influence="", resource="", intel="", research=""):
# Attributes
self.name = name
self.occupation = occupation
self.weakness = weakness
self.need = need
self.desire = desire
self.enemy = enemy
self.rumor = rumor
self.secret = secret
self.passion = passion
self.redeeming_quality = redeeming_quality
self.damning_quality=damning_quality
self.happy = happy
self.occ_desire = occ_desire
self.occ_complication = occ_complication
self.pc_opinion = pc_opinion
self.accomplishment = accomplishment
self.magical_gear = magical_gear
self.political_influence = political_influence
self.resource = resource
self.intel = intel
self.research = research
def __str__(self):
npc_output = "####NPC SUMMARY####\n"
for att, val in self.__dict__.items():
if val:
npc_output += (f"{att} = {val}\n")
return npc_output
# open a pickle file
# load your data back to memory when you need it
try:
with open(npcs_pickle_file, 'rb') as fi:
npcs = pickle.load(fi)
except FileNotFoundError as fne:
#file doesnt exist prob first time running so create a dict with the 170 npc id's
npcs = {id: None for id in range(npc_count)}
#select an NPC to modify / create
npc_id = None
while not npc_id:
try:
npc_id = int(input(f"Enter the id number of the NPC you wish to modify: "))
except ValueError as ve:
print("You must provide a numerical id")
if npc_id < 0 or npc_id >= npc_count:
npc_id = None
print(f"you must provide a value between 0 and {npc_count}")
if npcs[npc_id]:
npc = npcs[npc_id]
print(npc)
modify = input("This NPC already exists, do you want to continue and change them? (y/n): ")
if modify.lower() == "y":
name = input("Enter name of NPC: ")
occupation = input("Enter NPC occupation: ")
weakness= input("Enter Weakness: ")
need= input("Enter Need: ")
desire= input("Enter Desire: ")
enemy= input("Enter Enemy: ")
rumor= input("Enter Rumor: ")
secret= input("Enter Secret: ")
passion= input("Enter Passion: ")
redeeming_quality=input("Enter Redeeming Quality: ")
damning_quality=input("Enter Damning Quality: ")
happy= input("Enter, is this NPC happy?: ")
occ_desire= input("Enter an Occupational Desire: ")
occ_complication= input("Enter an Occupational Complication: ")
pc_opinion= input("Enter this NPC's disposition toward the PCs: ")
accomplishment= input("Enter an Accomplishment: ")
magical_gear= input("Enter Magical Gear: ")
political_influence=input("Enter Political Influence: ")
resource= input("Enter Resource Level: ")
intel= input("Enter Intel Tier: ")
research= input("Enter Research: ")
npc.name = name
npc.occupation = occupation
npc.weakness = weakness
npc.need = need
npc.desire= desire
npc.enemy= enemy
npc.rumor= rumor
npc.secret= secret
npc.passion= passion
npc.redeeming_quality= redeeming_quality
npc.damning_quality= damning_quality
npc.happy= happy
npc.occ_desire=occ_desire
npc.occ_complication=occ_complication
npc.pc_opinion=pc_opinion
npc.accomplishment=accomplishment
npc.magical_gear=magical_gear
npc.political_influence=political_influence
npc.resource=resource
npc.intel=intel
npc.research=research
else:
npcs[npc_id] = NPC(name=npc.name, occupation=npc.occupation,weakness=npc.weakness,need=npc.need,desire=npc.desire,\
enemy=npc.enemy,rumor=npc.rumor,secret=npc.secret,passion=npc.passion,redeeming_quality=npc.redeeming_quality,\
damning_quality=npc.damning_quality,happy=npc.happy,occ_desire=npc.occ_desire,\
occ_complication=npc.occ_complication\
,pc_opinion=npc.pc_opinion,accomplishment=npc.accomplishment,\
magical_gear=npc.magical_gear,political_influence=npc.political_influence,resource=npc.resource,\
intel=npc.intel,research=npc.research)
else:
name = input("Enter name of NPC: ")
occupation = input("Enter NPC occupation: ")
weakness= input("Enter Weakness: ")
need= input("Enter Need: ")
desire= input("Enter Desire: ")
enemy= input("Enter Enemy: ")
rumor= input("Enter Rumor: ")
secret= input("Enter Secret: ")
passion= input("Enter Passion: ")
redeeming_quality=input("Enter Redeeming Quality: ")
damning_quality=input("Enter Damning Quality: ")
happy= input("Enter, is this NPC happy?: ")
occ_desire= input("Enter an Occupational Desire: ")
occ_complication= input("Enter an Occupational Complication: ")
pc_opinion= input("Enter this NPC's disposition toward the PCs: ")
accomplishment= input("Enter an Accomplishment: ")
magical_gear= input("Enter Magical Gear: ")
political_influence=input("Enter Political Influence: ")
resource= input("Enter Resource Level: ")
intel= input("Enter Intel Tier: ")
research= input("Enter Research: ")
npc.name = name
npc.occupation = occupation
npc.weakness = weakness
npc.need = need
npc.desire= desire
npc.enemy= enemy
npc.rumor= rumor
npc.secret= secret
npc.passion= passion
npc.redeeming_quality= redeeming_quality
npc.damning_quality= damning_quality
npc.happy= happy
npc.occ_desire=occ_desire
npc.occ_complication=occ_complication
npc.pc_opinion=pc_opinion
npc.accomplishment=accomplishment
npc.magical_gear=magical_gear
npc.political_influence=political_influence
npc.resource=resource
npc.intel=intel
npc.research=research
with open(npcs_pickle_file, 'wb') as fi:
# dump your data into the file
pickle.dump(npcs, fi)
我是菜鸟,所以代码结构是作为我迄今为止在网站上唯一的其他问题的答案提供的。为了我的目的,我扩展了它。
问题是,索引为 [1] 的 NPC 已完美存储,可以根据需要显示,并且可以修改。
但是在定义新的 NPC 时,我首先得到一个新的 Indexable NPC 的 IndexError,我用
try: #the code for when the NPC has been previously defined
except IndexError:#the code on the last else block, for new indexes
为了检查其余代码是否有效,
最后一个 else 块出现 NameError,我将每个属性定义为
self.att=att
现在,我最好的猜测是它与局部变量定义和全局变量定义有关,但我不知道如何解决这两个错误。
感谢您一路看完,对不起。
如果可以并且愿意,请提供帮助。
您的 IndexError
问题来自对您的脚本的先前版本创建的文件的解封。如果这个文件包含有价值的数据,暂时重命名它,一旦你的脚本可以正常工作并且足够稳定,就可以编写一个迁移脚本来恢复你的旧数据了。否则,好吧,放弃吧 xD
wrt/ NameError,它在最后一个 else
块中:您正试图在 npc
变量上设置属性,此时确实未定义 - 它仅在 if
块:
if npcs[npc_id]:
npc = npcs[npc_id]
# way too much code here
else:
# repeated code here
# and here's the issue:
npc.something = something
你已经注意到"mashing together pieces of code without understanding them doesn't always work",这是一个好的开始(至少你意识到了,所以还是有希望的xD),现在再给你一个启示:"trying to understand messy code is hard"。这就是为什么良好的代码结构很重要的原因。此外,仅(或大部分)依赖于它们的参数的短函数比具有大量条件和代码块的长脚本更容易理解(和测试!),这些代码块依赖于某些变量(或不)定义了大约 20 多行。
我通常不这样做,但在这种情况下,您可能会受益于看到结构合理的代码是什么样的。它远非完美,可以从一些改进中受益(比如,在编辑现有的 npc 时,让用户指定他想要更改的属性,而不是要求他们重新输入所有内容)但是,那是你的工作,不是我的 ;-)
import pickle
# coding conventions: pseudo-constants should be ALL_UPPER
NPCS_PICKLE_FILE = 'NPCatt.pk'
NPC_COUNT = 200
# coding convention: class names should be CamelCase
class Npc:
def __init__(self, name="", occupation="", weakness="", need="", desire="", enemy="",
rumor="", secret="", passion="", redeeming_quality="",damning_quality="", happy="",
occ_desire="", occ_complication="", pc_opinion="", accomplishment="", magical_gear="",
political_influence="", resource="", intel="", research=""):
# Attributes
self.name = name
self.occupation = occupation
self.weakness = weakness
self.need = need
self.desire = desire
self.enemy = enemy
self.rumor = rumor
self.secret = secret
self.passion = passion
self.redeeming_quality = redeeming_quality
self.damning_quality = damning_quality
self.happy = happy
self.occ_desire = occ_desire
self.occ_complication = occ_complication
self.pc_opinion = pc_opinion
self.accomplishment = accomplishment
self.magical_gear = magical_gear
self.political_influence = political_influence
self.resource = resource
self.intel = intel
self.research = research
def update(self, **values):
for key, val in values.items():
# make sure we're only accepted known attributes
if not hasattr(self, key):
raise AttributeError("Npc object has no attribute '{}'".format(key))
setattr(self, key, val)
def __str__(self):
# in Python, string concatenation is better done by
# building a list and joining it afterward
npc_output = ["####NPC SUMMARY####"]
for att, val in self.__dict__.items():
if val:
npc_output.append(f"{att} = {val}")
npc_output.append("") # so we have a last newline
return "\n".join(npc_output)
class InvalidDataFile(ValueError):
pass
def load_npcs_from_file():
with open(NPCS_PICKLE_FILE, 'rb') as fi:
try:
npcs = pickle.load(fi)
except EOFError as e:
raise InvalidDataFile(
"looks like {} is empy - expected a dict, got {}".format(NPCS_PICKLE_FILE, e)
)
# make sure we don't have incorrect data from
# the previous version where what was pickled was a list
if not isinstance(npcs, dict):
raise InvalidDataFile(
"looks like {} is obsolete or corrupted - expected a dict, got {}".format(NPCS_PICKLE_FILE, ncps)
)
# make sure we ALWAYS have `NPC_COUNT` npcs whatever
# (ie: in case the pickle didn't have as many entries as expected)
missing = NPC_COUNT - len(npcs)
if missing > 0:
for id in range(NPC_COUNT):
ncps.setdefault(id, None)
return npcs
def init_npcs():
return {id: None for id in range(NPC_COUNT)}
def load_npcs():
try:
return load_npcs_from_file()
except (FileNotFoundError, InvalidDataFile) as e:
# so you know what's happening...
print("got {} when trying to load npcs from file - creating a new dataset".format(e))
return init_npcs()
def save_npcs(npcs):
with open(NPCS_PICKLE_FILE, 'wb') as fi:
# dump your data into the file
pickle.dump(npcs, fi)
def get_npc_values():
# factor out common stuff
# XXX you definitly want to validate user inputs
values = {}
values["name"] = input("Enter name of NPC: ")
values["occupation"] = input("Enter NPC occupation: ")
values["weakness"] = input("Enter Weakness: ")
values["need"] = input("Enter Need: ")
values["desire"] = input("Enter Desire: ")
values["enemy"] = input("Enter Enemy: ")
values["rumor"] = input("Enter Rumor: ")
values["secret"] = input("Enter Secret: ")
values["passion"] = input("Enter Passion: ")
values["redeeming_quality"] = input("Enter Redeeming Quality: ")
values["damning_quality"] = input("Enter Damning Quality: ")
values["happy"] = input("Enter, is this NPC happy?: ")
values["occ_desire"] = input("Enter an Occupational Desire: ")
values["occ_complication"] = input("Enter an Occupational Complication: ")
values["pc_opinion"] = input("Enter this NPC's disposition toward the PCs: ")
values["accomplishment"] = input("Enter an Accomplishment: ")
values["magical_gear"] = input("Enter Magical Gear: ")
values["political_influence"] = input("Enter Political Influence: ")
values["resource"] = input("Enter Resource Level: ")
values["intel"] = input("Enter Intel Tier: ")
values["research"] = input("Enter Research: ")
return values
def update_npc(npc):
new_values = get_npc_values()
npc.update(**new_values)
def create_npc():
values = get_npc_values()
return Npc(**values)
def get_npc_id():
#select an NPC to modify / create
npc_id = None
while npc_id is None:
try:
npc_id = int(input(f"Enter the id number of the NPC you wish to modify: "))
except ValueError as ve:
print("You must provide a numerical id")
if npc_id < 0 or npc_id >= NPC_COUNT:
npc_id = None
print(f"you must provide a value between 0 and {NPC_COUNT}")
return npc_id
def edit_npc(npcs):
npc_id = get_npc_id()
# this should be safe now... theoretically at least
npc = npcs[npc_id]
if npc is None:
ok = input("This NPC doesn't exist yet, do you want to create it (y/n): ")
if ok.strip().lower() == 'y':
npcs[npc_id] = create_npc()
# let the caller know something was changed
return True
else:
ok = input("This NPC already exists, do you want to continue and change them? (y/n): ")
if ok.strip().lower() == "y":
update_npc(npc)
# let the caller know something was changed
return True
# let the caller know nothing was changed
return False
def show_npcs(npcs):
for id, npc in npcs.items():
print("{} : {}".format(id, npc))
print("") # add a blank line
def get_next_action():
while True:
print("what do you want to do ?")
print("S - show existing npcs")
print("E - edit a npc")
print("Q - quit")
action = input(">> ").strip().upper()
if action not in "SEQ":
print("sorry, I don't undertand '{}'".format(action))
return action
def main():
npcs = load_npcs()
while True:
nb_valids = len([_ for _ in npcs.values() if _])
print("we have {} valid npcs".format(nb_valids))
action = get_next_action()
if action == "Q":
break
elif action == "E":
if edit_npc(npcs):
print("saving data")
save_npcs(npcs)
elif action == "S":
show_npcs(npcs)
if __name__ == "__main__":
main()
所以,我在 npc.name 上收到一个 NameError(我想它会出现在我试图重新定义的所有后续 class 方法链接变量中),而且,我有较早出现的 IndexError。
我会更详细地解释,但首先是我的代码。
这是我的完整代码,注意:
# import pickle
import pickle
npcs_pickle_file = 'NPCatt.pk'
npc_count = 200
class NPC:
def __init__(self, name="", occupation="", weakness="", need="", desire="", enemy="",
rumor="", secret="", passion="", redeeming_quality="",damning_quality="", happy="",
occ_desire="", occ_complication="", pc_opinion="", accomplishment="", magical_gear="",
political_influence="", resource="", intel="", research=""):
# Attributes
self.name = name
self.occupation = occupation
self.weakness = weakness
self.need = need
self.desire = desire
self.enemy = enemy
self.rumor = rumor
self.secret = secret
self.passion = passion
self.redeeming_quality = redeeming_quality
self.damning_quality=damning_quality
self.happy = happy
self.occ_desire = occ_desire
self.occ_complication = occ_complication
self.pc_opinion = pc_opinion
self.accomplishment = accomplishment
self.magical_gear = magical_gear
self.political_influence = political_influence
self.resource = resource
self.intel = intel
self.research = research
def __str__(self):
npc_output = "####NPC SUMMARY####\n"
for att, val in self.__dict__.items():
if val:
npc_output += (f"{att} = {val}\n")
return npc_output
# open a pickle file
# load your data back to memory when you need it
try:
with open(npcs_pickle_file, 'rb') as fi:
npcs = pickle.load(fi)
except FileNotFoundError as fne:
#file doesnt exist prob first time running so create a dict with the 170 npc id's
npcs = {id: None for id in range(npc_count)}
#select an NPC to modify / create
npc_id = None
while not npc_id:
try:
npc_id = int(input(f"Enter the id number of the NPC you wish to modify: "))
except ValueError as ve:
print("You must provide a numerical id")
if npc_id < 0 or npc_id >= npc_count:
npc_id = None
print(f"you must provide a value between 0 and {npc_count}")
if npcs[npc_id]:
npc = npcs[npc_id]
print(npc)
modify = input("This NPC already exists, do you want to continue and change them? (y/n): ")
if modify.lower() == "y":
name = input("Enter name of NPC: ")
occupation = input("Enter NPC occupation: ")
weakness= input("Enter Weakness: ")
need= input("Enter Need: ")
desire= input("Enter Desire: ")
enemy= input("Enter Enemy: ")
rumor= input("Enter Rumor: ")
secret= input("Enter Secret: ")
passion= input("Enter Passion: ")
redeeming_quality=input("Enter Redeeming Quality: ")
damning_quality=input("Enter Damning Quality: ")
happy= input("Enter, is this NPC happy?: ")
occ_desire= input("Enter an Occupational Desire: ")
occ_complication= input("Enter an Occupational Complication: ")
pc_opinion= input("Enter this NPC's disposition toward the PCs: ")
accomplishment= input("Enter an Accomplishment: ")
magical_gear= input("Enter Magical Gear: ")
political_influence=input("Enter Political Influence: ")
resource= input("Enter Resource Level: ")
intel= input("Enter Intel Tier: ")
research= input("Enter Research: ")
npc.name = name
npc.occupation = occupation
npc.weakness = weakness
npc.need = need
npc.desire= desire
npc.enemy= enemy
npc.rumor= rumor
npc.secret= secret
npc.passion= passion
npc.redeeming_quality= redeeming_quality
npc.damning_quality= damning_quality
npc.happy= happy
npc.occ_desire=occ_desire
npc.occ_complication=occ_complication
npc.pc_opinion=pc_opinion
npc.accomplishment=accomplishment
npc.magical_gear=magical_gear
npc.political_influence=political_influence
npc.resource=resource
npc.intel=intel
npc.research=research
else:
npcs[npc_id] = NPC(name=npc.name, occupation=npc.occupation,weakness=npc.weakness,need=npc.need,desire=npc.desire,\
enemy=npc.enemy,rumor=npc.rumor,secret=npc.secret,passion=npc.passion,redeeming_quality=npc.redeeming_quality,\
damning_quality=npc.damning_quality,happy=npc.happy,occ_desire=npc.occ_desire,\
occ_complication=npc.occ_complication\
,pc_opinion=npc.pc_opinion,accomplishment=npc.accomplishment,\
magical_gear=npc.magical_gear,political_influence=npc.political_influence,resource=npc.resource,\
intel=npc.intel,research=npc.research)
else:
name = input("Enter name of NPC: ")
occupation = input("Enter NPC occupation: ")
weakness= input("Enter Weakness: ")
need= input("Enter Need: ")
desire= input("Enter Desire: ")
enemy= input("Enter Enemy: ")
rumor= input("Enter Rumor: ")
secret= input("Enter Secret: ")
passion= input("Enter Passion: ")
redeeming_quality=input("Enter Redeeming Quality: ")
damning_quality=input("Enter Damning Quality: ")
happy= input("Enter, is this NPC happy?: ")
occ_desire= input("Enter an Occupational Desire: ")
occ_complication= input("Enter an Occupational Complication: ")
pc_opinion= input("Enter this NPC's disposition toward the PCs: ")
accomplishment= input("Enter an Accomplishment: ")
magical_gear= input("Enter Magical Gear: ")
political_influence=input("Enter Political Influence: ")
resource= input("Enter Resource Level: ")
intel= input("Enter Intel Tier: ")
research= input("Enter Research: ")
npc.name = name
npc.occupation = occupation
npc.weakness = weakness
npc.need = need
npc.desire= desire
npc.enemy= enemy
npc.rumor= rumor
npc.secret= secret
npc.passion= passion
npc.redeeming_quality= redeeming_quality
npc.damning_quality= damning_quality
npc.happy= happy
npc.occ_desire=occ_desire
npc.occ_complication=occ_complication
npc.pc_opinion=pc_opinion
npc.accomplishment=accomplishment
npc.magical_gear=magical_gear
npc.political_influence=political_influence
npc.resource=resource
npc.intel=intel
npc.research=research
with open(npcs_pickle_file, 'wb') as fi:
# dump your data into the file
pickle.dump(npcs, fi)
我是菜鸟,所以代码结构是作为我迄今为止在网站上唯一的其他问题的答案提供的。为了我的目的,我扩展了它。
问题是,索引为 [1] 的 NPC 已完美存储,可以根据需要显示,并且可以修改。 但是在定义新的 NPC 时,我首先得到一个新的 Indexable NPC 的 IndexError,我用
try: #the code for when the NPC has been previously defined
except IndexError:#the code on the last else block, for new indexes
为了检查其余代码是否有效, 最后一个 else 块出现 NameError,我将每个属性定义为
self.att=att
现在,我最好的猜测是它与局部变量定义和全局变量定义有关,但我不知道如何解决这两个错误。
感谢您一路看完,对不起。 如果可以并且愿意,请提供帮助。
您的 IndexError
问题来自对您的脚本的先前版本创建的文件的解封。如果这个文件包含有价值的数据,暂时重命名它,一旦你的脚本可以正常工作并且足够稳定,就可以编写一个迁移脚本来恢复你的旧数据了。否则,好吧,放弃吧 xD
wrt/ NameError,它在最后一个 else
块中:您正试图在 npc
变量上设置属性,此时确实未定义 - 它仅在 if
块:
if npcs[npc_id]:
npc = npcs[npc_id]
# way too much code here
else:
# repeated code here
# and here's the issue:
npc.something = something
你已经注意到"mashing together pieces of code without understanding them doesn't always work",这是一个好的开始(至少你意识到了,所以还是有希望的xD),现在再给你一个启示:"trying to understand messy code is hard"。这就是为什么良好的代码结构很重要的原因。此外,仅(或大部分)依赖于它们的参数的短函数比具有大量条件和代码块的长脚本更容易理解(和测试!),这些代码块依赖于某些变量(或不)定义了大约 20 多行。
我通常不这样做,但在这种情况下,您可能会受益于看到结构合理的代码是什么样的。它远非完美,可以从一些改进中受益(比如,在编辑现有的 npc 时,让用户指定他想要更改的属性,而不是要求他们重新输入所有内容)但是,那是你的工作,不是我的 ;-)
import pickle
# coding conventions: pseudo-constants should be ALL_UPPER
NPCS_PICKLE_FILE = 'NPCatt.pk'
NPC_COUNT = 200
# coding convention: class names should be CamelCase
class Npc:
def __init__(self, name="", occupation="", weakness="", need="", desire="", enemy="",
rumor="", secret="", passion="", redeeming_quality="",damning_quality="", happy="",
occ_desire="", occ_complication="", pc_opinion="", accomplishment="", magical_gear="",
political_influence="", resource="", intel="", research=""):
# Attributes
self.name = name
self.occupation = occupation
self.weakness = weakness
self.need = need
self.desire = desire
self.enemy = enemy
self.rumor = rumor
self.secret = secret
self.passion = passion
self.redeeming_quality = redeeming_quality
self.damning_quality = damning_quality
self.happy = happy
self.occ_desire = occ_desire
self.occ_complication = occ_complication
self.pc_opinion = pc_opinion
self.accomplishment = accomplishment
self.magical_gear = magical_gear
self.political_influence = political_influence
self.resource = resource
self.intel = intel
self.research = research
def update(self, **values):
for key, val in values.items():
# make sure we're only accepted known attributes
if not hasattr(self, key):
raise AttributeError("Npc object has no attribute '{}'".format(key))
setattr(self, key, val)
def __str__(self):
# in Python, string concatenation is better done by
# building a list and joining it afterward
npc_output = ["####NPC SUMMARY####"]
for att, val in self.__dict__.items():
if val:
npc_output.append(f"{att} = {val}")
npc_output.append("") # so we have a last newline
return "\n".join(npc_output)
class InvalidDataFile(ValueError):
pass
def load_npcs_from_file():
with open(NPCS_PICKLE_FILE, 'rb') as fi:
try:
npcs = pickle.load(fi)
except EOFError as e:
raise InvalidDataFile(
"looks like {} is empy - expected a dict, got {}".format(NPCS_PICKLE_FILE, e)
)
# make sure we don't have incorrect data from
# the previous version where what was pickled was a list
if not isinstance(npcs, dict):
raise InvalidDataFile(
"looks like {} is obsolete or corrupted - expected a dict, got {}".format(NPCS_PICKLE_FILE, ncps)
)
# make sure we ALWAYS have `NPC_COUNT` npcs whatever
# (ie: in case the pickle didn't have as many entries as expected)
missing = NPC_COUNT - len(npcs)
if missing > 0:
for id in range(NPC_COUNT):
ncps.setdefault(id, None)
return npcs
def init_npcs():
return {id: None for id in range(NPC_COUNT)}
def load_npcs():
try:
return load_npcs_from_file()
except (FileNotFoundError, InvalidDataFile) as e:
# so you know what's happening...
print("got {} when trying to load npcs from file - creating a new dataset".format(e))
return init_npcs()
def save_npcs(npcs):
with open(NPCS_PICKLE_FILE, 'wb') as fi:
# dump your data into the file
pickle.dump(npcs, fi)
def get_npc_values():
# factor out common stuff
# XXX you definitly want to validate user inputs
values = {}
values["name"] = input("Enter name of NPC: ")
values["occupation"] = input("Enter NPC occupation: ")
values["weakness"] = input("Enter Weakness: ")
values["need"] = input("Enter Need: ")
values["desire"] = input("Enter Desire: ")
values["enemy"] = input("Enter Enemy: ")
values["rumor"] = input("Enter Rumor: ")
values["secret"] = input("Enter Secret: ")
values["passion"] = input("Enter Passion: ")
values["redeeming_quality"] = input("Enter Redeeming Quality: ")
values["damning_quality"] = input("Enter Damning Quality: ")
values["happy"] = input("Enter, is this NPC happy?: ")
values["occ_desire"] = input("Enter an Occupational Desire: ")
values["occ_complication"] = input("Enter an Occupational Complication: ")
values["pc_opinion"] = input("Enter this NPC's disposition toward the PCs: ")
values["accomplishment"] = input("Enter an Accomplishment: ")
values["magical_gear"] = input("Enter Magical Gear: ")
values["political_influence"] = input("Enter Political Influence: ")
values["resource"] = input("Enter Resource Level: ")
values["intel"] = input("Enter Intel Tier: ")
values["research"] = input("Enter Research: ")
return values
def update_npc(npc):
new_values = get_npc_values()
npc.update(**new_values)
def create_npc():
values = get_npc_values()
return Npc(**values)
def get_npc_id():
#select an NPC to modify / create
npc_id = None
while npc_id is None:
try:
npc_id = int(input(f"Enter the id number of the NPC you wish to modify: "))
except ValueError as ve:
print("You must provide a numerical id")
if npc_id < 0 or npc_id >= NPC_COUNT:
npc_id = None
print(f"you must provide a value between 0 and {NPC_COUNT}")
return npc_id
def edit_npc(npcs):
npc_id = get_npc_id()
# this should be safe now... theoretically at least
npc = npcs[npc_id]
if npc is None:
ok = input("This NPC doesn't exist yet, do you want to create it (y/n): ")
if ok.strip().lower() == 'y':
npcs[npc_id] = create_npc()
# let the caller know something was changed
return True
else:
ok = input("This NPC already exists, do you want to continue and change them? (y/n): ")
if ok.strip().lower() == "y":
update_npc(npc)
# let the caller know something was changed
return True
# let the caller know nothing was changed
return False
def show_npcs(npcs):
for id, npc in npcs.items():
print("{} : {}".format(id, npc))
print("") # add a blank line
def get_next_action():
while True:
print("what do you want to do ?")
print("S - show existing npcs")
print("E - edit a npc")
print("Q - quit")
action = input(">> ").strip().upper()
if action not in "SEQ":
print("sorry, I don't undertand '{}'".format(action))
return action
def main():
npcs = load_npcs()
while True:
nb_valids = len([_ for _ in npcs.values() if _])
print("we have {} valid npcs".format(nb_valids))
action = get_next_action()
if action == "Q":
break
elif action == "E":
if edit_npc(npcs):
print("saving data")
save_npcs(npcs)
elif action == "S":
show_npcs(npcs)
if __name__ == "__main__":
main()