Convert double for loop into recursion func - arrays

I work with two 3D arrays, which the second arr changes according to the first arr.
I try to turn double for loop into a recursive function, but the same error is repeated, RecursionErroe: maximum recursion depth exceeded in comparison.
The for loops i'm trying to convert:
def to_rec(arr):
new = arr.copy()
row_max = len(arr)
col_max = len(arr[0])
for i in range(row_max):
for j in range(col_max):
new[i, j, :] = 255- arr[i, j, :]
return new
RECURSIVE
def rec2(img, row_max, col_max, i, j, new):
if j == col_mac:
return new
else:
new[i, j, :] = 255 - img[i, j, :]
return rec2(img, row_max, col_max, i, j+1, new)
****************************************************
def rec1(img, row_max, col_max, i, j, new):
if i == row_max:
return new
else:
rec2(img, row_max, col_max, i, j, new)
return rec1(img, row_max, col_max, i+1, 0, new)
********************************************************
def to_rec(arr):
......
# The same data as in to_rac func with the for loop
......
new = rec1(arr, row_max, col_max, 0, 0, new)
return new
I can't figure out what is wrong

While this doesn't answer your question about recursion depth, I think the solution is quite simple. It seems you want to invert an image (new[i, j, 0] = 255- arr[i, j, 0]) by looping over all pixels in the image, and then manipulating the pixel value. This can be done highly efficiently using NumPy:
import numpy as np
img = load_img_data() # Replace this by your own data
new_img = 255 - np.array(img)
When your data is stored in a NumPy array, you can trivially perform scalar arithmetics (addition, multiplication, etc.) on matrices. This way you don't have to perform nested loops (or recursive operations).

The search term RecursionError: maximum recursion depth exceeded has plenty of answers on SO - the reason is simple:
you try to recuse but your function/data does not allow it:
data too big so that you would need to recurse max_depth+n times to solve it
your data (or method) will never reach the end-condition of your recursion
your function has no end condition
Your recursion is flawed and you never reach the end - hence you dive deeper and deeper and put callstack upon callstack until python raises the error to avoid a Stackoverflow from accumulated stack frames due to thousands of function calls.
Ex:
# recurses crashes every time (no end condition)
def no_end_1(k = True):
no_end_1(not k)
# recursion works if you call it with some data but not with other data
def no_end_2(i):
if i == 0:
return "Done"
no_end_2(i-1)
no_end(25) # works
no_end(-3) # crashes
def flawed_collatz_testmethod(a):
# collatz conjectur holds for numbers up to
# 2.361.183.346.958.000.000.001 (wikipedia), they converge on 1
if a%2 == 0:
new_a = a//2
else:
new_a = 3*a+1
if new_a < 1:
print ("Collatz was wrong")
else:
# will eventually end in a loop of 4-2-1-4-2-1-4-2-1-... and crash
flawed_method(new_a)
In any case .. you need to fix your function. Best way to do it is to take a small datasample, a pen and paper and draw/calculate what the function does to see why it recurses endlessly.

Related

How to use a While Loop to repeat the code based on the input variable

