Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   Re: How to use "while" within the command in -c option of python? (http://www.velocityreviews.com/forums/t953313-re-how-to-use-while-within-the-command-in-c-option-of-python.html)

Etienne Robillard 10-12-2012 11:04 PM

Re: How to use "while" within the command in -c option of python?
 
On Fri, 12 Oct 2012 15:51:19 -0700
Herman <sorsorday@gmail.com> wrote:

> python -c "import os; while True: print('hello')"
> File "<string>", line 1
> import os; while True: print('hello')
> ^
> SyntaxError: invalid syntax
> --
> http://mail.python.org/mailman/listinfo/python-list


You get a syntax error since you didn't used tabs indents in your string
which is normal for python AFAIK.

Steven D'Aprano 10-13-2012 12:32 AM

Re: How to use "while" within the command in -c option of python?
 
On Fri, 12 Oct 2012 19:04:20 -0400, Etienne Robillard wrote:

> On Fri, 12 Oct 2012 15:51:19 -0700
> Herman <sorsorday@gmail.com> wrote:
>
>> python -c "import os; while True: print('hello')" File "<string>",
>> line 1
>> import os; while True: print('hello')
>> ^
>> SyntaxError: invalid syntax
>> --
>> http://mail.python.org/mailman/listinfo/python-list

>
> You get a syntax error since you didn't used tabs indents in your string
> which is normal for python AFAIK.


Incorrect. Python lets you use either spaces or tabs for indents, and in
this case the SyntaxError is BEFORE the missing indent. He gets
SyntaxError because you can't follow a semicolon with a statement that
begins a block. It's the `while` that causes the error, not the lack of
indent. Here's an example with `if` and an indented block that also
fails:


[steve@ando ~]$ python -c "pass; pass"
[steve@ando ~]$ python -c "pass; if True: pass"
File "<string>", line 1
pass; if True: pass
^
SyntaxError: invalid syntax


Solution: don't use semi-colons, use newlines.

In this example, I use `Ctrl-Q ENTER` to insert a literal newline in the
string, which shows as ^M. Note that you *cannot* just type ^ M (caret
M), that won't work, it must be an actual control character.


[steve@ando ~]$ python -c 'import time^Mwhile True:^M print("hello"); time.sleep(2)'
hello
hello
hello
Traceback (most recent call last):
File "<string>", line 3, in <module>
KeyboardInterrupt


In this example I just hit the Enter key to insert a newline, and let the
shell deal with it. The ">" marks are part of the shell's prompt.

[steve@ando ~]$ python -c "import time
> while True:
> print('hello'); time.sleep(2)"

hello
hello
hello
Traceback (most recent call last):
File "<string>", line 3, in <module>
KeyboardInterrupt




--
Steven

Thomas Bach 10-13-2012 08:41 AM

Re: How to use "while" within the command in -c option of python?
 
On Sat, Oct 13, 2012 at 12:32:41AM +0000, Steven D'Aprano wrote:
>
> He gets SyntaxError because you can't follow a semicolon with a
> statement that begins a block.


Can someone provide a link on where to find this type of information?
I was just hunting through “The Python Language Reference” and could
not find anything explicit. The only thing I found is

http://docs.python.org/reference/simple_stmts.html

“Several simple statements may occur on a single line separated by
semicolons.”

Anyways, this does not explicitly say “You shall not put a compound
statement after a simple statement separated by a semicolon.”, right?

Regards,
Thomas Bach.

Chris Angelico 10-13-2012 09:03 AM

Re: How to use "while" within the command in -c option of python?
 
On Sat, Oct 13, 2012 at 7:41 PM, Thomas Bach
<thbach@students.uni-mainz.de> wrote:
> On Sat, Oct 13, 2012 at 12:32:41AM +0000, Steven D'Aprano wrote:
>>
>> He gets SyntaxError because you can't follow a semicolon with a
>> statement that begins a block.

>
> Can someone provide a link on where to find this type of information?
> I was just hunting through The Python Language Reference and could
> not find anything explicit. The only thing I found is
>
> http://docs.python.org/reference/simple_stmts.html
>
> Several simple statements may occur on a single line separated by
> semicolons.
>
> Anyways, this does not explicitly say You shall not put a compound
> statement after a simple statement separated by a semicolon., right?


It's more that Python treats simple and compound statements as
completely separate beasts. You can combine simple statements on one
line, but compound statements mustn't be.

In my opinion, this is a major wart in Python syntax. You can argue
all you like about how it reduces code clarity to put these sorts of
things together, but that's a job for a style guide, NOT a language
requirement. Most code won't put an assignment followed by an
if/while/for, but when I'm working interactively, I often want to
recall an entire statement to edit and reuse, complete with its
initialization - something like (contrived example):

>>> a=collections.defaultdict(int)
>>> for x in open("RilvierRex.txt"): a[x]+=1


Then I keep doing stuff, keep doing stuff, and then come back to this
pair of lines. Since they're two lines, I have to recall them as two
separate entities, rather than as an initializer and the code that
uses it. Logically, they go together. Logically, they're on par with a
list comprehension, which initializes, loops, and assigns, all as a
single statement. But syntactically, they're two statements that have
to go on separate lines.

To force that sort of thing to be a single recallable statement, I can
do stupid tricks like:

>>> if True:

a=collections.defaultdict(int)
for x in open("RilvierRex.txt"): a[x]+=1

but that only works in IDLE, not in command-line interactive Python.

Note, by the way, that it's fine to put the statement _inside_ the for
on the same line. It's even legal to have multiple such statements:

>>> for x in (1,2,3): print(x); print(x);

1
1
2
2
3
3

If there's any ambiguity, it would surely be that, and not the simple
statement being first.

Okay, rant over. I'll go back to being nice now. :)

ChrisA

Chris Angelico 10-13-2012 05:23 PM

Re: How to use "while" within the command in -c option of python?
 
On Sun, Oct 14, 2012 at 3:38 AM, Joshua Landau
<joshua.landau.ws@gmail.com> wrote:
> This here isn't a flaw in Python, though. It's a flaw in the command-line
> interpreter. By putting it all on one line, you are effectively saying:
> "group these". Which is the same as an "if True:" block, and some things
> like Reinteract even supply a grouping block like "build".
>
> That said, because some shells suck it would be nice if:
>>
>> python -c "a=1\nif a:print(a)"

>
> worked (just for -c).


Yes, that'd be nice. But it still leaves the big question of why
Python requires \n to separate one statement from another. It IS a
flaw in Python that it requires one specific statement separator in
this instance, even though it'll accept two in another instance.

Here's a side challenge. In any shell you like, start with this
failing statement, and then fix it without retyping anything:

sikorsky@sikorsky:~$ python -c "a=1; if a: print(a)"
File "<string>", line 1
a=1; if a: print(a)
^
SyntaxError: invalid syntax

In bash, I was unable to insert a newline into the quoted string. My
only option was to backspace everything after the point where I wanted
the newline, then hit enter, then retype the if. I'm curious to know
if that's simply because I didn't think of (some bash feature), or
alternatively, if there's another shell that would have made this
easy.

Back to the main point. In C-like languages, the newline is nothing
special. (ECMAScript allows the omission of semicolons at end of line
in many cases, but many style guides recommend using them anyway.) You
can, if you so desire, put all your code into a single line. It's then
up to the project's style guide to decide how things should be laid
out. For instance, this is multiple statements in PHP, but I see it as
one logical action:

$bar=array(); for ($foo as $k=>$v) $bar[$k]="<p>".$v."</p>";

It's one statement in Python:

bar = ["<p>"+x+"</p>" for x in foo]

It's one statement in Pike:

array bar = map(foo,lambda(string x) {return "<p>"+x+"</p>";});

So it should be allowed to be put on one line. And in languages whose
syntax derives from C, you almost certainly can. (I can't think of any
counter-examples, though that certainly doesn't prove they don't
exist.) But the same thing is forced onto two lines in Python, and not
for syntactic reasons - at least, not that I can see. Perhaps someone
can enlighten me.

Is there any fundamental reason that the syntax couldn't be expanded
to permit "statement; statement" for any two given statements?

ChrisA

Jussi Piitulainen 10-13-2012 05:43 PM

Re: How to use "while" within the command in -c option of python?
 
Chris Angelico writes:

> Here's a side challenge. In any shell you like, start with this
> failing statement, and then fix it without retyping anything:
>
> sikorsky@sikorsky:~$ python -c "a=1; if a: print(a)"
> File "<string>", line 1
> a=1; if a: print(a)
> ^
> SyntaxError: invalid syntax
>
> In bash, I was unable to insert a newline into the quoted string. My
> only option was to backspace everything after the point where I
> wanted the newline, then hit enter, then retype the if. I'm curious
> to know if that's simply because I didn't think of (some bash
> feature), or alternatively, if there's another shell that would have
> made this easy.


C-v C-j inserts a newline for me, in bash.

Chris Angelico 10-13-2012 05:47 PM

Re: How to use "while" within the command in -c option of python?
 
On Sun, Oct 14, 2012 at 4:43 AM, Jussi Piitulainen
<jpiitula@ling.helsinki.fi> wrote:
> Chris Angelico writes:
>
>> Here's a side challenge. In any shell you like, start with this
>> failing statement, and then fix it without retyping anything:
>>
>> sikorsky@sikorsky:~$ python -c "a=1; if a: print(a)"

>
> C-v C-j inserts a newline for me, in bash.


Ah! So it does. Thanks.

*stashes that away in the "handy commands" index in his brain*

ChrisA

Chris Angelico 10-13-2012 06:41 PM

Re: How to use "while" within the command in -c option of python?
 
On Sun, Oct 14, 2012 at 5:21 AM, Joshua Landau
<joshua.landau.ws@gmail.com> wrote:
> Because Python uses indentation, what would "if A: print(1); if B: print(2)"
> even do? It has to fail, because we have to assume consistent indentation
> for ";"s*. With "\n" as I proposed, you still have to indent: it is just a
> method to bypass lame shells [it would become "if A: print(1)\nif B:
> print(2)"].


sikorsky@sikorsky:~/cpython$ python -c "if False: print(1); print(2)"
sikorsky@sikorsky:~/cpython$ python -c "if True: print(1); print(2)"
1
2
sikorsky@sikorsky:~/cpython$

The semicolon separates statements, but doesn't change nesting levels.
The if statement increases the nesting level, which demands a
corresponding indentation increase if you go onto a new line; the
statement you describe is illegal because the 'if' isn't allowed to
not be at the beginning of the line, but it's unambiguous.

Of course, since Python lacks a non-whitespace way of indicating the
end of an if block, there's no way to put your "if A" and "if B" onto
the same line as peers. But that's a consequence of a design decision,
and one that can't easily be changed. Every language has warts like
that; eschewing variable declarations prevents infinite nesting of
scopes, but demanding variable declarations makes interactive work
harder. To paraphrase the Pirate King: Always follow the dictates of
your conscience, and accept the consequences.

ChrisA

Dennis Lee Bieber 10-13-2012 07:19 PM

Re: How to use "while" within the command in -c option of python?
 
On Sun, 14 Oct 2012 04:23:25 +1100, Chris Angelico <rosuav@gmail.com>
declaimed the following in gmane.comp.python.general:

> Back to the main point. In C-like languages, the newline is nothing
> special. (ECMAScript allows the omission of semicolons at end of line
> in many cases, but many style guides recommend using them anyway.) You


That leads back to the Pascal even... The difference between a
semi-colon as a statement terminator (Ada) and a statement separator
(Pascal).

--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/


Dennis Lee Bieber 10-13-2012 08:42 PM

Re: How to use "while" within the command in -c option of python?
 
On Sun, 14 Oct 2012 05:41:11 +1100, Chris Angelico <rosuav@gmail.com>
declaimed the following in gmane.comp.python.general:

> On Sun, Oct 14, 2012 at 5:21 AM, Joshua Landau
> <joshua.landau.ws@gmail.com> wrote:
> > Because Python uses indentation, what would "if A: print(1); if B: print(2)"
> > even do? It has to fail, because we have to assume consistent indentation
> > for ";"s*. With "\n" as I proposed, you still have to indent: it is just a
> > method to bypass lame shells [it would become "if A: print(1)\nif B:
> > print(2)"].

>
> sikorsky@sikorsky:~/cpython$ python -c "if False: print(1); print(2)"
> sikorsky@sikorsky:~/cpython$ python -c "if True: print(1); print(2)"
> 1
> 2
> sikorsky@sikorsky:~/cpython$
>

Which isn't the same example... The former would be:

if False: print(1); if True: print(2)
--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/



All times are GMT. The time now is 07:37 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.