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\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()
-
\$\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\$Simon Forsberg– Simon Forsberg2016年12月13日 17:50:28 +00:00Commented Dec 13, 2016 at 17:50
1 Answer 1
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 theprint
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()