CSE 332S: Object Oriented Software Design Laboratory

Fall 2008: Lab 6

Due 11:59pm, May 5, 2008.

Purpose

This lab will let you get some practice with using the templates and algorithms of the STL. We covered a number of these in class, but you should make sure you're familiar with the ones that we didn't mention in class, by reading the relevant sections of the book. Much of this assignment is designed to highlight the STL functions and algorithms, so you don't want to implement algorithms that are already there.

Preparation

Make sure you understand the Qt graphical toolkit from TrollTech. We will not be making extensive use of Qt in this lab, but we will use it to build a test program for the code that you write.

Make sure you read all of the assignment before starting, because decisions you make early on might have consequences if you want to do some of the extra credit sections. Also, make sure you understand the algorithms in the STL, and how they can be modified, since we will be expecting you to use them heavily in this lab.

As in the previous labs, you should document all of your code with the doxygen documentation system. You should use the special commands in doxygen to document your parameters, return types, and the like.

Assignment

  1. The first thing that we're going to do is to construct an address book for the people who you might want to send instant messages to. Each of the entries in the book will have the following elements:
    1. Username
    2. Actual name
    3. Nickname
    4. Time of last message
    5. Number of messages send to you
    6. Number of messages you have sent to them
    7. Comments
    The username will be a single word, starting with an alphabetic character, and consisting of alphabetic and numeric characters (ie, similar to a standard unix/linux user name). The username is required, all of the other fields are optional. Design a class that stores and validates this information. The class should have the following features:
    1. Can be used by the standard STL containers.
    2. The class should have constructors for the common construction cases. It should also have a constructor that reads the information from an input stream. We'll use this to read the address book from a file.
    3. The copy constructor and assignment operator should be implemented.
    4. The class should be able to write its contents to an output stream. We will use this to save the address book to a file.
  2. Design and implement a class that holds the address book. This will consist of a number of address records, which you implemented in the first part of this lab. The address book class should have the following functionality:
    1. Read an address book from a named file, and write it to a named file.
    2. Make sure you implement the copy constructor and assignment operators.
    3. Implement operator+= so that it can be used to add records to the address book.
  3. Make your address book class work with the STL, just like the provided STL containers. In particular, you should provide iterators, and their associated functions. The following code should compile and print out each of the records in your address book:
    for(AddressBook::iterator it = book.begin(); it != book.end(); ++it){
        cout << *it << endl;
    }
    (assuming that your class is called AddressBook, and that there is an instance of it called book).
  4. Create an address book of at least 20 entries, and use it to verify that your code works.
  5. Now that you have some working code, we're going to wrap it up in a Qt GUI. The GUI will be used to test various searches that we're going to implement for your address book. The GUI should have the following features:
    1. An area where the search results are returned. This should allow you to see all of the address book entries that match your search, and to select searches, and search parameters.
    2. A way of selecting different searches.
    3. A way of providing parameters for the search.
    4. A button to initiate the search.
    5. You should be able to select a single line in the display, using the mouse.
    You should set up this as a single widget, so that it can be included in other code that you will write later. You should also include a quit button in the interface, but it should not be part of the widget. If you're looking for some inspiration, check out ~cse332/public/lab6.
  6. Implement the ability to search through your address book for specific entries. You should implement the following searches:
    1. By username
    2. By actual name
    3. By nickname
    4. By any field
    Hook this search functionality up to your interface, so that you can run each of these searches from the interface. Each of these searches will be parameterized by some string.
  7. Order the displayed list of records by the search term used in the previous question.
  8. Now implement the following searches:
    1. By number of messages. Return all of the records that have sent you more than a specified number of messages.
    2. Timestamp. Return the n most recent messages, where n is specified by the user.
  9. Integrate your address book with your IM client. Add a button to bring up the book widget in a separate window when you need it. You should be able to change the user that you're talking to by searching for and selecting an entry in your address book.
  10. Extra credit: Modify your address book so that it can deal with arbitrary fields. This means that you will need some mechanism to associate (arbitrary) field names with arbitrary values. You will also need a mechanism for reading and writing these values to the address book.

    As an example, you might decide to provide a function that you can call on a record that will add a new field and it's data, such as:

    record.addField("cse332", "yes");
    that will add a field called "cse332" to the record, and set its value to "yes".
  11. Extra credit: Write a widget that lets you edit the address book. We'll leave the exact features of this widget up to you, but you should consider (probably in this order) being able to add a new entry, delete an old entry, and edit an existing entry. Obviously, you should be able to load and save to the file on disk. Add a button to your interface that launches this widget.
  12. Extra credit: Implement a search that returns all of the records that have sent you a message after a specified date. Make the input box modal, so that it turns into a date entry mechanism when the search needs a date (and turns back into a text entry when it needs text). Also, turn the box into a number entry mechanism when this is called for.
  13. Extra credit: Implement regular expression searching. You are free to find and use an external library for this. The library should be on the CEC linux machines, or compiled into your own code. Basically, we need to be able to compile and run your code without downloading anything else ourselves. Document your search, and the use of any external code in your README file.
  14. Extra credit: Implement an interface element in your widget that allows the user to select the key on which the search is done, and the ordering (ascending or descending).

