This section outlines basic file handling in Python, including file
utilities in the numpy package.
Suppose we create a file with typical input data to our little demo program for evaluating the formula \( s(t)=v_0t + \frac{1}{2}at^2 \):
v0 = 2
a = 0.2
dt = 0.1
interval = [0, 2]
We want to read the parameters in the file into Python variables and
create a table with columns of \( t \) and \( S(t) \) for \( t\in [0,2] \) with
steps of \( \Delta t=0.1 \) (as specified by dt and interval in the file).
The code for reading the lines in the file, interpreting them, and assigning values to variables is given next.
infile = open('.input.dat', 'r')
for line in infile:
# Typical line: variable = value
variable, value = line.split('=')
variable = variable.strip() # remove leading/traling blanks
if variable == 'v0':
v0 = float(value)
elif variable == 'a':
a = float(value)
elif variable == 'dt':
dt = float(value)
elif variable == 'interval':
interval = eval(value)
infile.close()
The name of the file is here .input.dat, and it is opened with the
parameter 'r' for reading. The for loop for line in infile will
read the lines from the file, one by one, and in the current line
is available in the string line. To split a line into words separated
by a character '=', we use line.split('='), resulting in a list of
the words. For example,
>>> line = 'v0 = 5.3'
>>> variable, value = line.split('=')
>>> variable
'v0 '
>>> value
' 5.3'
Note that there are blanks in the strings. Leading and trailing blanks
can be removed by variable.strip(). We do this before comparing
the variable name with v0, a, etc.
It is important to note that value (the text to the right of = on
each line) is a string variable. We need to convert to a float object to
get a variable that we can compute with.
The assignment interval = eval(value) does some magic and deserve
an explanation: eval(s) interprets the text in the string s as
Python code. In the present example, value is [0, 2] and this
is interpreted as Python code, i.e., as a list, and interval becomes
a name for a list object with content [0, 2].
A more modern Python way of opening files is
with open('.input.dat', 'r') as infile:
for line in infile:
...
Now it is not necessary to close the file as it will be automatically done
after the with block.
Suppose we generate \( t \) and \( s(t) \) values in two lists, t_values and
s_values, and want to write these as a nicely formatted table to file.
The following code does the work:
outfile = open('table1.dat', 'w')
outfile.write('# t s(t)\n') # write table header
for t, s in zip(t_values, s_values):
outfile.write('%.2f %.4f\n' % (t, s))
Files intended for writing must be opened with a 'w' parameter.
The key statement is outfile.write(s) for writing a string to
a file (recall that while print automatically adds a newline
at the end of the string to be printed, outfile.write(s) does not
append a newline so s must contain the newline).
The numpy package contains a convenient function savetxt for saving
tabular data. The data must be stored in a two-dimensional numpy array.
The savetxt function enables control of the format of the numbers
in each column (fmt) through the printf syntax, a header can be
added (header) and the header lines begin with a comment character
(comment). The code reads
import numpy as np
# Make two-dimensional array of [t, s(t)] values in each row
data = np.array([t_values, s_values]).transpose()
# Write data array to file in table format
np.savetxt('table2.dat', data, fmt=['%.2f', '%.4f'],
header='t s(t)', comments='# ')
The tabular data in the file can be read back into a
numpy array by the loadtxt function:
data = np.loadtxt('table2.dat', comments='#')
Lines beginning with the comment character are skipped in the reading.
The resulting object data is a two-dimensional array: data[i,j] contains
row number i and column number j in the table, i.e., data[i,0]
holds the \( t \) value and data[i,1] the \( s(t) \) value in the i-th
row.