Python - function setting external variable to user input as side effect - python

I'm a casual gamer and hobbyist programmer who knows a bit of Python. I'm trying to make a simple text adventure game engine, so I need to get raw input from the player.
This is Python 3.2.2, so my line is this:
var = input("What do you want to do? ").lower()
And that line works, but rather than typing that whole line I'd like to make it into a function (something like "getinput()"). From what I've read about input() and functions I'm looking for a function that doesn't return anything, but changes another variable's state (here "var") as a "side effect."
I do have a working function "halt()" that takes no arguments:
def halt():
input("(Press Enter to continue...) ")
print("")
Calling "halt()" gives the prompt, waits for Enter, then prints a blank line and moves on, which I intended.
The function I'm trying to get to work looks like this:
def getinput(x):
x = input("What do you want to do? ").lower()
print("")
After defining getinput(x):
var = ""
getinput(var)
print(var)
That snippet does not print the user's input, and I'm confused as to why. What do I need to do to make this work in the intended fashion?
Is what I'm trying to do impossible with a function, or is there just something I don't know about scope? Should I be at codereview?

You are right that the issue is about scope. The x in this line:
x = input("What do you want to do? ").lower()
Does not change the value that is passed to it- it creates a new variable (also called x) in the local scope of the function.
The right way to do this would be:
def getinput():
return input("What do you want to do? ").lower()
x = getinput()
print(x)

NOTE: If you are going to use any version of Python before 3.x, definitely consider using the raw_input() function as the plain input() function only takes input that is SYNTACTICALLY VALID from the user, otherwise a SyntaxError will be raised.
I'm not sure what you're trying to do exactly, but I've moved around what you've written above so that it will work. Here's what I suggest trying:
First the function getinput()...
def getinput():
x = raw_input("What do you want to do? ").lower() #prompts for the value of x
print "" #prints a blank line
return x
Then the second part...
var = getinput()
print(var)

When you pass something to a Python function, it's generally impossible to modify it unless it's mutable. That restricts you to a small subset of Python types such as a list or dictionary.
def getinput(x):
x[0] = input("What do you want to do? ").lower()
print("")
var = [""]
getinput(var)
print(var[0])
You're far better off letting the function return a value. That's the way Python was meant to work.

var is a python string variable which is being passed by value to your getinput function, which means that your getinput function only modifies a local copy of the name "x", not the value pointed to by "x" from your calling scope.
Also in Python strings are immutable and so it is impossible to modify a string's underlying value in-place due to string interning/hash consing - you merely create a new string. You should really be returning your value:
x = getinput()
But if you still want to stick to your existing design, you can pass this string variable by reference by wrapping it in a list or other reference type:
def getinput(li):
li.append(input("What do you want to do? ").lower())
print("")
usage:
x = []
getinput(x)
print x[0]

Related

Executing a function in a dictionary | Python 3

So I am making a program in python 3.6 that selects and executes a specific function based on the user_input.
The code can properly decide what function to execute, just not actually execute it. The functions also work
def addition():
1+1
user_input = input("What operator do you wish to use?")
myOperators = {"Addition":addition}
if user_input in myOperators:
myOperators.get(user_input)
Using this code the function addition() never executes. However, I can check that it selects the correct value, because if I do this:
if user_input in myOperators:
print(myOperators.get(user_input))
it prints <function addition at 0x7f0973026620>
Python treats functions as object which can be passed around and stored in lists and dictionaries. To actually call the function you need to use parenthesis after the object.
In your case myOperators.get(user_input) returns the function object, so it would become
myOperators.get(user_input)()

Python, Explain Return Within a Function, (Amateur Programmer)

