The focus of this notebook is refactoring a loop that

  • gets user input
  • quits if that input matches some sentinel value
  • processes the user input

The interesting part starts around cell #4.


In [1]:
from functools import partial

In [2]:
def convert(s):
    converters = (int, float)
    
    for converter in converters:
        try:
            value = converter(s)
        except ValueError:
            pass
        else:
            return value
        
    return s

In [3]:
def process_input(s):
    value = convert(s)
    print('%r becomes %r' % (s, value))

Below is a typical loop for

  • getting user input
  • quitting the loop if the user enters a special value
  • processing the input

In [4]:
def main():
    prompt = 'gimme: '
    while True:
        s = input(prompt)
        if s == 'quit':
            break
        process_input(s)

It works as shown below.


In [5]:
main()


gimme: 123.34
'123.34' becomes 123.34
gimme: 1243
'1243' becomes 1243
gimme: hello
'hello' becomes 'hello'
gimme: quit

Below is a different way of writing that loop.

How would you apply it to loop at the bottom of 2016-04/2016-Apr-Gutenberg.py?


In [6]:
def main():
    prompt = 'gimme: '
    for s in iter(partial(input, prompt), 'quit'):
        process_input(s)

In [7]:
main()


gimme: 123.34
'123.34' becomes 123.34
gimme: 1243
'1243' becomes 1243
gimme: hello
'hello' becomes 'hello'
gimme: quit

It can be reduced to a generator expression.


In [8]:
prompt = 'gimme: '
get_values = (convert(s) for s in iter(partial(input, prompt), 'quit'))
for value in get_values:
    print(value)


gimme: 123.34
123.34
gimme: 1243
1243
gimme: hello
hello
gimme: quit

2017-10-06 More thoughts about partial(input, prompt) and alternatives to it.


In [9]:
prompt = 'gimme: '

def get_input():
    return input(prompt)

def main():
    for s in iter(get_input, 'quit'):
        process_input(s)

In [10]:
main()


gimme: 123.34
'123.34' becomes 123.34
gimme: 1243
'1243' becomes 1243
gimme: hello
'hello' becomes 'hello'
gimme: quit

In [11]:
def main():
    prompt = 'gimme: '
    for s in iter(lambda : input(prompt), 'quit'):
        process_input(s)

In [12]:
main()


gimme: 123.34
'123.34' becomes 123.34
gimme: 1243
'1243' becomes 1243
gimme: hello
'hello' becomes 'hello'
gimme: quit

In [13]:
def my_partial(function, *args, **kwargs):
    def helper():
        return function(*args, **kwargs)
    return helper

def main():
    prompt = 'gimme: '
    for s in iter(my_partial(input, prompt), 'quit'):
        process_input(s)

In [14]:
main()


gimme: 123.34
'123.34' becomes 123.34
gimme: 1243
'1243' becomes 1243
gimme: hello
'hello' becomes 'hello'
gimme: quit