How to call my function in another function - python-3.x

I am getting an value from the user in getInteger.
I need to get the output from sqInteger in getInteger.
No matter how I set up the parameters or indent the sqInteger function, variable x is undefined.
I added a return line to try and pass the x variable, but that's definitely not helping.
Please help me understand what I'm missing!
def getInteger():
while True:
try:
x = int(input('Enter an integer: '))
except ValueError:
print()
print('That\'s not an integer. Try again.')
continue
else:
return x
print(x)
break
def sqInteger(getInteger, x):
y = x**2
print(y)

Is this the entire code? You need to call the getInteger() function at some point in the code before that loop will begin. You're also not calling function sqInteger() at any point.
Your exception handler will immediately stop evaluating the try block and move down to the except block upon a non-integer being typed into the input. Therefore, you can place a call to the sqInteger() function after the input() function. If the user types a non-integer into the terminal, it will move down to your Exception handler and prompt the user to retry. If they enter an integer, the code will continue to evaluate and run the function sqInteger.
For this, you also do not need to pass getInteger into the sqInteger() function. You are technically allowed to pass functions as parameters in Python but it's not necessary for this and probably out of the scope of this program.
So the following code would be suitable:
def getInteger():
while True:
try:
x = int(input('Enter an integer: '))
# variable 'squared' now receives the return value from the function
squared = sqInteger(x) # call to function sqInteger necessary for this function to be executed
except ValueError:
print('That\'s not an integer. Try again.')
continue
else:
print(x) # if user entered 2, prints 2, not 4
return x # this value is still only what the user input, not the result of sqInteger()
break
def sqInteger(x):
y = x**2
print(y)
return y #you need to return values from functions in order to access it from outside the function
The reason you pass a variable into a function (as a parameter) is to give that function access to that variable. Creating a function creates a local scope for that function so that variables named within that function are in a separate namespace from variables outside that function. This is useful in large programs where many variables might exist and you need to keep them separate.
Because you've separately defined a sqrt function, it does not have access to variables outside of its scope. You need to pass in variables that you'd like it to have access to.
You also need to call functions before they will run. Defining a function only serves to set up the function so that it can be called as one functional unit. It's useful for separating concerns within a program. The ability to call a function is useful because it allows you to separate your code out and only mention a single call to a function rather than having the entire functionality jumbled in with the rest of the code. It also allows for reusability of code.
You can also have access to the result of the squared integer by returning a value and assigning this value to a function call, like such:
# lets say x = 4
squared = sqInteger(x)
def sqInteger(x):
y = x**2
return y
This would NOT work:
x = input("Enter integer") #lets say you enter 3
squared = sqInteger()
print(squared)
def sqInteger():
print(x) # error: x is not defined
return x**2 # error: x is not defined
The function does not have access to outside variables like x. It must be passed these variables as parameters so that you can call this function and set the parameters at will. This is for the sake of modularity in a program. You can pass it all sorts of different integers as parameters and it allows you to have a resuable function for anytime you need to square an integer.
Edit: Sorry this was a mess, I finally fixed all the errors in my explanation though...

Related

Functions - Variables - Scope

I have the below code.
a = 10
def f(x):
return x + a
a = 3
f(1)
If we print(f1) the result is 4. It seems that the second assignment of a is used here (a=3). Could someone explain to me if there is a particular reason or rule for not using the first assignment (a=10)?
Thank you,
Dimitrios
a and x are resolved each time return x + a is executed. You reassign a before calling f. f knows that a is not a local variable so looks up "a" in its enclosing scope. That "a" has a 3 in it, and that is what is used.
As a general rule, it would be very bad for f to use the original assignment when its executed. That would mean that functions couldn't take advange of global variables changing. It would also require that global variables be assigned before the function is even defined, which is not particularly useful for a dynamic language.
You can hack it, though. If you define a parameter with a default value, it will be assigned when the function is defined and you get what you want.
a = 10
def f(x, a=a):
return x + a
a = 3
print(f(1))
You see, you've defined a before you defined f(x). But your call to f(1) was after you assigned the value 3 to "a".
f(x) will always use the current value of "a" when it its called, not when it is defined. If you want a constant value for "a" inside f(x), you should declare it inside the function, something like:
def f(x):
a = 10
return x + a

What's wrong with my python recursive code?

