Some of my scenes can be visited multiple times, but every-time a scene is visited the choice the player chooses from a dictionary has to be deleted, so that the option is no longer available next time the scene is entered.
I’ve mocked up this little piece of code to play around with and I wonder if there is a way to alter the the input prompt so when a key in the dictionary is no longer the text changes accordingly?
class Restaurnante(object):
restaturantChoice = {1:['burgerjoint', '1) Local five guys'],
2:['cafe','2) The greasy spoon around the corner'],
3:['vegan','3) The new indie vegan cafe']
}
def go(self):
choice = int(input(f'These are the restaurants thats not full tonight.\nWhich do choose?\n{self.restaturantChoice.get(1)[1]}\n{self.restaturantChoice.get(2)[1]}\n{self.restaturantChoice.get(3)[1]}\n>>> '))
keep = self.restaturantChoice.get(choice)[0]
del self.restaturantChoice[choice]
return keep
returnspot = Restaurnante()
keep = returnspot.go()
print(keep)
Python pop() method removes an element from the dictionary. It removes the element which is associated to the specified key. If specified key is present in the dictionary, it remove and return its value. If the specified key is not present, it throws an error KeyError.
Thanks @gpkesley but how does that help altering the?
Or do I have to make if-statements for every possible scenario according to the amount of options that is in my dictionary?
choice = int(input(f'These are the restaurants thats not full tonight.\nWhich do choose?\n{self.restaturantChoice.get(1)[1]}\n{self.restaturantChoice.get(2)[1]}\n{self.restaturantChoice.get(3)[1]}\n>>> '))
Instead of altering the string every time an item gets popped from the dictionary, you could build the string based on the current choices each time you need it. That sounds more complicated than it actually is.
Personally I’d keep the question generic and the responses dict-driven. If the scene navigation is driven by the dict, you can remove values for dict items once visited. You could create a customer exception for the KeyError as a catch all behaviour in that case.
But given that you are learning, why not try implementing a few different things and see what is easiest, more logical, less maintenance, more testable? It’s all very useful learning.
Try putting the prompt formatting into a function on its own so that you just write:
int(input(prompt(state))
Then state is some dict with what’s going on right now, and prompt is a function that knows how to take state and return a string with the right prompt.
Also, you’re kind of overloading what input does. This is a good exercise for just figuring out how to do it, but I would print all the junk out then do a generic prompt rather than fill input() with overly complicated junk.
I settled on something like this.
Wondering if thats completely overkill and there is an easier way?
from random import randint
class Restaurnante(object):
restaturantChoice = {1:['burgerjoint', 'Local five guys'],
2:['cafe','The greasy spoon around the corner'],
3:['vegan','The new indie vegan cafe']
}
def go(self):
if len(self.restaturantChoice) > 0:
#choice = int(input(f'These are the restaurants thats not full tonight.\nWhich do choose?\n{self.restaturantChoice.get(1)[1]}\n{self.restaturantChoice.get(2)[1]}\n{self.restaturantChoice.get(3)[1]}\n>>> '))
prompt = self.promptcreation(self.restaturantChoice)
print('These are the restaurants thats not full tonight.\nWhich do choose?')
for choices in prompt:
print(f'{choices}) {prompt[choices][1]}')
choice = int(input('>>>'))
optionCheck = prompt.get(choice)
if optionCheck:
date = prompt.pop(choice)[0]
print(f'Very well, you chose: {date}')
else:
randomedate = randint(1,len(prompt)+1)
date = prompt.pop(randomedate)[0]
print(f"If you don't know how to key in the right number we'll just send you on a date\nYou are going {date}")
self.restaturantChoice = prompt
return date
else:
print('no more restaureantes to choose from')
return 'No restaurante'
def promptcreation(self, state):
oldprompt = state
options = range(1,len(oldprompt)+1)
newprompt = {}
for (key, options) in zip(oldprompt, options):
newprompt[options] = [f'{oldprompt[key][0]}' ,f'{oldprompt[key][1]}']
return newprompt
returnspot = Restaurnante()
date1 = returnspot.go()
print(date1)
date2 = returnspot.go()
print(date2)
date3 = returnspot.go()
print(date3)
date4 = returnspot.go()
print(date4)
Specifically choice, shuffle, and others that work on lists and sets to produce randomized selections. I think some of this code could simplify your code in the else: clause you have there.
Maybe read up a bit on iterators and generators. (EDIT: I see now that reading this might be more confusing than helpful now… sorry.)
You get a syntax error because there are no parentheses or brackets enclosing the x for x in y expression. And think about this: What does that expression create, is it really a string? (Maybe it helps to take a look at join again, what kind of argument does it take?
Here the syntax error is caused by a missing colon at the end of the first line.
But my idea was still a bit different.
Look at it this way: Do you really need a dictionary at all just for enumerating the choices?
Maybe you can use only a list, remove (pop) used items, and generate the prompt string from the result of enumerate(list).
That is a such a stupid mistake… But thank you for spotting it, I should have been capable of doing this myself. You are right I probably don’t need a dict.