i'm having a rough time trying to do a loop with the while function.
Basicly i want the code to show me all prime numbers from 0 to the number i wrote in input.
Then, to ask a question if i want to do it one more time (if yes to repeat the code from the start) or if not to exit.
How i got it now is just to repeat the last results infinitely.
All results i found online with the while loop don't really explain how to repeat a certain part of the code.
I'm by no means even a little bit educated when it comes to this stuff so if its a stupid question, please forgive me.
# Python program to print all primes smaller than or equal to
# n using Sieve of Eratosthenes
def start(welcome):
print ("welcome to my calculation.")
value = input("number?:\n")
print(f'you have chosen: {value}')
value = int(value)
def SieveOfEratosthenes(n):
prime = [True for i in range(n + 1)]
p = 2
while (p * p <= n):
if (prime[p] == True):
for i in range(p ** 2, n + 1, p):
prime[i] = False
p += 1
prime[0] = False
prime[1] = False
print("Primary numbers are:")
for p in range(n + 1):
if prime[p]: print(p)
# driver program
if __name__ == '__main__':
n = value
SieveOfEratosthenes(n)
pitanje = input("do you want to continue(yes/no)?")
while pitanje == ("yes"):
start: SieveOfEratosthenes(n)
print("continuing")
if pitanje == ("no"):
print("goodbye")
strong text
Firstly you should remove
value = input("number?:\n")
print(f'you have chosen: {value}')
value = int(value)
from the top of your code, everything must be inside your __main__ program.
Basically what you need to do is create a main While loop where your program is gonna run, it will keeps looping until the response is not "yes".
For each iteration, you ask a new number at the beggining and if it has to keep looping at the end.
Something like this:
# driver program
if __name__ == '__main__':
# starts as "yes" for first iteration
pitanje = "yes"
while pitanje == "yes":
# asks number
value = input("number?:\n")
print(f'you have chosen: {value}')
value = int(value)
# show results
start: SieveOfEratosthenes(value)
# asks for restart
pitanje = input("do you want to continue(yes/no)?")
#if it's in here the response wasn't "yes"
print("goodbye")

Updated Python Gurus: Find the difference between these two running sum functions(do they do the same thing?) Hackerrank: Array Manipulation

