Fall 2006

Clay Shields


front | classes | research | personal | contact

Parker's Implacable Camera, Co.

Assigned: November 7th
Program source code due: November 16th

Parker's Implacable Camera, Co.


On a recommendation from Sid, Parker of Parker's Implacable Camera Co. (Motto - "Getting all the pictures of your wedding day, even the ones you don't want. As seen on Springer!") has contacted you about coming up with a program that allows customers to look through a list of photos and select which ones they would like to order. To help you do this, an outline of a program has been provided for you. You can download this file here, or copy it to your account on seva by typing:

cp ~clay/picco-clean.cc ~/

If you look at the code provided, you will notice that it consists of two classes. One is an Image class that stores information about individual images, namely the file name provided by the camera and some tags which are notes made by Parker. The second is a Photo_set class which stores a name for the set and a bunch of Images in a vector. I would suggest that you don't try and write all the code at once - that is the path to debugging insanity. Instead, here is a step-by-step guide to finishing the project and keeping your sanity.

Step 1

First, we are going to build an object that will hold the images. This is a pretty simple object that just has two private data members: a picture name and a string that has a description or just tags about the picture. The object looks like this:



class Image{

  friend ostream &operator<<(ostream &, Image);
  friend istream &operator>>(istream&, Image &);

public:
  // Default constructor  
  Image();
  // Constructor with initial values
  Image(string, string);
  // Name observer
  string get_name();
  // Tags observer
  string get_tags();
  //Accesor for the tags. My assumption is that the name is assigned
  // by the camera, so there won't be any changes made to that
  void set_tags(string);
  ~Image();

private:
  string image_name;
  string image_tags;

};

// Default constructor
Image::Image(){
  // no need to do anything here, since the strings are empty to start with.
}

// Initializing Constructor
Image::Image(string initial_name, string initial_tags){

  // MAKE THIS WORK

}

// Return the image name
string Image::get_name(){

  // MAKE THIS WORK
  
}

// Return the tags
string Image::get_tags(){

  // MAKE THIS WORK

}

// Change the tags
void Image::set_tags(string new_tags){

  // MAKE THIS WORK

}

Image::~Image(){
  // Nothing to do with the deconstructor this time
}

ostream &operator<<(ostream & output, Image i){
  
    // MAKE THIS WORK

};


istream &operator>>(istream& input, Image & i){

    // MAKE THIS WORK

};


    
Your first task is to fill in the code above. To make sure it works, test it with the main function below. This function is commented out in the file provided with C style comments. Note that looking at these main functions is a good way to see how the objects work.



int main(){

  // A small main program to test the image class

  // Create a new image
  Image test_image("DSCF0020","Bride, groom, close up");
  // make sure the observers work
  cout << "Testing observers:" << endl;
  cout << "This should say DSCF0020: " << test_image.get_name() << endl;
  cout << "This should say 'Bride, groom, close up': " << test_image.get_tags() << endl;
  // make sure the accesor for the tags works:
  cout << "Testing accessors:" << endl;
  test_image.set_tags("Bride, groom, close up, pimple");
  cout << "This should say 'Bride, groom, close up, pimple': " << test_image.get_tags() << endl;
  // make sure the friend functions work as well
  cout << "The next line should say 'DSCF0020 Bride, groom, close up, pimple':"  << endl;
  cout << test_image << endl;
  // now test the input operator
  cout << "At the prompt, please type - D01 Bride, groom, family:" << endl;
  cin >> test_image;
  cout << "The next line should say 'D01 Bride, groom, family':"  << endl;
  cout << test_image << endl;
}

    
When you run the main function above, you should get the following output:



Testing observers:
This should say DSCF0020: DSCF0020
This should say 'Bride, groom, close up': Bride, groom, close up
Testing accessors:
This should say 'Bride, groom, close up, pimple': Bride, groom, close
   up, pimple
The next line should say 'DSCF0020 Bride, groom, close up, pimple':
DSCF0020 Bride, groom, close up, pimple

At the prompt, please type - D01 Bride, groom, family:
D01 Bride, groom, family
The next line should say 'D01 Bride, groom, family':
D01 Bride, groom, family
    
Step 2

Once you have that working, you can go on to work on the Photo_set class. It is a class that has a name to describe the pictures contained in the set of photos, and a vector of images. Brief comments decribing what each method does are included for your benefit. The outline of the class is:


class Photo_set{

public:
  // Default constructor for empty photo set
  Photo_set();
  // Method that loads the Image names and tags from a file
  void load_set(string source_file);
  // Show a numbered list of images
  void display_images();
  // return a copy of one of the images in the set
  Image extract_image(int);
  // Add an image to the set
  void add_image(Image);
  // Return the number of images
  int number_of_images();
  // Return the name of the set
  string get_name();
  // Set the name of the photo set
  void change_set_name(string);
  // Save the photo set into a file
  void save_set(string);
  // Destroy the photo set
  ~Photo_set();
  
private:
  string set_name;
  vector<Image> images;

};

// A default constructor that makes a blank set
Photo_set::Photo_set(){

    // MAKE THIS WORK

}

// A method that is given the name of a file and reads
// the information from the file. 
// The file has the format:
// One line with the set name
// Many lines, each with one image on them
void Photo_set::load_set(string filename){
  
    // MAKE THIS WORK

}

// Display a numbered list of images contained in the photo set
// Start with the name, so we know which set it is
// Notice that numbering starts at 1, because we don't want to 
// confuse grandma
void Photo_set::display_images(){

    // MAKE THIS WORK
  
}


