Python: Return possibly not returning value - python

Hello Stack Overflow Community,
I am trying to write a program that checks Fermat's Last Theorem. The issue I am running into is that an error appears saying "NameError: name 'a' is not defined. However, I define 'a' in my first function and return its value at the end of the function.
I am trying to use the inputed values from the first function in the second function so the user can define the parameters.
Am I misunderstanding how to leverage "Return"? All help is greatly appreciate and will keep me sane.
def input_fermat():
a=input('Enter the first variable \'a\': \n')
b=input('Enter the second variable \'b\': \n')
c=input('Enter the third variable \'c\': \n')
n=input('Enter the exponential variable \'n\': \n')
return a, b, c, n
def check_fermat(a,b,c,n):
calc_1=a**n
calc_2=b**n
calc_3=c**n
if n>2 and int(calc_1) + int(calc_2) == calc_3:
print('Holy smokes, Fermat was wrong!')
else:
print('No that doesn\'t work.')
input_fermat()
check_fermat(a,b,c,n)

The variables a, b, c, n defined in input_fermat only exists within the function, that's why you return them, but when you call the function you aren't saving them anywhere. You should replace:
input_fermat()
By:
a, b, c, n = input_fermat()
Or you can directly pass the return value of input_fermat to check_fermat like this:
check_fermat(*input_fermat())

You are not storing the values that the function input_fermat returns. Try:
a, b, c, n = input_fermat()
check_fermat(a,b,c,n)

This is happening because those variables are defined locally and are not available in check_fermat's namespace.
Refer to the LEGB-rule.
What you can do is define all of those variables using the global keyword in the function definition, although this isn't usually the best approach. You'll also want to cast all of your inputs to ints since input() will return a string.

Returned values don't just automatically show up in your namespace, you have to assign them to something.
a, b, c, n = input_fermat()

Variables a,b,c and n, which you receive as input in input_fermat(), are only available within the body of that function; once you return, you're out of input_fermat()'s scope and the values in a,b,c and n are handed off to whatever variables you called input_fermat() to assign .
A function's scope means the only variables available in any given function are
those that are declared in the body of the function
those passed to the function as arguments in parentheses.
variables declared globally
In check_fermat(),this means you could re-use variables a,b,c and for something other than the input, if you wanted (because a new function means a new scope).
But, in the code shown below, we decide that a,b,c and n in check_fermat() are going to be the same thing as a,b,c and d in input_fermat() with the declaration a,b,c,n = input_fermat(). This is a decision we chose to make; it's arbitrary.
Here's an edited version of your function that accomplishes what I think you were going for:
#Global variables would be declared up here, before all other function declarations.
#Global variables would be available to all the functions that follow.
def input_fermat(): #if there were arguments in these parentheses they'd be included in input_fermat scope
# input_fermat() scope begins
a=int(input('Enter the first variable \'a\': \n'))
b=int(input('Enter the second variable \'b\': \n'))
c=int(input('Enter the third variable \'c\': \n'))
n=int(input('Enter the exponential variable \'n\': \n'))
return a, b, c, n
#input_fermat() scope ends
def check_fermat(): #if there were arguments in these parentheses they'd be included in check_fermat scope
#check_fermat() scope begins
#just as you returned 4 variables at once in input_fermat(), 4 variables can be assigned at once here
a,b,c,n = input_fermat() #need to assign because a, b, c, n from input_fermat() no longer in scope
calc_1=a**n
calc_2=b**n
calc_3=c**n
if n>2 and int(calc_1) + int(calc_2) == calc_3:
print('Holy smokes, Fermat was wrong!')
else:
print('No that doesn\'t')
#python implicitly does a `return None` here
#check_fermat() scope ends
check_fermat()
Note that because of the scopes of these functions, I could have declared the variables in check_fermat() as follows and it would all still work (try running this code for yourself to see)
def input_fermat():
a=int(input('Enter the first variable \'a\': \n'))
b=int(input('Enter the second variable \'b\': \n'))
c=int(input('Enter the third variable \'c\': \n'))
n=int(input('Enter the exponential variable \'n\': \n'))
return a, b, c, n
def check_fermat():
any,variable,names,go = input_fermat()
calc_1=any**go
calc_2=variable**go
calc_3=name**go
if n>2 and int(calc_1) + int(calc_2) == calc_3:
print('Holy smokes, Fermat was wrong!')
else:
print('No that doesn\'t')
check_fermat()
The Process of execution (for both code snippets) goes like this:
check_fermat() on the last line is executed because it's the only function called (not just defined) in our .py file.
Python looks for the definition of check_fermat() to execute it
3.Python finds input_fermat() is called inside check_fermat and goes looking for input_fermat()s definition.
Python finds the definition, executes the function and asks for input.
Input is returned back to check_fermat() and is used to compute Fermat's Last Theorem.
The rest of check_fermat() is carried out (output is printed to terminal). Then, check_fermat() returns None, ending the function call with no variables to return.

