Due: , 11:59 pm
The goals of this week's project are to get further experience with modules and hierarchical design, and to expand your ability to communicate between a Python program and the Terminal.
In particular, we will be exploring the ability to pass information from the Terminal to a program when you execute the program. This is called using command-line arguments for a program. The concept is similar to passing arguments to a function in Python, except that you do this in the Terminal when you run a program.
If you have not already done so, mount your personal space, create a new project4 folder and bring up TextWrangler and a Terminal.
Create a new file com.py. Put your name, date, and the class at the
import sys. Then put the following line of code in your
file and run it.
What does it do? Run it again, but this time try typing some random things on the command line after python com.py.
What is contained in the variable sys.argv? What data type are the elements of the sys.argv list? How could we make use of that?
From your experimentation, you should see that the variable sys.argv contains a list of the strings on the command line. That means we can use sys.argv to bring information from the command line into a python program. However, we need to be aware of types. Add the following to com.py.
print(sys.argv + sys.argv)
Then run the program again as
python3 com.py 1 2 and see
what happens. Did it do what you expected?
Add another line to your program where you cast sys.argv and sys.argv to integers before adding them together and run your program again. Did it do what you expected that time?
What happens if you run your program as
When you are writing any program that expects command line arguments, it is important to check to see if the user actually provided them. This is called error-checking, and is an important component of useful programs. If your program is expecting two arguments, then your program needs to check if the user provided at least two arguments. If they didn't it's common courtesy to tell them how to use the program properly. This is called a usage statement.
We can always check how many command line arguments there are by looking at the length of sys.argv. At the beginning of your active code, test if the length of sys.argv is less than three (the name of the program plus two arguments). If the user did not provide enough arguments, then print out a usage statement and exit. A usage statement generally looks something like the following.
Usage: python3 com.py <number> <number>
To exit a Python program, just use the function exit().
To see examples of real usage statements, go to the terminal and type cp or mv with no arguments.
When you are using command-line arguments in your own programs, you should always use the following structure.
import sys def main(argv): # usage statement here # cast the command line strings to the appropriate type and assign # them to local variables # main code here return if __name__ == "__main__": main(sys.argv)
If you follow the above structure, then the only place you will use the sys.argv variable is when you call your main function. Inside your main function, it sees only a list of strings (argv). The usage statement checks the list of strings to see if there are enough, and the next section of code does the necessary casting to set up local variables--with informative names--to hold the command line parameters. This structure follows the concept of modular design: all relevant variables enter a function as parameters.
Rewrite com.py to use the above structure. Run it and verify that it continues to function properly.
Note that many command line programs use flags as part of their command-line parameters. For example, if you run the command ls with the flag -l then it lists many different attributes of the files in a directory. Other flags take numbers or strings after the flag to indicate a value. Often, the flags themselves are optional, and the program has to figure out what flags are given on the command line and then grab any values associated with those flags. This process of parsing command-line strings is a standard task that many programs do. There are packages for assisting in that task, or you can write your own code that loops over the components of command-line strings and figures out what is there. You don't need to do anything this complex for this project, but it is an extension if you want to try it.
Create a for loop that loops 10 times. Each time through the loop have it print the result of calling random.random(). Then run your program. It should generate 10 numbers from a uniform random distribution between 0 and 1. Running the program again should generate 10 different numbers.
You can create many different kinds of random numbers using the random package. For example, if you want integers randomly distributed between 0 and 100, inclusive, use the randint() method of the random package. Using the function random.randint(0,100) will generate numbers in the range 0 to 100, inclusive (i.e. including the bounds 0 and 100).
You can also create numbers following a Gaussian distribution (also called a normal distribution) using the random.gauss function, which takes two arguments: the mean and standard deviation. Try modifying your program to generate different types of random numbers and see what happens.
When you are done with the lab exercises, you may start on the rest of the project.
© 2019 Eric Aaron (with contributions from Colby CS colleagues).