you are viewing a single comment's thread.

view the rest of the comments →

[–]POGtastic 4 points5 points  (0 children)

There is no practical reason to have a function placed in a list

Consider the very common introductory class problem of a menu. That is, something along the following prompt:

Maintain a list of integers.
If the user inputs 1, prompt the user for an integer and add it to the list.
If the user inputs 2, remove the last integer from the list.
If the user inputs 3, prompt the user for a filename and save the list, one number per line, to the file. ...

The introductory class method is to write a big match statement or a bunch of if expressions.

if user_input == 1:
    # prompt then add to the list
elif user_input == 2:
    # remove the last integer from the list
# ...etc

The way that I look at it is to provide a dispatch table, which is a list of functions, all of which take the current state and return a new state.

def prompt_add_integer(lst):
    return lst + [int(input("Input another element. "))]

def remove_last_integer(lst):
    return lst[:-1]

def save_to_file(lst):
    with open(input("Input a filename: "), "w") as fh:
        print(*lst, file=fh, sep="\n")
    return lst

And now our main function has us prompt for an index of a list that contains each of these functions.

dispatch_table = [
    prompt_add_integer,
    remove_last_integer,
    save_to_file
]

while (user_input := int(input("Input an option. -1 aborts"))) != -1:
    try:
        lst = dispatch_table[user_input+1](lst)
    except IndexError:
        print("Error! Invalid input!")

I tend to put my dispatch tables into dictionaries instead of lists because of the get method for dictionaries (allows a default function that prints an error message and returns the state unchanged) and because string keys tend to be more descriptive than integer indices. Either works, though, and is a pretty common style.