The goal of this program is to:
- Take in 2 Folder paths
- Take in 1 Integer Value
- Validate both Folders are in the directory and that the Integer value is an int
- Move a specified number of files from the source folder into the destination folder. For example, if the source folder contains 8 files I want to move the last 4 files to the destination folder.
- In Command line: python main.py path1 path2 4
I'm in the testing phase of using Command line arguments instead of default value placeholders (Folder paths and integer values assigned to variables) and running through the console.
My issue is:
- Everything work as intended when path1, path2, and int are all present and correct values
- If the integer is not an int (Example, python main.py path1 path2 string) the program crashes and gives me errors.
- If the program reads that the CLI arg is not an int (num = int(sys.argv[3])) I want to default the value to 10, but the program does not seem to do this?
ERROR
Blank = block out personal info
python main.py Path1 Path2 L
Traceback (most recent call last):
File "C:\Users\blank\blank\blank\main.py", line 71, in <module>
main()
File "C:\Users\blank\blank\blank\main.py", line 66, in main
read_args()
File "C:\Users\blank\blank\blank\main.py", line 29, in read_args
num = int(sys.argv[3])
ValueError: invalid literal for int() with base 10: 'L'
Main
import os, sys, shutil, time
def main():
read_args()
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
exit()
Code
def validate_folder(folder):
"""Validates folders in working directory"""
try:
isDir = os.path.isdir(folder)
return isDir
except Exception as e:
print(e)
return None
def validate_number(number1):
"""Validates third argument is an integer value"""
try:
int(number1)
return True
except ValueError:
return False
def read_args():
"""Read CLI arguments"""
source_folder = sys.argv[1]
destination_folder = sys.argv[2]
num = int(sys.argv[3])
"""Get main folder and archive folder and validate they are in the directory"""
main_folder = validate_folder(source_folder)
archive_folder = validate_folder(destination_folder)
kept_files = validate_number(num)
"""If any of the inputs is not valid return None proceed with conditional checks"""
if main_folder is False or archive_folder is False:
print("Folders cannot be found")
if main_folder is True and archive_folder is True and kept_files is False:
num = 10
sortFiles_and_moveFiles(source_folder, destination_folder, num)
else:
"""If both folders are valid in the working directory pass parameters to sortFiles_and_moveFiles()"""
sortFiles_and_moveFiles(source_folder, destination_folder, num)
def sortFiles_and_moveFiles(path1, path2, n_files):
source_folder = path1
destination_folder = path2
"""Get list of all files only in the given directory"""
list_of_files = filter(lambda x: os.path.isfile(os.path.join(source_folder, x)), os.listdir(source_folder))
"""Sort list of files based on last modification time in descending order"""
list_of_files = sorted(list_of_files, key=lambda x: os.path.getmtime(os.path.join(source_folder, x)))
"""Iterate over sorted list of files and print file path, along with last modification time of file"""
for file_name in list_of_files:
file_path = os.path.join(source_folder, file_name)
timestamp_str = time.strftime('%m/%d/%Y :: %H:%M:%S', time.gmtime(os.path.getmtime(file_path)))
print(timestamp_str, ' -->', file_name)
print("Designated files have been moved")
"""Move designated number of files to archive folder using slice notation."""
for file_name in list_of_files[n_files:]:
shutil.move(os.path.join(source_folder, file_name), destination_folder)
CodePudding user response:
There is builtin function str.isdigit()
that returns True
if string could be casted to int
else False
. Also some of your if checks can be shortened
if main_folder is True and archive_folder is True and kept_files is False:
could be replaced with simple
elif kept_files is False:
But the whole method still can be modified as follows
def read_args():
"""Read CLI arguments"""
source_folder = sys.argv[1]
destination_folder = sys.argv[2]
num = sys.argv[3]
"""Get main folder and archive folder and validate they are in the directory"""
main_folder = validate_folder(source_folder)
archive_folder = validate_folder(destination_folder)
"""If any of the inputs is not valid return None proceed with conditional checks"""
if main_folder is False or archive_folder is False:
print("Folders cannot be found")
elif not num.isdigit():
num = 10
else:
"""If both folders are valid in the working directory pass parameters to sortFiles_and_moveFiles()"""
num = int(num)
sortFiles_and_moveFiles(source_folder, destination_folder, num)