HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Script for creating a hierarchy of directories

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
scriptcreatinghierarchyfordirectories

Problem

This script creates a hierarchy of directories. Is this a good approach or can it be made better? I am mainly concerned with maintainability here, not efficiency. Suppose I wanted to add more directories to this hierarchy. Would this structure of the script make it easier to do?

Hierarchy

./project_euler
    ./001_050
    ./051_100
    ...
    ./401_450
./codechef
    ./easy
    ./medium
    ./hard
./spoj
./functions
./utilities


The script

import os

TOP = ['project_euler', 'codechef', 'spoj', 'functions',
       'utilities']
CODECHEF = ['easy', 'medium', 'hard']

def safe_make_folder(i):
    '''Makes a folder if not present'''
    try:  
        os.mkdir(i)
    except:
        pass

def make_top_level(top):
    for i in top:
        safe_make_folder(i)

def make_euler_folders(highest):
    def folder_names():
        '''Generates strings of the format 001_050 with
        the 2nd number given by the function argument'''
        for i in range(1,highest, 50):
            yield (
                'project_euler' + os.sep +
                str(i).zfill(3) + '_' + str(i + 49).zfill(3)
                )

    for i in folder_names():
        safe_make_folder(i)

def make_codechef_folders(codechef):
    for i in codechef:
        safe_make_folder('codechef' + os.sep + i)

def main():
    make_top_level(TOP)
    make_euler_folders(450)
    make_codechef_folders(CODECHEF)

if __name__ == "__main__":
    main()

Solution

One of the things I would do is remove the double occurrence of the strings 'project_euler' and 'codechef'. If you ever have to change one of these in TOP, you are bound to miss the repetition in the functions.

You should at least use TOP[0] in make_euler_folders() and TOP[1] in make_codechef_folders. A better approach however would be to take both definitions out of TOP and change def safe_make_folder():

TOP = ['spoj', 'functions', 'utilities']

def safe_make_folder(i):
    '''Makes a folder (and its parents) if not present'''
    try:  
        os.makedirs(i)
    except:
        pass


The standard function os.makedirs() creates the 'project_euler' resp.
'codechef', as the first subdirectory of each is created.

The other is that I would create the directory names using os.path.join() (as it prevents e.g. the mistake of providing double path separators), in combination with standard string formatting to get the leading zeros on the subfolder names:

os.path.join('project_euler', '{:03}_{:03}'.format(i, i+49))


the {:03} gives a 3 character wide field with leading zeros. @Josay improvemed function would then become:

def make_euler_folders(highest):
    for i in (os.path.join('project_euler', '{:03}_{:03}'.format(i, i+49)) \
       for i in range(1,highest, 50)):
        safe_make_folder(i)


And the other function would become:

def make_codechef_folders(codechef):
    for i in codechef:
        safe_make_folder(os.path.join('codechef', i))

Code Snippets

TOP = ['spoj', 'functions', 'utilities']

def safe_make_folder(i):
    '''Makes a folder (and its parents) if not present'''
    try:  
        os.makedirs(i)
    except:
        pass
os.path.join('project_euler', '{:03}_{:03}'.format(i, i+49))
def make_euler_folders(highest):
    for i in (os.path.join('project_euler', '{:03}_{:03}'.format(i, i+49)) \
       for i in range(1,highest, 50)):
        safe_make_folder(i)
def make_codechef_folders(codechef):
    for i in codechef:
        safe_make_folder(os.path.join('codechef', i))

Context

StackExchange Code Review Q#28715, answer score: 4

Revisions (0)

No revisions yet.