CISC181, Lab05, Fall 2005

Concepts covered in this lab:

Part 1: Adding command line options to the wind chill program

Files you will use from last week's lab
lab04a.cc
Files you will create and submit via WebCT (also print ones in bold)
lab05a.cc, lab05a.txt

 

In Part 1 of this lab, you will take the wind chill program you did in lab04 (lab04a.cc) and modify it to use command line arguments.

This raises a question: What Unix command will you use to make a copy of your lab04a.cc program from your lab04 directory and put that copy into a file called lab05a.cc in your lab05 subdirectory?

The correct answer depends on your current directory. Listed below are several attempts. Some of them will work, and some will not. Think about whether each of these is correct or not (you'll have a question similar to this on your first midterm exam, so take advantage of the opportunity to practice). Print a copy of this page of the lab, and circle for each of these whether you think the command is correct or incorrect.

If you are not sure, ask your TA for help before proceeding. Also, you may consult with other students on THIS ASPECT OF THE LAB only. (Or, your instructor might go over this part of the lab in lecture before lab starts.). Unless you are told otherwise in lecture or lab, you do not have to turn in your answers "correct or incorrect"; these are just practice for the exam. Once you have found at least one of the correct answers, use that command to create your lab05a.cc file as a starting point for this lab.

READ INSTRUCTIONS (not all of these comands are correct)

cd ~/cisc181/lab04
cp lab04a.cc lab05/lab05a.cc

correct or incorrect?
cd ~/cisc181/lab04
cp lab04a.cc ../lab05/lab05a.cc
correct or incorrect?

cd ~/cisc181/lab05
cp ../lab04a.cc lab05a.cc

correct or incorrect?
cd ~/cisc181/lab05
cp ../lab04/lab04a.cc .
mv lab04a.cc lab05a.cc
correct or incorrect?
   

 

When you are done, you want to be able to run the windchill program in the following ways:

./windChill same output as before
./windChill 5 60 5 values 5, 10, 15, 20, 25 ... up to 60 down the left column
(just like in the table on the web site.)
./windChill 2 10 1 values 2, 3, 4, 5, 6, 7, 8, 9 and 10 (8 rows of wind chill factors)
./windChill 20 40 values 20 30 40 only (the step value defaults to 10)
./windChill 30 values 30 40 50 only (max defaults to 50, step defaults to 10)

Here's how to do it:

  1. Change the line
  2. int main(void)

    at the top of your program to

    int main(int argc, char *argv[])
  3. Add #include <cstdlib> to the #includes at the top of your program.
  4. Add the following code in your main:

    // initialize from command line arguments; default to 10, 50 and 10 int windMin, windMax, windStep; windMin = (argc <= 1)? 10 : atoi(argv[1]); windMax = (argc <= 2)? 50 : atoi(argv[2]); windStep = (argc <= 3)? 10 : atoi(argv[3]);
  5. Now make sure your program still compiles, and still works just as it did before.
  6. Finally, change your program so that the values of windMin, windMax,and windStep are used to control the for loop that chooses the values for wind (down the left hand column). That is, instead of

    for (w = 10; w<=50; w+=10)

    you'll have:

    for (w = windMin; w<=windMax; w+=windStep)

    You should find that if your run your program with the command ./windChill 10 50 10 for example, you will get the same table as before. However, you should now be able to run the program with commands such as the following:
  7. Test your program on all the possible values for the command line arguments in the above table.
  8. Now make a script lab05a.txt in which you cat your lab05a.cc file, compile it, and run it, showing the output for all the possible values of the command line arguments in the previous table. You will upload this script to WebCT along with your lab05a.cc file, and also give a printed copy of the script file to your TA.

Part 2: Yet more wind-chill stuff.

Files you will use from the previous step
lab05a.cc
Files you will create and submit via WebCT (also print ones in bold)
lab05b.cc, lab05b.txt

 

According to a news article on the USA Today web site, the U.S. National Weather Service and Canadian weather authorities modified the formula for calculating the wind chill factor in the Fall of 2001, based on "greater scientific knowledge".

(Link to the article: http://www.usatoday.com/weather/resources/basics/windchill/wind-chill-formulas.htm)

In this exercise, you will modify your previous wind chill program so that it can produce a table of the old wind chill factor, a table of the new wind chill factor, and a table that shows the difference between the two.

Copy your lab05a.cc file to lab05b.cc.
Then modify the lab05b file in the following manner:

  1. Rename your function windChill to be called windChillNew
  2. Add a function windChillOld that follows the old formula (see the USA Today web site.) Note that the USA Today web site's algebra notation may not be so clear. You'll have to interpret it as best you can by comparing their version of the new formula to that on the National Weather Service web site (linked to in lab04). With that help, you should be able to figure out what their notation means.
  3. Add an enumerated type as follows:
    enum WindChillOption  {WCO_NEW = 0,
                            WCO_OLD = 1,
                            WCO_DIFF = 2};
    
    This enumeration will be use to control what type of table is printed.
  4. Add a function as follows:
    void printTableHeader(WindChillOption opt)
    {
      switch(opt)
        {
        case WCO_NEW:
          cout << "  ******   NEW WIND CHILL FORMULA ******" << endl;
          break;
    
        case WCO_OLD:
          cout << "  ******   OLD WIND CHILL FORMULA ******" << endl;
          break;
    
        case WCO_DIFF:
          cout << "  ****** DIFFERENCE  (NEW - OLD)  ******" << endl;
          break;
    
        default: 
          cerr << "Unexpected case! Line number " 
               << __LINE__ << " in file " << __FILE__ << endl;
          exit(-1);
                
        }
    }
    
    This function prints a different header for each kind of table that you might want to print. You pass in one of the values WCO_NEW, WCO_OLD, or WCO_DIFF to get the kind of header you want.
  5. Write a function as follows:
    void printTable(WindChillOption opt, int windMin, int windMax, int windStep)
    { ... }

    This function essentially does everything that you used to do in your main program to print out the table. The new main program will look like the following:
    int main(int argc, char *argv[]) 
    { 
       
      // initialize from command line arguments; default to 10, 50 and 10 
     
      int windMin, windMax, windStep; 
      windMin  = (argc <= 1)? 10 : atoi(argv[1]); 
      windMax  = (argc <= 2)? 50 : atoi(argv[2]);  
      windStep = (argc <= 3)? 10 : atoi(argv[3]);  
     
      // print three tables:  
      //  one for new wind chill 
      //  one for old wind chill 
      //  one showing difference between them 
       
      printTable(WCO_NEW, windMin, windMax, windStep); 
     
      cout << "\n\n"; // skip a couple of lines 
      printTable(WCO_OLD, windMin, windMax, windStep); 
     
      cout << "\n\n"; // skip a couple of lines 
      printTable(WCO_DIFF, windMin, windMax, windStep); 
       
      return 0; 
    } 
    
    Note that most of the work is done by the functions that you call; the main is short and sweet; it is like an "outline" of what happens in the program.
  6. One more function that will help you structure your program well: write a function as follows:

    double tableEntry(int windMph, int tempF, WindChillOption opt) { switch(opt) { case WCO_NEW: return windChillNew(windMph, tempF); break; ...

    This is actually only the start of this function; you should be able to finish it off, following the pattern from the earlier similar function. The idea is that you'll replace the call to your windChill() function—the call that was nested inside the for loops to produce the table—replace that with a call to this function called tableEntry().

    The table entry function basically is like a chameleon that can change its color to be whatever the user passes in for the opt parameter: you want the old formula, you get the old formula. You want the new formula, you get the new formula. You want the difference... well, you get the idea. Good software is built up by composing building blocks such as these that can be combined in many different ways.
  7. Once you have completed the program, you should be able to get output such as the following. Script your program in the usual way in a file called lab05b.txt. (By now, you should be comfortable with the usual expectations for a script file, but if you are not sure, ask your TA during lab.)

    > CC lab05a.cc -o windChill
    > ./windChill 
      ******   NEW WIND CHILL FORMULA ******
               Temperature (degrees F)        
    ------------+-------+-------+-------+-------+-------+-------+
     wind (mph) |    40 |    30 |    20 |    10 |     0 |   -10 | 
    ------------+-------+-------+-------+-------+-------+-------+
             10 |    34 |    21 |     9 |    -4 |   -16 |   -28 | 
             20 |    30 |    17 |     4 |    -9 |   -22 |   -35 | 
             30 |    28 |    15 |     1 |   -12 |   -26 |   -39 | 
             40 |    27 |    13 |    -1 |   -15 |   -29 |   -43 | 
             50 |    26 |    12 |    -3 |   -17 |   -31 |   -45 | 
    
    
      ******   OLD WIND CHILL FORMULA ******
               Temperature (degrees F)        
    ------------+-------+-------+-------+-------+-------+-------+
     wind (mph) |    40 |    30 |    20 |    10 |     0 |   -10 | 
    ------------+-------+-------+-------+-------+-------+-------+
             10 |    28 |    16 |     4 |    -9 |   -21 |   -33 | 
             20 |    18 |     4 |   -10 |   -24 |   -39 |   -53 | 
             30 |    13 |    -2 |   -17 |   -32 |   -48 |   -63 | 
             40 |    10 |    -5 |   -21 |   -37 |   -53 |   -68 | 
             50 |     9 |    -7 |   -23 |   -39 |   -55 |   -71 | 
    
    
      ****** DIFFERENCE  (NEW - OLD)  ******
               Temperature (degrees F)        
    ------------+-------+-------+-------+-------+-------+-------+
     wind (mph) |    40 |    30 |    20 |    10 |     0 |   -10 | 
    ------------+-------+-------+-------+-------+-------+-------+
             10 |     5 |     5 |     5 |     5 |     5 |     5 | 
             20 |    12 |    13 |    14 |    15 |    17 |    18 | 
             30 |    15 |    17 |    19 |    20 |    22 |    23 | 
             40 |    16 |    18 |    20 |    22 |    24 |    26 | 
             50 |    16 |    18 |    20 |    22 |    23 |    25 | 
    > 
    

Part 3: Using ifstream to open an input file

Files you will copy from my web page:
readUsersFromFile.cpp, usernames.txt
Files you should look at on my web page (for reference) but don't necessarily need to copy into your directory
sample_usernames.html
Files you will create and submit via WebCT (also print ones in bold)
lab05c.cc, lab05c.txt
Files you will place on your web page when finished under the URL http://udel.edu/~userid/cisc181/lab05
usernames.txt, usernames.html

We already know how to read input from the keyboard (standard input) using operations such as:

  cin >> x;

However, it is more interesting and challenging to write programs that process many hundreds, thousands, or millions of lines of input. When you write such programs, you really test whether your program "scales" or not... that is, is the solution that works well for 10 pieces of input is still a good solution for 10,000 pieces of input. So, we are going to learn how to read out input directly from a file on the disk.

As a side note: An example of a well-known algorithm that doesn't scale well is bubblesort: it scales with n-squared, meaning that if you go from 10 pieces of input to 20,000 pieces of input, your program doesn't take about 2000 times longer; rather, it takes about 4,000,000 times longer (since 2000 squared is 4,000,000).

Instructions:

  1. Copy the file readUsersFromFile.cpp from the lab05 directory on my website into your directory.
  2. Look at the source code, especially the lines containing "ifstream" and "userInputFile". Here are some explanations of this code:
  3. Compile and run the program. Note that the program's output goes to the screen, and consists of listing the usernames from the file, along with a count of how many usernames there were.
  4. Copy the program to your own source code file called lab05c.cc, and change the comments in the file accordingly. Modify the program so that in addition to the output now going to the screen, the program also writes out an external file called "usernames.html". You will open that file with a statement such as:

    ofstream htmlfile("usernames.html",ios::out);

    Then write to that file the html code for a file containing usernames. An example of what that file should look like when you are done is in the lab05 subdirectory in the file "sample_usernames.html". The file shows a web page with pointers to the cisc181 pages for each student in the input file. Modify the input file to contain the names of 5 of your classmates (including yourself).

    Make a script of this program called lab05c.txt that shows that the program works.

    Before you do your script, think about what needs to be in the script to show that the program works correctly. What files do you need to "cat" as part of your script to show the TA everything that is happening? Input files? Output files? Is a before-and-after directory listing needed? Should you delete any particular files before you run your program?

    You need to think this all through before you create your script file.

    In lab04, I told you exactly what you needed to do in your script file. However, this week, you need to think about it yourself.

    As you advance in your computer science classes, there will be less and less "spoon feeding" of exactly what needs to be done, and to a larger extent, you have to determine yourself what is necessary to "build the case" that your program operates correctly.

    In real world software development environments, there are things called "code reviews", where you have to "make the case" to an audience of technical experts that your code is correct before it can become part of an officially released product. Preparing a script file is part of what you must do for a real world code review. In those cases, no-one is telling you step-by-step what needs to be done; on the other hand, if you leave out something important, you won't pass the review. So, we are challenging you to start developing those skills.

    If you are not sure what steps to take, write down what you think needs to be done and show it to your TA, and ask him/her about it. Your TA should be willing to tell you if you are missing any important steps, and give you a hint about what those are. Your TA should also be willing to tell you if your outline is complete. However, it is not his/her job to tell you exactly what steps to do, and in what order. In this lab, it is part of your responsibility to figure that out.

Finishing up and Submitting

  1. Make sure you have a lab05c.txt script file, per instructions. Upload to WebCT and print.
  2. Submit lab05c.txt and lab05c.cc to WebCT.
  3. Create a web directory ~/public_html/cisc181/lab05 and copy your usernames.txt and usernames.html file into that directory. Do NOT put your lab05c.txt or lab05c.cc file into that directory; you will lose points if you do. Only the .txt and .html files should be copied into that directory. Make the directory readable for all web users.

 

Grading

lab05a.cc (50 pts)

lab05b.cc (50 pts)

lab05c.cc (50 pts)

Total: 150 points