Python 3

home

Applications with Command Line Arguments

Why the Command Line is So Important

Most Python scripts are not run from an IDE.


Developers hang out on the command line for two important reasons:

  1. The command line features powerful utilities and commands that make working with files, directories and programs easier and more versatile
  2. The command line is where we usually run Python scripts and other scripts





Finding the path to Python

Your OS doesn't necessarily know where Python is until we tell it.


We should begin by seeing whether our OS already knows where python is; even if it does, we should learn the procedure for telling it where it is (for those future situations where it doesn't yet know): Windows

  1. Open a Command Prompt
  2. At the prompt type where python
  3. If you see a path, copy it to your clipboard and paste it into a text file.


If you don't see a path, please see the alternative approach, below. Mac

  1. Open a Terminal window
  2. At the prompt type which python
  3. If you see a path, copy it to your clipboard and paste it into a text file.
  4. If you get a "not found" message, try to determine the path as noted in the alternative approach below.


An alternative approach to determine the path to Python is to run this program from your IDE:

import sys

print(sys.executable)




Using the argparse Module to Process Command line Arguments

argparse allows us to collect and validate arguments


Many programs use command line arguments that follow the following pattern:

python myprog.py --year 2023  --factor SMB  --flavors cherry vanilla chocolate

The program may require certain arguments, and show an error if they aren't passed:

python myprog.py --year 2023

usage: myprog.py [-h] -y YEAR -f FACTOR
ProgramName: error: the following arguments are required: -y/--year, -f/--factor

Such programs also offer help messages when the user typs --help as an argument:

python myprog.py --help

usage: test.py [-h] -y YEAR -f FACTOR

Reads Fama-French file to show sum of values for a selected year and selected
factor

optional arguments:
  -h, --help            show this help message and exit
  -y YEAR, --year YEAR
  -f FACTOR, --factor FACTOR

This sets up our program to use more sophisticated command line arguments. We will add the argument options in the next step.

import argparse
import os
import sys

parser = argparse.ArgumentParser(
                    prog=os.path.basename(sys.argv[0]),
                    description='Reads Fama-French file to show sum of values for a selected year and selected factor')

All of the above arguments are optional, but if used will show up in a help message if the user passes the command line argument '-h' or '--help'


Here's how we add arguments. The optional required=True causes argparse to stop the program if the argument was not passed.

parser.add_argument('-y', '--year', required=True)
parser.add_argument('-f', '--factor', required=True, choices=['Mkt-RF', 'SMB', 'HML', 'RF'])
parser.add_argument('-v', '--flavors', nargs='+')     # allow 1 or more values

args = parser.parse_args()

print(args.year)       # retrieve the value passed as <B>--year</B>
print(args.factor)     # retrieve the value passed as <B>--factor</B>
print(args.flavors)    # retrieve list of values passed as <B>--flavors</B>

Once all arguments have been added, parser.parse_args() returns an object whose attributes match the argument name. See the documentation for more options to .add_argument() that can:








Setting the PATH environment variable

On Windows we use the GUI; on Mac we must edit a "hidden" file.


Windows

  1. On the Windows taskbar, right-click the Windows icon and select System.
  2. In the Settings window, under Related Settings, click Advanced system settings.
  3. On the Advanced tab, click Environment Variables.
  4. Under System variables, select PATH. Click Edit to modify. (If your computer doesn't allow you to edit System variables, you may instead modify the User variables.)
  5. Depending on your Windows version, you may need to either edit the entire string of paths in PATH (note that the paths are separated by semicolons) or add your path to the list of paths through the GUI.
  6. If editing the entire string: paste your path at the start of the string of paths, and then type a semicolon to separate it from the next one.
  7. If you are adding your path using the GUI: with PATH highlighted, click 'New' and add the path to Python that you saved earlier. You should see the new path added to the list of variables. Then, drag the path to the top of the list.
  8. After modifying the environment variable, click Apply and then OK to have the change take effect.


Mac

  1. From the Terminal prompt, type ps -p $$
  2. Under CMD, if you see -bash, you're using Bash shell and should edit the ~/.bash_profile file
  3. If you see -zsh, you're using Z shell and should edit the ~/.zshrc file (note that your Mac may announce that "the default shell is zsh". This is just information, not an indication of which shell you are using.
  4. Open a Finder window to your Home directory
  5. Press Cmd-Shift-. (Command Key + Shift Key + period)
  6. Locate and edit the file determined above (.bash_profile or .zshrc). If the file doesn't exist, you should create it. Remember the filename must start with a period - this is part of the expected name, and also what makes a file "hidden".
  7. The file may be very short, or very long. Locate the last instance of PATH= in this file.
  8. Beneath that last instance of PATH=, enter the following text: export PATH= followed by the path to Python you saved earlier (do not include a space), followed by :$PATH. Example: export PATH=/Library/Frameworks/Python.framework/Versions/3.12/bin/python
  9. Save and close this file
  10. To hide the hidden files, press Cmd-Shift-. (Command Key + Shift Key + period) again
When you are done, you must open a new Terminal or Command Prompt window to see the change. You should now be able to type which python or where python and see the path to Python. You should also be able to type python -V (capital V) and see a late Python version (in most cases, 3.8 or greater).





Using sys.argv to Process Command Line Arguments

sys.argv is a list that holds string arguments entered at the command line


sys.argv example


a python script myscript.py

import sys                           # import the 'system' library

print('first arg: ' + sys.argv[1])   # print first command line arg
print('second arg: ' + sys.argv[2])  # print second command line arg

running the script from the command line

$ python myscript.py hello there
first arg: hello
second arg: there

sys.argv is a list that is automatically provided by the sys module. It contains any string arguments to the program that were entered at the command line by the user. If the user does not type arguments at the command line, then they will not be added to the sys.argv list. sys.argv[0] sys.argv[0] always contains the name of the program itself Even if no arguments are passed at the command line, sys.argv always holds one value: a string containing the program name (or more precisely, the pathname used to invoke the script). example runs


a python script myscript2.py

import sys                            # import the 'system' library

print(sys.argv)

running the script from the command line (passing 3 arguments)

$ python myscript2.py hello there budgie
['myscript2.py', 'hello', 'there', 'budgie']

running the script from the command line (passing no arguments)

$ python myscript2.py
['myscript2.py']

Special note on debugging: command-line arguments can't be used when running the PyCharm debugger. Instead, you can hard-code your arguments thusly:

import sys

sys.argv = ['progname.py', 'shakespeare/', 'support']

Now you won't need to enter arguments on the command line as you have re-established them using the sys.argv variable.





Summary Exception: IndexError with sys.argv (when user passes no argument)

An IndexError occurs when we ask for a list index that doesn't exist. If we try to read sys.argv, Python can raise this error if the arg is not passed by the user.


a python script addtwo.py

import sys                            # import the 'system' library

firstint = int(sys.argv[1])
secondint = int(sys.argv[2])

mysum = firstint + secondint

print(f'the sum of the two values is {mysum}')

running the script from the command line (passing 2 arguments)

$ python addtwo.py 5 10
the sum of the two values is 15

exception! running the script from the command line (passing no arguments)

$ python addtwo.py
Traceback (most recent call last):
  File "addtwo.py", line 3, in <module>
firstint = int(sys.argv[1])
IndexError: list index out of range

The above error occurred because the program asks for items at subscripts sys.argv[1] and sys.argv[2], but because no elements existed at those indices, Python raised an IndexError exception. How to handle this exception? Test the len() of sys.argv, or trap the exception.





[pr]