Home > database >  Read in command line arguments for folder paths and integer values
Read in command line arguments for folder paths and integer values

Time:02-15

The goal of this program is to:

  1. Take in 2 Folder paths
  2. Take in 1 Integer Value
  3. Validate both Folders are in the directory and that the Integer value is an int
  4. 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.
  5. 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:

  1. Everything work as intended when path1, path2, and int are all present and correct values
  2. If the integer is not an int (Example, python main.py path1 path2 string) the program crashes and gives me errors.
  3. 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)
  • Related