$$ \newcommand{\tp}{\thinspace .} $$

 

 

 

This chapter is taken from the book A Primer on Scientific Programming with Python by H. P. Langtangen, 5th edition, Springer, 2016.

Reading from the command line

Programs running on Unix computers usually avoid asking the user questions. Instead, input data are very often fetched from the command line. This section explains how we can access information on the command line in Python programs.

Providing input on the command line

We look at the Celsius-Fahrenheit conversion program again. The idea now is to provide the Celsius input temperature as a command-line argument right after the program name. This means that we write the program name, here c2f_cml.py (cml for command line), followed the Celsius temperature:

c2f_cml.py 21
69.8

Inside the program we can fetch the text 21 as sys.argv[1]. The sys module has a list argv containing all the command-line arguments to the program, i.e., all the "words" appearing after the program name when we run the program. In the present case there is only one argument and it is stored in sys.argv[1]. The first element in the sys.argv list, sys.argv[0], is always the name of the program.

A command-line argument is treated as a text, so sys.argv[1] refers to a string object, in this case '21'. Since we interpret the command-line argument as a number and want to compute with it, it is necessary to explicitly convert the string to a float object. In the program we therefore write

import sys
C = float(sys.argv[1])
F = 9.0*C/5 + 32
print F

As another example, consider the program

v0 = 5
g = 9.81
t = 0.6
y = v0*t - 0.5*g*t**2
print y

for computing the formula \( y(t)=v_0t - \frac{1}{2}gt^2 \). Instead of hardcoding the values of v0 and t in the program we can read the two values from the command line:

ball2_cml.py 0.6 5
1.2342

The two command-line arguments are now available as sys.argv[1] and sys.argv[2]. The complete ball2_cml.py program thus takes the form

import sys
t  = float(sys.argv[1])
v0 = float(sys.argv[2])
g = 9.81
y = v0*t - 0.5*g*t**2
print y

A variable number of command-line arguments

Let us make a program addall.py that adds all its command-line arguments. That is, we may run something like

addall.py 1 3 5 -9.9
The sum of 1 3 5 -9.9 is -0.9

The command-line arguments are stored in the sublist sys.argv[1:]. Each element is a string so we must perform a conversion to float before performing the addition. There are many ways to write this program. Let us start with version 1, addall_v1.py:

import sys
s = 0
for arg in sys.argv[1:]:
    number = float(arg)
    s += number
print 'The sum of ',
for arg in sys.argv[1:]:
    print arg,
print 'is ', s

The output is on one line, but built of several print statements with a comma at the end to prevent the usual newline character that print otherwise adds to the text. The command-line arguments must be converted to numbers in the first for loop because we need to compute with them, but in the second loop we only need to print them and then the string representation is appropriate.

The program above can be written more compactly if desired:

import sys
s = sum([float(x) for x in sys.argv[1:]])
print 'The sum of %s is %s' % (' '.join(sys.argv[1:]), s)

Here, we convert the list sys.argv[1:] to a list of float objects and then pass this list to Python's sum function for adding the numbers. The construction S.join(L) places all the elements in the list L after each other with the string S in between. The result here is a string with all the elements in sys.argv[1:] and a space in between, which is the text that originally appeared on the command line.

More on command-line arguments

Unix commands make heavy use of command-line arguments. For example, when you write ls -s -t to list the files in the current folder, you run the program ls with two command-line arguments: -s and -t. The former specifies that ls is to print the file name together with the size of the file, and the latter sorts the list of files according to their dates of last modification. Similarly, cp -r my new for copying a folder tree my to a new folder tree new invokes the cp program with three command line arguments: -r (for recursive copying of files), my, and new. Most programming languages have support for extracting the command-line arguments given to a program.

An important rule is that command-line arguments are separated by blanks. What if we want to provide a text containing blanks as command-line argument? The text containing blanks must then appear inside single or double quotes. Let us demonstrate this with a program that simply prints the command-line arguments:

import sys, pprint
pprint.pprint(sys.argv[1:])

Say this program is named print_cml.py. The execution

print_cml.py 21 a string with blanks 31.3
['21', 'a', 'string', 'with', 'blanks', '31.3']

demonstrates that each word on the command line becomes an element in sys.argv. Enclosing strings in quotes, as in

print_cml.py 21 "a string with blanks" 31.3
['21', 'a string with blanks', '31.3']

shows that the text inside the quotes becomes a single command line argument.