I am an amateur Python coder learning in school. We recently went over functions and did some work at home. I am confused on the point/meaning of the return statement. Our goal was to simply turn a letter into its ASCII counter part using ord(). My code works as intended however what is the use of the return statement, and how can it be used in this situation to take this function further?
Letter = input("What is your letter? ")
def ordfunction ( x ):
x=ord(x)
print(x)
return[x]
ordfunction(Letter) x
Whenever we write a function it perform some task, on basis of execution it provide some result. Now we have lot of options to use this result.
One we can print/display that result on console. for which we use print to show o/p. Here is use:-
Letter = input("What is your letter? ")
def ordfunction ( x ):
x=ord(x)
print(x)
ordfunction(Letter)
So it will display output on console apart from this it dosn't perform any things. We can use this output to store in a file or send on any device.
Further other way is to use return to provide result of function. Here we can hold this value to use further in any kind of calculation like:-
Letter = input("What is your letter? ")
def ordfunction ( x ):
x=ord(x)
return x
a = ordfunction(Letter)
print (a+100)
So return with provide use result of execution to use it further throughout program.
Further you can refer:-
Why would you use the return statement in Python?
There are basically two things that a method/function can do: change some kind of state or give the caller some kind of information.
For example, if you write something to the console, you've changed something about the system state. This is sometimes called a side effect.
The second thing a method can do is give its caller some kind of information. return is a way to pass data back to the caller - it's the "result" of the method. (In many programming languages, you can also use it to exit a method immediately, but that's a different topic).
Think about a common function: 2 + 3. Most people aren't used to thinking of + as a function, but it is. (If it helps, you can think of this as plus(2, 3)). In this case, the plus function "returns" five - that's the result of the operation, the information you were looking for when you "called" it to begin with.
Hopefully, this clarifies things a little bit - if not please feel free to comment and I can edit.
Quoting definition of a math function:
In mathematics, a function is a relation between a set of inputs and a
set of permissible outputs with the property that each input is
related to exactly one output.
In short, the return is the output. Think about a math function f(x) = x + 100.
x is the input
x + 100 is the implementation of the function
The return is the output of the function, which is the result of x + 100
Equivalent python function:
def f_of_x(x):
result = x + 100
return result
Return is your answer to one statement; example: is it raining? Yes, it's raining
Your answer is returned to your question.
Simple
I also had trouble understanding the difference between return and print. After you return a function you should:
print(ordfunction(Letter))
To see your function. Print is just made for humans to see what is going on. We usually don't need the print function.

Return variable from a function

