While loops inside an if-statement? - python

Beginner programmer here:)) I am working on a school project, where the assignment is to find the roots to five functions in one file.
In one of my functions there are two roots, and my code can only find one. It seems like the second while-loop is ignored. I've tried to put only this code in a separate file, and it worked - but together with the other files it wont work...
Just ask if there is something that´s weird;)
def b(x: float):
return -x**2+x+6
def bgraf():
xlim(a1, b1)
ylim(-15, 25)
x = linspace(-5, 10, 1000)
y = b(x)
plot(x, y, 'r')
return
funksjoner = [0, 1, 2, 3, 4]
while response not in funksjoner:
i = int(input("choose a function from 0 to 4"))
response = i
if response in funksjoner:
print("you chose function ", int(funksjoner[i]))
a1 = float(input())
b1 = float(input())
z = a1
y = b1
m = a1
n = b1
NP = True
if int(funksjoner[i]) == funksjoner[1]:
while abs(y-z) > 1e-10:
null1 = (z+y)/2
if b(z)*b(null1)>0 and b(y)*b(null1)>0:
NP = False
print('No roots in this interval')
bgraf()
break
elif b(null1) == 0:
break
elif b(z)*b(null1)>0:
z = null1
else :
y = null1
while abs(n-m) > 1e-10:
null1_2 = (m+n)/2
if b(m)*b(null1_2)>0 and b(n)*b(null1_2)>0:
NP = False
print('No roots in this interval')
bgraf()
break
elif b(null1_2) == 0:
break
elif b(m)*b(null1_2)>0:
m = null1_2
else :
n = null1_2
if NP :
print('we have a root when x =', round(((z+y)/2), 1))
if null1 != null1_2:
print('and when x =', round(((m+n)/2), 1))
bgraf()
scatter(null1, 0)
if null1 != null1_2:
scatter(null1_2, 0)
It looks like python is ignoring the second while-loop I placed under the if-statement. Is there another way I could this?
Thanks for your attention!

Several things to think about:
what do you want to achieve with the following line of code:
If int(funksjoner[i]) == funksjoner[1]
You could simply check
If i == 1
i don‘t see any difference between the first and the second while loop.
z=m=a1
y=n=a2
So what should be the difference between those two?
In General the code is hard to read because of the naming of the variables, try to use variables which give you an impression what they contain.
For getting better impression what is going on in your code either use debugging, or if you are not familiar with debugging add print statements in your code to better understand what is stored in your variables at which time of the execution. And what statements are executed and which are skipped/not reached
When you give us more detailed information about your code (you could e.g. add comments to explain your code), have more detailed questions we can better support you

Related

If I take a user supplied value as a function parameter, how do I make it a global variable?

