Function Return But No Value - python

I have a function defined which includes a return statement but no value is handed back. My code is as follows:
def seed(addy):
# urllib2 stuff is here
seed_result = re.search('<td>Results 1 - \d+ of (\d+)',seed_query) # searches for '<td>Results 1 - x of y', captures 'y'
seed_result = seed_result.group(1) # this is 'y' from above
# there's a call to a different function here which works properly
# other stuff going on here pertaining to addy but seed_result still has my string
# now I want to return the seed_result string...
return seed_result
# ... some code outside of the seed function, then I call seed...
seed(addy)
print "Result is %s" % seed_result
I have tried this with and without defining seed_result outside of the function to "initialize" it but this has no impact on the outcome which is that my print statement at the end yields "Result is " - there's no seed_result. I have also wrapped seed_result in parenthesis in the return statement though I believe how I have it is correct. The parens didn't make a difference.
A set up a very basic, yet similar, function in the Python shell and called it as I do here but that works. Not sure what I'm missing.
Thanks for the feedback and guidance.

You're not using the return value (e.g. assigning it to a variable). Try this:
result = seed(addy)
print "Result is %s" % result

Two ways of solving this:
First, the proper, obvious, and easy way is actually using the returned value:
seedresult = seed(addy)
Or you use a global variable (bad style - avoid at any cost):
seedresult = None
def seed(addy):
global seedresult
...

This is caused by None being assigned to seed_result during the execution of your function.
As Jon Skeet identified, you are doing nothing with the return value of your function. You should also address the issues below, though.
In particular, you are doing nothing with the parameter addy, and searching a global variable seed_query. I imagine the behaviour you are seeing is a result of that.

Related

Why does this not print None then 7? Python

So I have this code and call me an idiot haha, but I cant get this to print None then 7.
Code:
def function(parameter):
parameter = parameter + 1
parameter = 6
print(function(parameter))
print(parameter == 7)
I need to know how to alter the variable that has the same name as the parameter in the function.
Any help would be greatly appreciated, and if you don't understand the question I'd be glad to explain more.
It prints None because your function() doesn't return anything.
It prints False because parameter (which is currently 6) does not equal 7.
To alter the global variable which is being masked by the local variable, use the globals() function:
def function(parameter):
globals()['parameter'] += 1
Since I truly hate globals variable this is how I would do it:
def function(parameter):
return parameter + 1
parameter = function(6)
print(parameter)
print(parameter == 7)
Output
7
True
Basically, by specifying a variable with the same name as the parameter and assigning the function you can alter parameter as if it was the same variable. Note that this is not the case, it is not actually the same object. But if your goal is to use the same name it works.
Define parameter as global and don't actually pass it as parameter:
def function():
global parameter
parameter += 1
What you can do is refer to it as a global. What will probably help you better is to use the concept of functions for what they are: provided any given input, they produce some result.
So, you'd probably want to use a return:
def fun(val):
return val;
parameter = val(10)
print(parameter) # prints '10'
However, if you want to refer to the variable, in python you can do all sorts of crazy stuff, like accessing the module scope as an object and alter it's value there:
def fun(val):
import sys;
sys.modules[__name__].parameter = val
parameter = 10
fun(1)
print(parameter) # prints '1'
However, there's a reason I call this crazy, and that's because if a function has side effects, you can never tell from the outside. And that is complexity you want to avoid. Because your code should be predictable as much as possible. For obvious reasons.
Using globals is neither thread safe nor recommended. Looks like the cleanest solution 'd be to pass your parameter argument in a mutable container. See https://docs.python.org/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference

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()

How can I have my function called again after storing its result in a variable, each time the variable is accessed?

