I am currently blank on how to do this in an effective way.I thought about using objects but I don’t see how they could help in this case. Any ideas?
from random import choice
from copy import deepcopy
def main():
def rand_int():
return choice(['yes', 'no'])
# any nesting, functions possible
spec = {
'answer': rand_int,
'next': {'answer': rand_int},
'the_answer': 42
}
#### looking for elegant (automatic) way to do this
result = deepcopy(spec)
result['answer'] = result['answer']()
result['next']['answer'] = result['next']['answer']()
#### until here
# result2 = ...
print 'result: %s' % result
if __name__ == '__main__':
main()
please do not tell me to use xsd!
You can do this with one line in a dictionary comprehension:
Of course, this will throw errors when a value isn’t a function, so if that is a possibility, we can simply add a check with the
callable()builtin:We then need to deal with the fact that your answer needs to be recursive, this makes it a little more complex, but not too hard to fix:
Note that if you have objects with an
itemsattribute or method you wish to store in adictthis function will be run on, this could cause problems. I would recommend changing the name of that attribute or method, or replacing the check withisinstance(dict).I would also like to note that for misleading function names
rand_intthat returns a string of'yes'or'no'is probably about as bad as it gets. Generally you wantTrue/Falsein those situations as well.As noted in the comments, pre-Python 2.7, you may not have dictionary comprehensions. To get around this,
dict()will take a generator of tuples, so you can replace a dict comprehension like so:With:
So, in full:
Gives us: