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

Automated batch and python skeleton script file creation

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

Problem

The code below uses a single command line 'filename' argument to create a batch and python skeleton script file in the cwd. The python file is then automatically opened in IDLE for convenience.

As a beginner making a significant amount of python files for worked educational examples this could save me 15 minutes per day.

Example usage for the below code which is named "make.py":

  • Cd in command line to the desired wd



  • Input script name("make") and the desired name of the files to be created minus any filename extension(in this case "test") as the single argument



Batch file created("test.bat"):

@py.exe C:\Users\Dave\Desktop\2016Coding\AutomateBoring\18-GUIAutomation\test.py %*
@pause


Python file("test.py") created in cwd and which is opened automatically in IDLE:

#! python3

#

import logging

logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - " +\
            "%(levelname)s - %(message)s")

def main():
    pass

if __name__ == "__main__":
    main()


Code:

```
#! python3

# Takes a command line filename and creates a batch file and .py file
# named "filename" in the cwd. The python file contains a basic script
# framework. In additon, the python file will be automatically opened.

import argparse
import os
import subprocess

def handle_input():
"""Parses user commandline input"""

parser = argparse.ArgumentParser()
parser.add_argument("filename", type=str,
help="The name of the files to create minus any" +\
"extensions.")
args = parser.parse_args()
return args.filename

def make_batch(filename: str, cwd: str):
"""Makes a batch file name "filename" in "cwd"""

filepath = os.path.join(cwd, filename + ".bat")
with open(filepath, "w") as f:
f.write("@py.exe " + os.path.join(cwd, filename + ".py ") +
"%*\n@pause")
print("\nCreated batch file: {}".format(filepath))

def make_py(filepath: str):
"""Makes a .py file in cwd writ

Solution

This is rather good code: no blatant style issues, doctrings for functions and some comments (albeit some are unnecessary). Well done.

Now for the critics:

  • traditional shebang would rather look like #!/usr/bin/python3 or #!/usr/bin/env python3;



  • the comments you put between the shebang and the imports should be the module docstring instead;



  • use 4 spaces per indentation level rather than tabs;



  • since you are creating files in the current working directory, you can check for file existence with the filename only; thus you can do it early and generate an argparse error instead of "rolling your own" ;



  • you could make the path to idle an optional parameter of the CLI instead of hardcoding your path to it;



  • I like to use the file argument of the print function to visualize the layout of the output file better. But for the python template, using a multiline string should be an improvement:



#!/usr/bin/env python3

"""Takes a command line filename and creates a batch file and .py file
named "filename" in the cwd. The python file contains a basic script
framework. In additon, the python file will be automatically opened.
"""

import argparse
import os
import subprocess

PYTHON_TEMPLATE = '''\
#!/usr/bin/env python3

"""DOCSTRING"""

import logging

logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s - %(levelname)s - %(message)s")

def main():
    pass

if __name__ == "__main__" :
    main()'''

def handle_input():
    """Parses user commandline input"""

    parser = argparse.ArgumentParser()
    parser.add_argument(
            'filename',
            help='The name of the files to '
                 'create minus any extensions.')
    parser.add_argument(
            '-i', '--idle-path',
            help='The path to the IDLE executable',
            default=r'C:\Users\Dave\AppData\Local\Programs'
                    r'\Python\Python35-32\Lib\idlelib\idle.bat')
    args = parser.parse_args()

    filename = args.filename
    # ensure an existing python file is not overwritten
    if os.path.exists(filename+'.py'):
        parser.error('file already exist: {}.py'.format(filename))
    return filename, args.idle_path

def make_batch(filename: str, cwd: str):
    """Makes a batch file name "filename" in "cwd"""

    filepath = os.path.join(cwd, filename + ".bat")
    with open(filepath, "w") as f:
        print('@py.exe', os.path.join(cwd, filename+'.py'), '%*', file=f)
        print('@pause', file=f)
    print('Created batch file:', filepath)

def make_py(filepath: str):
    """Makes a .py file in cwd written with a basic skelton script"""

    # *****I realize it's a simpler task to copy a template from a .
    # py file created for the purpose and write that to the new .py*****

    with open(filepath, "w") as f:
        print(PYTHON_TEMPLATE, file=f)
    print('Created .py file:', filepath)

def open_py_idle(filename: str, idle_path: str):
    """Opens a .py file in IDLE using subprocess"""

    subprocess.run([idle_path, filename], shell=True)

def main():
    """Creates .bat and .py file in cwd. Auto opens .py file"""

    filename, idle_path = handle_input()
    cwd = os.getcwd()
    python_file = os.path.join(cwd, filename + '.py')

    make_batch(filename, cwd)
    make_py(python_file)
    open_py_idle(python_file, idle_path)

    print('\n*****Done*****\n')

if __name__ == "__main__":
    main()

Code Snippets

#!/usr/bin/env python3

"""Takes a command line filename and creates a batch file and .py file
named "filename" in the cwd. The python file contains a basic script
framework. In additon, the python file will be automatically opened.
"""

import argparse
import os
import subprocess


PYTHON_TEMPLATE = '''\
#!/usr/bin/env python3

"""DOCSTRING"""


import logging


logging.basicConfig(
    level=logging.DEBUG,
    format="%(asctime)s - %(levelname)s - %(message)s")


def main():
    pass


if __name__ == "__main__" :
    main()'''


def handle_input():
    """Parses user commandline input"""

    parser = argparse.ArgumentParser()
    parser.add_argument(
            'filename',
            help='The name of the files to '
                 'create minus any extensions.')
    parser.add_argument(
            '-i', '--idle-path',
            help='The path to the IDLE executable',
            default=r'C:\Users\Dave\AppData\Local\Programs'
                    r'\Python\Python35-32\Lib\idlelib\idle.bat')
    args = parser.parse_args()

    filename = args.filename
    # ensure an existing python file is not overwritten
    if os.path.exists(filename+'.py'):
        parser.error('file already exist: {}.py'.format(filename))
    return filename, args.idle_path


def make_batch(filename: str, cwd: str):
    """Makes a batch file name "filename" in "cwd"""

    filepath = os.path.join(cwd, filename + ".bat")
    with open(filepath, "w") as f:
        print('@py.exe', os.path.join(cwd, filename+'.py'), '%*', file=f)
        print('@pause', file=f)
    print('Created batch file:', filepath)


def make_py(filepath: str):
    """Makes a .py file in cwd written with a basic skelton script"""

    # *****I realize it's a simpler task to copy a template from a .
    # py file created for the purpose and write that to the new .py*****

    with open(filepath, "w") as f:
        print(PYTHON_TEMPLATE, file=f)
    print('Created .py file:', filepath)


def open_py_idle(filename: str, idle_path: str):
    """Opens a .py file in IDLE using subprocess"""

    subprocess.run([idle_path, filename], shell=True)


def main():
    """Creates .bat and .py file in cwd. Auto opens .py file"""

    filename, idle_path = handle_input()
    cwd = os.getcwd()
    python_file = os.path.join(cwd, filename + '.py')

    make_batch(filename, cwd)
    make_py(python_file)
    open_py_idle(python_file, idle_path)

    print('\n*****Done*****\n')


if __name__ == "__main__":
    main()

Context

StackExchange Code Review Q#149639, answer score: 4

Revisions (0)

No revisions yet.