Hands-on 4b

Make, Reading Data (Isotopes)

Using Makefile

At this point the direct use of the compiler becomes inconvenient, that is why we will now proceed to use the make tool and a simple Makefile, provided with the start code.

The compilation of the testPoint has been now simplified to a single command:

$ make

Program readIsotopes

In this exercise we will exploit what we have learned in previous sessions:

  • reading in data of a given format
  • using object types (defined in classes)
  • using Make

We will develop a program that reads the isotopes.txt file containing data of several isotopes:

# name       Z    A    half-life[y] abundance
URANIUM     92   238   4.468e09       99.2745
URANIUM     92   235   7.040e08        0.7200
URANIUM     92   234   2.455e05        0.0054
PLUTONIUM   94   239   2.411e04        0.0
PLUTONIUM   94   238   8.774e01        0.0
THORIUM     90   232   1.405e10       99.98

The data format is fixed and it is explained in the comments on the first line. Each new line contains the data of one isotope in this order:

  • the name of the corresponding chemical element
  • the atomic number (or proton) number (Z)
  • the atomic mass number (the number of protons and neutrons) (A)
  • its half-life (if unstable) as a double (in years)
  • its abundance in Nature, relative to all other isotopes of the same element (in percent)

A skeleton of the new program to read these data is provided. We will implement the missing code in several steps.

Step 1 - Adapt Makefile to build new program

Save Makefile as Makefile.testPoint and then change it so that it can be used to compile your new readIsotopes.cxx. The new program will use the class Isotope.

The readIsotopes.cxx program skeleton is provided. To get the code compiled, comment out the lines which define while loop:

  while ( ! myFile.eof() ) {
  ...
  }

and which actually break compilation.

Verification

Check if changing a file triggers recompiling a program.

Instead of modifying a file content, you can use touch command to just change the file modification time.

Step 2 - Read data in local variables

Replace the commented lines

// ...

with your code. Each step should not take more than 5 minutes. Watch your time and if 5 minutes elapsed take the solution provided in the hints and move to the next // ... comment.

Step 3 - Read data in an object

Inspect the code in the Isotope.h file. The Isotope class data members can contain all the information which we read in the local variables.

First, we can just use the local variables and add the Isotope object:

     // Define local variables to hold read data
     // and fill them from the file
     // ...

     // Read data of one isotope
     myFile >> name >> Z >> A >> halflife >> abundance;

     // Define Isotope object
     Isotope isotope;
     isotope.setName(name);
     isotope.setZ(Z);
     isotope.setA(A);
     isotope.setHalflife(halflife);
     isotope.setAbundance(abundance);

We can further simplify the code above for reading data by reading the data directly in the Isotope object:

     // Define Isotope object
     Isotope isotope;
     myFile >> isotope; 

and replace printing of read local variables with printing the Isotope object:

    // Print read data
     myFile >> isotope; 
     cout << "Read: " << isotope;  

Step 4 - Save all read data in a vector

In this step, we will store all Isotope objects created during the reading loop in a vector. This will allow to exploit all the Isotope objects that we have just created. Add the lines as follows (at the right place in your program):

// ...
#include <vector>
// ...
vector<Isotope> isotopes;
// ...
isotopes.push_back(isotope);

Step 5 - Print all read data

We can now exploit the vector that contains all the Isotope objects. For example, we can print the characteristics of all objects on the screen. To do this we will add the following code after the while loop.

  // Print all isotopes
  cout << "Isotopes stored in a vector: " << endl;  
  for (Isotope isotope : isotopes) {
    cout << isotope << endl;
  }