.. index:: homework; booklist booklist homework OOP; homework .. _booklist: 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 :repsrc:`books_homework_stub` to your own project. Stubs for the assignment files are :repsrc:`book.cs `, :repsrc:`book_list.cs `, and :repsrc:`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 :file:`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 :file:`book_list.cs`, and concurrently add and run tests in :file:`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**, :file:`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 .. code-block:: none 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 list; It has a constructor (already written - creating an empty List):: public BookList() It should have public methods: .. literalinclude:: ../../examples/introcs/books_homework_stub/book_list.cs :start-after: AddBook chunk :end-before: { The regular version should just leave the final ``return true;`` The extra credit version is more elaborate. Further methods: .. literalinclude:: ../../examples/introcs/books_homework_stub/book_list.cs :start-after: PrintList chunk :end-before: { .. literalinclude:: ../../examples/introcs/books_homework_stub/book_list.cs :start-after: PrintTitlesByAuthor chunk :end-before: { .. literalinclude:: ../../examples/introcs/books_homework_stub/book_list.cs :start-after: PrintBooksInYears chunk :end-before: { 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! #. [2 points] Complete .. literalinclude:: ../../examples/introcs/books_homework_stub/book_list.cs :start-after: ToString chunk :end-before: { 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). #. [4 points] In the Book class, a new constructor: .. literalinclude:: ../../examples/introcs/books_homework_stub/book.cs :start-after: Book chunk :end-before: { In class BookList, a new constructor: .. literalinclude:: ../../examples/introcs/books_homework_stub/book_list.cs :start-after: BookList chunk :end-before: { For testing we included special files in the right format: :repsrc:`books_homework_stub/books.txt` and :repsrc:`books_homework_stub/morebooks.txt`. You will also want to include a reference to :repsrc:`fio/fio.cs`, so the text files are easy to find. #. [4 points] In class Book: .. literalinclude:: ../../examples/introcs/books_homework_stub/book.cs :start-after: IsEqual chunk 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: .. literalinclude:: ../../examples/introcs/books_homework_stub/book_list.cs :start-after: Contains chunk :end-before: { 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: .. literalinclude:: ../../examples/introcs/books_homework_stub/book_list.cs :start-after: Revised AddBook :end-before: } In TestBookList you need to react to the return value, too. #. [2 points] This one requires the previous elaboration of ``AddBook``. In BookList: .. literalinclude:: ../../examples/introcs/books_homework_stub/book_list.cs :start-after: AddAll chunk :end-before: { 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.