I'm writing a program that can riffle shuffle a given sequence (list l), m times. My function takes in the list l and the number m as inputs but Ive defined the shuffle itself for one shuffle and then used a for loop to do it m times. However, now the for loop does not take the user assigned value of m.
I'm a Python noob so it's likely I'm missing a simple thing. Ive tried using global m, to (re)define m within my function but either I dont know how to do it, or it doesn't seem to work.
def riffle_shuffle(l, global m):
#global m goes here?
r = np.random.binomial(len(l),0.5)
sd1 = l[:r]
d2 = l[r:]
fl = []
c = [sd2,sd1]
l2 = sd2+sd1
for i in range(1,len(l) + 1):
x = [sd2,sd1]
y = [(len(sd2))/(len(l) - i+1),(len(sd1))/(len(l) - i+1)]
a = choices(x,y)
a1 = a[0][0]
fl.append(a1)
#Deck Split is c
#Sub decks are',c
#Probabilities are',y
#Deck chosen is',a
#fl
if a1 in sd1:
sd1.remove(a1)
elif a1 in sd2:
sd2.remove(a1)
return fl,m
for j in range(1,m+1):
fl = riffle_shuffle(fl)
return fl
I've gotten errors that say m is not defined, invalid syntax, the following error message. I don't know what this last one means.
'maximum recursion depth exceeded in comparison'
Any help is much appreciated, thanks!
EDIT: I missed the for loop I'd mentioned in the description. It's up now sorry.
So... You want method that do riffle shuffle m times, right?
There is some problems with your code :
First, return is outside of the function.
Second, you call your function in your function, without breaking condition : So the function will call the function, and that will call the function again, and again, and so on, until error occurs. That is maximum recursion depth exceeded in comparison.
Third, you have use np.random.choice like this : np.random.choice(x, p=y). Otherwise, python don't know y is probabilities, and it will interpret it as second argument : size of the output. So error occurs here.
This might be the code you want to write :
import numpy as np
def riffle_shuffle(l, m):
if m == 0:
return l
else:
fl = []
r = np.random.binomial(len(l), 0.5)
sd1 = l[:r]
sd2 = l[r:]
c = [sd2,sd1]
l2 = sd2+sd1
for i in range(1,len(l) + 1):
x = [sd2,sd1]
y = [(len(sd2))/(len(l) - i+1), (len(sd1))/(len(l) - i+1)]
a = np.random.choice(2, p=y)
a = x[a]
a1 = a[0]
fl.append(a1)
#Deck Split is c
#Sub decks are',c
#Probabilities are',y
#Deck chosen is',a
#fl
if a1 in sd1:
sd1.remove(a1)
elif a1 in sd2:
sd2.remove(a1)
fl = riffle_shuffle(fl, m - 1)
return fl
a = riffle_shuffle([1, 2, 3, 4, 5, 6, 7, 8], 3)
print(a)
#output : [5, 6, 1, 7, 4, 8, 2, 3] (can be changed)
As you did, I called the function 'recursively' - call function in function - with break condition.
In this way, you don't have to use global variable - using global variable is not good idea in most situation.
And, about your question(How can I make user-supplied value to global variable), you can do something like this.
a = 0
def foo(m):
global a
a = m
#and your code here...

How to run my for loop with same i if i want?

def MH(x,y,sigma=0.1,iterasyon=100):
import random
import numpy as np
a=np.array([1])
b=np.array([1])
for i in range(5):
ayap=float(random.gauss(a[i],sigma))
byap=float(random.gauss(b[i],sigma))
rss0 = np.sum((a[i]+b[i]*x-y)**2)
rss1=np.sum((ayap+byap*x-y)**2)
if random.random() <= min(1,rss1/rss0):
a=np.append(a,ayap)
b=np.append(b,byap)
return a
So if my if condition wont work, i want to start again with same i. How can i do that? I tried to put a else: i=i-1 but didnt work
You can't really do that with a for loop (at least not without a lot of weird gymnastics revolving around generators). You can use a while loop:
i = 0
while i < 5:
# Do stuff
if condition:
# Increment ...
i += 1
def MH(x,y,sigma=0.1,iterasyon=100):
import random
import numpy as np
a=np.array([1])
b=np.array([1])
i, c = 0, 0
while i < 5:
try:
ayap=float(random.gauss(a[i],sigma))
byap=float(random.gauss(b[i],sigma))
rss0 = np.sum((a[i]+b[i]*x-y)**2)
rss1=np.sum((ayap+byap*x-y)**2)
if random.random() <= min(1,rss1/rss0):
a=np.append(a,ayap)
b=np.append(b,byap)
except:
# handle some error here, maybe
c = c + 1
# if code fails 3 times, break
if c == 3:
break
else:
# only increment when there was no exception
i = i + 1
return a
Just use an extra while loop:
def MH(x,y,sigma=0.1,iterasyon=100):
import random
import numpy as np
a=np.array([1])
b=np.array([1])
for i in range(5):
while True:
ayap=float(random.gauss(a[i],sigma))
byap=float(random.gauss(b[i],sigma))
rss0 = np.sum((a[i]+b[i]*x-y)**2)
rss1=np.sum((ayap+byap*x-y)**2)
if random.random() <= min(1,rss1/rss0):
a=np.append(a,ayap)
b=np.append(b,byap)
else:
break
return a
As soon as your if-condition is not met, the interpreter breaks out of the loop.
The kind of logic you want is very prone to run into an infinite loop. Watch out for that! That concern is equally valid for mgilson's answer.

