[Edu-sig] Emulating Pascal input

Steven Majewski sdm7g at Virginia.EDU
Wed May 22 18:43:06 EDT 2002


On Wed, 22 May 2002, Michael Williams wrote:

> On Wed, May 22, 2002 at 07:42:59AM -0400, Guido van Rossum wrote:
> > [Michael Williams is looking for a readln() replacement]
> >
> > If you're willing to change the input format to require commas between
> > numbers, you could use the standard built-in function input(), which
> > was put in Python specifically to support this kind of usage.
>
> I did consider this but:
>
> - the quasi-standard way of delimiting data is whitespace -- not
>   commas.
>
> - allowing users of programs to interact using input() is A Bad Thing.

Why is it a "Bad Thing" ?
If these are the students own programs then security isn't a problem.

It's really handy to be able to type expressions for input args instead
of having to get out a calculator to figure out the input args for your
program.

If you do want to restrict the input use something like:

>>> import math
>>> def expr( e ): return eval( e, math.__dict__, {} )

Now you can use string.split to get your whitespace delimited args:

>>> map( expr, sys.stdin.readline().strip().split() )
1 sqrt(2) pi/2 2 3.0 pi
[1, 1.4142135623730951, 1.5707963267948966, 2, 3.0, 3.1415926535897931]


If you want some latitude in the choice of separator, you should use
re.split -- commas change the evaluation of the string:

>>> map( expr, sys.stdin.readline().strip().split() )
1,2,3
[(1, 2, 3)]
>>> map( expr, sys.stdin.readline().strip().split() )
1, 2, 3
[(1,), (2,), 3]



>>> map( expr, re.split( '[, \t]', sys.stdin.readline() ) )


If you want some input error checking on the number types of input values,
you can use an explicit list of coercions:

map( lambda f,x: f(x), [ int, float, expr ], ...


You could wrap up your preferred style in a function or use something
like this (with all the options):

>>> def readln( source=sys.stdin, prompt='>', sep='[ ,\t]', coerce=None ):
...     if source is sys.stdin:  inp = lambda : raw_input( prompt )
...     else:  inp = source.readline
...     args = re.split( sep, inp().strip() )
...     if coerce is None:
...             return map( expr, args )
...     else:
...             return map( lambda f,x: f(x), coerce, args )
...


Using the coercion functions lets you input strings without requiring
quotes:

>>> readln( coerce=(str,int) )
> abc 1
['abc', 1]


-- Steve Majewski







More information about the Python-list mailing list