Are functions and helper functions treated differently in python? - python

Over here, the main function is g(x) and the helper function is h(). I noticed I can get the output for g(3), simply by binding x=3 and then doing any of the three
print(g(x))
g(x)
z=g(x)
But on the other hand, I noticed h() is outputted only when I type "print(h())". Are my observations correct or did I make a mistake? And also what is the logic behind this weird discrimination?
I like to think of it this way. Usually, if you had a line like "5" or "x=5", python doesn't give an output of 5. But functions have been given a special feature where they are invoked in any of the 3 ways. It's only that this special feature is being 'withdrawn' in the case of helper functions

The code you have written is equivalent to this:
def g(x):
def h():
any_name_you_want = 'abc'
return any_name_you_want
x += 1
print("in g(x)", x)
print(h())
return x
You cannot assign to a non-local variable inside a function. When Python creates the namespace for h, x is local to h because the assignment requires python to add the namespace for x at runtime.
Hence your code is also equivalent to :
def g(x):
def h():
return 'abc'
x += 1
print("in g(x)", x)
print(h())
return x
To get a sense of what is happening, run the following and then read up on UnboundLocalError:
def g(x):
def h():
x = x
return x
x += 1
print("in g(x)", x)
print(h())
return x

Related

Basic Python if statements

I'm learning Python and I'm trying to understand this line if I call f(-1):
x = 0
def f(x):
if x < 0:
return g(-x)
else:
return g(x)
def g(x):
return 2*x + 3
If I call f(-1) I get 5. But I incorrectly interpret that I would get 1. This is my interpretation process:
Since x=-1 it should return g(-x). There is no def g(-x) though. However if it returns def g(x) then we should get 2*x+3, which is 1?
Don't know where I misunderstand.
Thanks
Think of g as the function and x as input to the function.
Furthermore, x is also just like any other variable name.
This means I could instead rename the x variable in the g function to anything I want.
I could also call g anything I want.
Example:
def f(x):
if x < 0:
return grumpy_function(-x)
else:
return grumpy_function(x)
def grumpy_function(cool_value):
return 2*cool_value + 3
Now try to walk through the logic using these above functions...
f(-1) causes the if statement x<0 to be true.
So we will execute the line return grumpy_function(-x)
We know that x=-1, so this means -x = -(-1) = 1.
Therefore cool_value is actually 1 not -1.
Now go to grumpy_function: 2*1+3 = 5.
when call g(-x), in your case, it equals g(-(-1)), which is g(1)
When you specify def f(x) or def g(x), you're saying that, in the following context, x is going to be the name for the actual parameter of these two methods, regardless of the x=0 defined outside.
That being said, the following lines are equivalent:
f(-1)
g(1) # because if x < 0 is True
2 * 1 + 3
5
From your code, it is not exactly clear to me which of the xes you'd like to refer to the global x=0 and which of them should refer to the function's parameter, like -1 in your example. You should make this distinction yourself and name them differently, for example, x and y. As far as I know, if you name your function parameters the same as your global variables, you lose access to the global variables from within the function body (except for globals tricks).

In Python 3.0 a function returns none because a function does not store it’s output unless we use a return statement?

In Python, does a function just execute it’s code block & not store it unless we use a return statement?
When we print variables & expressions I understand we are printing values.
So I am thinking that a function performs it’s code block & then does not save that result unless we return it? Is this what’s happening in the computer?
Example 1
def add(a,b):
nums = a + b
print(add(2,4)+2)
Error
But when we use the return value statement it works
Example 2
def add(a,b):
nums = a + b
return nums
print(add(2,4) + 2)
Output: 8
The error was caused in the first example because the function just executed it’s code block & did not save the result therefore resulting in an error due to not being able to add None to an integer(2)?
&
It worked in example 2 because we saved the functions result with the return statement giving us an integer; Therefore allowing the print statement to print the result of the functions integer + the integer we added it to in the expression?
In python, functions are blocks of code that execute some logic of some sort (sometimes based on arguments passed into them and sometimes not). They are very broad and can do many different kinds of things depending on how they are constructed. I'm not exactly sure what you mean by "store the results" but hopefully some of the following explanation will help.
All variables created in a function are stored with the "local" scope, meaning that they are only existent when the function is running and are deleted the moment the function terminates. For example, in the following code, you cannot access the variable x after the function terminates:
def example():
x = 'Hello World'
print(x) #This prints: Hello World
example()
print(x) #This will give you a Reference error
If that is what you mean by "stores the results" then you are right: those results will not be stored. You can, however, declare a variable inside of a function to be a global variable, meaning that it can be accessed outside of the function too:
def example():
global x = 'Hello World'
print(x) #This prints: Hello World
example()
print(x) #This prints: Hello World
When you use the return statement in a function you are just telling the compiler that if a variable is set equal to a function call of said function, whatever follows the return statement is what that variable should be set equal to. However, simply returning a value does not "store" it. See the following code:
def example():
x = 'Hello World'
return x
example()
print(x) #This will still cause a reference error
x = example()
print(x) #This prints: Hello World
One final thing to note about the code above: as long as two variables are in different scopes, they can have the same name and not cause an error. The x inside the function is in a local scope and the x outside of the function is in the global scope which is why that does not cause an error.
Welcome to Stack Overflow. When I was learning programming, it helped me to think of calls to functions using an analogy to variables in math. In most languages, you can think of "substituting" the return value in for the function call, the same way you can substitute a literal number into a variable.
In math, you can do this:
m = 4
b = 2
y = m * x + b # Plug 4 and 2 in for "m" and "b"
y = 4 * x + 2
It's the same with value-returning functions:
def foo():
return 'bar'
>>> x = foo() # Plug the return value 'bar' in for "foo()"
>>> x
'bar'
In Python, when a function has no explicit return, the default return value is None. So:
def foo():
print('bar')
# No return, so Python implicitly returns None
>>> x = foo() # Plug the return value None in for "foo()"
'bar'
>>> x
None
the function define local variable even same name as global variable so when it executed if you don't return something or store the result in global variable the result not appears outside function
example
x = 10
def test():
x= 15
test()
print(x) # result 10
but if use global keyword you can access to global variable like this
x = 10
def test():
global x
x= 15
test()
print(x) #result 15
or if you return the value
x = 10
def test():
x= 15
return x
x = test()
print(x) #result 15

Python function argument can't be used as a variable in a child function

Here's the problem I try to solve:
I have a first function, to which I put in arguments. Then, later on, I have a second function, from which I want to call, as a variable, the said argument of the parent function. So it goes like:
def parent_function(argument=x):
if statement:
child_function()
else:
...
return result
def child_function():
x = x + 5
return x
If I run such a code, I get an error in the child function saying name 'x' is not defined.
However, if I fix my code to make x global in the parent function, like this:
def parent_function(argument=x):
global x
if statement:
child_function()
else:
...
return result
def child_function():
x = x + 5
return x
I get the error name 'x' is parameter and global
I need to import both functions in another file and I can't "dismantle" the child function inside the parent function.
Thanks very much for any help !
Don't use global Variables. Every function needs it's own arguments:
def parent_function(x):
if statement:
x = child_function(x)
else:
...
return result
def child_function(x):
x = x + 5
return x
name 'x' is parameter and global means you can't overwrite parameter x for being global also. To fix this, use another variable y, like this:
def parent_function(argument=x):
global y
y = x
if statement:
child_function()
else:
...
return result
def child_function():
y = y + 5
return y
This error happens because you are trying to overwrite a parameter in a function whose scope is local to that function by giving it a global scope. The problem is that variables defined in the context of a function are by definition local variables. To better illustrate this problem ,you can simply try to launch this piece of code:
def parent_function(argument="Hello"):
global argument
return argument
You will see that it will fail to run for the same reason that I have explained. I hope I have been clear in my explanation. Good luck.
The first thing you need to change is this:
def parent_function(argument=x):
If you search for how to make a default argument in a function you will get something like this: https://www.geeksforgeeks.org/default-arguments-in-python/
. This means instead of x you need to have some default value, for example:
def parent_function(argument=5):
This means that if you do not pass the argument called argument to the function value 5 will be passed.
On the other hand, it seems that you want x to be an argument, which means the def line should look like this:
def parent_function(x=5):
Second, global keyword needs to be used in the child_function since x has not been used in parent_function. This leads to this:
def parent_function(x=5):
if statement:
child_function()
else:
...
return result
def child_function():
global x
x = x + 5
return x
To have all this work, there must be at least two more lines one to set x and another to call parent_function, like this:
x = 6
parent_function(4)
But, to be even funnier, x from the arguments in parent_function and x used in child_function are not the same thing, and you can see for yourself in this example which is similar to your code, but fully executable:
def parent_function(x=5):
if True:
print(child_function())
else:
print("else branch")
return True
def child_function():
global x
x = x + 5
return x
x = 6
parent_function(4)
This prints out 11 even you might think it will print out 9!
This is due to fact that keyword global refers to the (as the word says) global variable declared outside of the functions, the variable with value 6. Usually, local and global variables should have different names, so either the argument x in parent_function or global x variable needs to be renamed.
IDK if this helps, but you will learn something from this, for sure!

