I'm a novice when it comes to recursion (and python, be kind haha), so I wanted to give it a go with a codewars problem (https://www.codewars.com/kata/541c8630095125aba6000c00/train/python)
I'm just super confused as to why the break gets ignored, and the recursion continues.
def digital_root(n):
x = list(str(n))
z = 0
while True:
for i in range(0, len(x)):
x[i] = int(x[i])
for i in x:
z = i + z
if z < 10:
break
elif z >= 10:
digital_root(z)
return z
print(digital_root(942))
After calling itself recursively, it's discarding the return value, so z and x remain unchanged. Change the recursive call to:
return digital_root(z)
That way the recursion will end. In fact, the while loop should never execute more than once, so you could just do:
def digital_root(n):
x = list(str(n))
z = 0
for i in range(0, len(x)):
x[i] = int(x[i])
for i in x:
z = i + z
if z < 10:
return z
return digital_root(z)
Or, if you'd rather eliminate the recursion entirely, all you really need is the following (which includes some additional simplifications):
def digital_root(n):
while n >= 10:
n = sum(int(d) for d in str(n))
return n
Here is my code in Python:
def my_sqrt(a):
x=1
while True:
y=(x+a/x)/2.0
if y==x:
break
x=y
return y
Output I get:
>>> my_sqrt(1.0)
>>> my_sqrt(2)
1.5
Looking to get:
my_sqrt(1.0)-->1.0
my_sqrt(2)-->1.41421356237
return ends the function and returns immediately. It's indented so it's in the loop and runs unconditionally at the end of the first iteration. Dedent it to run after the loop completes due to break:
def my_sqrt(a):
x = 1
while True:
y = (x + a / x) / 2.0
if y == x:
break
x = y
return y
Alternatively, since return ends the function and thus the loop, you don't even need break:
def my_sqrt(a):
x = 1
while True:
y = (x + a / x) / 2.0
if y == x:
return y
x = y
So, for school, I got an exercise on recursion, which goes as follows:
I'm given a string and a random int value 'N'. The string is a boolean expression, for example '3*x - 2* y <0' . The result has to be a list of tuples(x, y), (-N < x < N and -N < y < N), from all the possible tuple combinations who meet the expression. I did this exercise first with for loops etc and that was not so difficult, but then I had to do it recursively, and here's where I got stuck:
As you can see, I just add up x and y by '1' at the end of the code, which will give me all tuple combinations where X and Y are the same. For example, if N = 5, my code only evaluates the combinations (-4,-4), (-3,-3) ... (4,4) but not (-2,1) or (1,3) for example. So my question is: can anyone help me writing a recursive code which evaluates the boolean expression in all the possible tuple combinations?
My code has to be written recursively and I can't use functions as 'itertools' etc, it's not allowed in our school.
**MY CODE:**
def solution(expression, N,x=None,y=None):
if x is None: x = -N + 1
if y is None: y = -N + 1
res = []
if x >= N and y >= N:
return []
if eval(expression) == True:
res.append((x, y))
return res + solution(expression, N, x+1, y+1)
I have modified your code and I think it works now:
UPDATE: I have corrected this expression if x < N - 1 : to that one if x < N - 1 or y < N - 1:
def solution(expression, N, x=None, y=None):
if x is None: x = -N + 1
if y is None: y = -N + 1
res = []
if eval(expression) == True:
res.append((x, y))
# if x < N - 1 :
if x < N - 1 or y < N - 1:
if y < N - 1:
y += 1
else:
x += 1
y = - N + 1
return res + solution(expression, N, x, y)
else:
return res
print(solution('3*x - 2* y <0', 4))
Slightly different approach building on getting permutations for a list and in the end checking the expression. Not the prettiest code but does the job.
results = []
def check(expression, items):
x = y = None
if len(items) == 1:
x = y = items[0]
if eval(expression) and (x, y) not in results:
results.append((x, y))
if len(items) == 2:
x = items[0]
y = items[1]
if eval(expression) and (x, y) not in results:
results.append((x, y))
x = items[1]
y = items[0]
if eval(expression) and (x, y) not in results:
results.append((x, y))
if len(items) > 2:
for i in items:
remaining_elements = [x for x in items if x != i]
check(expression, remaining_elements)
expression = "3*x - 2*y < 0"
N = 4
items = range(-N + 1, N)
check(expression, items)
print(results)
this is my code so far
x = 100000
while x < 100000:
y = x + 100000
z = (3*10000)-1/(10-3)
if y != z:
x += 1
else:
print(x)
break
I know the answer should be 42857 but it's giving me 10000
The loop never executes because of the wrong initialization of x. Besides, z is constant (doesn't depend on x)
In your code it probably prints 100000 because of the broken indentation that makes else statement match the while. Since no break occurs, the last value of x is printed.
Better do a for loop. That works:
for x in range (1,100000):
y = x + 100000
z = x*10 + 1
if y == z//3:
print(x)
break
else:
# for loop completed without break
print("not found")
or in one line, using next and a generator comprehension:
result = next(x for x in range (1,100000) if x + 100000 == (x*10 + 1)//3)
in both cases the result is indeed 42857
I want it to stop once one of the variables gets to the desired number. Why does this code wait until both variables equal 20 or greater to end?
z = 20
x = 1
y = 0
while x < z or y < z:
inp = int(input('enter a number'))
if x > y:
y += inp
elif y > x:
x += inp
print(x, y)
or using something like these examples just keeps adding and never stops:
while x != z or y != z:
while x or y < z:
while x or y != z:
If the loop must stop when at least one of the variables is >= z, then you must use and to connect the conditions:
while x < z and y < z:
In your code, by using or you state that as long as one of the variables is < z, the loop must continue - and that's not what you want.