Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #12547 > unrolled thread

idiomatic analogue of Perl's: while (<>) { ... }

Started bySahil Tandon <sahil@FreeBSD.org>
First post2011-09-01 00:56 -0400
Last post2011-09-01 18:25 +0300
Articles 5 — 4 participants

Back to article view | Back to comp.lang.python


Contents

  idiomatic analogue of Perl's: while (<>) { ... } Sahil Tandon <sahil@FreeBSD.org> - 2011-09-01 00:56 -0400
    Re: idiomatic analogue of Perl's: while (<>) { ... } Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-09-01 16:02 +1000
      Re: idiomatic analogue of Perl's: while (<>) { ... } Sahil Tandon <sahil@FreeBSD.org> - 2011-09-01 22:02 -0400
      Re: idiomatic analogue of Perl's: while (<>) { ... } Dan Sommers <dan@tombstonezero.net> - 2011-09-02 02:32 +0000
    Re: idiomatic analogue of Perl's: while (<>) { ... } Anssi Saari <as@sci.fi> - 2011-09-01 18:25 +0300

#12547 — idiomatic analogue of Perl's: while (<>) { ... }

FromSahil Tandon <sahil@FreeBSD.org>
Date2011-09-01 00:56 -0400
Subjectidiomatic analogue of Perl's: while (<>) { ... }
Message-ID<mailman.644.1314853527.27778.python-list@python.org>
I've been tasked with converting some programs from Perl -> Python, and
am (as will soon be obvious) new to the language.  A few archive/google
searches were inconclusive on a consensus approach, which is OK, but I
just wonder if there is a more Python-esque way to do the following in
Python 2.7.1:

%%
# unbuffer STDOUT
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

# process input, line-by-line, and print responses after parsing input 
while 1:
  rval = parse(raw_input())
  if rval == None:
    print('foo')
  else:
    print('bar')
%%

This works, but while reading the documentation, I thought of using 'for
line in fileinput.input()' in lieu of 'while 1:' construct.  This does
not work when debugging the program on the command line -- the script
appears to just hang no matter what is typed into STDIN.  I believe this
is because of some internal buffering when using fileinput.  Is there a
recommended way to disable such buffering?  Am I taking a totally wrong
approach?

Feel free to just link me to previous discussions on the topic(s) if I
have missed them.  Please be gentle with your cluebats. :-)

Thanks,
-- 
Sahil Tandon <sahil@FreeBSD.org>

[toc] | [next] | [standalone]


#12548

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2011-09-01 16:02 +1000
Message-ID<4e5f2010$0$29987$c3e8da3$5496439d@news.astraweb.com>
In reply to#12547
On Thu, 1 Sep 2011 02:56 pm Sahil Tandon wrote:

> I've been tasked with converting some programs from Perl -> Python, and
> am (as will soon be obvious) new to the language.  A few archive/google
> searches were inconclusive on a consensus approach, which is OK, but I
> just wonder if there is a more Python-esque way to do the following in
> Python 2.7.1:
> 
> %%
> # unbuffer STDOUT
> sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)

I've never bothered with unbuffered stdout, but that looks fine to me.

I'm not sure if it is necessary though, because print seems to automatically
flush the buffer after each line in my testing. Unless you're printing
repeatedly to the same line, I'm not sure unbuffered stdout is helpful.


> # process input, line-by-line, and print responses after parsing input
> while 1:
>   rval = parse(raw_input())
>   if rval == None:
>     print('foo')
>   else:
>     print('bar')
> %%

"while True" is considered slightly more idiomatic (readable), but
otherwise, that seems fine.

 
> This works, but while reading the documentation, I thought of using 'for
> line in fileinput.input()' in lieu of 'while 1:' construct.  This does
> not work when debugging the program on the command line -- the script
> appears to just hang no matter what is typed into STDIN.  I believe this
> is because of some internal buffering when using fileinput.  Is there a
> recommended way to disable such buffering?  Am I taking a totally wrong
> approach?

I'm not sure anything about fileinput is exactly *recommended*, it's kinda
discouraged on account of being a bit slow. See help(fileinput) at the
interactive prompt.