Related

How to reuse a variable

I have the variable total in a function. Say that I'd like to use that variable in an if statement in another function. I can use the return keyword and return that variable from my first function but how would I use that variable in an if statement that would be outside that function or even in a different function?
You could re-declare the variable with the value from the function. I don't have a lot of information, but I think this is what you mean.
def some_function():
total=10
return total
total=some_function()
print(total)
return the value from your first function, and then a call to that function will evaluate to that value. You can assign the value to a variable, or pass it directly to another function. In either case, the value doesn't need to be assigned to the same variable name in different scopes.
def func_a():
total = 42
return total
def func_b(the_answer):
if the_answer == 42:
print("That's the answer to the ultimate question!")
func_b(func_a())

Dictionary - printing result multiple times?

I'm coding this program but running it and typing "2" when I type a subject it doesn't print the result once but nine times. Where is the problem? 9 is the number of subjects in the list named mat so it's strictly connected. Now to check some files .txt as placeholder but I'd like also using the module json.
import os
def spat():
a=len(list(os.listdir('C:/Users/SUINO/Desktop/python/prob/cache/'+y)))
print(a)
b=100/(25-a)
print(b)
mat=["latino","greco","storia","latino","scienze","matematica","grammatica",
"promessi sposi,","eneide"] #mat means subject
c=input("Do you want to add a placeholder or calculate probabilties? 1|2: ")
if c == "1":
c=input("Insert a subject: ")
c=c.lower
if c in mat:
name=input("Insert the name of the student: ")
open('C:/Users/SUINO/Desktop/python/prob/cache/'+c+'/'+name+".txt")
else:
print("Materia non esistente!")
if c == "2":
y=input("Materia: ")
y=y.lower()
x={"latino":spat(),"greco":spat(),"eneide":spat(),"promessi sposi":spat(),
"mate":spat(),"grammatica":spat(),"storia":spat(),"scienze":spat(),
"inglese":spat(),}
The objective of the program is to calculate the probabilities of being interrogated using the files .txt that have as name the name of the student interrogated yet.
If I understand your question correctly, you're basically trying to create a CLI for accessing homework or other school work that students can interact with and access their files.
I just noticed you are also trying to access var y within function spat(). You need to pass this value into the function call. If you want to map each key to the function.
If you want the key to be a reference, you need to structure your dict like this:
x = {
'latino': spat,
'greco': spat,
...
}
Then when the user enters in a value, you simply declare a new variable to be the value of the key, which in turn, creates a variable which is a reference to that function.
So if you receive input y with
y = input("Materia: ")
Then you should create a new variable like such
func = x[y]
This will find the key value entered in from the above input function and assign that reference to the variable func. Essentially, func now is equal to the function and you can execute func like any other normal function as well as pass in variables.
func(y)
This will execute the function referenced (spat) and pass in variable y. You also need to rewrite spat() as such:
def spat(y):
a = len(list(os.listdir('C:/Users/SUINO/Desktop/python/prob/cache/'+y)))
print(a)
b = 100/(25-a)
print(b)
Essentially the same except you're now passing in y from the input below.
You also need to move the declaration of the dictionary to the top so that your reference to this dictionary will be recognized when you declare func.
So whole code:
import os
def spat(y):
a = len(list(os.listdir('C:/Users/SUINO/Desktop/python/prob/cache/'+y)))
print(a)
b=100/(25-a)
print(b)
x = {"latino":spat,"greco":spat,"eneide":spat,"promessi sposi":spat,
"mate":spat,"grammatica":spat,"storia":spat,"scienze":spat,
"inglese":spat,} # x moved up from bottom
mat = ["latino","greco","storia","latino","scienze","matematica","grammatica",
"promessi sposi,","eneide"] #mat means subject
c = input("Do you want to add a placeholder or calculate probabilties? 1|2: ")
if c == "1":
c = input("Insert a subject: ")
c = c.lower
if c in mat:
name = input("Insert the name of the student: ")
open('C:/Users/SUINO/Desktop/python/prob/cache/'+c+'/'+name+".txt")
else:
print("Materia non esistente!")
if c == "2":
y=input("Materia: ")
y=y.lower()
func = x[y] # creates reference to the key which is a ref to a function
func(y)
However, since every key value is executing the same function, you might be better served not writing new dictionary entries for each new key and just simply making a list of recognized subjects that the student may enter:
subjects = ['latino', 'greco', 'grammatica', ...]
Then you can simply check whether the input exists within this list and, if it does, run spat() and pass in y.
if y in subjects:
spat(y)
else:
print("Unrecognized command...")
Mapping functions within a dictionary is useful for creating an 'interface' that can route the various inputs to a function that will be executed for that given option. You can check whether or not their command works by simply checking for their input within a list/dict and if it doesn't exist, then you can skip running the function and output an error message--if the command exists, then you can reference it to a key value (which in turn, references it to the value of that key) and then it will run the proper function.
The short answer is it's printing nine times because of all the calls to spat() you put in the statement:
x={"latino":spat(),"greco":spat(),"eneide":spat(),"promessi sposi":spat(),
"mate":spat(),"grammatica":spat(),"storia":spat(),"scienze":spat(),
"inglese":spat(),}
There are a number of other issues with your code, but since I don't completely understand everything it's trying to accomplish, I'm not going to attempt to tell you what to do other than not to call it some many times like that.