Local variable referenced before assignment error python

def outside(x=1):
def printHam():
x = x+1
print x
return printHam
myfunc = outside(7)
myfunc()
This doesn't works gives error Local variable referenced before assignment error python
However this works
def outside(x=1):
def printHam():
print x + 1
return printHam
myfunc = outside(7)
myfunc()
Because you are assigning x in the first case, python will assume x is a local variable (which is the default). In the second case you aren't assigning it so it will check the global scope.
If you want this example to work, you have to pass the outer x into the inner function like so:
def outside(x=1):
def printHam(x=x):
x = x+1
print x
return printHam
That being said, this seems like a horribly contrived use case, so there's probably a better solution for your actual use case. But I can't tell you what it is without knowing more about what you're trying to do.

Using a list from one function, inside another function python

I am new to python. This might be a simple question, but if I have many functions that are dependent on each other how would I access lists from one function to use in another.
So...
def function_1():
list_1=[]
def function_2():
list_2= [2*x for x in list_1]
def function_3():
list_3= [x * y for x, y in zip(list_1, list_2)]
That is not the exact code but that is the idea of my problem. I would just put them all together in one function but I need them to be separate.
The correct way to do this would be to use a class. A class is an object that has internal variables (in your case, the three lists), and methods (functions that can access the internal methods). So, this would be:
class Foo(object):
def __init__(self, data=None):
self.list_1 = data if not data is None else []
def function_2():
self.list_2 = [2 * x for x in self.list_1]
And so on. For calling it:
foo = Foo() # list_1 is empty
foo2 = Foo([1,2,3]) # list_1 is not empty
foo2.function_2()
print foo2.list_2
# prints [2, 4, 6]
Make them arguments and return values:
def function_1():
return []
def function_2(list_1):
return [2*x for x in list_1]
def function_3(list_1, list_2):
return [x * y for x, y in zip(list_1, list_2)]
(this suggests that function_1 isn't much worth having...)
The exact way will depend on exactly how you want things to work, but here is a simple example:
def function_1():
return []
def function_2():
return [2*x for x in function_1()]
def function_3():
return [x * y for x, y in zip(function_1(), function_2())]
The key point is that functions do not generally just "do" things, they return things. If you have a value in one function that you want to use in another function, the first function should return that value. The second function should call the first function, and use its return value.
Functions are basically black boxes -- the outside world doesn't really know what goes on inside or what variables exist there. From the outside, other code only sees what goes in (the function's arguments) and what goes out (its return value).
So if your function computes some value that is to be used elsewhere, it should be returned as the result of the function.
E.g.,
def square(x):
return x * x
Takes a number, computes its square, and returns it.
Then you could do:
print(square(5))
and it will print 25.
So in your case you can return the lists and use them in the other functions, as the other answers showed:
def function_1():
return []
def function_2():
return [2*x for x in function_1()]
def function_3():
return [x * y for x, y in zip(function_1(), function_2())]

Categories

Resources