The Grid Search (HackerRank) - Python

I'm a developer for a few years but I'm practicing my algorithm skills.
I'm faced with "The Grid Search" in HackerRank and even though I could solve it, I want to know if this is a decent method to do it.
PS: I'm trying to to do most of it with simple instructions, developing the whole logic instead of using pre-built functions. My objective is to improve my logical thought, not my knowledge of a language's magic methods.
#!/bin/python3
import sys
t = int(input().strip())
for a0 in range(t):
R,C = input().strip().split(' ')
R,C = [int(R),int(C)]
G = []
G_i = 0
for G_i in range(R):
G_t = list(input().strip())
G.append(G_t)
r,c = input().strip().split(' ')
r,c = [int(r),int(c)]
P = []
P_i = 0
for P_i in range(r):
P_t = list(input().strip())
P.append(P_t)
mIsEqual = False
#For each line of the matrix
for a1 in range(0,len(G) - (len(P)-1)):
#For each column of the given line
for a2 in range(0,len(G[a1]) - (len(P[0])-1)):
#If the top left value of the pattern matches the current value of the matrix, try to match it
if(P[0][0] == G[a1][a2]):
#If the pattern 'fits' horizontally in the matrix, try to match it
if(len(P[0]) <= (len(G[a1]) - a2)):
#If the pattern 'fits' vertically in the matrix, try to match it
if(len(P) <= (len(G) - a1)):
#Match every single field of the pattern to the given area of the matrix.
for a3 in range(0,len(P)):
for a4 in range(0,len(P[0])):
#If the fields are equal mIsEqual is true
if(P[a3][a4] == G[a3+a1][a4+a2]):
mIsEqual = True
else:
#If the fields are not equal stop matching this area of the matrix.
mIsEqual = False
break
#If one field in a line was not equal, stop matching this area of the matrix.
if(mIsEqual == False):
break
#If, after matching the whole area with the pattern mIsEqual is still true, the pattern is there.
if(mIsEqual):
break
#If the pattern was found in the previous line, no need to keep this going.
if(mIsEqual):
break
if(mIsEqual == True):
print("YES")
else:
print("NO")
I'm looking for any suggestions to improve this script or, if you think it's completely wrong, the reason why this is not a good way to do it.
Thanks!
This is better on a code review site.
Your algorithm as described looks roughly right. However it would be easier to follow if you mentally chunked things into functions. That would also remove some duplicated code, and also reduces how much you need to write the same thing both in code and in commends.
Compare what you wrote with the following untested code. Which is essentially what you wrote only with functions broken out and only one comment per function:
#!/bin/python3
import sys
# Read the dimensions then a matrix from stdin
def read_matrix():
R,C = input().strip().split(' ')
R,C = [int(R),int(C)]
M = []
M_i = 0
for M_i in range(R):
M_t = list(input().strip())
M.append(M_t)
return M
# See if P can be found anywhere in G.
def found_match_in(G, P):
for a1 in range(0,len(G) - (len(P)-1)):
for a2 in range(0,len(G[a1]) - (len(P[0])-1)):
if found_match_at(G, P, a1, a2):
return True
return False
# See if P can be found in G at location (a1, a2).
def found_match_at(G, P, a1, a2):
for a3 in range(0,len(P)):
for a4 in range(0,len(P[0])):
if G[a1+a3][a2+a4] != P[a3][a4]:
return False
return True
t = int(input().strip())
for a0 in range(t):
G = read_matrix()
P = read_matrix()
if found_match_in(G, P):
print "YES"
else:
print "NO"

Trying to factorise

