I had a situation where I needed to pass code to Python in the form of a single command instead of a script file. While this is easily done by invoking Python in command mode, the code contained a conditional statement that caused Python to throw an error.
Consider this simple Python script named if-test.py
. It initialises the variable price
, sets its value to 25
and then prints it.
#!/usr/bin/env python3 price=25 print(price)
To run the script we pass the file name to python3
on the command line:
python3 /path/to/if-test.py
25
The same can be achieved by passing the code to python3
not as a script file, but as a command using the -c
option (command mode).
python3 -c 'price=25; print(price)'
25
To include a conditional if
statement in the script the syntax is:
if condition: indented statement block else: indented statement block
Adding an if
statement, the script now checks the value of price
and if it’s less than 10
prints Cheap
otherwise Expensive
.
#!/usr/bin/env python3 price=25 if price < 10: print("Cheap") else : print("Expensive")
As the value of price
is greater than or equal to 10
the script prints Expensive
:
python3 /path/to/if-test.py
Expensive
However, passing the same code to python3
in command mode throws a syntax error:
python3 -c 'price=25; if price < 10: print("Cheap") else: print("Expensive")'
File "<string>", line 1 price=25; if price < 10: print("Cheap") else: print("Expensive") ^ SyntaxError: invalid syntax
This is because the Python interpreter expects the indented statement blocks for the if
statement to be proceeded by a newline and significant leading whitespace as they are in the script file.
I haven’t found a practical way to include newlines nor whitespace when invoking python3
in command mode, but Python – like many other scripting/programming languages – does have a one-line if
statement often referred to as a ternary operator. The syntax is:
expression1 if condition else expression2
In our example expression1 is "Cheap"
, condition is price < 10
and expression2 is "Expensive"
.
Let’s change the if
statement to a ternary operator in the script file:
#!/usr/bin/env python3 price=25 print("Cheap" if price < 10 else "Expensive")
Running the amended script gives:
python3 /path/to/if-test.py
Expensive
As the ternary operator requires no newline nor whitespace it doesn’t throw a syntax error when invoking python3
in command mode:
python3 -c 'price=25; print("Cheap" if price < 10 else "Expensive")'
Expensive
Update 2020-06-03
Here in 2020 I had the same issue using Python in command mode, but this time with a for
loop. Unfortunately, there’s no alternative like the ternary operator for the if
statement, but I did find a solution for both the for
loop and the if
statement that uses ANSI-C Quoting.
To recap the original issue, the following command throws an error as the Python interpeter expects the indented statement blocks for the if
statement
to be proceeded by a newline and significant leading whitespace:
python3 -c 'price=25; if price < 10: print("Cheap") else: print("Expensive")'
File "<string>", line 1 price=25; if price < 10 : print("Cheap") else: print("Expensive") ^ SyntaxError: invalid syntax
At the time, I was unable to find a way to insert a newline nor whitespace into the command string passed to the Python interpreter. However, using an ANSI-C-quoted string $'...'
, backslash escape sequences are treated differently so that \n
is interpreted as a newline and \t
is interpreted as a tab (whitespace).
The amended ANSI-C-quoted command string when echoed to a terminal window resembles our script file complete with newlines and whitespace (\t
can be substituted with 4 spaces):
echo $'price=25\nif price < 10:\n\tprint("Cheap")\nelse:\n\tprint("Expensive")'
price=25 if price < 10: print("Cheap") else: print("Expensive")
Passing this ANSI-C-quoted command string to the Python interpreter in command mode no longer throws an error, but gives the expected result:
python3 -c $'price=25\nif price < 10:\n\tprint("Cheap")\nelse:\n\tprint("Expensive")'
Expensive
It’s worth noting that indented statement blocks don’t always need to be placed on a new line nor actually indented. This code is perfectly valid:
#!/usr/bin/env python3 price=25 if price < 10:print("Cheap") else:print("Expensive")
Consequently, our ANSI-C-quoted command string can be changed to:
python3 -c $'price=25\nif price < 10:print("Cheap")\nelse:print("Expensive")'
Expensive
Further examples below show valid scripts using for
and while
loops. In addition, each example script has been transformed into an ASCI-C-quoted string and passed to the Python interpreter in command mode.
For Loop Examples
#!/usr/bin/env python3 alphabet = ["A", "B", "C", "etc."] for a in alphabet: print(a)
python3 -c $'alphabet = ["A", "B", "C", "etc."]\nfor a in alphabet:\n\tprint(a)'
A B C etc.
#!/usr/bin/env python3 alphabet = ["A", "B", "C", "etc."] for a in alphabet:print(a)
python3 -c $'alphabet = ["A", "B", "C", "etc."]\nfor a in alphabet:print(a)'
A B C etc.
While Loop Examples
#!/usr/bin/env python3 i = 1 while i < 6: print(i) i += 1
python3 -c $'i = 1\nwhile i < 6:\n\tprint(i)\n\ti += 1'
1 2 3 4 5
#!/usr/bin/env python3 i = 1 while i < 6:print(i); i += 1
python3 -c $'i = 1\nwhile i < 6:print(i); i += 1'
1 2 3 4 5
Hi, can you tell me what’s wrong with my code? 🙂
I’m trying to learn but struggling with this already in the beginning. There’s an error on last line, but just can’t see it. If there’s also another error, please let me know.
elif 0.7 >= score >=0.6 :
print (“D”)
else (“The error message is here”)
Thanks!
@Maya,
score=.5 returns The error message is here
score=.6 returns D
score=.7 returns D
score=.8 returns The error message is here
However, not sure what you’re trying to do with if 0.7 >= score >=0.6: as it’s only true if score=.6 or score=.7.
Regards, Steve