Recursion in python, python crashes everytime it is run

physics, python, recursion, sys

Solution

(This got too big for a comment.)

Recursion is good for solving many problems, but iterating a numerical simulation is not one of them. The number of stack frames is a limited quantity, to be used sparingly (Python has a limit on the number of stack frames because it's usually an error when you use too many of them). You might be running out of memory allocated for the stack (as opposed to heap) or you might be running out of all memory, stack and heap. Out-of-memory errors sometimes come without warning because the program or operating system doesn't have the resources to generate a warning.

You'll probably find that your program is more efficient, easier to debug, and maybe even bug-free if you rewrite it as a `for` or `while` loop.

Some programming languages, like Scheme, encourage the use of recursion for iteration, but these languages internally convert your recursive functions into `while` loops ("tail-call optimization"). Python is not one of those languages: every time you call a function, it creates a new stack frame and does not delete the old stack frame until the recursion ends, which is effectively like a memory leak. (That is, the objects are no longer useful, but they're still referenced and still in memory.)

Problem

I am trying to write a program that uses recursion to solve for the velocity of an object shot straight into the air and calculates when it hits the ground while accounting for gravity changing with altitude with this equation `g(s) = G∙ME / (RE + s)^2` displacement with this equation `s(t) = s(t-∆t) + v(t)∙∆t` and velocity with this equation `v(t) = v(t-∆t) - g(s(t-∆t)) ∙ ∆t` I am using the previous values (denoted by t-∆t) as inputs and then updating the variables and returning them which makes sense to me but I must be doing something wrong. Originally I was getting an error saying the maximum recursion limit was exceeded but after some googling I found that I should change the recursion limit. Now the program seems like it begins to run but then python crashes before outputing anything. I have been unable to figure out what I could do to make this work. Any help would be greatly appreciated ``` import math as m import sys sys.setrecursionlimit(20000) # # # Method that runs the simulation # def run(deltat, G, ME, RE, velocity): # set initial time to 0 s = 0 t = 0 # Save the initial velocity because it is needed to find when the ground is hit initialvelocity = velocity # while the height is greater than 0 execute the loop while s >= 0: # Find the height based on gravity, and velocity s = calculatedisplacement(t ,deltat, velocity, s, G, ME, RE) # Calculate the velocity based on the changing gravity velocity = calculatevelocity(velocity, t ,deltat, s, G, ME, RE) # If s is larger than 0 print where the object is if s >= 0: print ("At time t = " + str(t) + " The object is " + str(s) + " meters high") t = t + deltat print("Time: " + str(t)) elif s < 0: print ("The object hits the ground at t = " + str(quadraticsolver((-0.5 * (G * ME)) / (m.pow(RE, 2)), initialvelocity, 0))) # Function used to calculate gravity def calculategravity(s, G, ME, RE): gravity = ((G * ME) / (m.pow((RE + s), 2))) print ("Gravity = " + str(gravity)) return gravity # Function used to calculate height def calculatedisplacement(t ,deltat, velocity, s, G, ME, RE): s = s + (calculatevelocity(velocity, t ,deltat, s, G, ME, RE) * deltat) print("height = " + str(s)) return s # Function used to calculatevelocity def calculatevelocity(t ,deltat, velocity, s, G, ME, RE): velocity = velocity - ((calculategravity(G, ME, RE,calculatedisplacement(t ,deltat, velocity, s, G, ME, RE)))* deltat) print("Velocity " + str(velocity)) return velocity # Used to solve quadratic equations and find where the object hits the ground def quadraticsolver(a, b, c): discriminant = (m.pow(b, 2)) - (2 * a * c) # Two solutions to account for the + or - in the quadratic formula solution1 = (((-b) + (m.sqrt(discriminant))) / (2 * a)) solution2 = (((-b) - (m.sqrt(discriminant))) / (2 * a)) # One solution will always be 0 because height is 0 when time is 0 so return the solution that is not zero # This is the time when height = 0 if solution1 == 0: return solution2 elif solution2 == 0: return solution1 ```

Original source