NameError: name 'capital' is not defined - python

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)

Related

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.

How do I call a variable that I assigned in an if statement in python?

I am learning python and I wanted to make a script that makes you calculate what your after-tax salary is. When I tried to call a variable I assigned in an if statement it said,
NameError: name 'bruto1' is not defined.
This is the code:
if bruto<20142 and bruto>0:
bruto1 = (bruto*0.3655)
netto = (bruto - bruto1)
I already found the problem thanks to konserw
In an event bruto was < 0 or > 20142 you tried to access bruto1 variable that don't exist (because block in if statement wasn't executed).
You have 2 possibilities - either start with defining default value to bruto1, for example 0, so that whenever you try accessing that variable it has some value; or make sure all execution paths that are possible in your program lead to assignment of some value to that variable, for example by using if...else...
brutto1 = 0
if brutto < 20142 and bruto > 0:
brutto1 = (brutto * 0.3655)
netto = (brutto - brutto1)
I think more pythonic way is conditional assignment to variable in one line, for example:
netto = (brutto - (brutto*0.3655)) if brutto < 20142 else (<place another calculation here>)
EDIT:
Fixed typo in variable names.
P.S. I suggest using pylint to catch such smells (or good IDE like pycharm, that would underline typos and use-before-assignment of variables)

Can i have multiple global varibles within a python script?

Is it possible to have more than one global variable within a python script?
import os,csv,random
def user():
global Forname
Forname = input('What is your forname? ').capitalize()
while True:
try:
global answerr
answerr = input('Welcome to the phone troubleshooting system '
'\nApple\nSamsung '
'\nOut of the following options enter the name of the device you own ').lower()
except ValueError:
continue
if answerr in ('apple','samsung'):
break
myfile = open(answerr+'_device.csv','r')
answer = input(Forname + ', do you have anymore problems? ').lower()
if 'yes' in answer:
#do whatever
else:
#do whatever
Using the global variable 'answerr' I'd like to open a csv file, and the refer to the user with the forname they input, but I want to use them multiple times through out my code within def functions. I apologise in advance if you do not understand what I'm asking, I'm relatively new to coding given the fact that I'm still a school student.
Of course it's possible. But there is absolutely no reason to use any global variables in this code, let alone multiple.
The point of a function is that it can return a value:
def user():
forename = input('What is your forename? ').capitalize()
return forename
Can I have multiple global variables within a Python script?
Yes and here's how:
When you're assigning any variable at the top-level of a module like: n = "Stackoverflow!" then your variable is global automatically. So let's say we have this modules:
#globals.py
x = 2 + 2
y = 5 + x
both x and y are global variables which means they're accessible to functions, classes and so on. *Just remember any assignment at the top-level of a module is actually global (this is what we call a global scope and it can contain as much variables as your memory allows). This is just like the code you posted. However, what we cannot have is same named variables in any scope:
same = 20
same = "s"
print(same)
will print s, not 20.
Hope you'll find this helpful :-)

python summing random integers

#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.

Checking that array doesn't contain negative numbers, and running function again if it does

My task today is to create a way for checking if a function's output contains negative numbers, and if it does, then I must run the function until it contains no negative numbers.
I'll post the full code later in the post, but this is my attempt at a solution:
def evecs(matrixTranspose):
evectors = numpy.linalg.eig(matrixTranspose)[1][:,0]
return evectors
if any(x<0 for x in evectors) == False:
print(evectors)
evecs() is my function, and evectors is the output array, but I only want to print evectors if there are no negative entries in it. I also want to later add that if there are negative entries in it, the code should run the evecs function again until it finds an evectors that has no negative entries.
However, whenever I run it I get the error:
global name evectors is not defined
Here's a link to my code, and the full output from the iPython console. http://pastebin.com/3Bk9h1gq
Thanks!
You have not declared the variable evectors other than within the scope of your function evecs.
evectors = evecs(matrixTranspose)
if any(x<0 for x in evectors) == False:
print(evectors)
EDIT
There are several issues:
Indentation is VERY important in Python. MarkovChain and evecs are two seperate functions. You had your evacs function indented an extra level in, embeddeding it within MarkovChain.
MarkovChain should return matrixTransponse if you plan to use it in another function call.
As a result of the above issue, your function call to MarkovChain needs to be assigned to a variable, matrixTranponse, otherwise you will get an error stating that matrixTranspose is not defined when you make your function call to evecs with it.
Since the initialization of the variable matrixTranspose isn't set until the function call to MarkovChain is completed, the remainder of your logic will need to be re-ordered.
I have applied all the above changes below and added comments to the changed areas:
def MarkovChain(n,s) :
"""
"""
matrix = []
for l in range(n) :
lineLst = []
sum = 0
crtPrec = precision
for i in range(n-1) :
val = random.randrange(crtPrec)
sum += val
lineLst.append(float(val)/precision)
crtPrec -= val
lineLst.append(float(precision - sum)/precision)
matrix2 = matrix.append(lineLst)
print("The intial probability matrix.")
print(tabulate(matrix))
matrix_n = numpy.linalg.matrix_power(matrix, s)
print("The final probability matrix.")
print(tabulate(matrix_n))
matrixTranspose = zip(*matrix_n)
return matrixTransponse # issue 2
# issue 1
def evecs(matrixTranspose):
evectors = numpy.linalg.eig(matrixTranspose)[1][:,0]
return evectors
matrixTranponse = MarkovChain(4, 10000000000) # issue 3
# issue 4
evectors = evecs(matrixTranspose)
if any(x<0 for x in evectors) == False:
print(evectors)

Categories