Homework: Book List

Objectives:

  • Complete a simple data storing class (Book), with fields for title, author, and year of publication.

  • Complete a class with a Collection (BookList) that uses the public methods of another class you wrote (Book), and select various data from the list.

  • Complete a testing program (TestBookList), that creates a BookList, adds Books to the BookList, and tests BookList methods clearly and completely for a user looking at the output of the program and not the source code..

Copy stub files from the project books_homework_stub to your own project. Stubs for the assignment files are book.cs, book_list.cs, and test_book_list.cs,

Some of the method stubs included are only to be fleshed out if you are doing the corresponding extra credit option. They include a comment, just inside the method, // code for extra credit. There are also extra files used by the extra credit portion. They are discussed in the Extra Credit section at the end of the assignment.

Complete the first line in each file to show your names. At the top of the Book class include any comments about help in all of the classes.

Create methods one at a time, and test them. Complete book.cs first, preferably testing along the way. (You can write an initial version of the testing program, so it does not depend on BookList.) Then add methods to book_list.cs, and concurrently add and run tests in test_book_list.cs. Testing the Book class first means that when you get to BookList you can have more confidence that any problems you have are from the latest part you wrote, not parts written earlier in the class Book.

Remember to have each individual submit a log, log.txt, in the same format as the last assignment.

Book class

See the stub file provided. It should have instance fields for the author, title, and year (published).

Complete the constructor:

public Book(string title, string author, int year)

that initializes the fields. (Be careful, as we have discussed in class, when using the same names for these parameters as the instance variables!)

It should have three standard (one line) getter methods:

public string GetTitle()

public string GetAuthor()

public int GetYear()

and

public override string ToString()

ToString should return a single string spread across three lines, with no newline at the end. For example if the Book fields were “C# Yellow Book”, “Rob Miles”, and 2011, the string should appear, when printed, as

Title: C# Yellow Book
Author: Rob Miles
Year: 2011

The override in the heading is important so the compiler knows that this is the official method for the system to used implicitly to convert the object to a string.

Remember the use of @ with multi-line string literals.

BookList class

It has just one instance variable, already declared:

private List<Book> list;

It has a constructor (already written - creating an empty List):

public BookList()

It should have public methods:

      // Add book to the list.
      // The regular assignment version always returns true.
      public bool Addbook(Book book)

The regular version should just leave the final return true; The extra credit version is more elaborate.

Further methods:

      /// List the full descriptions of each book,
      /// with each book separated by a blank line.
      public void PrintList() //
      // List the titles (only!), one per line, of each book
      // in the list that is by the specified author.
      public void PrintTitlesByAuthor(string author)
      // List the full descriptions of each book printed
      // in the range of years specified,
      // with each book separated by a blank line.
      public void PrintBooksInYears(int firstYear, int lastYear)

For instance if the list included books published in 1807, 1983, 2004, 1948, 1990, and 2001, the statement

PrintBooksInYears(1940, 1990);

would list the books from 1983, 1948, and 1990.

TestBookList class

It should have a Main program that creates a BookList, adds some books to it (more than in the skeleton!), and convincingly displays tests of each of BookList’s methods that exercise all paths through your code. Check for one-off errors in PrintBookYears. With all the methods that print something, the results are easy to see. Do print a label, as in the skeleton, before printing output from each method test, so that the user of the program can see the correctness of the test without any knowledge of the source code!

Grading Rubric

Book class

  • [1 point] public Book(string title, string author, int year)

  • [1] public string GetTitle()

  • [1] public string GetAuthor()

  • [1] public int GetYear()

  • [2] public override string ToString()

BookList class

  • [2] public bool AddBook(Book book)

  • [2] public void PrintList()

  • [2] public void PrintTitlesByAuthor(string author)

  • [2] public void PrintBooksInYears(int firstYear, int lastYear)

TestBookList

  • [2] Supply data to screen indicating what test is being done with what data and what results, so it is clear that each test works without looking at the source code.

  • [5] Convincingly display tests of each of BookList’s methods that exercise all paths through your code.

Overall:

  • [4] Make your code easy to read - follow indenting standards, use reasonable identifier names…. Do not duplicate code when you could call a method already written.

Extra Credit

You may do any of the numbered options, except that the last one requires you to do the previous one first.

To get full credit for any particular option, tests for it must be fully integrated into TestBookList!

  1. [2 points] Complete

          /// Return a single string containing the same data as
          /// printed by PrintList, including a final newline.
          public override string ToString()
    

    Also change the PrintList method body to the one line:

    Console.Write(this);
    

    (The Write and WriteLine methods print objects by using their ToString methods.)

    Be sure to make this addition to TestBookList: Test the ToString method by converting the resulting BookList description string to upper case before printing it (which should produce a different result than the regular mixed case of the PrintList method test).

  2. [4 points]

    In the Book class, a new constructor:

          /// Construct a Book, taking data from reader.
          /// Read through three lines that contain the
          /// title, author, and year of publication, respectively.
          /// There may be an extra blank line at the beginning.
          /// If so ignore it.
          /// Nothing beyond the line with the year is read.
          public Book(StreamReader reader)
    

    In class BookList, a new constructor:

          // Construct a new BookList using Book data read from
          // reader.  The data coming from reader will contain groups
          // of three line descriptions useful for the Book constructor
          // that reads from a stream.  Each three-line book description
          // *may or may not* be preceded by an empty line.
          public BookList(StreamReader reader)
    

    For testing we included special files in the right format: books_homework_stub/books.txt and books_homework_stub/morebooks.txt.

    You will also want to include a reference to fio/fio.cs, so the text files are easy to find.

  3. [4 points]

    In class Book:

          // Return true if all the corresponding fields in this Book
          // and in aBook are equal.  Return false otherwise.
          public bool IsEqual(Book aBook)
          {  // code for extra credit
    
             return true; //so skeleton compiles
          }
       }
    }
    

    It is essential to have the IsEqual method working in Book before any of the new code in BookList, which all depends on the definition of IsEqual for a Book.

    NOTE: We chose the name IsEqual to distinguish it from the more general Equals override that you could write. The Equals override allows for a parameter of any object type. With skills from Comp 271 you you be able to write the Equals override.

    In class BookList:

          // Test if aBook is contained in this BookList.
          // Return true if book IsEqual to a Book in the list,
          // false otherwise.
          public bool Contains(Book book)
    

    Caution: Do NOT try to use the List method Contains: Because we did not override the Equals method to specialize it for Books, the List method Contains will fail. You need to do a litle bit more work and write your own version with a loop.

    Change the AddBook method from the regular assignment, so it satisfies this documentation:

          /// Adds aBook to the list if aBook is
          /// not already in the list.
          /// Return true if aBook is added,
          /// and false if it was already in the list.
    

    In TestBookList you need to react to the return value, too.

  4. [2 points] This one requires the previous elaboration of AddBook. In BookList:

          // Add each Book in books to this BookList.
          // if it is not already contained in this BookList.
          // Return true if the current list was changed.
          // Return false if each Book in books is a
          // duplicate of a Book in the current list.
          public bool AddAll(BookList books)
    

    You might want to code it first without worrying about the correct return value; then do the complete version. There are multiple approach to determining the return value, some much easier than others!

    To fully test in TestBookList, you need to react to the return value, too.