Sorry for my ugly English.
This is one of my homework.
I'm making function that finds the max integer in any list, tuple, integer..
like "max_val((5, (1,2), [[1],[2]])) returns 5"
When I ran my code, there was no syntax error. I ran as many various cases I can.
But the homework system told me this code was incorrect.
Anyone give me hint?
numList = []
def max_val(t):
if type(t) is int:
numList.append(t)
else:
for i in range(len(t)):
if t[i] is int:
numList.append(t[i])
else:
max_val(t[i])
return max(numList)
Your code gives wrong results when called several times:
>>> max_val((5,4,3))
5
>>> max_val((2, 1))
5
That's because numList is a global variable that you don't "reset" between calls of your function.
You can simplify your code quite a bit, without needing that global variable:
def max_val(t):
if isinstance(t, int):
return t # t is the only element, so it's by definition the biggest
else:
# Assuming max_val works correctly for an element of t,
# return the largest result
return max(max_val(element) for element in t)
As explained in L3viathan's answer, the main issue with your code is that numList is a global variable. Here is a simple way to fix it without changing the logic of your code:
def max_val(t):
numList = [] # local variable
max_val_helper(t, numList) # fill numList with elements from t
return max(numList)
def max_val_helper(t, numList): # this function modifies its second argument and doesn't return a value
if type(t) is int:
numList.append(t)
else:
for i in range(len(t)):
max_val_helper(t[i], numList)
The function max_val_helper is recursive and appends all numbers in the nested iterables to its argument numList. This function doesn't have a return value; the effect of calling it is that it modifies its argument. This kind of function is sometimes called a "procedure".
The function max_val, on the other hand, is a "pure" function: it returns a value without any side-effect, like modifying its argument or a global variable. It creates a local variable numList, and passes this local variable to max_val_helper which fills it with the numberss from the nested iterables.
The code suggested in L3viathan's answer is arguably more elegant than this one, but I think it's important to understand why your code didn't work properly and how to fix it.
It's also good practice to differentiate between functions with side-effects (like modifying an argument, modifying a global variable, or calls to print) and functions without side-effects.

Receiving function as another function´s parameter

Let´s say I have 2 functions like these ones:
def list(n):
l=[x for x in range(n)]
return l
def square(l):
l=list(map(lambda x:x**2,l))
print(l)
The first one makes a list from all numbers in a given range which is "n" and the second one receives a list as a parameter and returns the squared values of this list.
However when I write:
square(list(20))
it raises the error "map object cannot be interpreted as an integer" and whenever I erase one of the functions above and run the other one it runs perfectly and I have no idea what mistake I made.
You redefined the standard function list()! Rename it to my_list() and clean the code accordingly.
As a side note, your function list() is doing exactly what list(range(n)) would do. Why do you need it at all? In fact, for most purposes (including your example), range(n) alone is sufficient.
Finally, you do not pass a function as a parameter. You pass the value generated by another function. It is not the same.

Function changing variables outside of the function (that is not Returned by the function)

First off really sorry for the nondescript title, I don't know how to phrase my question.
Given the code below:
x = [9]
y = [2,4,6]
def f(x, y):
if len(x) > 0:
z = x + y
x.pop(-1)
return z.pop(0)
print(f(x,y)
print(f(x,y))
The second print line gives me an UnboundLocalError: local variable 'z' referenced before assignment
I understand what this error is, as the function is skipping the if clause and going straight to the return z.pop(0), but z doesn't exist because z is defined in the if clause.
What I would like to know is why the value of x is changed by the function
The function skips the if loop because after the first call, x has been changed from x = [9] to x = []
I thought that unless it is a Return statement, then any variables changed or created within a function are local to the function?
For example, geeksforgeeks.org states that
Any variable which is changed or created inside of a function is local, if it hasn’t been declared as a global variable
So why is the value of x changing when it hasn't been returned by the function? Shouldn't the value of x always be [9]?
Thank you
Lists are mutable. When you pass one into the function then you are really passing in a pointer to the list. It's better to think of Python as pass by reference than pass by value. The x you are changing is not created in the function it is passed in as an argument. You're not changing x (the memory address pointed to by the label x), you're changing the contents of that memory address.
See this answer Python functions call by reference

how to use a raw_input as argument in a function in python 3

I'm trying to write a simple program with python 3 for practice. What I want to do is draw a function that takes an user input() as argument. I have tried storing the input() in a variable, but everytime I try to proceed the variable calls itself asking for the input(), so it doesn't store anything. I have also tried something like this:
def function(input('give me a '), input('give me b ')):
# do stuff with the inputs
but it gives syntax error in the parenthesis.
Any idea on how to set a function to use user's input() as arguments?
It depends on what you are trying to do. Most likely you want to pass the user input to the function call rather than the definition:
def function(a, b):
print(a, b)
a = input('give me a ')
b = input('give me b ')
function(a, b)
However, if you want to pass a given user input as the default argument to a function, you could do it like this:
def function(a=input('give me a '), b=input('give me b ')):
print(a, b)
function() # prints whatever the user inputted when the file was initially run
The reason your code raises an exception is because the content in the () in a function definition (as opposed to a function call, i.e., function()) is the names of the parameters rather than the arguments passed to the function. You can use input() in this part of the function signature only if you assign it as a default value to be associated with a parameter name, as I did above. This second use case seems pretty strange though, and every time function() is called it will be passed the same arguments as defaults that the user initially entered. Even if that is what you want to do, you should probably do this instead:
input_a = input('give me a ')
input_b = input('give me b ')
def function(a=input_a, b=input_b:
print(a, b)
function()
Alternatively, if you want to get a different pair of inputs every time the function is called (this actually seems most likely now that I think about it):
def function():
a = input('give me a ')
b = input('give me b ')
print(a, b)
You should know that inputs are considered as strings. When you want to use their value, try doing int() in the code.
If you use the named arguments with them set to default values with input(), it seems that all the parameters have to be inputs as well. But if you set a variable to a default value without input, that can be used with just other variables as parameters.

Resources