python program behaves differently in python shell vs terminal - python

I have a simple Python program that asks yes or no question and I validate that input.
If I run this Python shell, it runs fine. If I enter invalid characters it loops back to top of while.
However, if I run this in the terminal window and try to enter an invalid character it errors as shown below.
endProgram = 0
while endProgram != 1:
userInput = input("Yes or No? ");
userInput = userInput.lower();
while userInput not in ['yes', 'no']:
print("Try again.")
break
endProgram = userInput == 'no'

Looks like your RPi is using Python 2; the input function does an eval there.
input in Python 3 is equivalent to raw_input in Python 2. (See PEP-3111)
Ideally, you should change your RPi interpreter to Python 3. Failing that, you can make it version-agnostic like so:
try:
input = raw_input
except NameError:
pass

I can clearly see in the interactive shell you working in python 3.2.3 (background). But I can not see the python version you're running from the command line (foreground).
On your raspberrypi, execute this command from the shell:
python --version
I am expecting to see python 2.x here, because the behaviour of input() differs between python 2 and python 3, in a way that would cause exactly the behaviour you have seen.
You might want to add a line like
#!/usr/bin/env python3
To the top of your .py file, and then chmod +x on it. Afterward you should be able to execute it directly (./guipy01.py) and the correct python interpreter will be selected automatically.

Related

Why does Rstudio console not run the python script the way other IDEs like Spyder or Jupyter notebook does?

I am trying to run a chunk of python code in Rstudio using the reticulate package. Be it a standard python script or RMarkdown, the Rstudio console shoots through the code and does not stop to ask me for input whenever it runs an input command.
Here's an example:
print('How much do you think Zuck owns?')
Zuck = int(input("Enter Zuck's net worth: "))
if Zuck < 5000000000:
print("That ain't much!")
elif Zuck == 5000000000:
print("That's 5 billion!")
else:
print("Ima make more after I graduate")
If I were running this code in Spyder/Jupyter notebook, the code will stop at the input command and ask me to enter Zuck's net worth before proceeding. Instead, here's what it does in Rstudio:
It is not stopping at the input command for me to enter Zuck's net worth. It rather goes ahead with the if statement, without assigning any value to the input - thus generating an error.
The same problem happens even in RMarkdown python code chunk.
Please let me know if there is any way for this to work.

Execute multi-line python code inside Windows Batch script

