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