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 if 0.7 >= score >=0.6: print ("D") else: print ("The error message is here")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