Maximum-recursion-depth-exceeded-while-calling-a-python-object

python

#1

def create_folder_stress(self,testcasename,directory,devices,index):
i = str(index)
t = testcasename
print t
if not os.path.exists(directory):
os.makedirs(directory)
today = datetime.date.today()
todaystr = today.isoformat()
myfolder=os.path.join(directory, todaystr)
if not os.path.isdir(myfolder):
os.mkdir(myfolder)
mypath=os.path.join(myfolder, t)
if not os.path.isdir(mypath):
os.mkdir(mypath)
myfullpath=os.path.join(mypath, i)
if not os.path.isdir(myfullpath):
os.mkdir(myfullpath)
if devices == "1":
# print devices
finalfolder1=os.path.join(myfullpath, "DUT1")
if os.path.exists(finalfolder1):
os.system('rmdir /S /Q \"{}\"'.format(finalfolder1))
src = "C:\DUT1"
dst = myfullpath
shutil.move(src, dst)
if devices == "2":
# print devices
finalfolder1=os.path.join(myfullpath, "DUT1")
print finalfolder1
if os.path.exists(finalfolder1):
os.system('rmdir /S /Q \"{}\"'.format(finalfolder1))
finalfolder2=os.path.join(myfullpath, "DUT2")
if os.path.exists(finalfolder2):
os.system('rmdir /S /Q \"{}\"'.format(finalfolder2))
src = "C:\DUT1"
dst = myfullpath
shutil.move(src, dst)
src = "C:\DUT2"
dst = myfullpath
shutil.move(src, dst)
if devices == "3":
print devices
finalfolder1=os.path.join(myfullpath, "DUT1")
if os.path.exists(finalfolder1):
os.system('rmdir /S /Q \"{}\"'.format(finalfolder1))
finalfolder2=os.path.join(myfullpath, "DUT2")
if os.path.exists(finalfolder2):
os.system('rmdir /S /Q \"{}\"'.format(finalfolder2))
finalfolder3=os.path.join(myfullpath, "DUT3")
if os.path.exists(finalfolder3):
os.system('rmdir /S /Q \"{}\"'.format(finalfolder3))
src = "C:\DUT1"
dst = myfullpath
shutil.move(src, dst)
src = "C:\DUT2"
dst = myfullpath
shutil.move(src, dst)
src = "C:\DUT3"
dst = myfullpath
shutil.move(src, dst)
if devices == "4":
finalfolder1=os.path.join(myfullpath, "DUT1")
if os.path.exists(finalfolder1):
os.system('rmdir /S /Q \"{}\"'.format(finalfolder1))
finalfolder2=os.path.join(myfullpath, "DUT2")
if os.path.exists(finalfolder2):
os.system('rmdir /S /Q \"{}\"'.format(finalfolder2))
finalfolder3=os.path.join(myfullpath, "DUT3")
if os.path.exists(finalfolder3):
os.system('rmdir /S /Q \"{}\"'.format(finalfolder3))
finalfolder4=os.path.join(myfullpath, "DUT4")
if os.path.exists(finalfolder4):
os.system('rmdir /S /Q \"{}\"'.format(finalfolder4))
# shutil.rmtree(finalfolder)
src = "C:\DUT1"
dst = myfullpath
shutil.move(src, dst)
src = "C:\DUT2"
dst = myfullpath
shutil.move(src, dst)
src = "C:\DUT3"
dst = myfullpath
shutil.move(src, dst)
src = "C:\DUT4"
dst = myfullpath
shutil.move(src, dst)
return myfullpath


#2

this happens when there is too much resources(memory) been taken via recursion. one suggestion is to use generators


#3

Thanks Rydan, Can u please construct my code through generators as i am new to python. This wil be much appreciated.


#4

If you are going to post this much code please codify it with the </> key or put

```python
# Code here
```

Around your code, those little ticks are from the tilde key.

Moving on.

Ok first things first import these

from os.path import join as join_
from os import getcwd
from os import listdir

Now move that huge lump of code somewhere else, and do something more elegant, like the following

# The following few line can be placed in an .ini file and loaded so your whole program's file location can change at once.
_path = getcwd()
_path_data = join_(_path, "Data")

def _create_dirs():
    if not path.exists(_path_gamedata):
        makedirs(join_(_path, "Data"))
    if not path.exists(_path_data_pointmaps):
        makedirs(join_(_path_data, "PointMaps"))

def check_dir_files(path):
    """
    Here you can have it return all the files in a dir 
    so you can search through it or have a GUI let you select from one.
    """
    return listdir(path)

def load_file(file, path, device):
    data = []
    with open(join_(path, file, "DUT%s" % device)) as file:
        file.seek(0)
        for line in file:
            data.append(eval(line))
    return data

