import tester.*; // Lecture 5 // CS U213 Fall 2008 // bookstore-methods4.java /* ;; A Book is (make-book String Author Num Symbol) ;; There are three kinds of books: fiction, nonfiction, textbook ;; represented by symbols 'F 'N 'T (define-struct book (title author price kind)) ;; An Author is (make-author String Num) (define-struct author (name yob)) ;; Examples of authors (define eh (make-author "Hemingway" 1900)) (define ebw (make-author "White" 1920)) (define mf (make-author "MF" 1970)) ;; Examples of books (define oms (make-book "Old Man and the Sea" eh 10 'F)) (define eos (make-book "Elements of Style" ebw 20 'N)) (define htdp (make-book "HtDP" mf 60 'T)) */ /* +---------------+ | Book | +---------------+ | String title | | Author author |--+ | int price | | | char kind | | +---------------+ | v +-------------+ | Author | +-------------+ | String name | | int yob | +-------------+ */ // //***** ** // * * * // * * *** *** * *** // **** * * * * * * // * * * * * * *** // * * * * * * * * // * * * * * * * * //***** *** *** ** **** // // // to represent a book in a bookstore class Book{ String title; Author author; int price; char kind; Book(String title, Author author, int price, char kind){ this.title = title; this.author = author; this.price = price; this.kind = kind; } /* TEMPLATE: FIELDS: ... this.title ... -- String ... this.author ... -- Author ... this.price ... -- int ... this.kind ... -- char METHODS FOR FIELDS: ... this.author.sameName(String) ... -- boolean METHODS FOR THIS CLASS: ... this.writtenBy(String) ... -- boolean ... this.salePrice() ... -- int */ // was this book written by the given author? boolean writtenBy(String authorName){ return this.author.sameName(authorName); } /* the sale price of the book depends on the daily discounts these may differ depending on the kind of book suppose today we have the following discounts: there is 30% discount on fiction books there is 20% discount on nonfiction books textbooks sell at full price */ // compute the discounted sale price for this book int salePrice(){ if (this.kind == 'F'){ return this.price - 3 * (this.price / 10); } else {if (this.kind == 'N'){ return this.price - 2 * (this.price / 10); } else { return this.price; }} } } class Author{ String name; int yob; Author(String name, int yob){ this.name = name; this.yob = yob; } /* TEMPLATE: ... this.name ... -- String ... this.yob ... -- Author ... this.sameName(String) ... -- boolean */ // is this author's name the same as the given name? boolean sameName(String name){ return this.name.equals(name); } } // // // ***** *** ***** // * * * * // * * *** * * // * * * * **** // * * * * * * // * * * * * * * // * * * * * * * // ***** ***** *** ***** // // // to represent a list of books interface ILoB{ // compute the total sale price of all books in this list int totalPrice(); // produce a list of books sorted by their sale price from this list of books ILoB sort(); // produce a list with the given book inserted into this sorted list of books // according to the book's sale price ILoB insert(Book b); // is this list of books sorted by the sale price? boolean isSorted(); // is this list of books sorted by the sale price, // with the given book cheaper that all the rest? boolean isSortedAcc(Book cheapest); } // // //*** *** *** ***** // ** ** * * * * // ** ** ***** * *** * * // * * * * * * * **** // * * * * * * * * * // * * * * * * * * * // * * * * * * * * * * //*** *** *** ***** *** ***** // // // to represent an empty list of books class MtLoB implements ILoB{ MtLoB(){} // compute the total sale price of all books in this list public int totalPrice(){ return 0; } // produce a list of books sorted by their sale price from this list of books public ILoB sort(){ return this; } // produce a list with the given book inserted into this sorted list of books // according to the book's sale price public ILoB insert(Book b){ return new ConsLoB(b, this); } // is this list of books sorted by the sale price? public boolean isSorted(){ return true; } // is this list of books sorted by the sale price, // with the given book cheaper that all the rest? public boolean isSortedAcc(Book cheapest){ return true; } } // // // **** *** ***** // * * * * * // * *** ** ** **** * *** * * // * * * ** * * * * * * **** // * * * * * *** * * * * * // * * * * * * * * * * * * // * * * * * * * * * * * * * * // *** *** *** *** **** ***** *** ***** // // // to represent a nonempty list of books class ConsLoB implements ILoB{ Book first; ILoB rest; ConsLoB(Book first, ILoB rest){ this.first = first; this.rest = rest; } /* TEMPLATE: FIELDS: ... this.first ... -- Book ... this.rest ... -- ILoB METHODS FOR FIELDS: ... this.first.writtenBy(String) ... -- boolean ... this.first.salePrice() ... -- int ... this.rest.totalPrice() ... -- int ... this.rest.insert(Book) ... -- ILoB ... this.rest.sort() ... -- ILoB ... this.rest.isSorted() ... -- boolean ... this.rest.isSortedAcc(Book) ... -- boolean */ // compute the total sale price of all books in this list public int totalPrice(){ return this.first.salePrice() + this.rest.totalPrice(); } // produce a list of books sorted by their sale price from this list of books public ILoB sort(){ return this.rest.sort().insert(this.first); } // produce a list with the given book inserted into this sorted list of books // according to the book's sale price public ILoB insert(Book b){ if (b.salePrice() < this.first.salePrice()){ return new ConsLoB(b, this); } else{ return new ConsLoB(this.first, this.rest.insert(b)); } } // is this list of books sorted by the sale price? public boolean isSorted(){ return this.rest.isSortedAcc(this.first); } // is this list of books sorted by the sale price, // with the given book cheaper that all the rest? public boolean isSortedAcc(Book cheapest){ return cheapest.salePrice() <= this.first.salePrice() && this.rest.isSortedAcc(this.first); } } // // //****** ** // * * * // * * ** ** *** *** * ** ** * *** **** // *** * * * * * * * ** * * * * * * // * * ** **** * * * * * * ***** *** // * ** * * * * * * * * * * // * * * * * * * * * * * * * * * //****** ** ** ************ **** ***** **** **** // * // *** // // Examples and tests for books and lists of books class Examples{ Examples(){} Author eh = new Author("Hemingway", 1900); Author ebw = new Author("White", 1920); Author mf = new Author("MF", 1970); Book oms = new Book("Old Man and the Sea", this.eh, 10, 'F'); Book eos = new Book("Elements of Style", this.ebw, 20, 'N'); Book htdp = new Book("HtDP", this.mf, 60, 'T'); Book ll = new Book("Little Lisper", this.mf, 30, 'N'); ILoB mtlob = new MtLoB(); ILoB blist2 = new ConsLoB(this.oms, new ConsLoB(this.eos, this.mtlob)); ILoB blist3 = new ConsLoB(this.htdp, this.blist2); ILoB blist3Sorted = new ConsLoB(this.oms, new ConsLoB(this.eos, new ConsLoB(this.htdp, this.mtlob))); ILoB blist3Insert = new ConsLoB(this.oms, new ConsLoB(this.eos, new ConsLoB(this.ll, new ConsLoB(this.htdp, this.mtlob)))); // test the method salePrice in the class Book boolean testSalePrice(Tester t){ return t.checkExpect(this.oms.salePrice(), 7) && t.checkExpect(this.eos.salePrice(), 16) && t.checkExpect(this.htdp.salePrice(), 60) && t.checkExpect(this.ll.salePrice(), 24);} // test the method totalPrice in the classes that implement ILoB boolean testTotalPrice(Tester t){ return t.checkExpect(this.mtlob.totalPrice(), 0) && t.checkExpect(this.blist2.totalPrice(), 23) && t.checkExpect(this.blist3.totalPrice(), 83);} // test the method sort in the classes that implement ILoB boolean testSort(Tester t){ return t.checkExpect(this.mtlob.sort(), this.mtlob) && t.checkExpect(this.blist2.sort(), this.blist2) && t.checkExpect(this.blist3.sort(), this.blist3Sorted);} // test the method insert in the classes that implement ILoB boolean testInsert(Tester t){ return t.checkExpect(this.mtlob.insert(this.oms) , new ConsLoB(this.oms, this.mtlob)) && t.checkExpect(this.blist2.insert(this.htdp), this.blist3Sorted) && t.checkExpect(this.blist3Sorted.insert(this.ll), this.blist3Insert);} // test the method isSorted in the classes that implement ILoB boolean testIsSortedAcc(Tester t){ return t.checkExpect(this.mtlob.isSortedAcc(this.htdp), true) && t.checkExpect((new ConsLoB(this.htdp, this.mtlob)).isSortedAcc(this.eos) , true) && t.checkExpect(this.blist2.isSortedAcc(this.htdp), false) && t.checkExpect(this.blist2.isSortedAcc(new Book("LS", this.mf, 5, 'N')) , true);} // test the method isSorted in the classes that implement ILoB boolean testIsSorted(Tester t){ return t.checkExpect(this.mtlob.isSorted(), true) && t.checkExpect((new ConsLoB(this.htdp, this.mtlob)).isSorted(), true) && t.checkExpect(this.blist3.isSorted(), false) && t.checkExpect(this.blist3Sorted.isSorted(), true);} }