This section of a program I am writing is supposed to take the random choice and then print it outside the function (I can't print from within as I need the variable later).
I am sure there is a simple solution to this, but I am unsure what it is.
#python2
def CompTurn():
RandTurn = [Column1,Column2,Column3,Column4]
Choice = random.choice(RandTurn)
return(Choice)
print Choice
Thank you.
Add the line
Choice = CompTurn()
before your print statement. Because the variables you declare within the function are not known outside of it, you have to store (or print directly, but then you cannot store it) the returned variable in a new variable.
You have defined your function correctly, but you never executed it! (You'll see that if you make it print something as a diagnostic.) You must run it to get the result:
chosen = CompTurn()
print chosen
Note that I used a different variable name. You could use the same variable name as a variable in your function, but it's still a different variable than the one in your function.
It is also important to realize that your function returns a value, not a variable. You can assign the value to a variable (as above) or print it immediately.
print CompTurn()
About your program, you don't need the brackets for return. It's s statement, not a function.
def CompTurn():
RandTurn = [Column1,Column2,Column3,Column4]
Choice = random.choice(RandTurn)
return Choice
Shorter:
def CompTurn():
RandTurn = [Column1,Column2,Column3,Column4]
return random.choice(RandTurn)
To print the return value, You can save it in a variable and print it
ret = CompTurn()
print ret
Or print directly:
print CompTurn()

NameError when using a variable returned by a function

I want to return the variable aRoll, and use it as the argument for the next function. In this case, aRoll holds the answer to the question "Let's roll your ability scores. ready? (y/n)" Once the question is answered, it raw input is stored in the variable aRoll and returned.
import random
pAbility = ['Str', 'Dex', 'Con', 'Int', 'Wis', 'Cha']
pScore = []
i = 0
def pQuestion():
aRoll = raw_input("Let's roll your ability scores. ready? (y/n)")
if aRoll not in ('y', 'n'):
print "Please type 'y' or 'n'"
return pQuestion()
else:
return aRoll
def pStats(aRoll):
while aRoll == "y":
while i < 6:
pScore.append(random.randint(7, 18))
i = i + 1
for score, ability in zip(pAbility, pScore):
print str(score) + ":\t\t " + str(ability)
def pReroll():
aRoll = raw_input("Do you wish to reroll? (y/n)")
aRoll = aRoll.lower()
if aRoll not in ('y', 'n'):
print "Please type 'y' or 'n'"
return pReroll()
pQuestion()
pStats()
pReroll()
When putting print aRoll after pQuestion(), at the bottom of the script, it tells me aRoll isn't defined. Am I not returning aRoll correctly?
aRoll as defined is a separate local variable in each function. You either need to declare it as a global (not a good idea), or explicitly pass the return value of one function as an argument to the next. For example,
rv = pQuestion()
rv2 = pStats(rv)
rv3 = pReroll(rv2)
(Note the change in the definition of pReroll this requires.)
A couple of the other answers have it partly right, but you have to put their answers together to get what you want. At the bottom, it should look like this:
aRoll = pQuestion()
pStats(aRoll)
First, you're assigning what pQuestion() returns to aRoll. Next, you're passing that in as a parameter to pStats(). There are a couple things that will happen if you don't do this:
Since you defined a parameter for pstats(), the interpreter will tell you that you're missing a parameter when you try to run this.
Due to the local scope of aRoll, that variable is not defined outside of the function pQuestion().
For more information about variable scope, look here. This page may also prove useful:
http://gettingstartedwithpython.blogspot.com/2012/05/variable-scope.html
pQuestion() returns aRoll but you never assign the return value. pStats() expects you to pass in aRoll but you never do.
You don't return "the variable" but the value of the variable at the point of the return statement. The name of the variable in the function is completely irrelevant. This is a Good Thing: functions are a way to encapsulate pieces of code. Imagine a simple function that adds two numbers:
def add(a, b):
result = a+b
return result
and then the author changes his mind and renames the variable inside the function:
def add(a, b):
sum = a+b
return sum
and finally, he's clever and just does
def add(a, b):
return a+b
As a user of this function, you should not bother about the names inside the function. You use the add function because you expect it to return the sum of the arguments, no matter how the function works internally.
If you want to use the result of a function, you must store it in a variable yourself:
sum_of_2_and_3 = add(2,3)
print(sum_of_2_and_3)
Not to be discouraging, but your code is a long way from working even once we correct the issue with aRoll. You'll probably have to follow up with some other questions.
As for your immediate problem:
aRoll is defined in pQuestion() and only exists for the duration of that function call (it is in scope only within that function).
When you return aRoll in the function the name aRoll is lost and the value of aRoll "pops out" of the function into the calling code. Unfortunately, you're not catching that value so it basically dissolves into the ether, never to be seen again.
In order to catch the value you need to assign it, like this:
answer = pQuestion()
Now, you have a new variable called answer containing the value "popped out" of the function pQuestion() (y or n in this case). Note that you could also write aRoll = pQuestion() and you'd have a variable named aRoll containing the value from pQuestion() but, importantly, it would not be the same variable as the one INSIDE pQuestion() because that one was already lost. While you're learning, it's probably a better idea to use different variable names everywhere so you don't get confused and believe that the same-named variables are actually the same (rather than variables in different scopes that coincidentally share a name)
That's thing one. Next, you have somehow get the value of answer or aRoll or foobar or whatever name you gave to that value into pStats(). You've already told pStats() to expect to receive one value and to name that value aRoll -- but this aRoll, like the first one, is in scope only inside the pStats() function. The problem is, you're not actually supplying the value to pStats(), which you would do like this:
pStats(answer)
or
pStats(aRoll)
or
pStats(foobar)
or whatever name you chose for the variable.
There is another solution to this problem which is to declare the variables as global and not pass them around. I urge you not to pursue this solution as it leads to very bad programming habits and should only be used in rare circumstances after you fully understand the idea of local scope.

Calling a function from a set variable? [duplicate]

This question already has answers here:
Calling a function from string inside the same module in Python?
(2 answers)
Python function pointer
(8 answers)
Closed 9 years ago.
Im writing a python script and what I would like to do is capture the input into a variable and then use that to call a function with that name. Here is an example:
def test():
print "You want to do a test!"
option = raw_input("What do you want to do? ") #User types in test
option()
Now this isnt working since python is not seeing option as a variable but rather is trying to call the function "option". What is the bast way to go about doing this?
eval() will work, but as #MattDMo said it can be dangerous.
A much safer way to do this, if your functions are module globals:
globals()[option]()
globals() is a dictionary mapping strings to the module global objects those strings are bound to. So globals()[option] looks up the string bound to option in that dict, and returns the object; e.g., globals["test"] returns the function object for test(). Then adding () at the end calls that function object. Bingo - you're done.
You want to be very careful about running arbitrary code, but if you absolutely need to, you can use the eval() function.
What might be a better way is to give your user a menu of options, then do testing on the contents of option to see which one they picked, then run that function.
You can use python eval.
From the help page, eval evaluates the source in the context of globals and locals. The source may be a string representing a Python expression or a code object as returned by compile().
For example:
def a():
print "Hello"
inp = raw_input()
eval(inp + "()")
On entering a at the stdin, the function a will be executed. Note that this could be dangerous without any safety checks.
This is, I suppose, an actual use for bare input:
option = input("What do you want to do? ") #User types in test
option()
This is semantically equivalent to eval(raw_input()). Note that in python 3, raw_input becomes input so you will explicitly have to eval it.
The usual caveats of this type of operation being incredibly unsafe apply. But I think that's obvious from your requirement of giving the user access to run arbitrary code, so...
I like using a dict in situations like this. You can even specify a default option if the user provides an answer that isn't expected.
def buy_it():
print "use it"
def break_it():
print "fix it"
def default():
print "technologic " * 4
menu = {"buy it": buy_it, "break it": break_it}
option = raw_input("What do you want to do? ")
menu.get(option, default)()

Categories