Why doesn't Python include non-blocking keyboard input function?

BartC bc at freeuk.com
Sat Oct 29 11:24:53 EDT 2016


On 29/10/2016 15:19, Steve D'Aprano wrote:
> On Sat, 29 Oct 2016 10:53 pm, BartC wrote:

>> But I'd like to see Python running on a 64KB system
>> (Micropython doesn't count!).
>
> Hmmm. So tell me... how do you expect Python to run on tiny systems by
> *adding* new features?
>
> Regardless of how "small" this feature is, it is not negative size. The
> implementation is at least 1 byte. The documentation is at least 1 byte.
> The tests are at least 1 byte. If you think Python is too big now, then
> adding this feature will make it at least 3 bytes bigger.

The /effective/ size could well be negative! If someone really needs the 
feature they might need to drag in 'curses' or require 'tkinter', 
substantial add-ons even though they only need one minor feature.

> print as a statement was always an anomaly, and yes, it got pretty weird:
>
> print >>sys.stderr, spam, eggs

> So much nicer now that it is a function that takes proper keyword arguments.

I guess ">>" is what I used "#" or "@" for. But what does it look like 
in function form?

Functions are great for adding general-purpose utility but their syntax 
is limited; sometimes dedicated syntax is better for things you use all 
the time.

 > What I said
> looked weird was your syntax:
>
>     read a:"h", b:"r", c:"s"
>
>
> If you're going to introduce special syntax for types, why make the types
> strings rather than symbols?

(I can't remember where that came from. The colon syntax I think was 
from Pascal. I used strings for the Print counterpart as there can be 
other stuff in there: x:"z8hs'" might display x as "0001'E800".

Read formats could have been single unquoted characters I suppose (they 
were once). But a string means the format can be dynamic: read a:fmt,b:fmt.

But this is a detail. The main thing is trivially just listing the 
things you want to read in a similar manner to print.)

>> BTW what does reading three integers from the user look like in Python?
>
> for i in range(3):
>     n = int(input(""))

OK, one per line. Just so each input line corresponds to exactly one 
integer! (I can do this too but I write it as:

  n := strtoval(sreadln())       # int default
  x := strtoval(sreadln(),"r")   # floating point ('real') )

> You want a prompt? Change the empty string to your prompt.
>
> You want to assign to three different variables? Unroll the loop:
>
> n = int(input(""))
> p = int(input(""))
> q = int(input(""))

>
> If the user types something that isn't an integer, you want to try again?

The idea of read and print statements, in my languages at least, are for 
simple or throwaway programs, or when dealing with known file formats:

  r := "r"
  readln @file, x:r, y:r, z:r

It's not /meant/ to be sophisticated. Just convenient.

> Write a loop. If you're sensible, of course you will put it into a helper
> function:
>
>
> _SENTINEL = object()
>
> def read_int_with_all_the_trimmings(
>         prompt1='Enter an int: ',
>         prompt2='Invalid value for an int; please try again: ',
>         prompt3='Value out of range; please try again: ',
>         max_times=2**31,
>         low=None,
>         high=None,
>         default=_SENTINEL):
>     msg = prompt1
>     for attempt in range(max_times):
>         s = input(msg)
>         try:
>             n = int(s)
>         except ValueError:
>             msg = prompt2
>         else:
>             out_of_range = (low is not None and n < low) or (
>                             high is not None and n > high)
>             if out_of_range:
>                 msg = prompt3
>             else:
>                 return n
>     if default is _SENTINEL:
>         raise ValueError('not a valid int')
>     return default
>

> Does your `read` statement do all that? Why not?

I don't understand your point. No, it doesn't, but neither does Python 
(it doesn't have 'read' for a start). You've had to write it; I can too. 
And that example still reads one number per line!

Suppose you have to read a ppm file which might start like this:

P6
600 800
255

I can read this using 'read': (checking and comment-skipping code omitted):

  readln @f, sig:"s"
  readln @f, width, height
  readln @f, maxpix

It doesn't need anything fancy and you don't want to bother with parsing 
the input lines and converting text to numbers.

-- 
Bartc



More information about the Python-list mailing list