[Tutor] Help with if-elif-else structure

Peter Otten __peter__ at web.de
Sat Aug 27 08:25:38 CEST 2011


Robert Sjoblom wrote:

> #assuming target number 15
> roll = (result, initial_mins, initial_max)
> if roll[0] > 15:
>     if roll[1] >= 2:
>         print("Success")
>     elif roll[2] >= 2:
>         print("Critical failure!")
>     else:
>         print("Failure.")
> elif roll[0] <= 15:
>     if roll[1] >= 2:
>         print("Critical success!")
>     elif roll[2] >= 2:
>         print("Failure")
>     else:
>         print("Success")
> 
> This handles all the test cases I've come up with, but it feels very
> ugly. Is there a better way to do this?

Sometimes a table-driven approach is preferable. Your code would become 
something like

def show_result(result, initial_mins, initial_max):
    messages = [
        ["Critical success!", "Failure", "Success"],
        ["Success", "Critical failure!", "Failure."]]
    messages = messages[result > 15]
    if initial_mins >= 2:
        message = messages[0]
    elif initial_max >= 2:
        message = messages[1]
    else:
        message = messages[2]
    print(message)

or, taken to the extreme,

def first(pairs):
    for predicate, value in pairs:
        if predicate:
            return value
    raise ValueError

def show_result(result, initial_mins, initial_max):
    messages = [
        ["Critical success!", "Failure", "Success"],
        ["Success", "Critical failure!", "Failure."]]
    def checks():
        yield initial_mins >= 2
        yield initial_max >= 2
        yield True
    print(first(zip(checks(), messages[result > 15])))

I don't think these alternatives have an advantage over the nested ifs in 
this case.



More information about the Tutor mailing list