i'm a python newbie & wrote my first script, can someone critique it?

mad scientist jr mad.scientist.jr at gmail.com
Sat Jun 11 13:59:44 EDT 2016


Thanks to everyone for your replies.  I see my script was as horrific as I feared, but I read all the responses and made a few changes.  I'm not 100% sold on not checking types, but took it out, because it made sense that other programmers might want to use some custom type with my functions for their own nefarious purposes.  

One question I have is, can someone point me to a full listing of all the error types I can trap for?  It seems like a Pandora's box, trying to think of all the things that could go wrong, which is why I originally just printed the error #. Is it better to not trap errors, and let the stack trace tell what went wrong?  Does it give all the information on the error type etc.?

Anyway, for those charitable (or masochistic, or both) enough to critique my code again, here is the updated version:

# For Python 3.x

# This script creates multiple numbered empty folders
# in the desired location. To change the folder names
# or location, edit function get_default_options.

###############################################################################
# REFERENCE MODULES
###############################################################################
import datetime
import os
import errno
import sys

###############################################################################
# SUPPORT FUNCTIONS
###############################################################################

# returns: dictionary containing options for this script
def get_default_options():
    dict = {
        "s_for_python_version": "3",
        "s_folder_path_template": "C:/temp/test/MP3 Disk {count:03}", 
        "i_from_count": 3,
        "i_to_count": 7,
        }
    return dict

# returns: string containing exact version #, eg "3.5.1"
# TODO: update to use
#   sys.version_info[:3] by itself gives a three-element tuple.
#   Probably easier to use than thestring version. 
#   A couple alternatives: 
#   sys.version[:5] or perhaps a bit safer -- sys.version.split()[0] both directly give you the 
#  string version.  (Note this uses version not version_info.)
def get_exact_python_version():
    s_version = ".".join(map(str, sys.version_info[:3]))
    s_version = s_version.strip()
    return s_version

# returns: string containing general version #, eg "3"
# TODO: return to the left of first "."
def get_general_python_version():
    s_version = get_exact_python_version()
    return s_version[0]

# checks python version
# if it's wrong then gracefully exit before it blows up
# (damn, python 2.x still complains with syntax errors!!)
#
# receives:
#   s_right_version (string) = python version # to check against
# 
# TODO: more granular check, eg if version >= 3.5.0
def exit_if_wrong_python_version(s_right_version):
    s_current_version = get_general_python_version()
    if (s_current_version != s_right_version):
        print(
            "Wrong Python version ({}), "
            "this script should be run using " 
            "Python {}.x,  Exiting..."
            "".format(s_current_version, s_right_version))
        sys.exit() # SAME AS os._exit(0)

# assists in script readability
# returns: string containing name of the current script
def get_script_filename():
    return sys.argv[0]

# returns: string containing the current date/time in the format eg 2016-05-22 13:01:55
def get_timestamp():
    return datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S')

# creates a folder at the specified path
# receives:
#   s_path (string) = full path of folder to create
def create_folder(s_path):
    try:
        os.makedirs(s_path, exist_ok=True)
    except (FileExistsError, IsADirectoryError) as e:
        print("FileExistsError IN makedirs")
        raise
        return False
    except OSError as exception:
        print("ERROR #" + str(exception.errno) + "IN makedirs")
        raise
        return False
    print("" + get_timestamp() + " " + "Created folder: " + s_path + "")
    
# creates multiple numbered folders named per template
# receives:
#   s_folder_path_template (string) = template containing full path of folder to create,
#                                     where "{count:n}" is replaced by the folder count (n digits)
#   i_from_count (int) = number to begin counting at
#   i_to_count (int) = number to stop counting after
#
# returns: count of folders created, 0 if error or none
def create_folders(
        s_folder_path_template:str="",
        i_from_count:int=1,
        i_to_count:int=0
        ):
    i_count=0
    for i_loop in range(i_from_count, i_to_count + 1): 
        create_folder(s_folder_path_template.format(count=i_loop))
        i_count += 1
    
    return i_count
    
###############################################################################
# MAIN LOGIC
###############################################################################

def main():
    options_dict = get_default_options()
    exit_if_wrong_python_version(options_dict["s_for_python_version"])
    
    print("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
    print("" + get_timestamp() + " " + get_script_filename() + " started.")
    
    i_total_created = create_folders(
        options_dict["s_folder_path_template"],
        options_dict["i_from_count"],
        options_dict["i_to_count"])

    print("" + get_timestamp() + " " + str(i_total_created) + " folders created.")
    print("" + get_timestamp() + " " + get_script_filename() + " finished.")

###############################################################################
# GLOBAL CODE (minimal!)
###############################################################################
if __name__ == '__main__': 
    main()


More information about the Python-list mailing list