For what it's worth, the default buffersize for fileinput.input is 0, so if
that doesn't do what you want, I don't think fileinput is the right
solution.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#12600

FromSahil Tandon <sahil@FreeBSD.org>
Date2011-09-01 22:02 -0400
Message-ID<mailman.678.1314928995.27778.python-list@python.org>
In reply to#12548
[Thanks to everyone who responded]

Steven D'Aprano wrote:
> On Thu, 1 Sep 2011 02:56 pm Sahil Tandon wrote:
>> %%
>> # unbuffer STDOUT
>> sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
>
> I've never bothered with unbuffered stdout, but that looks fine to me.
>
> I'm not sure if it is necessary though, because print seems to automatically
> flush the buffer after each line in my testing. Unless you're printing
> repeatedly to the same line, I'm not sure unbuffered stdout is helpful.

I found it necessary because without reopening sys.stdout with buffering 
explicitly turned off, I would have to manually flush the buffer after 
each print.  This is because the program must reply (via writing to 
STDOUT) after parsing each line read via STDIN.  If I neither disable 
buffering nor manually flush after each print, the program just hangs 
instead of printing right away.

>> # process input, line-by-line, and print responses after parsing input
>> while 1:
>>    rval = parse(raw_input())
>>    if rval == None:
>>      print('foo')
>>    else:
>>      print('bar')
>> %%
>
> "while True" is considered slightly more idiomatic (readable), but
> otherwise, that seems fine.

Ah, thanks -- I've changed '1' to 'True'.

>> This works, but while reading the documentation, I thought of using 'for
>> line in fileinput.input()' in lieu of 'while 1:' construct.  This does
>> not work when debugging the program on the command line -- the script
>> appears to just hang no matter what is typed into STDIN.  I believe this
>> is because of some internal buffering when using fileinput.  Is there a
>> recommended way to disable such buffering?  Am I taking a totally wrong
>> approach?
>
> I'm not sure anything about fileinput is exactly *recommended*, it's kinda
> discouraged on account of being a bit slow. See help(fileinput) at the
> interactive prompt.
>
> For what it's worth, the default buffersize for fileinput.input is 0, so if
> that doesn't do what you want, I don't think fileinput is the right
> solution.

Got it.  Based on your and others' response, I will stick with my 
existing approach.

-- 
Sahil Tandon <sahil@FreeBSD.org>

[toc] | [prev] | [next] | [standalone]


#12608

FromDan Sommers <dan@tombstonezero.net>
Date2011-09-02 02:32 +0000
Message-ID<mailman.681.1314930753.27778.python-list@python.org>
In reply to#12548
On Thu, 01 Sep 2011 16:02:54 +1000, Steven D'Aprano wrote:

> On Thu, 1 Sep 2011 02:56 pm Sahil Tandon wrote:

>> # process input, line-by-line, and print responses after parsing input
>> while 1:
>>   rval = parse(raw_input())
>>   if rval == None:
>>     print('foo')
>>   else:
>>     print('bar')
>> %%

> "while True" is considered slightly more idiomatic (readable), but
> otherwise, that seems fine.

Arguably more readable, but arguably less idomatic, is to describe the
actual condition that controls the loop in a string (non-empty strings
are equivalent to True in this context):

while "there is more input":
    rval = parse(raw_input())
    if real is None:
        print('foo')
    else:
        print('bar')

(Although now that I've said that, this looks like an infinite loop
unless parse, raw_input, or print raises an exception.)

Dan

[toc] | [prev] | [next] | [standalone]


#12568

FromAnssi Saari <as@sci.fi>
Date2011-09-01 18:25 +0300
Message-ID<vg31uw0p9lg.fsf@coffee.modeemi.fi>
In reply to#12547
Sahil Tandon <sahil@FreeBSD.org> writes:

> I've been tasked with converting some programs from Perl -> Python, and
> am (as will soon be obvious) new to the language. 

If it's any help, I have usually done handling of standard input line by
line with this kind of thing:

for inputline in sys.stdin:

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web