Input generator

Updated TrustyTony 0 Tallied Votes 547 Views Share

Gribouillis has allready posted code similar to this in his snippets, but here version for input suitable for for expressions, generators and list comprehensions. Need to add robustness by some try...except blocks for real world use.

# make this code to work in both Python 2 and 3 template
from __future__ import print_function, division
try:
    input, range = raw_input, xrange
except:
    pass

def input_generator(prompt='> ', stop=''):
    '''
    keep asking for input until stop value entered
    '''
    while True:
        inp = input(prompt)
        if inp.lower() == stop.lower():
            return
        yield inp

print('Give words for me to capitalize, end by "quit".')
print(' '.join(inp.strip().capitalize() for inp in input_generator('word> ',  'quit')))
ZZucker 342 Practically a Master Poster

Ah, I always wanted something like that:

# an input generator for strings
# works with Python2 or Python3

try:
    input = raw_input
except:
    pass

def input_generator(prompt='> ', stop=''):
    '''
    keep asking for input until stop value entered
    '''
    while True:
        inp = input(prompt)
        if inp.lower() == stop.lower():
            return
        yield inp

# test
print('Enter names you want in the list (press just Enter to end input loop): ')

mylist = [inp for inp in input_generator('>> ')]

print(mylist)

''' possible output:
Enter names you want in the list (press just Enter to end input loop): 
>> Fred
>> Karl
>> Paul
>> Helga
>> 
['Fred', 'Karl', 'Paul', 'Helga']
'''
TrustyTony 888 ex-Moderator Team Colleague Featured Poster

@ZZucker

mylist = [inp for inp in input_generator('>> ')]

This would simplify to only

mylist = list(input_generator('>> '))

For robbustness, you may want to strip the input in the generator or out of it.

I left my full template there in top, as I thought it would be usefull for somebody to reuse in there code, not only the input adaptation needed in this code (if you use only single parameter print with () around it like you did).

Ene Uran 638 Posting Virtuoso

How about an input generator for numeric input.

TrustyTony 888 ex-Moderator Team Colleague Featured Poster

For integers you just chain with my snippet: http://www.daniweb.com/software-development/python/code/364647/jail-input-and-looping-exercise

# int_generator
# generator function for inputing
# integer numbers
try:
    input = raw_input
except:
    pass


def get_int(prompt, min=None, max=None, count=None, stop=''):
    """
        Do not leave until count correct range integers are inputted
        or stop string is entered if count is not given
    """
    while True:
        try:
            limits = ''
            if min is not None:
                limits = '%s..' % min
                if max is not None:
                    limits += str(max)
            elif max is not None:
                limits = ' < %i' % max

            if limits:
                limits = ' (%s)' % limits

            if count:
                limits = '%i numbers more: %s' % (count, limits)

            a = input('%s%s ' % (limits, prompt))
            a = int(a)

            if ((min is None or a >= min) and
                (max is None or a <= max)):
                yield a # made generator
                if count:
                    count -=1
                    if not count:
                        return
            else:
                print('Entered value was not in correct range! Try again!')
        except ValueError:
            if a.lower() == stop and not count:
                return
            else:
                print('Need to input integer')

if __name__ == '__main__':
    print('Enter numbers you want in the list (press just Enter to end input loop): ')
    mylist = list(get_int('>>'))

    print(mylist)

    print('Enter non-negative numbers you want in the list (press just Enter to end input loop): ')
    mylist = list(get_int('>>', min=0))

    print(mylist)

    print('Enter 4 numbers at given range you want in the list (press just Enter to end input loop): ')
    mylist = list(get_int('>>', count=4, min=-10, max=10))

    print(mylist)

    """ Example session:
Enter numbers you want in the list (press just Enter to end input loop): 
>> 2
>> 6
>> 3453
>> -2432
>> 
[2, 6, 3453, -2432]
Enter non-negative numbers you want in the list (press just Enter to end input loop): 
 (0..) >> 32
 (0..) >> -32
Entered value was not in correct range! Try again!
 (0..) >> 3
 (0..) >> 
[32, 3]
Enter 4 numbers at given range you want in the list (press just Enter to end input loop): 
4 numbers more:  (-10..10) >> -23
Entered value was not in correct range! Try again!
4 numbers more:  (-10..10) >> 10
3 numbers more:  (-10..10) >> -10
2 numbers more:  (-10..10) >> 3
1 numbers more:  (-10..10) >> 5
[10, -10, 3, 5]
    """
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

Or you can modify this old code to suit your needs ...

# input a sequence of integer numbers separated by a space and convert to a list
# works with Python2 or Python3

try:
    input = raw_input
except:
    pass

def get_integer_list():
    while True:
        # get the sequence string and strip off any trailing space (easy mistake)
        str1 = input("Enter a sequence of integers separated by a space: ").rstrip()
        try:
            numlist = []
            for num in str1.split(" "):
                numlist.append(int(num))
            return numlist
        except ValueError:
            print("Error: '%s' is not an integer! Try again." % num)

print(get_integer_list())

''' my result >>
Enter a sequence of integers separated by a space: 1 2 3 4 5
[1, 2, 3, 4, 5]
'''
TrustyTony 888 ex-Moderator Team Colleague Featured Poster

>

for num in str1.split(" "):
numlist.append(int(num))
return numlist

This could of course be:

return [int(num) for num in str1.split(" ")]

Also I often find it more user friendly to get to write only one number immediately again, instead of inputting all numbers again (even line editing history helps).

vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

The usual

return [int(num) for num in str1.split(" ")]

won't work with Python3 because variable num does not leak anymore for the error message.

TrustyTony 888 ex-Moderator Team Colleague Featured Poster

@vegaseat: interesting info, thanks for sharing/reminding

TrustyTony 888 ex-Moderator Team Colleague Featured Poster

This does work in Python3 also:

# input a sequence of integer numbers separated by a space and convert to a list
# works with Python2 or Python3

try:
    input = raw_input
except:
    pass

def get_integer_list():
    while True:
        # get the sequence string and strip off any trailing space (easy mistake)
        str1 = input("Enter a sequence of integers separated by a space: ").rstrip()
        try:
            return [int(num) for num in str1.split(" ")]
        except ValueError as e:
            print("%s. Try again." % e)

print(get_integer_list())

''' example:
Enter a sequence of integers separated by a space: 1 2 3 234 sdf
invalid literal for int() with base 10: 'sdf'. Try again.
Enter a sequence of integers separated by a space: 123456 12 323 23
[123456, 12, 323, 23]
'''
vegaseat commented: learned something new +14
vegaseat 1,735 DaniWeb's Hypocrite Team Colleague

thanks tony ...

Looks like Python26 and Python27 accept the new version
except ValueError as e:
and the old Python25 version
except ValueError, e:

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.