[Edu-sig] Re: Emulating Pascal input

Siemssen, Bradford bradford.siemssen@intel.com
Wed, 22 May 2002 11:55:29 -0700


Michael,

I'd recommend using the input function as suggested by Guido. However, if
you really feel the need to get the functionality you described try this. I
modified your original routine to have more error handling, and to be a bit
more robust. Note I haven't tested this myself, I'm writing this on company
time, and hey it's python it often works first try, but look over the code
and you should get an idea how to make it work.

The code below when given non-number values in the input will interpret the
values as some default value (typically zeros). The code will prompt the
user to re-enter the values when used interactively when the "strictInput"
flag is passed to the function. Note "strictInput" is incompatible with
reading from a file, there is no way to prompt a file to re-enter bad input.
When the conflict is found an exception is thrown. The code could be
simplified by removing the strictInput flag and associated logic entirely.

Cheers,
Brad

The new code is below.


############ ninput.py ############

import string

# You will need the input part as a separate function so you can use it
# easily when dealing with errors.
def promptedSeparatedInput(fin, prompt, sep):
    # If not file input then get string from stdin, else get from file
    if fin == None: 
       linestring = raw_input(prompt)
    else: 
       linestring = fin.readline()
    
    # Split up into list with optional seperator argument
    responses = string.split(linestring, sep)	
    return responses


def ninput(n, fin = None, prompt = '', sep = None, 
           strictInput = 0, errMsg = "Enter numbers numbskull!!",
           defaultValue = 0.0):

    if strictInput and fin != None:
	raise "invalid parameters to ninput, can not use strictInput with a
file"

    # force reading the input at least once, technically since we don't have
    # any input yet there is an error that will be remedied by getting it.
    inputErrors = 1

    while inputErrors:
        # Assume everything will go right, and we don't have to
        # continue this loop. Error handling code may change that though.
        inputErrors = 0

        # Get the input.
        responses = promptedSeparatedInput(fin, prompt, sep)

        for i in range(len(responses)):
           # You need to catch exceptions that may occur 
           # when converting data of the wrong type
           try:
              if '.' in responses[i] or 'e' in responses[i] or \ 
              'E' in responses[i]:
                  # i.e. if it looks like a float
                  responses[i] = float(responses[i])
              else:
                  # i.e if it doesn't look like a float    
                  responses[i] = int(responses[i])
           except:
              # when doing strict input checking, print the error message,
              # and keep the while loop from terminating so we will get the 
              # input from the user again.
              if strictInput:
                 inputErrors = 1
                 print errMsg
                 break # exit the for loop
              else:
                 # When not doing strictInput just set the value to the
default.
                 responses[i]= defaultValue
            
    # you should take care of the case where less was entered than was
    # expected, fill in spaces with the default value.
    while (n - len(responses)) > 0:
       responses.append(defaultValue)

    # If there was only one response then don't return a list.
    #wrong -> if len(responses) == 1: responses = responses[0] 
    # you really mean if only one response was _EXPECTED_ then don't return
a list
    if n == 1: 
       return responses[0]
    
    return responses[:n]


##############

example usage:

x = ninput(2)
x
[5, 6.0]

# use list unpacking instead of unpacking the list by hand,
# note you'll get an exception if the number of variables to
# unpack into is different than the number returned.
x, y, z = ninput(3)

# or just assign the resulting list
x = ninput(3)

P.S.

Regarding passing the values you want the results stored in to the function
is not possible using python. All variables are just references, and
parameters are local variables, so they are copies of references. Changing
what a local variable references does not change what the outer variable
references.