python summing random integers - python

#Use main and a void function named randnums.
#randnums takes no arguments and return none.
#The randnums function generates 6 random integers between 1 and 9.
#The total should be printed on a new line.
#Main should call the randnums function.
import random
total=0
def main():
randnums()
def randnums():
for nums in range(6):
nums=random.randrange(1,10)
total=total+nums
print(nums,end=' ')
print("\nThe total is:",total)
main()
I keep getting:
local variable 'total' referenced before assignment
Or when total=nums it only shows the last int generated.
Can someone please explain to a beginner what I'm doing wrong?

When you assign to a variable inside a function, Python interprets it as local variable to that function. So when you do -
total=total+nums
You are actually trying to access the local variable total before defining it.
Based on your program, does not look like you need total to be a global variable, you can simply define it as 0 at the start of randnums() . Example -
def randnums():
total = 0
for nums in range(6):

You are facing problem because of variable scope.
total=total+nums
Notice that line, in your local scope, total doesn't exist but you are trying to get it's value and then add some num with it, which is the cause of your error.
If you really want to use it, use it like below:
global total
total=total+nums
So, that it recognises the global total variable.

Related

value returned by a function is disappearing

I have 2 functions: check_question_count() that asks a user to give an input of a number between 1 and 15 , validates the input, then returns it; random_question() function takes that returned number and generates a number of questions.
The issue is that the returned value from the first function does not seem to be returned, because i get an error that says: UnboundLocalError: local variable 'q_count' referenced before assignment.
def random_question():
check_question_count()
q_index = 1
global saved_question_count
saved_question_count = int(q_count)
print('Awesome! you will be asked ', saved_question_count,' randomly selected questions out of the total of 15 questions available.')
#Using a while loop to print out a randomly selected question:
while q_count != 0:
b = len(questions_list) - 1
rand_num = random.randint(0,b)
global selected_question
selected_question = questions_list[rand_num]
print('\n')
print(q_index,'.',selected_question)
global user_answer
user_answer = input('Your answer is: ').capitalize()
#Using a function to validate the user_answer input:
check_submitted_answers(user_answer)
questions_list.remove(selected_question)
questions_list = questions_list
q_count = q_count - 1
q_index = q_index +1
#4- Function to check the question count input and make sure its a number between 1 to 15:
def check_question_count():
global q_count
q_count = input('\nHow many questions do you like to take? You can choose a number between 1 to 15: ')
while True:
if q_count not in ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']:
print('Error: Invalid input! Please type in only a number between 1 and 15: ')
q_count = input('\nHow many questions do you like to take? You can choose a number between 1 to 15: ')
continue
else:
return q_count
random_question()
Any help is appreciated, thanks.
There are two problems with your code. One is severe, the other is not.
The root cause of the error UnboundLocalError: local variable 'q_count' referenced before assignment is the line q_count = q_count - 1 in random_question(). This supposed to modify the variable, but that variable is supposed to be global, and thus, not writable. This makes python believe you have a local, modifiable variable q_count, and thus, all the mentions of it in the current scope must mean this local one - and when you reference it first, it is referenced before assigned.
One solution would be to just use the global version, i.e. global saved_question_count, q_count. Another one would be to remove the line q_count = q_count - 1 - but you probably need that line. A third one would be to create a new (local) variable, and initialize it with q_count.
The best solution would be (that also fixes the second problem of unnecessary global variables) is to just return the value. Others have already explained that in detail.
You are not saving the returned value in any given variable i.e instead of
check_question_count()
try:
q_count = check_question_count()
in order to save the returned value in a variable.
You should also look into the proper use of global keyword because it is being used unnecessarily here-Use of "global" keyword

NameError: name 'capital' is not defined

