My script executes depending on user’s input, like this:
while option != e option = input("What to do? ") if option == 'l': sh.send('lock') elif 's1': sh.send('start','program1') elif 's2': sh.send('start','program2)
The problem is that I can have over 15 different choices, so I would like to make it cleaner using dicts, but I can’t get it to work. This is what I did. In the class init for sh:
self.operations = {"l": lambda: self.send('lock'), "s1": lambda x: self.send('start', x), "s2": lambda x: self.send('start', x)}
And so on. Further down in the class:
def user_input(self, key): return self.operations[key]
And finally the input part of my script is much cleaner
while option != e option = input("What to do? ") try: sh.user_input(option)() except KeyError: print('Invalid Operation')
This is as far as I got, and while it works for options without parameters, how can I make it work also for commands that need a second parameter?
Advertisement
Answer
To create a dispatcher, you need to combine the function/dictionary/lambdas like this:
def operations(self, key, x): return { "l": lambda: self.send('lock'), "s1": lambda: self.send('start', x), "s2": lambda: self.send('start', x) }.get(key, lambda: None)
which you can call with self.operations("s1", 2)
. To evaluate it and get the result, you may need to do self.operations("s1", 2)()
.
Or, you need a value evaluated and returned, you can also write the function with the ()
at the end:
def operations(self, key, x): return { "l": lambda: self.send('lock'), "s1": lambda: self.send('start', x), "s2": lambda: self.send('start', x) }.get(key, lambda: None)()
lambda: None
, is the default for what happens if no valid key is passed. It needs to be a lambda to avoid getting: TypeError: 'NoneType' object is not callable
(because None
itself isn’t), but you can change this to something that makes sense for your purpose.