I want to use multiline python statements inside Windows Batch script.
For example, my BAT script is:
#echo off
echo "Executing Python Code..."
goto python_code
:python_code_back
echo "Executed Python Code!"
pause
exit()
:python_code
python -c print("""Python code running""")
goto python_code_back
python -c works fine for single statements. But let my python code be embedded is:
import random
num = input("Enter Number: ")
num = int(num)
if num%2 == 0:
print("Even")
else:
print("Odd")
exit()
How do I embed this Python code into my Windows Batch Script without calling another python script or making temporary python files?
I have some options that I have gone through:
Use python -c with semicolons: How do I intend the code like if
statements above? If there are ways, one might still want clean code
in multiple lines but I would appreciate the answer for this.
Can I just run python and find a way to send commands to the interpreter? Maybe using subprocesses?
Is there any way I can build a multi-line string that has the python code and then send it to the python interpreter or python command?
In bash we could use EOF to keep multi-lines clean. Is there any similar method to this in BAT? I think no because people have proposed many workarounds to this.
Can ''' (three single-quotes) or """ (three douuble-quotes) syntax be used that are specially interpreted by Batch? Like here?
Try like this:
0<0# : ^
'''
#echo off
echo batch code
python %~f0 %*
exit /b 0
'''
import random
import sys
def isOdd():
print("python code")
num = input("Enter Number: ")
num = int(num)
if num%2 == 0:
print("Even")
else:
print("Odd")
def printScriptName():
print(sys.modules['__main__'].__file__)
eval(sys.argv[1] + '()')
exit()
Example usage:
call pythonEmbeddedInBatch.bat isOdd
call pythonEmbeddedInBatch.bat printScriptName
The first line will be boolean expression in python ,but a redirection to an empty label in batch. The rest of the batch code will be within multiline python comment.

How to create a shell program that accepts commands and prints a "$" prompt to indicate that a user can input a command using a while loop?

I'm a beginner Python coder and I'm very unsure on how to create a simple shell program that accepts commands (ex. printrecipes, printinventory, load etc.)
The input should look like:
$ loadrecipes
$ printmoney()
20
For this shell, I'm trying to use a while loop so it continues through the program without crashing even if they input a command that is acceptable.
def handle_commands():
keep_going=True
command=input("$" + " ")
while keep_going:
if command == '$ quit':
keep_going = False
break
elif command == "$ loadrecipefile(recipe_file)"
j
elif command == "$ printrecipes":
printrecipes()
elif command == "$ printiinventory":
printiinventory()
elif command == "$ printmoney":
printmoney()
elif command == "$ buyingredient":
I have no idea what to go from here.
The commands are that loadrecipes(recipe_file) takes in one argument, all print commands don't take an argument, buyingredient(ingredient_name, number:int) takes in 2 arguments (the ingredient name and how many of those ingredients).
So, for each command I have created a function in correspondence. Such as for printiinventory() I have:
def printiinventory():
print(iinventory['apple'],iinventory['beets'],iinventory['carrots'])
so if the command is:
$ printiinventory
0 4 3
it should come out to be like this
So your flow should look like this:
while True:
command = input("$ ")
if command is ...
elif ...:
Very similar to what you have, with the difference that you don't need to expect $ into the user's input. Input function prints the argument passed and returns SOLELY the user's input, not the rest of the content in the same line. So you should check for commands like command == "printrecipes", etc.
Explanation:
This piece of code:
x = input(str)
Is equivalent to:
print(str); x = input(str)
with the only difference that print() creates a new line, so the input will be taken from the line just below the printed content.
You could emulate this behaviour (the printing in the same line, that is) with the IO low-level Python modules, but there is no need when you can do just that.
Edit
In order to parse the commands, you can opt for the classical command line interface syntax, that separates command name and argument with spaces, or you could make your own parser. In case you go for the first, you could use Python's built-in argparse module. In case you'd rather use the second (which is more of a headache, especially if you are a starter), you have to write your own parser from scratch. Is not that big of a deal if you know regex, but I'm afraid that's a different question you should ask in the site. I would recommend you to take a look at some tutorials. Just googling: "make my own command parser python" gives you thousands of results, even though most of them will go for classic command line parsing syntax.
Edit 2
I've noticed you use some sort of flag to check if you need to keep going inside the loop. That is useless in the piece of code you use; just use break command and you're good to go.
Edit 3
Taking a close look at the OP's comments, I see you are trying to write Python code to be executed by a Python script. You can for sure do that; you've got the eval and exec modules, BUT note that this is a very risky practice, code can very easily be injected into your program, causing huge security holes. It is highly discouraged to do that. You have to separate command parsing from task executing. The user cannot ever have direct access to the control flow of the program.

Python code not working in CMD but works in IDLE? [duplicate]

This question already has answers here:
Differences between `input` and `raw_input` [duplicate]
(3 answers)
Closed 6 years ago.
I'm new to Python and have been trying to make a small test game but when I run my program in CMD it gives of this error.
What Is Your Name?
Test
Traceback (most recent call last):
File "C:\Users\User\Documents\Python Games\Test.py", line 2, in <module>
myName = input()
File "<string>", line 1, in <module>
NameError: name 'Test' is not defined
Though this works fine in IDLE. This is the top of the code.
print('What Is Your Name?')
myName = input()
print('Hello '+str(myName)+' It is good to meet you!')
Its because of python version change. You probably have two pythons installed.
Python2.x is in the PATH. And you have the Python 3.x IDLE.
NameError: name 'Test' is not defined is because its python 2.x
Change myName = input() to myName = raw_input().
And it would work in python 2.x
Your IDLE version must be python 3.x where there is no raw_input().
Explanation
There as been few changes between Python 2.x and Python 3.x .
One of them is the change of the input function.
In Python 2, the input function evaluate what the user is typing. This function is used when the user have to type a number. It will be parsed and the variable containing the return value of input will be of type numeric (float or int).
https://docs.python.org/2/library/functions.html#input
In your case, since the name of the user is probably not a number, and if you are working with Python 2, you should use the function raw_input which return the input of the user as a String without parsing. Meaning that if the user type a number, it is the String containing this number which will be returned.
https://docs.python.org/2/library/functions.html#raw_input
For security reasons, the input function of Python 2 is not recommended to use because the function evaluate the input, and though it is very convenient for parsing numbers without cast, it allows also the user to inject malicious code into your application ;)
>>> print str(input("Enter your name: "))
Enter your name: __import__('os').listdir('.')
['super_secret.txt']
Thus, the input function has been replaced by the raw_input function in Python 3 and the raw_input function has been removed.
Fix
I think that the default behaviour of your os is to call python2 when you want to run python. So, if you want to run python3, you have to say it explicitly:
on windows: https://docs.python.org/3.3/using/windows.html#python-launcher-for-windows
py -3
on ubuntu (it is probably the same for other distributions):
python3
Your IDE seems to be correctly configured to use python3 as default interpreter.

Python inside bash Input Error

I have inserted python code inside bash script like this:
#!/bin/bash
echo "You are in Bash"
python <<END
# -*- coding: utf-8 -*-
import os
import sys
import getpass
print "You are in python"
username=raw_input('Bitbucket Username : ')
END
echo "Python ended"
But the problem is I am not able to take input using raw_input or input when I insert python in bash. Python alone works fine. What is the problem here in my code?
Instead of a heredoc, just user the -c parameter to pass a command:
$ python -c "username = raw_input('Enter name: ')
print 'Hello', username
"
Enter name: Chris
Hello Chris
Once you say END, you are telling bash that your program is over. Bash gives your lines as input to Python. If you are in python, type each line that you wrote there, regardless of what prompt, and when you are done, signify EOF by Ctrl-D on linux, Ctrl-Z on windows. You will see that raw_input() will have a EOFError. That is what bash is doing. It gives Python each line, and then says "We're done. Send EOF". It pays no attention to what prompt is given. It doesn't know that you are asking for input. This is a useful feature, however, because if it didn't have that, there would be nothing telling Python to exit...ever. You would have to send KeyboardInterrupt to get that program to exit.

Categories

Resources