I run this code commission,profit_target all other variable works but only capital giving error. Please anyone can resolve this.
def strategy_logic(df,open_position=0,state='Close',capital=0,commission=0,profit_target=0,
stoploss=0,quantity=0):
last_buy=0
print(open_position,state,capital,commission,profit_target,stoploss,quantity)
# Run Loop and check Strategy
for i in range(len(df)):
df['capital'][i]=capital
PT=profit_target+last_buy # PT (Profit Target)
SL=last_buy-stoploss # SL (Stoploss)
# BR (BarRange)
def BarRange(value):
if df['High'].iloc[i] >= value >=df['Low'].iloc[i] :
return True
return False
def calculate_open_position():
global open_position,capital
print(open_position,commission,stoploss)
open_position=1
capital=capital-commission*quantity
capital=capital-df[state].iloc[i]*quantity
df['capital'][i]=capital
df['Buy'][i]=1
last_buy=df[state].iloc[i]
print('buy',last_buy)
calculate_open_position()
strategy_logic(df,open_position=0,state='Close',capital=1000,commission=1,profit_target=6,stoploss=3,quantity=1)
Here:
global open_position,capital
Those variables are not global; they are nonlocal. They belong to the namespace of the enclosing function, not the global namespace.
nonlocal open_position,capital
Not sure why you are defining functions inside the for loop and then only calling the last definition after the loop. It would be better to just define them separately and call them with the necessary arguments.
Furthermore, inside calculate_open_position() you are assigning last_buy inside the function, where its scope is inside the function. You can verify and see that your variable last_buy in the strategy_logic() scope is still 0 at the end of the function (assigning it from within the calculate_open_position function scope does not change the value in the outer scope).
Also, not sure where you are calling BarRange() since it is stuck inside the strategy_logic()'s scope and can't be called anywhere else. You might want to read up more about scopes before trying to add global from within your function, which is generally a bad practice.
The simplest answer is to remove the definition and run the code directly:
def strategy_logic(df, open_position=0, state='Close', capital=0,
commission=0, profit_target=0, stoploss=0, quantity=0):
last_buy = 0
print(open_position,state,capital,commission,profit_target,stoploss,quantity)
# Run Loop and check Strategy
for i in range(len(df)):
df['capital'][i]=capital
PT = profit_target + last_buy # PT (Profit Target)
SL = last_buy - stoploss # SL (Stoploss)
# Run the code here directly instead of defining a function
open_position = 1
capital = capital - commission * quantity
capital = capital - df[state].iloc[i] * quantity
df['capital'][i] = capital
df['Buy'][i] = 1
last_buy = df[state].iloc[i]
print('buy', last_buy)

Updating a variable from a function in a different file in python

I am trying to keep the value of a variable between files on a python script. The end goal is to separate functions from an algorithm.
The function is very simple - I have saved it in a file called test:
def tests(x):
global y
x=10
y=x
return y
Then the algorithm part is again simple - saved in a different file, called test1:
import test as t
y=0
t.tests(y)
print("new value is "+str(y))
However, the value does not seem to be updated to 10 - it keeps its initial value of 0.
I am sure I am missing sth very obvious, but could you pls help?
The above code works if I contain the function and the algorithm parts in the same fie, but I would like to separate them.
Thank you
The error is pretty minute, the only reason the value is not updated is because you forgot to assign the value to the variable y
The code in the second file(test1) should be:
import test as t
y = 0
y = t.tests(y)
print("New value is " + str(y))

Python will not change a boolean value after it runs through a function [duplicate]

This question already has answers here:
Function not changing global variable
(4 answers)
Closed 1 year ago.
from random import randrange
on = ''
max_number = 0
random_number = 0
def start():
max_number = int(input('Enter max generated number: '))
random_number = randrange(max_number)
print(random_number)
on = True
start()
print(on) # returns false??
for a school project, i need to make a number guessing game. This is the start code i have. I declared "on" before the start function but the function wont change the value of the boolean to true
Right now, on is a "local" variable, only seen and used inside the scope of the function. To change the value of any variable inside and outside the function, you need to type the command global {variable}, usually at the top of a function. In your case, add this to your function:
def start():
global on <-- Right Here
max_number = int(input('Enter max generated number: '))
You can research more about global and nonlocal variables online.
Acknowledging #Samwise comment, global and nonlocal variables aren't always the best option, but I think that it's best to learn it anyway (the more you know!). He is correct, that you will likely not even need the on variable, and also that using a return statement is the best option.

What is causing Python not to recognize a variable defined in a for loop?

I was hoping that someone could explain to me what I'm doing to cause a variable defined in a for loop to not be recognized when I attempt to call it later on. Basically, I've got a large list of frequencies that each have a bunch of possible molecules matches listed under them, and I marked the correct molecule with a '%' when I identified it to come back to later. Now I'm trying to pull those frequency-molecule matches out for something else, and my method was this:
frequencies = [17.987463, ...etc] # large list
for k in frequencies:
g = open('list', 'r')
for line in g:
if line[0:9] == k[0:9]:
# if the entry in the list matches the observed frequency
for _ in range(25):
check = str(g.next()) # check all lines under it for a % symbol
if check[0] == '%':
q = check.split('\t')[-1]
break
# if you find it, save the last entry and stop the for loop. Continue until you find it.
else:
continue
else:
continue
table.write(str(q))
table.write(str(k))
But this says "UnboundLocalError: local variable 'q' referenced before assignment".
If I'd defined q inside a function I would understand, but I'm confused why it's saying this because you can write something like
for i in range(5):
x=i**2
print x
and get 16, so we know that variables defined in for loops will exist outside of them.
I thought that whatever the problem was, it could be fixed by making a global variable so I added in a line so that middle part read:
if check[0]=='%':
global q
q=check.split('\t')[-1]
but then it says "NameError: global name 'q' is not defined".
Could someone please explain what I'm doing wrong? Thank you.
The assignment is never executed.
This will never evaluate to true:
if line[0:9]==k[0:9]:
g.read() will yield a str object, while the elements of frequencies are floats.
You probably want something like:
if line[0:9]==str(k)[0:9]
This will convert the float k to a str and then trim it to 9 characters, including the separator(.).

Categories