On Hackerrank, I was solving the Array Manipulation question and when I submitted my code with runningSum_A my code passed all the test cases. But when I submitted runningSum_B, it failed many test cases. Can someone please explain the logic behind this? Is there something inherently different between these two functions, because they seem the same to me? (Link to the question: https://www.hackerrank.com/challenges/crush/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=arrays)
def runningSum_A(arr):
maxSum = -math.inf
runningSum = 0
for i in arr:
runningSum += i
maxSum = max(maxSum, runningSum)
return maxSum
def runningSum_B(arr):
for i in range(1, len(arr)):
arr[i] += arr[i - 1]
return max(arr)
def arrayManipulation(n, queries):
arr = [0]*(n+2)
for query in queries:
arr[query[0]] += query[2]
arr[query[1]+1] -= query[2]
############################################################
#call runningSum_A or runningSum_B function here

For loops with promises

I want to write three for loops with promises something like this:
for i = 1 .. 3
for j = 1 .. 5
for k = 1 .. 6
post call to db to check if there is item on location i, j, k
step 1: check 1,1,1
step 2: check 1,1,2 item is found or inc next index
...
I searched for similar questions but I get only one-dimensional array loops examples.
I found this very hard problem and I hope you guys can help me. Thanks.
piping promises can be done linearly. So in your case, you have to first generate an array which holds all possible combinaisons like so:
$locations = [
[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 1, 4],
....
];
Then you can easily loop over this array and pipe your promises. Hope this helps
You can't combine a synchronous for loop with asynchronous operations and get things to sequence properly because there's no way to make a for loop "wait" for a promise to finish. The for loop runs synchronously so it will just start all the async operations at once.
So, instead you have to do your iterations another way. If you were iterating just one parameter, there would be a number of ready-made ways to do that, but I'm not aware of any pre-built solutions for iterating three nested variables so you will have to build your own. Here's one way to do it. This method is custom coded for your iterations which makes it a bit less code that a general scheme:
// fn gets called like this fn(i, j, k) and must return a promise
function iterateLevels(fn) {
var i = 1, iMax = 3;
var j = 1, jMax = 5;
var k = 1, kMax = 6;
function next() {
if (k > kMax) {
j++;
k = 1;
}
if (j > jMax) {
i++;
j = 1;
}
if (i > iMax) {
return;
}
return fn(i, j, k).then(function(result) {
k++;
// process result here
// if you want to continue processing, then
return next();
});
}
return next();
}
Here's a working demo implementation using a promise with a random delay: https://jsfiddle.net/jfriend00/q2Lnhszt/
The next() function with the outer scope variables i, j and k is essentially a state machine where each time you call next() it runs the next iteration and updates its state.
This could be made generic so you pass in how many levels of iteration and what the start and stop values for each level are and you could pass in a function for processing the result. Making it generic adds more code to the implementation and makes the logic a little harder to follow.

Force evaluate index expression before passing to sum()

I want to write an (somehow) enhanced sum function which takes a number of indices at once, but I cannot understand how to get it work. Here is what I currently have:
(%i1) nsum(indexes, expr) :=
if indexes = []
then expr
else nsum(rest(indexes), sum(expr, first(indexes),1, N)) $
(%i2) nsum([i,j], i+j), nouns;
sum: index must be a symbol; found intosym(first(indexes))
#0: nsum(indexes=[k,j],expr=k+j)
I think this could be fixed by forcing Maxima expand first(indexes) into a symbol before passing to sum function. I tried ''(...) and ev(..., nouns), but without any success.
After some reading and trying I came to the following solution which uses apply function to pre-evaluate arguments for sum:
nsum(indexes, expr) :=
if indexes = []
then expr
else nsum(rest(indexes), apply(sum, ['expr, indexes[1], 1, N])) $
UPD1:
Unfortunately, there is something wrong with the above code, as it works well only for relatively simple expressions. In my case the straightforward approach works fine where nsum fails:
(%i1) rot[i](f) := sum(sum(sum(sum(
G[r,i]*G[q,j]*w[i,j,k]*('diff(f[k], y[q]) + sum(K[k,q,m]*f[m], m, 1, N)),
r, 1, N),
j, 1, N),
k, 1, N),
q, 1, N) $
(%i2) rot2[i](f) := nsum( [r,j,k,q],
G[r,i]*G[q,j]*w[i,j,k]*('diff(f['k], y[q]) + sum(K[k,q,m]*f[m], m, 1, N))) $
(%i3) rot[1](f);
(%o3) ... Yelds the result.
(%i4) rot2[1](f);
apply: subscript must be an integer; found: k
lambda([i,j],diff(ys[i],x[j]))(i=k,j=1)
UPD2:
The code works indeed. It was 'k accidentally left in rot2 definition instead of just k.

Array.tabulate StackOverFlowError

I'm new to Scala and I was playing around with the Array.tabulate method. I am getting a StackOverFlowError when executing this simplified piece of code snippet (originally a dp problem).
import Lazy._
class Lazy[A](x: => A) {
lazy val value = x
}
object Lazy {
def apply[A](x: => A) = new Lazy(x)
implicit def fromLazy[A](z: Lazy[A]): A = z.value
implicit def toLazy[A](x: => A): Lazy[A] = Lazy(x)
}
def tabulatePlay(): Int = {
lazy val arr: Array[Array[Lazy[Int]]] = Array.tabulate(10, 10) { (i, j) =>
if (i == 0 && j == 0)
0 // some number
else
arr(0)(0)
}
arr(0)(0)
}
Debugging, I noticed that since arr is lazy and when it reaches the arr(0)(0) expression it tries to evaluate it by calling the Array.tabulate method again -- infinitely over and over.
What am i doing wrong? (I updated the code snippet since I was basing it off the solution given in Dynamic programming in the functional paradigm in particular Antal S-Z's answer )
You have effectively caused an infinite recursion. You simply can't reference a lazy val from within its own initialization code. You need to compute arr(0)(0) separately.
I'm not sure why you are trying to access arr before it's built, tabulate seems to be used to fill the array with a function - calling arr would always result in infinite recursion.
See Rex's example here (and a vote for him), perhaps that will help.
In a multidimensional sequence created with tabulate, is the innermost seq the 1. dimension?
I was able to solve this by wrapping arr(0)(0) in Lazy so it is evaluated as a call-by-name parameter, thereby not evaluating arr in the tabulate method. The code that I referenced was automatically converting it using implicits (the binary + operator), so it wasn't clear cut.
def tabulatePlay(): Int = {
lazy val arr: Array[Array[Lazy[Int]]] = Array.tabulate(10, 10) { (i, j) =>
if (i == 0 && j == 0)
1 // some number
else
new Lazy(arr(0)(0))
}
arr(0)(0)
}
Thanks all.

Resources