How to make global empty integer?

How to declare global empty integer? I have simple code but i don't know how to declare a variable before def. In java I can do just that: public int a;
but how to do it in python? Without this, the third if not working
My code:
def abcd:
if s<0.72:
if e>30:
a=0
return a
else:
a=0
return a
else:
if a == 1:
a = 1
return a
else:
a=1
return a
while True:
abcd
Python is dynamic, so you don't need to declare things; they exist automatically in the first scope where they're assigned. So, all you need is a regular old assignment statement as above.
You can declare as follow, if you want a non-value variable:
a = None
Or you can declare as follow, if you want a zero value int variable:
a = int()
At the top:
a = int()
int() returns 0 to start.
Also, you need to use proper function syntax:
def abcd():
If e or s are arguments passed to abcd, you need to add those to the function signature:
def abcd(e, s):
Python is a dynamic language with duck typing. So if you gonna declare an empty variable use None as it's initial value. That means no value.
Yes dont make it equal to zero, depending on what you are doing your program will not work if equal to zero.
REMEMBER ZERO IS NOT THE SAME AS NONE

Python - Name is not defined in a function variable?

I seem to be somehow screwing up the most basic thing. I have:
def function(a, b, c):
return 'hi'
print(function(a,b,c)) results in a NameError for every variable.
What is the cause of this?
The names of the arguments of a function are local variables, they are not available as global names. a, b and c exist only inside of the function, and receive the values you pass to the function.
You need to create new variables or use literal values when calling the function:
print(function(1, 2, 3))
would work because 1, 2 and 3 are actual values to pass into the function.

Do you change variables AFTER you run a function in python?

So I wrote this function from a book I am reading, and this is how it starts:
def cheese_and_crackers(cheese_count, boxes_of_crackers):
print "You have %d cheeses!" % cheese_count
print "You have %d boxes of crackers!" % boxes_of_crackers
print "Man that's enough for a party!"
print "Get a blanket.\n"
ok, makes sense. and then, this is when this function is run where I got a little confused and wanted to confirm something:
print "OR, we can use variables from our script:"
amount_of_cheese = 10
amount_of_crackers = 50
cheese_and_crackers(amount_of_cheese, amount_of_crackers)
the thing that confused me here is that the amount_of_cheese and amount_of_crackers is changing the variables (verbage? not sure if i am saying the right lingo) from cheese_count and boxes_of_crackers repectively from the first inital variable labels in the function.
so my question is, when you are using a different variable from the one that is used in the initial function you wrote, why would you change the name of the AFTER you wrote out the new variable names? how would the program know what the new variables are if it is shown after it?
i thought python reads programs top to bottom, or does it do it bottom to top?
does that make sense? i'm not sure how to explain it. thank you for any help. :)
(python 2.7)
I think you are just a bit confused on the naming rules for parameter passing.
Consider:
def foo(a, b):
print a
print b
and you can call foo as follows:
x = 1
y = 2
foo(x, y)
and you'll see:
1
2
The variable names of the arguments (a, b) in the function signature (1st line of function definition) do not have to agree with the actual variable names used when you invoke the function.
Think of it as this, when you call:
foo(x, y)
It's saying: "invoke the function foo; pass x in as a, pass y in as b". Furthermore, the arguments here are passed in as copies, so if you were to modify them inside the function, it won't change the values outside of the function, from where it was invoked. Consider the following:
def bar(a, b):
a = a + 1
b = b + 2
print a
x = 0
y = 0
bar(x, y)
print x
print y
and you'll see:
1
2
0
0
The script runs from top to bottom. The function executes when you call it, not when you define it.
I'd suggest trying to understand concepts like variables and function argument passing first.
def change(variable):
print variable
var1 = 1
change(var1)
In the above example, var1 is a variable in the main thread of execution.
When you call a function like change(), the scope changes. Variables you declared outside that function cease to exist so long as you're still in the function's scope. However, if you pass it an argument, such as var1, then you can use that value inside your function, by the name you give it in the function declaration: in this case, variable. But it is entirely separate from var! The value is the same, but it is a different variable!
Your question relates to function parameter transfer.
There are two types of parameter transfer into a function:
By value ------- value changed in function domain but not global domain
By reference ------- value changed in global domain
In python, non-atomic types are transferred by reference; atomic types (like string, integer) is transferred by value.
For example,
Case 1:
x = 20
def foo(x):
x+=10
foo()
print x // 20, rather than 30
Case 2:
d = {}
def foo(x): x['key']=20
foo(d)
print d // {'key': 20}

Categories

Resources