Our Makefile has a lot of duplication. For example, the names of text
files and data files are repeated in many places throughout the
Makefile. Makefiles are a form of code and, in any code, repeated code
can lead to problems e.g. we rename a data file in one part of the
Makefile but forget to rename it elsewhere.

D.R.Y. (Don’t Repeat Yourself)

In many programming languages, the bulk of the language features are
there to allow the programmer to describe long-winded computational
routines as short, expressive, beautiful code. Features in Python
or R or Java, such as user-defined variables and functions are useful in
part because they mean we don’t have to write out (or think about)
all of the details over and over again. This good habit of writing
things out only once is known as the “Don’t Repeat Yourself”
principle or D.R.Y.

Let us set about removing some of the repetition from our Makefile.

In our results.txt rule we duplicate the data file names and the
name of the results file name:

Update Dependencies

Solution

The rules for *.dat are not executed because their corresponding .txt files
haven’t been modified.

If you run:

$ touch books/*.txt
$ make results.txt

you will find that the .dat files as well as results.txt are recreated.

As we saw, $^ means ‘all the dependencies of the current rule’. This
works well for results.txt as its action treats all the dependencies
the same - as the input for the testzipf.py script.

However, for some rules, we may want to treat the first dependency
differently. For example, our rules for .dat use their first (and
only) dependency specifically as the input file to countwords.py. If
we add additional dependencies (as we will soon do) then we don’t want
these being passed as input files to countwords.py as it expects only
one input file to be named when it is invoked.

Make provides an automatic variable for this, $< which means ‘the
first dependency of the current rule’.

Rewrite .dat Rules to Use Automatic Variables

Rewrite each .dat rule to use the automatic variables $@ (‘the
target of the current rule’) and $< (‘the first dependency of the
current rule’).
This file contains
the Makefile immediately before the challenge.