Homework 8: Julia’s Western Library
Due: Tuesday April 21, 2020 at 9:00PM anywhere in the world.
Setup and Handin
- When finished, download your file and make sure it is called
hw8_code.py
. Hand in your work on Gradescope, making sure to use your anonymous account.
Remember your resources!
The Assignment
Julia just opened up a library of rare books from the frontier! She wants to let people take out books from her library, but she needs to keep close tabs on the books since they’re highly sought-after. Help Julia create a system to organize her library and keep track of which books have been checked out by whom!
Field Updates and Memory
This assignment explores sharing of data as reflected in the contents of memory. For this part of the assignment we will work with dataclasses for (library) books and patrons (people who check out library books). Here are our data classes: (you should copy these into your homework file)
from dataclasses import dataclass
@dataclass
class Patron:
name: str
books_out: list
@dataclass
class Book:
title: str
author: str
checked_out: bool = False
borrower: Patron = None
replacement_fee: float = 100.0
The idea here is that when a patron checks out a book, the book is marked as checked out and the book is stored in the patron’s list of checked-out books. When a patron returns a book, the book is marked as checked in and removed from the patron’s list.
Note: In the Book
dataclass, we see a new feature: we can give fields default values that get set whenever you create a value of a dataclass. To create a Book
, we only provide the title and author data; the other two fields are created and set automatically. For example, here is a library catalog with four books:
clean_catalog = [Book("The Mysterious Affair at Styles", "Agatha Christie"),
Book("The Adventures of Sherlock Holmes", "Arthur Conan Doyle"),
Book("The Secret of the Old Clock", "Carolyn Keene"),
Book("Crooked House", "Agatha Christie")]
Programs with Mutation
Task: Copy and paste the following code into a new file called hw8_code.py
.
from testlight import *
from dataclasses import dataclass
from copy import deepcopy
def find_books(books, query):
def check_out(book, patron):
def check_in(book, patron):
def display_books(books):
def update_replacement_fee(books, amount):
def cheapest_replacement_fee(books):
def total_replacement_fee(patron):
Task: Fill in the function definitions as specified below. Remember to add type annotations and a test function for EACH of these functions (e.g. test_find_books
to test the find_books
function)!
-
find_books
, which takes a list of books and a search term and returns the list of books with the given term in the title or author fields.
-
check_out
, which takes a book and a patron and updates both to check out the book out to the patron. Nothing gets returned. Don’t check for potential errors, just update the fields to check out the book.
-
check_in
, which takes a book and a patron and updates both to indicate that the patron has returned the book. The borrower
field of the Book
should be set to None
. Nothing gets returned. Don’t check for potential errors, just update the fields to check in the book.
-
display_books
, which takes a list of books and prints out a summary of each book, each book on one line. This gives a more readable view of a list of books than just printing out the entire list. The summary for one book should look like:
Crooked House by Agatha Christie [not available]
[not available] means the book is checked out. Print [available] for a book that is not checked out.
String formatting hints!
You can build messages to print using a combination of the built-in function str
, which converts its argument to a string, and +
to concatenate strings. Here’s an example:
print("Today is " + str(date(2018, 7, 26)))
There are also more specialized ways to format strings, which, though not necessary for this course, can be extremely useful for everyday Python usage. Check out this link to learn about f-Strings
(don’t worry about the “class
” stuff).
Note: Since display_books doesn’t return anything and just prints, you don’t need to (and can’t!) test it.
-
update_replacement_fee
, which takes a list of books and a dollar amount, and increases the replacement fee of each book in the list by that dollar amount. This function does not return anything; it just updates the list of books.
-
cheapest_replacement_fee
, which takes a list of books and returns the book with the lowest replacement fee. If there are no books, return None.
-
total_replacement_fee
, which takes a patron and returns the total replacement fee a patron would have to pay if they lost all of the books they currently have checked out. If a Patron has no books checked out, the total_replacement_fee
function should return 0.0.
What’s Going on in Memory?
Here, we have provided three programs that use the functions you have just written.
Task: Copy and paste the code to the bottom of your hw8_code.py
file.
Task: Answer the questions in each program comment. Some of it will involve writing code, and some will be just making comments. Refer to class notes to see the format for how to write out memory contents.
Note: A deep copy is a way to copy clean_catalog
so when we modify it, it doesn’t affect clean_catalog
itself.
Note: You DO NOT need to test these three functions.
def program1():
"""Sample program #1"""
catalog = deepcopy(clean_catalog)
Moses = Patron("Moses", [])
check_out(catalog[0], Moses)
check_out(catalog[1], Moses)
def program2():
"""Sample program #2"""
catalog = deepcopy(clean_catalog)
check_out(catalog[0], Patron("Kathi", []))
check_out(catalog[2], Patron("Kathi", []))
def program3():
"""Sample program #3"""
catalog = deepcopy(clean_catalog)
Julia = Patron("Julia", [])
Annie = Patron("Annie", [])
search = find_books(catalog, "Holmes")
check_out(search[0], Julia)
check_out(search[0], Annie)
print("Julia's books:")
display_books(Julia.books_out)
print("Annie's books")
display_books(Annie.books_out)
Theme Song
Robin Hood Rooster Song by unknown
Brown University CSCI 0111 (Spring 2020)
Do you have feedback? Fill out this form.
Homework 8: Julia’s Western Library
Due: Tuesday April 21, 2020 at 9:00PM anywhere in the world.
Setup and Handin
hw8_code.py
. Hand in your work on Gradescope, making sure to use your anonymous account.Remember your resources!
testlight.py
download instructions)The Assignment
Julia just opened up a library of rare books from the frontier! She wants to let people take out books from her library, but she needs to keep close tabs on the books since they’re highly sought-after. Help Julia create a system to organize her library and keep track of which books have been checked out by whom!
Field Updates and Memory
This assignment explores sharing of data as reflected in the contents of memory. For this part of the assignment we will work with dataclasses for (library) books and patrons (people who check out library books). Here are our data classes: (you should copy these into your homework file)
from dataclasses import dataclass @dataclass class Patron: name: str books_out: list @dataclass class Book: title: str author: str checked_out: bool = False borrower: Patron = None replacement_fee: float = 100.0
The idea here is that when a patron checks out a book, the book is marked as checked out and the book is stored in the patron’s list of checked-out books. When a patron returns a book, the book is marked as checked in and removed from the patron’s list.
Note: In the
Book
dataclass, we see a new feature: we can give fields default values that get set whenever you create a value of a dataclass. To create aBook
, we only provide the title and author data; the other two fields are created and set automatically. For example, here is a library catalog with four books:clean_catalog = [Book("The Mysterious Affair at Styles", "Agatha Christie"), Book("The Adventures of Sherlock Holmes", "Arthur Conan Doyle"), Book("The Secret of the Old Clock", "Carolyn Keene"), Book("Crooked House", "Agatha Christie")]
Programs with Mutation
Task: Copy and paste the following code into a new file called
hw8_code.py
.from testlight import * from dataclasses import dataclass from copy import deepcopy def find_books(books, query): def check_out(book, patron): def check_in(book, patron): def display_books(books): def update_replacement_fee(books, amount): def cheapest_replacement_fee(books): def total_replacement_fee(patron):
Task: Fill in the function definitions as specified below. Remember to add type annotations and a test function for EACH of these functions (e.g.
test_find_books
to test thefind_books
function)!find_books
, which takes a list of books and a search term and returns the list of books with the given term in the title or author fields.check_out
, which takes a book and a patron and updates both to check out the book out to the patron. Nothing gets returned. Don’t check for potential errors, just update the fields to check out the book.check_in
, which takes a book and a patron and updates both to indicate that the patron has returned the book. Theborrower
field of theBook
should be set toNone
. Nothing gets returned. Don’t check for potential errors, just update the fields to check in the book.display_books
, which takes a list of books and prints out a summary of each book, each book on one line. This gives a more readable view of a list of books than just printing out the entire list. The summary for one book should look like:[not available] means the book is checked out. Print [available] for a book that is not checked out.
String formatting hints!
You can build messages to print using a combination of the built-in function
str
, which converts its argument to a string, and+
to concatenate strings. Here’s an example:print("Today is " + str(date(2018, 7, 26)))
There are also more specialized ways to format strings, which, though not necessary for this course, can be extremely useful for everyday Python usage. Check out this link to learn about
f-Strings
(don’t worry about the “class
” stuff).Note: Since display_books doesn’t return anything and just prints, you don’t need to (and can’t!) test it.
update_replacement_fee
, which takes a list of books and a dollar amount, and increases the replacement fee of each book in the list by that dollar amount. This function does not return anything; it just updates the list of books.cheapest_replacement_fee
, which takes a list of books and returns the book with the lowest replacement fee. If there are no books, return None.total_replacement_fee
, which takes a patron and returns the total replacement fee a patron would have to pay if they lost all of the books they currently have checked out. If a Patron has no books checked out, thetotal_replacement_fee
function should return 0.0.What’s Going on in Memory?
Here, we have provided three programs that use the functions you have just written.
Task: Copy and paste the code to the bottom of your
hw8_code.py
file.Task: Answer the questions in each program comment. Some of it will involve writing code, and some will be just making comments. Refer to class notes to see the format for how to write out memory contents.
Note: A deep copy is a way to copy
clean_catalog
so when we modify it, it doesn’t affectclean_catalog
itself.Note: You DO NOT need to test these three functions.
def program1(): """Sample program #1""" catalog = deepcopy(clean_catalog) Moses = Patron("Moses", []) check_out(catalog[0], Moses) check_out(catalog[1], Moses) # FILL in the blank so the following test passes # (take the test out of comment when you are done) # test("program1 Moses' books", Moses.books_out, ____) def program2(): """Sample program #2""" catalog = deepcopy(clean_catalog) check_out(catalog[0], Patron("Kathi", [])) check_out(catalog[2], Patron("Kathi", [])) # WRITE out the memory contents at this point. # You don't need to write out the # original catalog in memory, just the copy. # __________________________ # # Either write a statement to print all the books Kathi # has checked out, or write a comment explaining why # this can't be done. # __________________________ def program3(): """Sample program #3""" catalog = deepcopy(clean_catalog) Julia = Patron("Julia", []) Annie = Patron("Annie", []) search = find_books(catalog, "Holmes") check_out(search[0], Julia) check_out(search[0], Annie) print("Julia's books:") display_books(Julia.books_out) print("Annie's books") display_books(Annie.books_out) # WRITE out the memory contents at this point. # You don't need to write out the # original catalog in memory, just the copy. # __________________________ # # In a few sentences, discuss whether the # memory contents look as you'd expect # for a program that properly checked books # in and out. If not, what program error # does this suggest? # __________________________
Theme Song
Robin Hood Rooster Song by unknown