Homework 9
Objectives
The goal of this assignment is to practice:
- Writing code that creates and manipulates objects from an existing class definition.
- Creating Python classes both with and without constructors.
Docstrings
For this homework, and all of the remaining homeworks, all of your modules and functions must exhibit correct documentation. Submissions that don’t pass docstring checks will receive no credit.
You should read the Docstring Requirements carefully to see how it should be done.
Exercise 9.1 Course Registration (Using Existing Classes)
Each semester the computer science department needs to determine the appropriate number of sections for each course based on the expected number of students who will enroll. For this exercise you will write a function to help us out with that process by creating an appropriate collection of Section
objects to meet student demand. The Section
class has been completed for you in the fileregistration.py
. The examples below illustrate the process of creating a single Section
object and calling its instance methods.
sec1 = Section("CS 159", 1, 32) # Create a section object.
print(sec1.course_code) # Prints: 'CS 159'
print(sec1.section_number) # Prints: 1
print(sec1.capacity) # Prints: 32
print(sec1.enrolled) # Prints: 0
sec1.add_students(10)
print(sec1.enrolled) # Prints: 10
sec1.add_students(25) # Prints: 'Error: not enough seats!'
print(sec1.enrolled) # Prints: 10
For this exercise, you must complete the unfinished create_sections
method that is stubbed out in registration.py
. You should not modify the provided Section
class. The following code snippet shows an example of calling the completed function.
In this case the output should be:
CS 149 0001 (30/30)
CS 149 0002 (30/30)
CS 149 0003 (30/30)
CS 149 0004 (10/30)
Exercise 9.2 Shopping Cart
Typically, an online store will have the concept of a “shopping cart”. In this problem we implement such a shopping cart.
Start from the file called shopping.py
. In this file create a class called ShoppingCart
. The class will have the following structure:
- An attribute
contents
, which is a list containing the names of what the user wants to buy. - Methods:
buy
, which takes one parameter – the name of the product the user wants to buy. It returns nothing.total_cost
, which takes no parameters and returns the total cost of everything in the listcontents
.
The starter code contains a price dictionary you will use to calculate the total cost.
Here are some examples illustrating the expected behavior:
>>> cart = ShoppingCart()
Exercise 9.3
When a bank makes a loan to a private individual, they typically charge some percentage interest every month, and the borrower pays a monthly payment. You will create a class to represent a loan and its repayment. In a file named loan.py
, create a class named Loan
. It will have the following attributes:
loan_amount
: the current amount of the loanmonthly_rate
: the monthly percentage interest charged, expressed as a decimal (i.e., 5% will be expressed as 0.05)total_paid
: the total amount paid on the loan to date.
It will have a constructor and one function:
- Create a constructor that takes the appropriate parameters and initializes anything else it needs to initialize.
pay_monthly_bill
: calculates the new value ofloan_amount
after interest is charged and the monthly payment is made. The function accepts one parameter representing the amount of payment being made. This function should also updatetotal_paid
so that it includes the new amount paid. Take special care when the borrower makes a payment that is higher than the current loan amount plus interest.
Here are some examples illustrating the expected behavior:
Exercise 9.4 Object-Oriented Book Cipher
In Exercise 8.5 we implemented a book cipher using books downloaded from Project Gutenberg. For this exercise you will create a more user-friendly implementation using classes. Your class must be named BookCipher
and it must have the the following methods:
- The constructor
__init__
, must take a single string argument containing a url representing the web address of a text document. The constructor must complete the following steps:- Download the text of the book and convert it into a list of words. These words must be stored in an instance variable named
book_words
. - Create a dictionary that maps from all words in
book_words
to the index of their final appearance. This dictionary must be stored in an instance variable namedword_locations
.
- Download the text of the book and convert it into a list of words. These words must be stored in an instance variable named
encode
This method will take a single argument containing a list of strings. It must return a list of integers corresponding to the locations of the words inbook_words
. Words that do not appear inbook_words
must be encoded as -1.encode
This method will take a single argument containing a list of integers representing an encoded message. It must return the decoded message as described in HW 8.5.
The following interaction illustrates the desired behavior:
Notes:
- Don’t worry if you didn’t complete HW 8.5. We’ll post a reference solution after the HW8 deadline that you can use as a starting point.
- The url in the example above, https://w3.cs.jmu.edu/spragunr/jabberwock.txt, refers to a very tiny except from Lewis Carroll’s Through the Looking Glass. This is provided to help you debug your implementation using a manageable input size. The full text is located here:https://www.gutenberg.org/files/12/12-0.txt
Exercise 9.5 Parking Lot
There’s a major event happening at the fairgrounds, and cars are lining up from everywhere. We need a program to help vehicles find a parking space when they arrive. Since parking is limited, and not all of the spaces are the same size, we need to be careful to put smaller vehicles in the smaller spots so that we can save the larger spots for vehicles that need them.
For the sake of simplicity both cars and parking spots will be represented as rectangles. A simple Rectangle
class has been provided. Download the following two files:
shapes.py
DO NOT MODIFY THIS FILE.parking.py
Your code goes here.
Define a class named ParkingLot
in parking.py
with the following methods:
-
A constructor that takes a list of rectangle objects representing available parking spots. The constructor must store a copy of this list in an instance variable named
spaces
. -
best_fit
- This method takes a singleRectangle
argument representing a car that needs to be parked. It must return the index of the smallest available parking spot that can accommodate the car. There must be at least two feet of space around all sides of the car when parked. Otherwise the passengers will have a hard time getting out without damaging adjacent vehicles. In the case of ties, the space with the larger index should be selected. If there is no spot that can accommodate the car, then the method must return -1. -
park
- This method takes a singleRectangle
argument representing a car that needs to be parked. The car must be parked in the most appropriate spot as selected by thebest_fit
method.When a car is parked, two changes must happen:
- The list element for the space must be set to
None
(i.e., “occupied”). - The car object must be “moved” to be centered within the space.
For example, if the space is 10x10 at location (0, 0) and the car is 6x6, then the car’s location must be updated to (2, 2) as shown in the diagram:
The
park
method must return the index where the car was parked. If no appropriate parking space is available, the method must return -1 (and no changes should be made to the spaces list or car object). - The list element for the space must be set to
-
num_spaces
- This method must return the remaining number of unoccupied parking spaces.
For this exercise, you may assume that widths will be less than or equal to heights (i.e., portrait orientation). There is no need to “rotate” the rectangles – there is no parallel parking at the fairgrounds.
Submit only parking.py
to Gradescope.
Note: We are not providing any sample code illustrating usage for the class described above. The feedback provided by Gradescope probably won’t be very useful. In order to complete this exercises you will probably need to spend some time developing your own testing code. I suggest adding an if __name__ == "__main__"
block and writing code to test various parking scenarios. Don’t bother submitting to Gradescope until you have convinced yourself that your code is working correctly.