# Then at ens create a __name__ statement and call your _create_dirs once
if __name_- == "__main__":
    _create_dirs()
    # Code to interact with rest of program IE GUI

What I am getting at is that your code is convoluted because you have multiple parts rather than a huge class that does unnecessary things.

Not only are short methods/functions easier to read but you can call on the specific parts you need ONLY when you need them.

With your dir creation you can also do something like the following, it is easier to update and maintain.

_current_dir = getcwd()
_dir_names = {
    1: 'Data',
    2: 'PointMaps'
}

def _create_dirs(path_data):
    for item in path_data:
        if not path.exists(join(_current_dir, item)):
            makedirs(join(_create_dir, item))

_create_dirs(_dir_names)

#5

@coremaster00380 @rydan

While it is acceptable to use generators for this type of task they are ill suited for it.

When loading and unloading files you want to have them as simple as possible, you also want them to throw an error anytime something unexpected happens so that you can catch it and then proceed to fix the issue.

To much error handling in a load/save system will cause headaches like noting else. So you want to keep your exception handling to basic needs.

Now on to generators, they are mighty fun things that codeacademy never really gets to and they only touch what list comprehension(a generator) can do.

One thing you can do is make state machines,

State Machine

# Generators need to have a yield in the main body
def on_off_machine(state=1):
    while True:
        yield state
        state *= -1

# Then you call it like the following
state = on_off_machine()
next(state)
next(state)

OR

# This will run forever as is, so don't do this unless you want it to.
for state in on_off_machine():
    print(state)

Now the SUPER nice thing about generators is that they hold on to their state even after calling them, as long as you have it stored to a variable or other data type the state is kept in memory. Thus you can make a state machine!

Here is another use for a generator,

def multiples_of_three(start=0):
    current_multiple = start
    while True:
        yield 3 * current_multiple
        current_multiple += 1

# OR

def is_prime(number):
    if number > 1:
        if number == 2:
            return True
        if number % 2 == 0:
            return False
        for current in range(3, int(sqrt(number) + 1), 2):
            if number % current == 0:
                return False
        return True
    return False


def next_prime(default_num=1):
    while True:
        if is_prime(default_num):
            yield default_num
        default_num += 1

# OR

def generate_pair_factors(number=2):
    while True:
        for i in range(1, number):
            if number % i == 0:
                yield int(i), int(number / i)
        break


def generate_pythagorean_triplets_dickson(number):
    triplets = []
    r = number
    factors = generate_pair_factors(int(r**2 / 2))
    for pair in factors:
        s = pair[0]
        t = pair[1]
        x = r + s
        y = r + t
        z = r + s + t
        if x**2 + y**2 == z**2:
            triplets.append((x, y, z))
    return triplets

As you can see there are tons of ways to use generators! Do a little research on them and you will see the power you hold in your hands when you use them!

As always best of luck!


#6

Thanks a lot zeziba, I appreciate your help and will surely your guidelines, I will try your code


#7

Actually What i wanted is :

1) First Create directory in the location : D:\srk\Robot_Logs
2) Then inside Robot_Logs directory create a directory by name as CURRENT DATE
3) Then Inside CURRENT DATE folder, COPY folders DUT1 DUT2 from other location

But everytime we have to create directory only if it doesnt exist


#8

The load/save stuff I worked on a decent amount when i was creating my Battleship AI. I wanted to save what the AI was computing for that turn so I had to come up with a way to save to a dir and change the name of the save, having the separate players as two different files and having the game number as the lead of the file name also.

Here is some parts of my code to save a file from my AI's point-maps.

from os.path import join as join_
from os import getcwd
from os import makedirs
from os import path

_game_number = None
_path = getcwd()
_path_gamedata = join_(_path, "GameData")
_path_gamedata_pointmaps = join_(_path_gamedata, "point_maps")

def _create_master_game_number():
    global _game_number
    try:
        with open(join_(_path_gamedata, "GameNumber.txt"), "r+") as file:
            file.seek(0)
            game_number = file.readline()
            _game_number = int(game_number[12:]) + 1
        with open(join_(_path_gamedata, "GameNumber.txt"), "w") as file:
            file.seek(0)
            file.write("Game Number: %s" % str(_game_number))
    except FileNotFoundError:
        with open(join_(_path_gamedata, "GameNumber.txt"), "w") as file:
            file.seek(0)
            _game_number = 1
            file.write("Game Number: %s" % str(_game_number))

def _create_dirs():
    if not path.exists(_path_gamedata):
        makedirs(join_(_path, "GameData"))
    if not path.exists(_path_gamedata_pointmaps):
        makedirs(join_(_path_gamedata, "point_maps"))