Grading

Most of the points in this lab will be for having the code work as described above. We will deduct points for the following things:
  1. Not compiling. If your code does not compile, then you will get no points for this lab.
  2. Warnings or errors in the compile. Your code should not generate any warning messages when compiled with the -Wall flag.
  3. Not using the STL when possible. In particular, we will penalize you for reimplementing functionality that is already in the STL.
  4. Incorrect or poorly-written algorithms.

What to Hand In

You should hand in all of your code, your README, your Makefile, and your Doxyfile. As with the previous lab, make sure you list all of your object files in your Makefile. You should make a tarball of your code and other files, and submit it through our web-based submission system.

Thoughts

  1. Sitting down and sketching out a design for the lab, especially for the second part of it, will save you a lot of pain. We really, really suggest that you do it. Choosing the right bits of the STL from the start will save you a lot of coding time. Trust us.
  2. For a class to be usable by the standard STL containers, it needs (at least) operator== and operator< to be defined. Think what equality and "less than" means for these records, and implement something appropriate. Document your reasoning in your README file.
  3. You might consider the common constructors for the address book record to be without any information (other than the username), and with the other information. You might, if you like, also consider other constructors to be "common".
  4. We'll leave you to your own devices on the format of the address book file. You can make it as simple or as complex as you like. However, if you're going for the extra credit, then a simple file format isn't likely to work very well.
  5. The address book class is an excellent opportunity to use one of the STL containers. We will leave the choice of container up to you. Read the whole assignment, and choose the one you think is the most appropriate. Document your choice in your README file. When making your choice, make sure that you consider the algorithms that you are going to run on the entries in the address book.
  6. When writing the address book code, try to write everything as generically as possible. This will let you change to another container easily, if you should decide to do so. In particular making sure all of the functions that you call on the container apply to other containers, and using iterators whenever possible.
  7. Making your implementation of the address book isn't as complex as you think it is. Read over your notes and the slides from class again, and you'll see how it might be done. Concentrate on the use of typedef, and think about how you've included the STL containers in your class. See this example code.
  8. Verifying that you code works with the STL might involve running the code provided above, and also making sure that the following code does the right thing:
    sort(book.begin(), book.end());
  9. Since we're trying to leverage the STL in this lab, then you should use stream iterators to read from/write to files whenever possible.
  10. To save you some searching through the documentation, the classes we used in the interface examples are QTable and QComboBox. Notice that the example interfaces are, to put it bluntly, whipped together in a couple of minutes. Your interfaces should be a lot more polished than ours. Also, your quit button will probably not be in the same place as our quit button.
  11. The searches can all be implemented efficiently by defining a class that acts as a functor, and using it with the supplied STL algorithms. If the previous sentence does not make sense to you, ask in class, and we can talk about it some more. The whole searching part of this lab is to get you to play with the STL algorithms and functors, so knowing how to use them will save you a lot of pain. Do not implement your own sort function!
  12. Think about how to implement a general searching system, parameterized by the functors. This will make adding extra searches much easier.
  13. You're going to find yourself coping more than one item from the address book to some (probably STL) container. Think about how best to do this, and what container to use before you start to implement things. Doing so will save you a considerable amount of pain.
  14. We've told you to implement a number of classes for this lab. Remember that you're allowed to (and sometimes encouraged to) write additional classes, if you think they will be useful. Yes, this is a hint.
Page written by Bill Smart.