I've try to implement a recursion algorithm: 'X' is a global variable
def build_paths(m,n):
Result = []
Move = X[(m,n)][1]
if Move[0] == "None":
return(Move[0])
else:
if Move[0]=="UP":
m -= 1
elif Move[0]=="Left":
n -= 1
else:
m -= 1
n -= 1
Result = [build_paths(m,n),Move[0]]
return(Result)
This generates
[[[[[[['None', 'LEFT'], 'DIAG'], 'DIAG'], 'DIAG'], 'UP'], 'DIAG'], 'DIAG']
This is in essence what I want, but I really want is
['None','LEFT','DIAG','DIAG','UP','DIAG','DIAG']
Then I changed the 2nd last line of my recursion function to
Result = [build_paths(m,n)].extend(Move[0])
I think logically it is correct, i.e., I keep on extend my list, but eventually, it only outputs
None
I couldn't figure out why it happens...
build_paths() returns a list, and extend returns None (it modifies its argument), so you'd want:
Result = build_paths(m,n)
Result.append(Move[0])
Related
so i have a recursive function that i call 2 times with different arguments but the second time i call it, it doesnt give the correct result, it only gives the correct result when i call it the first time not the second time. Maybe a memoy or cache issue ?
def m(n):
s= [int(char) for char in str(n)]
product = 1
for x in s:
product *= x
return product
i = 0
def persistence(n):
global i
if len(str(n)) == 1:
return i
else:
j = m(n)
i+=1
s = persistence(j)
return s
print(persistence(39))
print(persistence(4)) #returns 3 when called with the top one but 0 when called alone
You have a condiction len(str(n)) in your function persistence, so that if n is a number between 0 and 9, you return global i.
When you call print(persistence(4)) alone, your function return global i (equal to 0).
When you call print(persistence(39)) first, and then print(persistence(4)), the first call set global i to 3, and the second call juste return the value value of global i, that as just been set to 3.
I don't really get what you want to do, but maybe your problem comes from the usage of global.
The problem is that you are using i as global variable. When you execute the method again, your i
def m(n):
s= [int(char) for char in str(n)]
product = 1
for x in s:
product *= x
return product
def persistence_recursive(n, i):
if len(str(n)) == 1:
return i
else:
j = m(n)
i+=1
s = persistence_recursive(j, i)
return s
def persistence(n):
return persistence_recursive(n, 0)
print(persistence(39)) # returns 3
print(persistence(4)) # returns 0
i = 0
def find_max(seq):
if i == len(seq) - 1:
return seq[0]
else:
first = seq[i]
i = i + 1
max_of_rest = find_max(seq)
return max(first, max_of_rest)
I do not know what is wrong with this function? It is a infinite loop.
Please check out the following solution and follow comments:
def find_biggest(_list, max_element, first_run):
"""
_list is a list of floats or integers or both,
max element is used to store max value,
first run checks if _list is not empty
"""
if first_run and not _list: # check if _list is not empty
raise ValueError("_list should have float or integer values inside")
first_run = False
if not _list: # exit from recursion, we checked all elements
return max_element
element = _list.pop() # take one element
if type(element) not in (int, float,): # check element type
raise TypeError("_list should contain only int or float values")
if element >= max_element: # check if it is more than max
max_element = element
return find_biggest(_list, max_element, first_run) # next step of recursion
if __name__ == "__main__":
# test
print(find_biggest([-1, 4, 2, 3, 1, 0, 10, 3, 1, 7], 0, True))
# print(find_biggest([], 0, True)) # empty case
# print(find_biggest([-1, 4, 2, 3, "1", 0, 10, 3, 1, 7], 0, True)) # string in list
You can check this:
def find_max(seq):
if len(seq) == 1:
return seq[0]
else:
if seq[0] > seq[1]:
seq.pop(1)
else:
seq.pop(0)
return find_max(seq)
Your code has a lot of indentation issues, that may skip execution of some lines.
Your code should look like this:
i = 0
def find_max(seq):
global i
if i == len(seq) - 1:
return seq[0]
else:
first = seq[i]
i = i + 1
max_of_rest = find_max(seq)
return max(first, max_of_rest)
You missed the global, and thus there is no definition of i inside the function.
Your code contains an IndentationError and does not reduce its data on recursive calls - hence data never getting shorter - hence never ending recursion:
def find_max(seq):
if i == len(seq) - 1: # fixed indentation here and below
return seq[0]
else:
first = seq[i]
i = i + 1
max_of_rest = find_max(seq) # never reducing your data size, hence endless
return max(first, max_of_rest)
This would be a fixed recursive solution:
def find_max(seq):
if not seq:
return None # or raise ValueError if you want find_max([]) to crash
if len(seq) == 1:
return seq[0]
else:
return max(seq[0], find_max(seq[1:]))
The problem is inheritently bad for recursive solutions, it is far better to solve it linearly (no max(..) calls needed):
def find_max_lin(seq):
if not seq:
return None
m = seq[0]
for value in seq[1:]:
m = m if value < m else value
return m
or even better simply use the built in max(sequence):
def find_max_builtin(seq):
# no need to create your own function for that though
return max(seq)
See ternary operator for an explanation of what m = m if value < m else value does.
You are using uneeded i variable, in recursion you have base case (your first if), and recursion case, which in this case would be accessing first and second element of your list. As you already checked that the list seq has more than 1 element, you can confidently access positions 0 and 1 of the list.
In your specific case, you are not really using recursion because you never reduce your case, but instead you increment an i variable, whilst recursion is based on always calling the same function with a "simpler" or reduced problem.
With that in mind, several things can be improved in your solution.
i = 0 # Not adviced
def find_max(seq):
# Here you want to check length, making it
# depend on i = problems
if i == len(seq) - 1:
return seq[0]
else:
first = seq[i] # Remove all references to i
i = i + 1 # Remove
# Here you want to call the function with the list
# except the element you know is lower, making the problem
# smaller until you get to the base case
# Instead you are calling find_max with the same
# sequence you had (infinite loop) and returning a
# totally different result.
max_of_rest = find_max(seq)
return max(first, max_of_rest)
A complete solution based on your code would look like this
def find_max(seq):
if len(seq) == 0:
return None
if len(seq) <= 1:
return seq[0]
else:
current_max = max(seq[0], seq[1])
reduced_seq = [current_max] + seq[2:]
return find_max(reduced_seq)
i = 0
def find_max(seq):
global i
if i == len(seq) :
return seq[0]
else:
first = seq[i]
i = i + 1
max_of_rest = find_max(seq)
return max(first, max_of_rest)
print(find_max([-10,2,4,-5]))
thank me later
What is the problem?
i even tried this at the starting soas to get a output
print("enter list elements")
arr = input()
def AlternateRearr(arr, n):
arr.sort()
v1 = list()
v2 = list()
for i in range(n):
if (arr[i] % 2 == 0):
v1.append(arr[i])
else:
v2.append(arr[i])
index = 0
i = 0
j = 0
Flag = False
#set value to true is first element is even
if (arr[0] % 2 == 0):
Flag = True
#rearranging
while(index < n):
#if 1st elemnt is eevn
if (Flag == True):
arr[index] = v1[i]
index += 1
i+=1
Flag = ~Flag
else:
arr[index] = v2[j]
index +=1
j += 1
Flag = ~Flag
for i in range(n):
print(arr[i], end = "" )
arr = [9, 8, 13, 2, 19, 14]
n = len(arr)
AlternateRearr(arr, n)
print(AlternateRearr(arr))
There's no error.
Just the driver code dosen't work i guess, there's no output.
no outputs
The only place where it could output anything is print(AlternateRearr(arr)). But let's take a look at AlternateRearr itself - what does it return?
There's no return statement anywhere in AlternateRearr, so the print would show None. Well, it's something, not completely nothing...
But the code doesn't reach this part anyway - if it did, it would throw an error because print(AlternateRearr(arr)) passes only one argument to the function AlternateRearr that takes 2 arguments. You don't have default value set for n, so it wouldn't work.
Okay, so we came to conclusion that we don't reach the print anyway. But why? Because you never call it. You only define it and it's a different thing from calling it.
You might encounter a problem if you just try calling it near your normal code - Python is an interpreted language, so your main-level code (not enclosed in functions) should be at the bottom of the file because it doesn't know anything that is below it.
Is that your complete code?
Because you do have a function called AlternateRearr but you never call it
Call the function and also pass the integer for iteration.
Add after the function:
AlternateRearr(arr, 5)
I have some textbook code that calls itself recursively. I don't understand the program flow. Here is the code:
def Recur_Factorial_Data(DataArray):
numbers = list(DataArray)
num_counter = 0
list_of_results = []
for num_float in numbers:
n = int(num_float)
1. result = Recur_Factorial(n)
list_of_results.append(result)
def Recur_Factorial(num):
if num == 1:
2. return num
else:
result = num*Recur_Factorial(num-1)
3. return result
if num < 0:
return -1
elif num == 0:
return 0
else:
return 0
In Recur_Factorial_Data, I loop through the data elements and call Recur_Factorial, which returns its value back to the calling function (Recur_Factorial_Data). I would expect that the lines marked 2 ("return num") and 3 ("return result") would always return a value back to the calling function, but that's not the case. For example, where the initial value (from the array DataArray) is 11, the function repeatedly calls itself until num is 1; at that point, the program falls to the line marked 2, but it does not loop back to the line marked 1. Instead, it falls through to the next line. The same happened on the line marked 3 -- I would expect it to return the result back to the calling function, but it does that in some cases and not in others.
I hope this is enough description to understand my question -- I just don't know why each return does not loop back to return the result to the calling function.
EDIT: The question at Understanding how recursive functions work is very helpful, and I recommend it to anyone interested in recursion. My question here is a bit different -- I asked it in the context of the program flow of the Python code where the recursive function is called.
If it call itself recursively 10 times, it will be at the 10th level of recursion and should go back 10 times at the point where there was a recursive call with an intermediate result and only then exit from the recursive function to the place where it was called. Learn more about recursion
Also try to rearrange instructions in Recur_Factorial function in this way:
def Recur_Factorial(num):
if num < 0:
return -1
elif num == 0:
return 0
elif num == 1:
return num
else:
return num * Recur_Factorial(num-1)
my mission is to build a function which return the number of "uncles" in a given binary tree A node is an uncle only if his brother(the second child of his father) has children.
This is my code:
"
def uncle(root,count = None):
if count is None:
count = [0]
a,b = 0,0
if root.left:
if root.left.left or root.left.right:
a = uncle(root.left)
a = 1
if root.right:
if root.right.right or root.right.left:
b = uncle(root.right)
b = 1
if b > 0:
count[0] += 1
if a > 0:
count[0] += 1
return count[0]
"
And this is the bin_tree class:
"
Class bin_tree():
def __init__(self,data, left_child = None, right_child = None):
self.data = data
self.left = left_child
self.right = right_child
"
My problem is this:
When I switched the lines:
a = uncle(root.left)
a = 1
It didn't work(meaning = the variable a has changed back its value to 0 for some reason), and I absolutely doesn't know why..I thought it should have worked because
it doesn't matter if I call in recursion to the function first or say a = 1 firstly.
Can someone help me please?
I haven't tested this but it should work. The code you wrote can be cut down a lot.
For starters you have count as a list when it doesn't really need to be.
Your a and b never get used so there is no point in assigning anything to them. That is probably why you get an error regardless of what value you give to a or b.
Then you don't need to check if a or b are greater than 1. You can just increment count when you find out there is another uncle in the tree.
However the main reason that it is not working is that everytime you call uncle you are not passing your new count. This means that it takes the default value of which you have given as None. This then causes the list to reset to [0]. Well actually a new list is been created which is different from the previous one even though they have the same name. So although you may think you are updating the same count, you are not. This is a scope problem.
def uncle(root,count=0):
if root.left:
if root.left.left or root.left.right:
count = uncle(root.left, count)
count += 1
if root.right:
if root.right.right or root.right.left:
count = uncle(root.right, count)
count += 1
return count