BYU logo Computer Science

Best practices for program arguments

Only reference sys.argv inside of the main block

The main block is a special if statement:

if __name__ == "__main__":
    # this is the main block

This main block is run whenever you use python program.py, and it only runs the main block located in program.py.

Since this is the first block of code that is run when a program is run, it is best practice to only reference sys.argv inside of this block.

Bad example

First, let’s show a bad example of a program that references sys.argv outside of the main block:

import sys


def main():
    # this accesses sys.argv outside of the main block
    print(f"This prints sys.argv[1], {sys.argv[1]}, inside of the main function!")


if __name__ == "__main__":
    print("This is the bad example!")
    main()

Good example

Now, here’s a good example that only references sys.argv inside of the main block. We encourage you to model your code after this example.

import sys


def main(argument: str):
    print(f"This prints the argument, {argument}, that was passed to the main function!")


if __name__ == "__main__":
    print("This is the good example")
    # This references sys.argv inside of the main block
    main(sys.argv[1])

Running the program:

python good_example.py argument1

produces the following output:

This is the good_example!
This prints the argument, argument1, that was passed to the main function!

While the output of both the good and bad examples are nearly the same, keeping all references to sys.argv in the main block will make a critical difference in the future as you learn about modularization and testing. Following the better design now will help you avoid trouble later.

Passing the wrong number of arguments to your program

A common error that occurs when dealing with sys.argv is an IndexError. This occurs when the user doesn’t provide enough arguments to the program and the program tries to reference an argument that doesn’t exist.

Using the good example above, running the program:

python good_example.py

results in the following error message:

This is the good example
Traceback (most recent call last):
  File "good_example.py", line 10, in <module>
    main(sys.argv[1])
         ~~~~~~~~^^^
IndexError: list index out of range

Here, we see that the error occured on line 10 of good_example.py. The tilde ~ and caret ^ symbols point to where the error occured. In this case, the error occured when trying to reference sys.argv[1] when using it as a parameter for the main() function.

Finally, the error message tells us that the error was an IndexError. This means that we tried to access an index of a list that doesn’t exist. In this case, sys.argv only has one item at sys.argv[0], which is the name of the program, "good_example.py". As a result, the program throws an error when it tries to access sys.argv[1].

Check the length of sys.argv before using it

It is common for a program to check the number of arguments before trying to access them. If the user doesn’t provide enough arguments, the program can print a helpful message to help the user understand which arguments they need to provide. This is easier for the user to understand than an IndexError message.

For example, you could write code like this:

import sys


def main(argument: str):
    print(f"This prints the argument, {argument}, that was passed to the main function!")


if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("You didn't provide the correct number of arguments!")
        print("Call this program with like this:")
        print("python good_example.py argument1")
        exit()

    main(sys.argv[1])

In this class, the tests we give you will always provide the correct number of arguments to your programs, so you don’t need to worry about checking the length of sys.argv in your code.