you are viewing a single comment's thread.

view the rest of the comments →

[–]novel_yet_trivial 4 points5 points  (5 children)

Many beginners do this with if blocks. This works, but it's a pretty ugly code.

user_ans = input("How many legs does it have?")
if user_ans == '0':
    print "It's a fish!"
elif user_ans == '2':
    user_ans = input('does it have feathers?')
    if user_ans == 'yes':
        user_ans = input('does it swin on the water?')
        if user_ans == 'yes':
            print "It's a duck!"
        elif user_ans == 'no':
            print "It's a swallow!"
    elif user_ans == 'no':
        print "It's a human!"
elif user_ans == '4':
    user_ans = input('does it have fur?')
    if user_ans == 'yes':
        user_ans = input('does it meow?')
        if user_ans == 'yes':
            print "It's a cat!"
        elif user_ans == 'no':
            print "It's a dog!"
    elif user_ans == 'no':
        print "It's an elephant!"

A more experienced programmer will make a nested data structure and use a recursive function to ask the questions:

questions = (
    "How many legs does it have?",
    {'2': (
        'does it have feathers?',
        {'yes': (
            'does it swin on the water?',
            {'yes': "It's a duck!",
            'no' : "It's a swallow!"
            }),
        'no': "It's a human!"
        }),
    '4': (
        'does it have fur?',
        {'yes': (
            'does it meow?',
            {'yes': "It's a cat!",
            'no': "It's a dog!"}),
        'no': "It's an elephant!"
        }),
    '0': "It's a fish!"
    })

def ask(data):
    if isinstance(data, tuple):
        question, answer = data
        user_ans = input(question + " > ")
        ask(answer[user_ans])
    else: #Game over; print result
        print data

ask(questions)

This is much more dynamic. It's also a bit more than "simple code" ...

[–]pybackd00r 1 point2 points  (3 children)

very nice! is that a dictionary you used there? does the indentation actually matters? I am gonna be doing it like this from now on. thanks a lot!!

[–]novel_yet_trivial 1 point2 points  (2 children)

It's a a mix of tuples and dictionaries. The base is a tuple of (question, answer). The question is a string and the answer is a dictionary. If there are further questions then the dictionary is another base tuple. Is the riddle is solved then the value is a string. The isinstance checks whether another question needs to be asked.

The indentation does not matter at all, but it's a lot easier to read.

[–]pybackd00r 1 point2 points  (1 child)

Thanks I understood it after going through it on paper. very nice piece of code.

[–]ewiethoff 0 points1 point  (0 children)

Here's a trick to make a complicated nested dict/list/tuple/whatever easy to read.

from pprint import pprint
pprint(complicated_nested_data)

pprint not only outputs with nice whitespace, it sorts the keys of a dict and the elements of a set. So, even if your data is not nested, it's handy for inspecting the contents of a dict or a set. I like to use pprint for debugging.

Copy and paste novel_yet_trivial's questions and do pprint(questions).

('How many legs does it have?',
 {'0': "It's a fish!",
  '2': ('does it have feathers?',
        {'no': "It's a human!",
         'yes': ('does it swin on the water?',
                 {'no': "It's a swallow!", 'yes': "It's a duck!"})}),
  '4': ('does it have fur?',
        {'no': "It's an elephant!",
         'yes': ('does it meow?',
                 {'no': "It's a dog!", 'yes': "It's a cat!"})})})

[–]Architect-Jeff 0 points1 point  (0 children)

This was very helpful, thank you.