DAY33
Thursday, 26 July 2012


Today is a LAB day.

LAB #10 and Homework #10 are the last lab and homework assignments for this course.

We have a LAB #10 to be done during class time, for credit. When you have completed the lab, please let Detelina know so that she can approve and record your work.


LAB#10:

Task 1:: get a copy of the tiny.pgm file to work on. This is a Portable Gray Map (PGM) file, containing a "black and white" graphic image. You can view the image with the command

        eog tiny.pgm
      
The image is tiny, so you may have to zoom in to see the pattern of stripes. Notice that parts of the image are rather dark.

The ASCII version of the Portable Gray Map format assumes that the picture is stored as an MxN array G of integers between 0 and GMAX. The format of the file is then

        P2          <-- This will always be the characters "P2"
        m  n        <-- The number of rows, the number of columns.
        gmax        <-- The largest G value.
        first row of G
        second row of G
        ...
        Mth row of G 
      
For the tiny example, m, n and gmax are 10, 10 and 100.

Task 2:: Write a program which can read in ANY file in the PGM format. It should ask the user for the name of the file, "filename", then open the file as a readable text file. From this point on, we will be reading information from the file. First read the initial "P2" as a word. (We don't need to do anything with this, but we have to read it so we can get to the next information.) Now read M, N, and GMAX as integers. Now that you know the values of M and N, declare the G array. Finally, read the G data, close the file, and check that G[5][2] is equal to 16.

        printf ( ? );          <-- ask user for filename.
        scanf ( ?, filename ); <-- get filename from user.
        input = fopen (?,?);   <-- open the file.
        fscanf ( "%s", p2 );   <-- read the first two characters "P2" into a character array.
        fscanf ( ?, ? );       <-- now read three integers, M, N, and GMAX.
        declare G              <-- an int array with M rows and N columns.
        loop on i
          loop on j
            fscanf ( ?, ? );   <-- read the value g[i][j].

        fclose ( ? );          <-- close the file.
        printf ( "Check: g[5][2] = %d, should be 16!\n", g[5][2] );  <-- Check one value
      

Task 3:: Our image is dark. In the PGM format, dark colors are low numbers. We'd like to shift some of the darker colors up. One way to do this is to use the square root function. The square root of any number between 0 and 1 is actually bigger than the original number. So if we take each entry of the G array and divide it by GMAX, it will be between 0 and 1. Then we can take the square root, and multiply it back by GMAX. But we have to be careful because we are starting with an integer, temporarily operating on it like a real number, and then putting it back as an integer again. And also, if we ask for the square root function, we need to include the appropriate library.

        printf ( ? );
        scanf ( ?, filename );
        input = fopen (?,?);
        fscanf ( "%s", p2 );
        fscanf ( ?, ? );
        declare G
        loop on i
          loop on j
            fscanf ( ?, ? );
        fclose ( ? );
        printf ( "Check: g[5][2] = %d, should be 16!\n", g[5][2] );

        NEW STUFF BEGINS HERE

        loop on i
          loop on j
            g[i][j] = gmax * sqrt ( g[i][j] / gmax )  <-- This won't quite work!

        printf ( "Check: g[5][2] = %d, should be 40 now!\n", g[5][2] );  <-- Check one value
      

Task 4:: Now we'd like to write our modified information out to a new PGM file so that we can look at it. Ask the user for the name of the new file, open the file as a writable text file, then write 'P2', M, N, GMAX, and the G array and close the file.

        printf ( ? );
        scanf ( ?, filename );
        input = fopen (?,?);
        fscanf ( "%s", p2 );
        fscanf ( ?, ? );
        declare G
        loop on i
          loop on j
            fscanf ( ?, ? );
        fclose ( ? );
        printf ( "Check: g[5][2] = %d, should be 16!\n", g[5][2] );
        loop on i
          loop on j
            g[i][j] = gmax * sqrt ( g[i][j] / gmax )  <-- This won't quite work!
        printf ( "Check: g[5][2] = %d, should be 40 now!\n", g[5][2] );  <-- Check one value

        NEW STUFF BEGINS HERE

        printf ( ? );           <-- Ask for output filename
        scanf ( ?, filename );
        output = fopen (?,?);
        fprintf ( "P2\n" );     <-- Print the string "P2"
        fprintf ( ?, ? );       <-- Print M, N and GMAX, with a space between each value
        loop on i
          loop on j
            fprintf ( ?, ? );   <-- Print G[I][J], with a space before or after it.
          fprintf new line      <-- at the end of each row, print a new line character.
        fclose ( ? );
        
      

Run your program, and ask it to read the file "tiny.pgm" and to create the file "medium.pgm". You can use the editor gedit to examine either file as a text file. You can use the program eog to display either file as an image. If you zoom in, you should see that "medium.pgm" is brighter.

Task 5:: If you have written your program correctly, you can now use it to read ANY PGM file that is in text format, and lighten it in this way. Copy the file "smile.pgm", run your program to create "smile2.pgm", and display it using eog. When you have got this far, show Detelina your results.


HOMEWORK #10 (must be turned in by next Thursday):

Homework 10.1:: as part of Lab #9, we wrote a program that counted the number of characters in the input. Start from those ideas, and write a program which

  1. asks the user to type in the name of a file;
  2. opens the file named by the user and counts the number of characters in it.
Demonstrate your program by asking it to count the characters in the Gettysburg address file. Your program MUST read the name of the file from the user.

Homework 10.2: Write a program which reads the Gettysburg address file, and writes the even words into the file "even.txt" and the odd words into "odd.txt". Since C starts counting at zero, let's say the "even.txt" is going to contain "Four" and "and" and so on, while "odd.txt" should contain "score" and "seven" and so on. Your program should open 3 files at the same time, the Gettysburg file as input, and the even and odd files as output. It should read one word at a time, and then write that word to the correct file. When the program realizes there are no more input words, it should close all three files.

Demonstrate your program on the Gettysburg address file.

Homework 10.3: (Graduate students only!): Write a program which asks the user to specify the name of a file, and a number "n". Your program should then open the specified file, and print out line number "n" from the file. Since C starts counting at 0, we will suppose that the first line of the file is line number 0, and so on.

Demonstrate your program by asking it to print out line 7 of the Gettsyburg address.

For each of your homework programs, turn in a copy of the program, the printed output, and any output files created.


Programs we might discuss:


Last revised on 20 July 2012.