Emulating Pascal input
Andrei Kulakov
ak at silmarill.org
Fri May 24 23:05:32 EDT 2002
In article <mailman.1022065417.1277.python-list at python.org>,
Michael Williams wrote:
> Hi,
>
> We're currently running a trial implementation of a teaching course in
> Python here at the University of Oxford Physics department. The current
> course uses Pascal and, although it works well, is obviously sub-optimal
> for a modern undergraduate education.
>
> Details of the results of the trial will be posted to EDU-sig when it is
> complete, but for now we're trying to address what we see as a
> limitation of Python for introductory programming, namely input.
>
> Consider the following Pascal code:
>
> (******** Pascal code **********)
> (* Pascal ascii input of numbers: stdin and file *)
> readln(x, y);
> readln(fin, x, y);
>
> The first line is for stdin, the second for from file. The variables
> x and y will then contain the first two white space separated numbers
> the program encounters when that function is called.
>
> Here's how we're currently getting students to do the equivalent in
> Python:
>
> ######### Python code ###########
> # Either: stdin
> linestring = raw_input()
>
> # Or: file
> linestring = f.readline()
>
> linelist = string.split(linestring)
> x = int(linelist[0])
> y = int(linelist[1])
>
> # Or perhaps
> linestring = raw_input()
> x,y = string.split(linestring) # x and y are now strings eg. '1'
> # and '2'
> x = int(x)
> y = int(y)
>
> Having read through the many threads on this topic on comp.lang.python I
> realise and understand that modern programs' input generally requires
> thought and customization from the program author. However, we strongly
> feel there should be an equivalent to Pascal's readln (which is
> basically C's scanf but without the formatting strings) for simple,
> generally numerical, whitespace-separated input.
>
> In the two weeks out trial has been running (one to go), students'
> attempts to read in simple two column tables from a file has
> consistently caused problems due to the (relative!) complexity of string
> splitting.
>
> However, There is no need for a scanf (if your input is sufficiently
> complex to require formatting strings then either string or regex
> splitting is definitely a more elegant solution).
>
> I have been attempting to write such a function in Python but have been
> struggling with (a) the lack of pointers, and (b) my total ignoarnce of
> classes, which I suspect would be helpful. Here's what I have so far
> (although note there is no error handling--give it a string response and
> it falls over and dies, give it the wrong number of responses and it
> falls over and dies, etc., etc.):
>
> ############ ninput.py ############
>
> import string
>
> def ninput(n, fin = None, prompt = '', sep = None):
>
> # 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)
>
> for i in range(len(responses)):
> 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])
>
> # If there was only one response then don't return a list.
> if len(responses) == 1: responses = responses[0]
>
> return responses[:n]
>
> ####################################
>
> And here is a usage example:
>>>> x, y = ninput(2)
> 5 6.0
>>>> print x, type(x)
> 5 <type 'int'>
>>>> print y, type(y)
> 6.0 <type 'float'>
>
Here's my implementation:
# Note def. args should follow equal sign without a space
def n(f=None, prompt='> ', sep=' '):
"""Read in and convert properly some number of numeric
variables.
"""
if not f:
line = raw_input(prompt)
else:
line = f.readline()
vals = line.split(sep)
newvals = []
for val in vals:
try:
val = int(val)
except ValueError:
val = float(val)
newvals.append(val)
if len(newvals) == 1:
return newvals[0]
else:
return newvals
>>> x = test.n()
> 5
>>> x
5
>>> x = test.n()
> 5 10
>>> x
[5, 10]
>>> x, z
([5, 10], 101)
>>> x, z = test.n()
> 5
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unpack non-sequence
>>> x, z = test.n()
> 5 5 10
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: unpack list of wrong size
The only part where it's worse than pascal version is that if you ask
for one var but enter more than one you'll get a list instead of
an error. But I don't think it's a big deal because you'll see
immediately you've got a list.
I'm pretty sure something like this won't make it into standart
distribution because it's a niche function. It simply don't
belong there. I never used Pascal but afaik it was specifically
created for the education niche; Python is an omnivore.
It *does* belong in a python directory like Vaults of Parnassus
at www.vaults.ca or could be included in some sort of educational package.
HTH,
- Andrei
>
> This has the limitation that the user must pass the number of results
> they expect back. This is done implicitly in the Pascal version too (the
> number of variables passed to the function). However, error checking is
> difficult as this version stands.
>
> If the student using the ninput function does, e.g.
>
>>>> x = ninput(2)
> 5 6.0
> [5, 6.0] <type 'list'>
>
> This is possibly what should be expected. However, passing the numerical
> argument representing the number of results expected does not strike me
> as a particularly graceful solution. We would prefer something like the
> Pascal way, where the global variables in which the results are to be
> stored are passed as parameters. Can anyone suggest a way of doing this?
>
> And if such an equivalent to the Pascal construct was implemented, what
> would be the chances of getting it included in, say, the string module
> of core Python. We would like such a function but would be reluctant to
> use it as we would then be teaching our students a ``dialect'' of
> Python.
>
--
Cymbaline: intelligent learning mp3 player - python, linux, console.
get it at: cy.silmarill.org
More information about the Python-list
mailing list