Search code examples
pythonrecursionlinelimit

Python shell restarts after printing 4788 lines


So I've been trying to make a recursive-heavy code for completely ethical purposes and I noticed the python shell would restart after about 30 seconds.

At first I thought it was stack overflow from a memory leak so i dealt with it appropriately; still no luck. I then used tracemalloc to see my memory usage and saw that it was only getting to about 1.3 MB before restarting. I tried a bunch of methods to stop memory leak all giving different final memory sizes but still restaring.

This was when I noticed that, each time, it restarts after printing 4788 lines regardless of the amount of total memory used.

Is there a limit to how many lines python can print or something? Pls help!

import random
import sys
import gc
import tracemalloc

tracemalloc.start()

def cleartrash():
    #gc.collect()

##    del genphrase

    print('clearedddddddddddddddddddddddddd')

sys.setrecursionlimit(99999999)
capitalsandlowers = ('qwertyuiopasdfghjklzxcvbnm')

print ('monkey experiment')
def generatephrase():
    generatedlength = random.randint(5,5)
    genphrase = ( ''.join(random.choice(capitalsandlowers) for i in range(generatedlength)) )
    
    print(genphrase)
    
    if genphrase == 'henry':
        print('done',genphrase)
    else:
        current, peak = tracemalloc.get_traced_memory()
        print(f"Current memory usage is {current / 10**6}MB; Peak was {peak / 10**6}MB")

        #cleartrash()
        del genphrase
        del generatedlength
        #gc.collect()
        generatephrase()

generatephrase()
tracemalloc.stop()

Sorry for having to include my entire code but I simply have no clue where or how to go about fixing/ where the problem is.

Thanks in advance!


Solution

  • This isn't a valid use of recursion as the problem itself isn't recursive. If we change the code to be iterative, it runs in a fixed amount of memory indefinitely:

    from random import randint, choices
    from string import ascii_lowercase as capitalsandlowers
    
    print("Monkey Experiment")
    
    def generatephrase():
        while True:
            generatedlength = randint(5, 5)
            genphrase = ''.join(choices(capitalsandlowers, k=generatedlength))
    
            print(genphrase)
    
            if genphrase == 'henry':
                print("Done:", genphrase)
                break
    
    generatephrase()
    

    In my test run, it found the target phrase in four minutes:

    Done: henry
    193.963u 28.280s 3:53.61 95.1%  0+0k 0+0io 0pf+0w
    

    Having tested 9,356,241 random strings.