So, I'm still learning how to code and I'm making this higher or lower game, and I made a function that pulls out info from a huge list with dictionaries inside it called "data":
Here is my code so far:
def choice_of_oponents(opponent1, opponent2):
"""
Gets the info on 2 people randomly and assigns them to the variables 'opponent1' and 'opponent2'
"""
opponent1 = random.choice(data)
opponent2 = random.choice(data)
def winner(opponent1, opponent2):
#This function is supposed to pull out the info stored in the parameters in the first function and determine the winner based on the data
I'm not sure how to write the second function or if it is even possible to pull out info from the parameters of the 1st function without making extra variables. Can someone help solve this?
Maybe what you're missing is the concept of return-ing the output of a function. Also, you don't need any inputs to your first function (note that you didn't use them anyway).
Try something like this:
def choice_of_opponents():
"""
Gets the info on 2 people randomly and assigns them to the variables
'opponent1' and 'opponent2'
"""
opponent1_result = random.choice(data)
opponent2_result = random.choice(data)
return opponent1_result, opponent2_result
def winner(opponent1, opponent2):
if opponent1 > opponent2:
return 1
elif opponent2 > opponent1:
return 2
else:
return 0 # A tie
op1, op2 = choice_of_opponents()
print(winner(op1, op2))
Related
This question already has answers here:
Static variable in Python?
(6 answers)
Closed 1 year ago.
I'm trying to write a function that updates its local variable each time it is run but it is not working for some reason.
def max_equity(max_equity=0):
if current_equity() > max_equity:
max_equity = current_equity()
print(max_equity)
return max_equity
else:
print(max_equity)
return max_equity
and the function which it is calling
def current_equity():
for n in range(len(trade_ID_tracker)-1):
equity_container = 0
if (trade_ID_tracker[n,2]) == 0:
break
else:
if (trade_ID_tracker[n, 1].astype(int) == long):
equity_container += (df.loc[tbar_count,'Ask_Price'] - trade_ID_tracker[n, 2]) * trade_lots * pip_value * 1000
elif (trade_ID_tracker[n, 1].astype(int) == short):
equity_container += 0 - (df.loc[tbar_count,'Ask_Price'] - trade_ID_tracker[n, 2]) * trade_lots * pip_value * 10000
return (current_balance + equity_container)
but for some reason the max_equity() function prints current_equity() which I can only imagine means that either:
if current_equity() > max_equity:
is not doing it's job and is triggering falsely
or
max_equity = current_equity()
is not doing its job and max_equity starts at zero every time it is run.
In other words if I put max_equity() in a loop where current_equity() is
[1,2,3,4,5,4,3,2,1]
then max_equity() should return
[1,2,3,4,5,5,5,5,5]
But instead it returns
[1,2,3,4,5,4,3,2,1]
Here's a quick example test
ar = [1,2,3,4,5,4,3,2,1]
def stuff(max_equity=0):
if ar[n] > max_equity:
max_equity = ar[n]
print(max_equity)
else:
print(max_equity)
for n in range(len(ar)):
stuff()
Either way I'm kind of stumped.
Any advice?
local function variables are reset at each function call. This is essential for the behavior of functions as idempotent, and is a major factor in the success of the procedural programming approach: a function can be called form multiple contexts, and even in parallel, in concurrent threads, and it will yield the same result.
A big exception, and most often regarded as one of the bigger beginner traps of Python is that, as parameters are reset to the default values specified in the function definition for each call, if these values are mutable objects, each new call will see the same object, as it has been modified by previous calls.
This means it could be done on purpose by, instead of setting your default value as 0 you would set it as a list which first element was a 0. At each run, you could update that value, and this change would be visible in subsequent calls.
This approach would work, but it is not "nice" to depend on a side-effect of the language in this way. The official (and nice) way to keep state across multiple calls in Python is to use objects rather than functions.
Objects can have attributes tied to them, which are both visible and writable by its methods - which otherwise have their own local variables which are re-started at each call:
class MaxEquity:
def __init__(self):
self.value = 0
def update(max_equity=0):
current = current_equity()
if current > self.value:
self.value = current
return self.value
# the remainder of the code should simply create a single instance
# of that like ]
max_equity = MaxEquity()
# and eeach time yoiu want the max value, you should call its "update"
# method
new to Python - struggling with functions. - Image of code attached.
It inputs the name & scores just fine with the validation checks.
I need to use the scores input by the user and total them.
However, when I've tried to sum(score) it doesn't like it.
I can't work out how to sum the 4 total scores.
Please help :) Also would love any feedback on the style of coding etc.
Thanks in advance x
Image: Code in Python
I would rewrite the main function to be something like:
def GetStudentInput():
score = 0
for i in range (4):
print("Mrs Pearson's Class Test Score Data")
name = CheckStringInput("What's Your Name: ")
score += CheckNumericInput("What's Your Score: ")
print(score)
This eliminates the need for an extra function and avoids using a list since you don't appear to need the individual values elsewhere -- only the sum total.
In the absense of code for people to see, we have something like
def get_stuff():
for i in rnage(4):
name = input("Name?")
score = int(input("Score?"))
and another function
def TotalScore():
pass
How do we call total score?
Answer: Make sure we don't forget the user inputs and return them:
def get_stuff():
names = []
scores = []
for i in range(4):
names.append(input("Name?"))
scores.append(int(input("Score?")))
return names, scores
and take the scores in the summing function:
def TotalScore(scores):
return sum(scores)
This, of course, changes the calling code.
For example, you need to capture the returns when you call get_stuff:
names, scores = get_stuff()
total = TotalScores(scores)
beside(picture,picture) #beside takes two pictures as arguments and prints them side by side in a 1:1 ratio.
stackn(n,picture) #stackn takes a number and a picture as arguments and prints n number of shapes in a vertical row.
show(picture) #show takes a picture as an argument and shows it on the canvas
In this case picture is the parameter heart_bb:
(n=2)# show(beside((stackn(1,heart_bb)),(stackn(2,heart_bb))))
(n=3)# show(beside((stackn(1,heart_bb)),(beside((stackn(2,heart_bb)),(stackn(4,heart_bb))))))
(n=4)# show(beside((stackn(1,heart_bb)),(beside((stackn(2,heart_bb)),(beside((stackn(4,heart_bb)),(stackn(8,heart_bb))))))))
My task is to come up with a recursive function(I’m going to call it test):
def test(n, picture):
I need this function to return the corresponding line of code shown above. For example, test(3,heart_bb) should return the line of code for n=3. Likewise, test(4,heart_bb) will return the line of code for n=4.
It has to work for any n>1, but after n=5 coding it gets really tedious.
def fractal(picture,n):
if n==1:
return(picture)
else:
return(beside((fractal(picture,(n-1))),(stackn((2**(n-1)), (picture)))))
I suppose you mainly need an idea of how you can do it and not a way to find someone that writes the code for you.
I would suggest to use a n-ary beside operation in place of your one, in such a way to simplify the code for n=2,3,4,... Since I cannot modify it I will define a new one in terms of your binary operation in this way:
def beside_pictures(pictures):
assert len(pictures) > 0
result = pictures[-1]
for tmp in pictures[:-1:-1]: # reverse order, starting from -1
result = beside(tmp, result)
return result
Now we are ready to transform your test function in a one line function:
def test(n, picture):
assert n > 0
show(beside_pictures([stackn(2**i,picture) for i in range(n)]))
UPDATE: If the requirement to have a recursive function is strict, one possible solution is the following one:
def test(n, picture):
if n == 1:
return stackn(1,picture)
return beside(test(n-1, picture), stackn(2**(n-1),picture))
I'm drawing my name using turtles and I have a bunch of different functions for each of the letters
like so (for letter r)
def letter_r(t):
def letter_r_top(t):
turtle.lt(90)
turtle.fd(150)
turtle.rt(90)
turtle.circle(-37.5,180)
turtle.lt(130)
def letter_r_leg(t):
csquare = ((75**2) + (37.5**2))
sidec = math.sqrt(csquare)
turtle.fd(sidec)
letter_r_top(rob)
letter_r_leg(rob)
After each letter, i need to move the turtle into the right place to setup for the next letter. Because each of the letters are different sizes I need to make custom movements depending on what the previous letter is but I dont want to make separate functions for each of those movements.
At the end of my code I have the list of functions to be called in the correct order to spell my name
letter_t(rob)
letter_setup(rob)
letter_r(rob)
letter_setup(rob)
.....
Is there a way that I can do something like this so that I will only need 1 setup function.(Not real code, just a conceptualization of what I'm thinking
def letter_setup(t):
if previously executed function A
turtle.fd(75)
if previously executed function B
turtle.fd(75)
turtle.lt(90)
if previously executed function C
turtle.fd(75)
turtle.lt(90)
Why not the movement to the right place for the next letter at the end of the previous letter?
Perhaps there is a better way to do this but you could make a variable last_function_called and in each function you give it a different value then you'll know wich one was the last called :
last_function_called = NONE;
def function1():
last_function_called = FUNCTION1
blablabla
...
if (last_function_called == FUNCTION1):
call another one
and before of course something like :
NONE = 0
FUNCTION1 = 1
FUNCTION2 = 2
ect...
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)