noob question Letters in words?

Steven D'Aprano steve at
Sat Oct 8 05:19:48 CEST 2005

On Fri, 07 Oct 2005 22:06:31 -0400, Ivan Shevanski wrote:

> Right but see what if the user wants to type Start? I've already used the 
> number menu but too many people get confused by it. . .Any other ideas?

Then let them type either the word or the number. Don't penalise your
smart users because of your stupid ones. And don't make the stupid ones
suffer because of the smart ones.

def make_menu(words):
    """Takes a list of words and prints a text menu.
    Items are numbered from 1 onwards, not zero.
    for i in len(words):
        print ("%d:%s" % i+1, words[i])

def check_response(response, words, default=None):
    """Tests the user response against the list of words.

    Accepts either a number, or the entire word, or the first letter of
    the word *provided it is not ambiguous*. An optional default can be

    Returns the _index_ of the word entered, counting from zero.
    s = response.strip().lower()
    if s == "":  # user just hit Enter
        if default is not None:
             s = default.strip().lower()
    for i in len(words):
        if s == str(i+1): 
            return i
        if s == words[i].lower():
            return i
        if s == words[i].lower()[0]:
            # the user response is a single letter, and it matches
            # the current word, so we check for ambiguity
            n = count_matches(s, words)
            if n == 1:
                return i
            # otherwise there could be two or more matches
    # if we get here, nothing matched
    return -1

def count_matches(s, words):
    temp = [word.lower().startswith(s) for word in words]
    return len(temp)

def get_response(commands):
    raw_response = raw_choice("> ")
    choice = check_response(raw_response, commands, default="start")
    if choice == -1:
        # the response matched either nothing, or too many things
        print "I don't understand your response. Please try again."
        return get_response(commands)
        return choice

Now finally use the whole thing:

(warning, code is untested)

commands = ["Start", "End", "Scratch head", "Burp"]
cmd = get_response(commands)

This should accept any combination of:

1 "start" <enter>
2 "end" "e"
3 "scratch head"
4 "burp" "b"

in any mix of upper and lower case.

Hope this works for you.


More information about the Python-list mailing list