// Given an integer that represents a number from the display_images
// list, return a copy of that image
Image Photo_set::extract_image(int image_number){

    // MAKE THIS WORK

}

// Add an image to the set
// Just slap it on the end of the vector
void Photo_set::add_image(Image new_image){

    // MAKE THIS WORK

}

// Return the number of images
// This is just the size of the vector
int Photo_set::number_of_images(){
  
    // MAKE THIS WORK
 
}

// Get name simply returns the name of the set
string Photo_set::get_name(){
  
    // MAKE THIS WORK

}

// Set the name of the photo set
void Photo_set::change_set_name(string new_name){
  
    // MAKE THIS WORK
  
}

// Save the photo set into a file of the specified name
void Photo_set::save_set(string filename){
  
    // MAKE THIS WORK
  
}


// Destroy the photo set
Photo_set::~Photo_set(){

    // MAKE THIS WORK

}
   
    
Once you have written the code for these methods, you can test them using this data file and the main function below:

// A main function to test that the photo_set class works

int main(){

  string filename = "11-04-2006-wedding.txt";
  
  cout << "starting" << endl;
  // test the default constructor
  Photo_set test_set;
  test_set.display_images();

  // test the file loading constructor
  Photo_set file_set;
  file_set.load_set(filename.c_str());
  file_set.display_images();

  // test the extract image
  cout << endl << endl << "The next line should say:"
       << " DSCF0364.JPG Bride and groom kneeling, closeup" << endl;
  cout << endl << file_set.extract_image(5) << endl;
  
  // test the add image
  test_set.add_image(file_set.extract_image(10));
  test_set.display_images();

  // check the count of images
  cout << "The next number should be 1: " << test_set.number_of_images() << endl;

  // Check the set_name
  cout << "The next line should read: 11-04-2006-wedding" << endl;
  cout << file_set.get_name() << endl;

  // Check that we can change the name
  cout << "The next line should read: Elizabeth and John's wedding" << endl;
  file_set.change_set_name("Elizabeth and John's wedding");
  cout << file_set.get_name() << endl;

  // Check that we can save a photo set
  test_set.save_set("test_output");
  Photo_set new_set;
  new_set.load_set("test_output");

  cout << "This set:" << endl;
  test_set.display_images();
  cout << endl << "Should be the same as this set:" << endl;
  new_set.display_images();



  cout << "ending" << endl;
}
     
The output when this main is run should be:

starting

11-04-2006-wedding
    1        DSCF0360.JPG                       Groom and groomsmen outside
    2        DSCF0361.JPG                         Bride getting veil put on
    3        DSCF0362.JPG                    Church interior, fish-eye view
    4        DSCF0363.JPG                        Flower girls in procession
    5        DSCF0364.JPG                 Bride and groom kneeling, closeup
    6        DSCF0365.JPG               Bride and groom kneeling, long view
    7        DSCF0366.JPG               Bride and groom kneeling, side view
    8        DSCF0367.JPG                  Bride and groom lighting candles
    9        DSCF0368.JPG                Bride and groom walking down aisle
   10        DSCF0369.JPG                            Family photos on table
   11        DSCF0370.JPG                          Bride and groom laughing
   12        DSCF0371.JPG        Bride and groom arriving at reception tent
   13        DSCF0372.JPG                   Bride and groom kissing legally
   14        DSCF0373.JPG                     Bride and groom swing dancing
   15        DSCF0374.JPG                          Close up of wedding cake
   16        DSCF0375.JPG                     Bride and bridemaids laughing
   17        DSCF0376.JPG                   Bride and groom kissing by cake


The next line should say: DSCF0364.JPG Bride and groom kneeling, closeup

DSCF0364.JPG Bride and groom kneeling, closeup


    1        DSCF0369.JPG                            Family photos on
    table
The next number should be 1: 1
The next line should read: 11-04-2006-wedding
11-04-2006-wedding
The next line should read: Elizabeth and John's wedding
Elizabeth and John's wedding
This set:

    1        DSCF0369.JPG                            Family photos on table

Should be the same as this set:

    1        DSCF0369.JPG                            Family photos on table
ending


    
Step 3

Once you have the objects working, all you have left to do is create your own main function that provides the functionality shown in the print_instructions function. You can also test a working copy of the program as noted below.

Resources
As with the last projects, you can copy my solution to your seva account and experiment with it as needed. To do this, type:

cp ~clay/picco ~/

You can also download the sample photo set file or copy it over to your seva account by typing:

cp ~clay/11-04-2006-wedding.txt ~/

What to turn in

Include the following header in your source code.

            //
            // Project 4
            // Name: <your name>
            // E-mail: <your e-mail address>
            // COSC 071
            //
            // In accordance with the class policies and Georgetown's
            // Honor Code, I certify that I have neither given nor
            // received any assistance  on this project with the
            // exceptions of the lecture notes and those  items noted
            // below.
            //
            //
            // Description: <Describe your program>
            //
          

You will submit your source code using the submit program. This is the .cc file. Do not submit the compiled version! I don't speak binary very well.

To submit your program, make sure there is a copy of the source code on your account on seva. You may name your program what you like - let's assume that it is called picco.cc. To submit your program electronically, use the submit program like we did in Homework 2 and Project 1, 2, and 3, but with the command:

submit -a p4 -f picco.cc