3
\$\begingroup\$

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":

  1. Cd in command line to the desired wd
  2. 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\Desktop2016円Coding\AutomateBoring18円-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 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*****
 shebang = "#! python3\n\n"
 comment = "#\n\n"
 imports = "import logging\n\n"
 logging = "logging.basicConfig(level=logging.DEBUG, format=\"%(asctime)s - " \
 "\" +\\\n\t\t \"%(levelname)s - %(message)s\")\n\n"
 functions = "def main():\n\tpass\n\n"
 main = "if __name__ == \"__main__\":\n\tmain()"
 with open(filepath, "w") as f:
 f.write(shebang + comment + imports + logging + functions + main)
 print("Created .py file: {}".format(filepath))
def open_py_idle(filename: str):
 """Opens a .py file in IDLE using subprocess"""
 idle_path = r"C:\Users\Dave\AppData\Local\Programs\Python\Python35" +\
 r"-32\Lib\idlelib\idle.bat"
 subprocess.run([idle_path, filename], shell=True)
def main():
 """Creates .bat and .py file in cwd. Auto opens .py file"""
 filename = handle_input()
 cwd = os.getcwd()
 python_file = os.path.join(cwd, filename + ".py")
 # ensure an existing python file is not overwritten
 if not os.path.exists(python_file):
 # make .bat file named "filename" in cwd
 make_batch(filename, cwd)
 # make .py file
 make_py(python_file)
 # open .py file in idle
 open_py_idle(python_file)
 else:
 print("\n.py file already exists: {}".format(python_file))
 print("\n*****Done*****\n")
if __name__ == "__main__":
 main()
Simon Forsberg
59.7k9 gold badges157 silver badges311 bronze badges
asked Dec 12, 2016 at 14:21
\$\endgroup\$
1
  • \$\begingroup\$ Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers . \$\endgroup\$ Commented Dec 13, 2016 at 17:50

1 Answer 1

4
\$\begingroup\$

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()
answered Dec 12, 2016 at 21:23
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.