I have a concept where I store values returned by functions in variables which makes it easier for me.
But I am having the problem that the value in the variable isn't dynamically calling the function each time. So it returns the same value all the time.
I have made a code snip to illustrate it in a easy way:
def value():
resp = requests.get('http://www.google.com').elapsed.total_seconds()
return resp
test = value()
while True:
print test
time.sleep(10)
Output:
0.00649
0.00649
In this case, in the while true when I print test, it returns the same value, even though I am calling the function value(). How can I solve this issue? I know I can put the function in the while loop, but I want to have it as a variable.
The previous answers are correct, but please let me elaborate.
In the world of Python, things have very precise meanings but it's not always clear what is what if you are just getting started.
Expressions are things that have a value, and they include things like 123, some_variable and 10 / 2. The name some_variable is called an identifier, simply because it identifies a value. Just like the name Scruffy might identify your dog.
Statements are things that affect the program flow or the state of your program, but lack a value. The following are examples of statements:
if x > 10:
x -= 1
And
def foo(x):
print("The value of x is", x)
Unlike in JavaScript, for example, where almost everything is an expression (and has a value), you can not do this:
my_function = def foo(x): print("The value of x is", x)
The previous def statement will create a function by the name foo, but the statement itself doesn't have a value. The name foo will refer to a value, however. It means that when you write foo, the value will be a thing, and this thing is a function!
The expression x() on the other hand will do two things. First it will look up the value of the identifier x. Hopefully this value is a function. After that, the parentheses means that the value will be called. What happens if x is not a function, then?
>>> x = 10
>>> x()
Traceback (most recent call last):
File "<ipython-input-3-7354d77c61ac>", line 1, in <module>
x()
TypeError: 'int' object is not callable
Big Fat Error: 10 is not a "callable". Callable means something that can be called like a function.
The parentheses are, as you probably know, a list of arguments. In this case the list is simply empty so when you write x() you are saying "call whatever the name 'x' is referring to but don't send any arguments".
A function call always has a value, since it's an expression. If you don't explicitly return anything, the value will simply be None.
To answer your question, finally, let's play the substitution game. The rules are simple, any expression can be replaced by its value:
def value():
resp = requests.get('http://www.google.com').elapsed.total_seconds()
return resp
This is a statement, so it doesn't have a value. A function is created with the name value, however.
The function consists of two statements (no value, again), a variable assignment and a return statement.
The thing to the right of the = is an expression however. Short story:
requests is referring to the requests module
get is referring to a module-global function in the above module
get('...') is calling this function, and something is returned.
The "something" has a property called elapsed, which has a property called total_seconds.
total_seconds is an identifier that refers to a callable. The callable is called without any arguments (total_seconds()) and something is returned. Probably a number, based on the name. Let's say its value is always 10, for simplicity.
The next statement is another assignment:
test = value()
This can be thought of as "let the name 'test' refer to the value that is returned by the callable identified by the name 'value' when it is called with an empty argument list". In our case, the function object called value will be called, resp will be assigned the value 10, then the return statement will let the caller know that this call is sending the value 10 back. The name test will refer to the value 10, from now on.
Let's go over the loop, quickly:
while True:
print test
time.sleep(10)
Do the following until the end of Time:
print (a statement in Python 2, an expression in Python 3!) has the side-effect of printing stuff to the screen. Otherwise it doesn't do much.
The stuff, in this case, is whatever the value of the expression test is. We already know that the identifier test is referring to the value 10. It will simply print "10" to the screen.
Sleep for ten seconds.
Repeat.
You probably want to invoke some function at each iteration of the loop ("invoke" is basically latin for "call", I like fancy words). Otherwise the program will just print "10", "10", "10", over and over again. To fix this this, you first have to change the expression evaluated as part of the print statement from just an identifier (test) to a function call:
print test()
But this will, as we saw before, raise a Big Fat Error since 10 is not a callable function. To fix it (that's what programmers do, right?) you also need to change the value of test from 10, since it's not a callable, to the function. A function can be referred to simply by its name, so just change this line:
test = value() # equals ten
To this:
test = value # equals the function called "value"
The function now has two names, the old name "value", and the new name "test". Each step in the loop will request the page again and return the new time it took for the request to complete. If the request times out you will have a different kind of crash, but that's another story.
Further information can be found in the Python Language Reference.
test = value() isn't storing the function it's storing the results. You should just call value() in your loop or if you want to assign the function it would be test = value and then test() in your loop.
test = value() calls the function and stores the return value. It does not store the function. test = value would store the function, but the you need to print test() in order to call it.
def value():
resp = requests.get('http://www.google.com').elapsed.total_seconds()
return resp
test = value
while True:
print test()
time.sleep(10)
You can change your code like this..
def value():
resp = requests.get('http://www.google.com').elapsed.total_seconds()
return resp
test = value()
while True:
print test
time.sleep(10)
change this line
test = value
to
test = value()
Now means you are storing your function in a variable.

Parentheses in Python's functions and decorators(wrappers)

Thanks for reading my question. As I'm still new to Python, I would like to ask about the () in Python.
def addOne(myFunc):
def addOneInside():
return myFunc() + 1
return addOneInside # <-----here is the question
#addOne
def oldFunc():
return 3
print oldFunc()
Please note that on line four, although the programme returns a function, it does not need parentheses(). Why does it NOT turn out with an error for syntax error? Thank you very much for your answers in advance!
The parentheses are used to run a function, but without them the name still refers to the function just like a variable.
return myFunc() + 1
This will evaluate the myFunc function, add 1 to its value and then return that value. The brackets are needed in order to get the function to run and return a numeric value.
return addOneInside
This is not actually running addOneInside, it is merely returning the function as a variable. You could assign this to another name and store it for later use. You could theoretically do this:
plusOne = addOneInside
plusOne()
And it will actually call the addOneInside function.
The particular instance in your initial question is known as a Decorator, and it's a way for you to perform code on the parameters being passed to your function. Your example is not very practical, but I can modify it to show a simple use case.
Let's say that you want to only have positive numbers passed to your function. If myFunc is passed a negative number, you want it to be changed to 0. You can manage this with a decorator like this.
def addOne(myFunc):
def addOneInside(num):
if num < 0:
num = 0
return myFunc(num)
return addOneInside # <-----here is the question
#addOne
def oldFunc(number):
return number
To explain, the #addOne is the decorator syntax, and it's attaching the addOneInside function to be called on the argument/s of oldFunc whenever you call it. So now here's some sample output:
oldFunc(-12)
>>> 0
oldFunc(12)
>>> 12
So now you could add logic to oldFunc that operates independently of the parameter parsing logic. You could also relatively easily change what parameters are permitted. Maybe there's also a maximum cap to hit, or you want it to log or note that the value shouldn't be negative. You can also apply this decorator to multiple functions and it will perform the same on all of them.
This blogpost explained a lot for me, so if this information is too brief to be clear, try reading the long detailed explanation there.
Your indentation in function addOne() was incorrect (I have fixed it), but I don't think that this was your problem.
If you are using Python3, then print is a function and must be called like this:
print(oldFunc())

Why inspect.stack() does not work properly?

I'm trying to write name of the current executed function. But it does not work properly.
When I put 'print inspect.stack()[0][3]' after the def func(), it works, but when I try to put this command after the if, it prints nothing.
import inspect
debug = True
def debug():
print inspect.stack()[0][3]
if debug==True:
print "test"
print inspect.stack()[0][3]
debug()
returns 'debug' but it should return
'debug'\n'test'\n'debug'
Where is the problem?
When you define the function:
def debug():
you are loosing the last reference to the previously created variable debug from the global scope. You redefine the debug variable from being a boolean holding True to a function reference. So the condition debug==True is not met (because debug is a function now, not a boolean). And thus only the first print statement works (see an illustrative demo).
This will work as intended, for example:
import inspect
debug = True
def f():
print inspect.stack()[0][3]
if debug==True:
print "test"
print inspect.stack()[0][3]
f()
This is a common mistake in Python, especially from people used to other languages, in which function names are treated in a special way. In Python they are not - after you define a function, you can use its name as any other variable. Which has many advantages, but as seen here sometimes can be confusing.
In python 3 and hight you need to use print () if. It becomes a syntax error and won't print any thing if you don't have the ()

Categories