I'm newbie in python. I'm study hard to know well how python work since I starting study in 2013 at college. Sorry, if little messy.
Let me showing my problem below.
I have some def function looks like:
def thread_1():
a = input('Value UTS (100) = ')
if a > 100:
print line2
d=raw_input('Dont higher than 100. Input y to repeat : ')
d='y'
if d=='y' :
thread_1()
return a
def thread_2():
b = input('Value UAS (100) = ')
if b > 100:
print line2
d=raw_input('Dont higher than 100. Input y to repeat : ')
d='y'
if d=='y' :
thread_2()
return b
def thread_3():
c = input('Value Course (100) = ')
if c > 100:
print line2
d=raw_input('Dont higher than 100. Input y to repeat : ')
d='y'
if d=='y' :
thread_3()
def thread_4():
value_total = a*50/100+b*30/100+c*20/100
and this my expression def into program list
if p==1:
thread_1()
thread_2()
thread_3()
thread_4()
Finally, I running this program :
As long as I input number is well, but in the end program showing the error code like that :
Traceback (most recent call last): File "ganjil-genap.py", line 71, in <module>
thread_4() File "ganjil-genap.py", line 36, in thread_4
value_total = a*50/100+b*30/100+c*20/100 NameError: global name 'a' is not defined
Can anyone let me know what I have done wrong?
Thanks in advance.
The variables a,b and c you are using on thread_1, thread_2 an thread_3 are only defined inside those functions. 'a' is only defined inside thread_1, b inside thread_2 and c inside thread_3, but theay are not global variables of the main program. The statement
return a
returns only the value of variable a.
you should make the vaiables global. I think it should look like this:
a=0
def thread_1():
global a
a= raW_input....
this will make your a,b,c variables global.
Then in thread_4() a,b and c should be passed as a parametres of the function.
def thread_4(a,b,c):
I think this should work.
You probably forgot the parameters to the thread_* functions.
For example, the thread_4 function declaration need to look like this:
def thread_4(a, b, c):
value_total = a*50/100+b*30/100+c*20/100
Also you have to give the arguments to your functions in the function call, for example:
if p==1:
a=1, b=2, c=3
thread_1(a, b, c)
thread_2(a, b, c)
thread_3(a, b, c)
thread_4(a, b, c)
Related
A simple addtion program:
def addition(a, b):
print( 'input a')
a = input()
print( 'input b')
b = input()
c = a + b
print (c)
Above give me a EOFError: EOF when reading a line
I know it's something simple, but I cannot see it.
This doesn't look like a complete program, This error usually occur due to a syntax error of parenthesis.
Here you are taking input, you first must convert that input to int, for the addition because input takes input as a string.
And if you are taking a,b as input inside the function what are those (a,b) parameters therefor.
If you want to call the function with parameters, first take the input outside the function and then call the function with those parameters.
EOFError: EOF when reading a line. This error occurs mainly due to syntax errors like completion of paranthesis. Check whether you've indented your contents properly.
First of all if in the function you are already feeding a and b, why are you asking for it again. Either feed them, or ask them in the function. I have given the solution and reason for error both.
Try one of these 2 snippets
def addition():
print( 'input a')
a = input()
print( 'input b')
b = input()
c = a + b
print (c)
addition()
OR
def addition(a,b):
c = a + b
print (c)
print( 'input a')
a = input()
print( 'input b')
b = input()
addition(a,b)
ERROR
The EOF could be occuring if you did something like this
def addition(a,b):
print( 'input a')
a = input()
print( 'input b')
b = input()
Here you stared to define a function but did not indent it so Python crashed.
As mentioned above, you need to choose if you would like use arguments in your function or not. I see that you would like to print input a and b hence you shouldn't add arguments in the function just ask for the input inside the function. Also, you can declare multiple variables in one line as below.
def addition():
a, b = input("Write a and b separated by a comma").split(",")
print("a: ", a)
print("b: ", b)
c = a + b
print (c)
addition()
First, here's my example code:
EDIT: I should have specified, in my real code, that_func() is already returning another value, so I want it to return one value, and change c in addition
EDIT 2: Code edited to show what I mean
def this_func():
c=1 # I want to change this c
d=that_func()
print(c, d)
def that_func():
this_func.c=2 #Into this c, from this function
return(1000) #that_func should also return a value
this_func()
What I want to do is change the local variable c in this_func() to the value I assign it in that_func(), so that it prints 2 instead of 1.
From what I've gathered online, this_func.c=2 should do just that, but it doesn't work. Am I doing something wrong, or have I misunderstood?
Thanks for any and all help.
Yes, you misunderstood.
functions are not class. You can't access variables of a function like that.
Obviously, it's not the smartest of code that can be written, but this code should give an idea about how to use variables of a function.
def this_func():
c=1 # I want to change this c
c=that_func(c) # pass c as parameter and receive return value in c later
print(c)
def that_func(b): # receiving value of c from this_func()
b=2 # manipulating the value
return b #returning back to this_func()
this_func()
Wrap it in an object and pass it to that_func:
def this_func():
vars = {'c': 1}
d = that_func(vars)
print vars['c'], d
def that_func(vars):
vars['c'] = 2
return 1000
Alternatively, you can pass it in as a regular variable and that_func can return multiple values:
def this_func():
c = 1
c, d = that_func(c)
print c, d
def that_func(c):
c = 2
return c, 1000
If I write this:
c = []
def cf(n):
c = range (5)
print c
if any((i>3) for i in c) is True:
print 'hello'
cf(1)
print c
Then I get:
[1, 2, 3, 4]
hello
[]
I'm really new to programming, so please explain it really simply, but how do I stop Python from forgetting what c is after the function has ended? I thought I could fix it by defining c before the function, but obviously that c is different to the one created just for the function loop.
In my example, I could obviously just write:
c = range (5)
def cf(n)
But the program I'm trying to write is more like this:
b = [blah]
c = []
def cf(n):
c = [transformation of b]
if (blah) is True:
'loop' cf
else:
cf(1)
g = [transformation of c that produces errors if c is empty or if c = b]
So I can't define c outside the function.
In python you can read global variables in functions, but you cant assigned to them by default. the reason is that whenever python finds c = it will create a local variable. Thus to assign to global one, you need explicitly specify that you are assigning to global variable.
So this will work, e.g.:
c = [1,2,3]
def cf():
print(c) # it prints [1,2,3], it reads global c
However, this does not as you would expect:
c = [1,2,3]
def cf():
c = 1 # c is local here.
print(c) # it prints 1
cf()
print(c) # it prints [1,2,3], as its value not changed inside cf()
So to make c be same, you need:
c = [1,2,3]
def cf():
global c
c = 1 # c is global here. it overwrites [1,2,3]
print(c) # prints 1
cf()
print(c) # prints 1. c value was changed inside cf()
To summarise a few of these answers, you have 3 basic options:
Declare the variable as global at the top of your function
Return the local instance of the variable at the end of your function
Pass the variable as an argument to your function
You can also pass the array c into the function after declaring it. As the array is a function argument the c passed in will be modified as long as we don't use an = statement. This can be achieved like this:
def cf(n, c):
c.extend(range(5))
print c
if any((i>3) for i in c) is True:
print 'hello'
if __name__ == '__main__':
c = []
cf(1, c)
print c
For an explanation of this see this
This is preferable to introducing global variables into your code (which is generally considered bad practice). ref
Try this
c = []
def cf(n):
global c
c = range (5)
print c
if any((i>3) for i in c) is True:
print 'hello'
cf(1)
print c
If you want your function to modify c then make it explicit, i.e. your function should return the new value of c. This way you avoid unwanted side effects:
def cf(n, b):
"""Given b loops n times ...
Returns
------
c: The modified value
"""
c = [transformation of b]
...
return c # <<<<------- This
c = cf(1)
This question already has answers here:
Using global variables in a function
(25 answers)
Closed 8 years ago.
I have a variable a, and I want a to be added with b, like so:
a = a + b
Now, I have my program set up like so:
a = 2
b = 3
def add() :
a = a + b
print(str(a))
add()
Every time I run this, I get
Traceback (most recent call last):
File "<stdin>", line 8, in <module>
File "<stdin>", line 5, in add
UnboundLocalError: local variable 'a' referenced before assignment
instead of
5
Please explain the obvious mistake that I am making.
It's because of a thing called scope. You can read up about it, but essentially it means that inside a function, you may not have access to things defined on the outside.
To make the function aware of these variables, you need to pass them in. Try this:
a = 2
b = 3
def add(x, y) :
x = x + y
print(str(x))
add(a, b)
It's worth noting that these values are being passed into the function, but are actually not modified themselves. I won't go into the complexities surrounding the way variables are passed to functions, but suffice it to say that after you call add(a, b) here, the values of a and b will still be 2 and 3, respectively.
I guess you are just learning about how to do this stuff, and you really don't want to go making everything global or you're going to get in a big mess.
Here, a and b are passed into the function. Inside the function, a and b are local variables and are distinct from the ones you declared outside the function
a = 2
b = 3
def add(a, b) :
a = a + b
print(str(a))
return a
a = add(a, b)
The return a is so the function returns that local a so you can do something with it
I wrote a test program that looked like this:
#!/usr/bin/python
def incrementc():
c = c + 1
def main():
c = 5
incrementc()
main()
print c
I'd think that since I called incrementc within the body of main, all variables from main would pass to incrementc. But when I run this program I get
Traceback (most recent call last):
File "test.py", line 10, in <module>
main()
File "test.py", line 8, in main
incrementc()
File "test.py", line 4, in incrementc
c = c + 1
UnboundLocalError: local variable 'c' referenced before assignment
Why isn't c passing through? And if I want a variable to be referenced by multiple functions, do I have to declare it globally? I read somewhere that global variables are bad.
Thanks!
You're thinking of dynamic scoping. The problem with dynamic scoping is that the behavior of incrementc would depend on previous function calls, which makes it very difficult to reason about the code. Instead most programming languages (also Python) use static scoping: c is visible only within main.
To accomplish what you want, you'd either use a global variable, or, better, pass c as a parameter. Now, because the primitives in Python are immutable, passing an integer can't be changed (it's effectively passed by value), so you'd have to pack it into a container, like a list. Like this:
def increment(l):
l[0] = l[0] + 1
def main():
c = [5]
increment(c)
print c[0]
main()
Or, even simpler:
def increment(l):
return l + 1
def main():
c = 5
print increment(c)
main()
Generally, global variables are bad because they make it very easy to write code that's hard to understand. If you only have these two functions, you can go ahead and make c global because it's still obvious what the code does. If you have more code, it's better to pass the variables as a parameter instead; this way you can more easily see who depends on the global variable.
When a variable is assigned to in a scope, Python assumes it's local for the whole scope unless you tell it otherwise.
So, to get this to work as you think it will, you need to use two global statements:
#!/usr/bin/python
def incrementc():
global c
c = c + 1
def main():
global c
c = 5
incrementc()
main()
print c
Otherwise, you're talking about a local variable named c in both situations.
The normal way to solve this, however, does not involve globals.
#!/usr/bin/python
def incrementc(c):
c = c + 1
return c
def main():
c = 5
c = incrementc(c)
return c
c = main()
print c
Here, in each function and in the global scope, c refers to a different variable, which you are passing around as an argument and with return values. If you wanted only one c, use a class:
class Foo:
def __init__(self, c):
self.c = c
self.incrementc()
def incrementc(self):
self.c = self.c + 1
foo = Foo(5)
print foo.c
The variable c isn't passing through because you do not hand any reference to c to the function incrementc.
What you're looking at here are 3 scopes, the global scope and those within the functions main and incrementc. In main you've properly defined a variable c, but increment c has no knowledge of this - so attempting to increment it is going to fail. Even if those two functions succeeded, trying to print c would fail in the global scope because it has no knowledge of the c you've defined in main.
You have a few options. One way to do this:
def incrementc(c):
c = c + 1
return c
def main():
c = 5
c = incrementc(c)
return c
c = main()
print c
Notice how c is being handed around. Of course, the name doesn't have to be preserved, you very well could write it like this:
def increment(z):
z = z + 1
return z
def main():
bar = 5
bar = increment(bar)
return bar
foo = main()
print foo
Another option that many would probably dislike (for good reason) is to use globals. In that case:
def incrementc():
global c # indicate intention to write to this global, not just read it
c = c + 1
def main():
global c # declares c in global space
c = 5
incrementc()
main()
print c
Any function in which you hope to MODIFY the GLOBAL instance of c, you need to inform the function. So you state, 'global c'. You can READ from the global without doing so. This would ensure (to some extent) that you don't make a mistake and overwrite a value in the global space unintentionally with a similar name, should you decide to use one in the local space of a function.
Hopefully that's clear enough, but feel free to ask for clarification on any point (I'm also open to being corrected if I've mistakenly described any part of this).
Global variables are bad.
Just like friends and enemys. Keep your friends close but keep your enemys even closer.
The function main last a local variable c, assignment the value 5
You then call the function inc..C. The c from main is now out of scope so you are trying to use a value of c that is not in scope - hence the error.