[Edu-sig] Re: Emulating Pascal input
Wed, 22 May 2002 11:55:29 -0700
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.
The new code is below.
############ ninput.py ############
# 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)
linestring = fin.readline()
# Split up into list with optional seperator argument
responses = string.split(linestring, sep)
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
# 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
# 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
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])
# i.e if it doesn't look like a float
responses[i] = int(responses[i])
# 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.
inputErrors = 1
break # exit the for loop
# When not doing strictInput just set the value to the
# 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:
# If there was only one response then don't return a list.
#wrong -> if len(responses) == 1: responses = responses
# you really mean if only one response was _EXPECTED_ then don't return
if n == 1:
x = ninput(2)
# 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)
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