This tries to factorise, I have made the code in this way as I intend to change some features to allow for more functionality but what I want to know is why my results for xneg and xpos are both 0.
import math
sqrt = math.sqrt
equation = input("Enter the equation in the form x^2 + 5x + 6 : ")
x2coe = 0
xcoe = 0
ecoe = 0
counter = -1
rint = ''
for each in range(len(equation)+1):
if equation[each] == 'x':
break
x2coe = int(equation[each])
counter = counter + 1
for each in range(len(equation)):
if equation[each] == 'x':
break
xcoe = int(equation[counter + 5:counter + 6])
ecoe = int(equation[len(equation) - 1])
if x2coe == 0:
x2coe = 1
if xcoe == 0:
xcoe = 1
xpos = (-xcoe+sqrt((xcoe**2)-4*(x2coe*ecoe)))/(2*x2coe)
xneg = (-xcoe-sqrt((xcoe**2)-4*(x2coe*ecoe)))/(2*x2coe)
print("Possible Solutions")
print("-----------------------------------------------")
print("X = {0}".format(xpos))
print("X = {0}".format(xneg))
print("-----------------------------------------------")
It's because your x2coe and xcoe variables are both 0 when you reach the computations for xpos and xneg. You would have received a division by zero, except for what looks like another problem. The xpos & xneg expressions look like the quadratic formula, but you are dividing by 2 and then multiplying by x2coe at the end. Multiplication and division have equal precedence and group from left to right, so you need to use one of:
xpos = (-xcoe+sqrt((xcoe**2)-4*(x2coe*ecoe)))/(2*x2coe) # one way to fix
xneg = (-xcoe-sqrt((xcoe**2)-4*(x2coe*ecoe)))/2/x2coe # another, slower way
I suggest that you get the "business" logic of your program debugged first, and just input the three coefficients as a tuple or list.
x2coe, xcoe, ecoe = eval(input("Enter coefficients of ax^2+bx+c as a,b,c: "))
When your factoring code gives the results you want, then go back and put in a fancy input handler.
Hint: import re. Regular expressions are a good tool for simple parsing like this. (You'll need something even fancier if you want to handle parentheses/brackets/braces some day.) Take a look at the how-to document at http://docs.python.org/3.3/howto/regex.html first, and also bookmark the re module documentation at http://docs.python.org/3.3/library/re.html
The problem is probably that you're hard-coding how long you think each coefficient should be: 1 digit. You should use another function that would make it more flexible. Any of the coefficients could be blank, in which case A or B should be assumed to be 1 and C should be assumed to be 0.
Hopefully this will help:
p = re.compile('\s*(\d*)\s*x\^2\s*\+\s*(\d*)\s*x\s*\+\s*(\d*)\s*')
A, B, C = p.match(equation).group(1, 2, 3)
print(A, B, C)
All of the instances of \s* are to allow for flexibility in input, so spaces don't kill you.

variable within a nested loop in python

I'm trying to figure what the values of xcoord_orig and ycoord_orig are when the last conditional statement is true i.e. when board[xcoordT][ycoordT] == computer. I feel that as I have it right now, I'm simply printing their values if the conditional statement is true. But what I really want are the values of xcoord_orig and ycoord_orig under the first loop at the point where the last conditional statement is true. I'm not sure if this is clear but I thought I would ask.
for num in range(8):
for i in range(len(valid_list)):
xcoord_orig = valid_list[i][0]
ycoord_orig = valid_list[i][1]
xcoord1 = valid_list[i][0] + num_list[num]
ycoord1 = valid_list[i][1] + num_list2[num]
if 0 <= xcoord1 <= 7 and 0 <= ycoord1 <= 7:
piece = board[xcoord1][ycoord1]
if piece == player:
move_list = []
for i in range(2,8):
xcoordT = xcoord_orig
ycoordT = ycoord_orig - i
print(xcoord_orig, ycoord_orig)
if board[xcoordT][ycoordT] == computer:
move_list.append([xcoordT, ycoordT])
print(xcoord_orig, ycoord_orig)
This
for i in range(len(valid_list)):
...
for i in range(2,8):
Is epic fail. It can't be correct.

Categories