class AI(Player):
    self._point_map = {(x, y): 0 for x in range(1, self.sides+1) for y in range(1, self.sides+1)}

    def _save_ai_point_board(self):
        try:
            with open(join_(_path_gamedata_pointmaps, "%s_%s.txt" % (_game_number, id(self.playerType))), "a+") as file:
                file.write("{'turn_%s': %s}\n" % (turns, str(self._point_map)))
        except FileNotFoundError:
            open(join_(_path_gamedata_pointmaps, "%s_%s.txt" % (_game_number, id(self.playerType))), "w+").close()
            self._save_ai_point_board()

i didn't paste all the code but you can find it all here, the save function uses a bunch of methods to cut down on the line count. While it may seem complex it really isn't it's just a condensed loop and if statements.


#9

Just change the path sting, and that's all there is to it.

Doing it like this makes it easy to maintain.

_path = getcwd() # Just change this for main path
_path_data = join_(_path, "Data") # Change this to your sub path

def _create_dirs():
    if not path.exists(_path_gamedata):
        makedirs(join_(_path, "Data")) # You can just use the variable here or what I did
    if not path.exists(_path_data_pointmaps):
        makedirs(join_(_path_data, "PointMaps")) # Same here

#10

@coremaster00380

You can also change this to meet your needs and would most likely be the easiest to maintain

_current_dir = getcwd()
_dir_names = {
    1: 'D:',
    2: 'srk',
    3: 'Robot_Logs'
}

# You can also rename the keys into things like 'root' or what ever have you
def _create_dirs(path_data):
    for item in path_data:
        if not path.exists(join(_current_dir, item)):
            makedirs(join(_create_dir, item))

_create_dirs(_dir_names)

Then create a function to generate the robot folder, just use the same path data you have in the dir dict and just simply use join with the information you want.

EXAMPLE:

# We are assuming you already have the paths built for the base structure,
# so we only need to add a robot folder
import time

def create_robo_folder(end_path, robot_info):
    dir  = join("%s%s%s" % (path[1], path[2], (robo_info + str(time.time()))))
    if not path.exists(dir):
        makedirs(dir)

Something like that would definitely do the trick for you.

You can also pass a dictionary to your file builder with all the information you need. If you create a robot class and store the path you want it to have in the class it's self you can then pass the class __dict__ to the dir builder and just pull the information out of the passed object like a normal dict object.

EXAMPLE:

class Robot(object):
    
    def __init__(self):
        self.save_location = getcwd()
        self.robot_name = 'name'
        self.robot_time = 'time'

Then when you pass your dict to your builder you do it like this,

def builder(**dict_obj):
    print(**dict_obj)

robot = Robot()
builder(**robot.__dict__)

Or you can select what attributes to send too, it's all up to you as the programmer.

As always Best of Luck!


#11

Thanks a lot for ur detailed reply, My last question, How does ur code get me out of Maximum recursion depth error issue, I think here also recursion happening, Can u please explain me. And by the way if i try to execute the below code

import os
import traceback
import sys

sys.setrecursionlimit(100000)

import subprocess
import shutil
import time, datetime
from os.path import join as join_
from os import getcwd
from os import listdir
from inspect import getsourcefile
from os.path import abspath

path_data = "D:\Tech_Connect"
currentdir = getcwd()
dirnames = {
1: 'D:',
2: 'srk',
3: 'Robot_Logs'
}

def createdirs(path_data):
for item in path_data:
if not path.exists(join(currentdir, item)):
makedirs(join(createdir, item))

createdirs(dirnames)

I get this error:
Traceback (most recent call last):
File "F:/create_dir.py", line 27, in
createdirs(dirnames)
File "F:/create_dir.py", line 24, in createdirs
if not path.exists(join(currentdir, item)):
NameError: global name 'path' is not defined


#12

Sorry to bother you, I m new to programing and python, I m trying hard to do it so thanks for patiently replying to me


#13

Never mind i solved that Name Error issue NameError: global name 'path' is not defined


#14

Get rid of that line, if you are having recursion issues run a debugger while you run your code or a profiler.

There is a builtin one

import cProfile

def afunction(stuff):
    print(stuff)

cProfile.run("afunction('word')")

You can run it on all of your code just create a function to run all of your code autonomously and then call it on that function it will tell you the time it take s and how many times a function is called normally and recursively. Then go from there to get rid of the stuff that is not needed.

As for that function I purposely had the wrong names in there so that you would notice them,. It does you no good if I tell you how to do everything and not give you a chance to learn it for yourself.

Also with recursion, you should never even approach the builtin limit of 1000 if you have good stable code. So do the debugger and profiling and you will be able to then optimize your code.

As always best of luck!


#15

Thanks a lot, Code is working like a charm.