Assignment 7 - Representing a Course Schedule
Due: Thursday, May 9, 2024, at 10pm
You may work alone or with a partner, but you must type up the code yourself. You may also discuss the assignment at a high level with other students. You should list any student with whom you discussed each part, and the manner of discussion (high-level, partner, etc.) in a comment at the top of each file. You should only have one partner for an entire assignment.
You should submit your assignment as an a7.zip
file on Moodle.
Parts of this assignment:
You will work in two different files for this assignment.
- Part 1: skeleton code. You should save the code file as
course.py
. - Parts 2+3: skeleton code. You should save the code file as
courseSchedule.py
.
There is also a data file for testing, and a Python file used to generated it:
- CS course data file. You should save this as
courseData.csv
in the same folder as your code. - data file generator. You don’t need to use or read this, it’s just kind of fun.
Comments and collaboration
As with all assignments in this course, for each file in this assignment, you are expected to provide top-level comments (lines that start with #
at the top of the file) with your name and a collaboration statement. For this assignment, you have multiple programs; each needs a similar prelude.
You need a collaboration statement, even if just to say that you worked alone.
Note on style:
The following style guidelines are expected moving forward, and will typically constitute 5-10 points of each assignment (out of 100 points).
- Variable names should be clear and easy to understand, should not start with a capital letter, and should only be a single letter when appropriate (usually for
i
,j
, andk
as indices, potentially forx
andy
as coordinates, and maybep
as a point,c
for a circle,r
for a rectangle, etc.). - It’s good to use empty lines to break code into logical chunks.
- Comments should be used for anything complex, and typically for chunks of 3-5 lines of code, but not every line.
- Don’t leave extra print statements in the code, even if you left them commented out.
- Make sure not to have code that computes the right answer by doing extra work (e.g., leaving a computation in a for loop when it could have occurred after the for loop, only once).
- Avoid having tons of lines of code immediately after another that could have been in a loop.
- Use lowercase first letters for variables and methods, and uppercase first letters for classes.
Part 1: Representing a course
# You should be fully equipped to complete this problem after Lesson 18 (Monday May 6).
In this problem, you will complete the implementation of the Course
class to represent courses. Each course has a name, a number of credits, an amount of effort required, and a value due to taking the course.
Here is the specification of the Course
class:
- The constructor takes in four normal parameters: the name, the credits, the effort, and the value.
- Each of the four instance variables has an accessor method:
getName()
,getCredits()
,getEffort()
, andgetValue()
. - There should be a
__str__()
method that is used to generate a string representation of a Course instance. (More info on this below.)
Fill in the class definition for Course
in course.py
. As an exercise in test-driven developent, there is testing code provided for you in an if __name__ == "__main__":
block at the bottom of this file. Once your implementation is complete, the tests should all pass:
Testing Course.getName(): pass
Testing Course.getCredits(): pass
Testing Course.getEffort(): pass
Testing Course.getValue(): pass
Testing Course.__str__(): pass
Most of the methods you’ll implement for this part are straightforward accessor methods. However, you’ll also be implementing the __str__()
method. Remember that in Python double underscores (__
) have special meaning. When a function __str__()
is defined in Python, this is what gets called when the str()
function is used (including when you try to call print()
on an object). The __str__
function should take only one formal parameter (self
), and return a string. Here is an example for our MultiSidedDie
class:
def __str__(self):
return str(self.numSides) + "-sided die (val=" + \
str(self.val) + ")"
We can use it like this:
d4 = MultiSidedDie(4) # 4-sided die
d4.roll()
print(d4) # prints: 4-sided die (val=3)
As an aside, recall that there is an easier way to build strings using “f-strings” in Python. If you precede a string with a letter f
, you can use {}
with variable names to plug them in directly. We could rewrite the MultiSidedDie.__str__
function cleanly like this:
def __str__(self):
return f"{self.numSides}-sided die (val={self.value})"
Part 2: Representing a course schedule
# You should be fully equipped to complete this problem after Lesson 18 (Monday May 6).
In addition to representing an individual course, we’ll implement another class to represent a course schedule.
For this part, you’ll complete the following class definition:
from course import Course
class CourseSchedule:
def __init__(self, courses = []):
self.courses = courses[:] # copy the courses
def addCourse(self, course):
pass # TODO
def getNumCourses(self):
return 0 # TODO
def getTotalCredits(self):
return 0 # TODO
def getAverageEffort(self):
return 0 # TODO
def getMedianValue(self):
return 0 # TODO
The CourseSchedule
class represents the schedule as a list of Course
objects. It includes the following functions:
addCourse
: add a newCourse
object to the schedulegetNumCourses
: return the number ofCourse
objects in the schedulegetTotalCredits
: calculates (and returns) the total number of credits among allCourse
s in the schedulegetAverageEffort
: calculates (and returns) the average effort among allCourse
s in the schedulegetMedianValue
: calculates (and returns) the median value among allCourse
s in the schedule
Here are a few helpful notes:
- Recall that the average of items in a list is the sum of those items divided by the number of items. Depending on your approach, you may find the
sum()
function useful. - The median is the center of a sorted list. This method should be slightly more challenging than the others, but it doesn’t need to be much more challenging. Remember that the median of an odd number of items is the middle, and the median of an even number is the average of the two middle items. You may find the
sorted()
function helpful.
Here’s an example using sorted()
:
# Build a list of numbers
mylist = [3, 1, 4, 1, 5, 9]
print(mylist) # [3, 1, 4, 1, 5, 9]
# Sort a copy of the list
mylist_sorted = sorted(mylist)
print(mylist_sorted) # [1, 1, 3, 4, 5, 9]
# The original is unchanged :)
print(mylist) # [3, 1, 4, 1, 5, 9]
This is the expected output once you’ve completed this class definition, given the test code in courseSchedule.py
:
Number of courses: 4
Total credits: 19
Average effort: 5.5
Median value: 6.0
Number of courses: 5
Total credits: 21
Average effort: 5.2
Median value: 7
Part 3: Reading in a course schedule
# You should be fully equipped to complete this problem after you complete Parts 1 and 2; you already know how to parse CSV files and just need the two classes implemented.
To give you a little more practice working with CSV files, you should fill in the function readScheduleFromCSV
to parse a given file into a CourseSchedule
object. The CSV file can be assumed to have each row contain one course’s information in the order name,credits,effort,value
.
I’ve generated a CSV file, roughly corresponding to Carleton’s CS course offerings. Note: these are entirely made up randomly, except for CS 111 which has suspiciously high value for the amount of effort…
CS 100,6,5,4
CS 111,6,2,10
CS 200,6,5,9
CS 201,6,8,8
CS 202,6,2,3
CS 208,6,10,6
For example, in this file, the course with name “CS 111” is for 6 credits, with effort=2 and value=10.
Once you implement this function, you can change the if __name__ == "__main__":
block at the end of the file to call testReadScheduleFromCSV
, which should then generate this output:
# Testing readScheduleFromCSV:
------------------------------
Number of courses: 36
Total credits: 210
Average effort: 5.444444444444445
Median value: 4.5
Reflection
# You should be equipped to complete this part after finishing your assignment.
Were there any particular issues or challenges you dealt with in completing this assignment? How long did you spend on this assignment? Write a brief discussion (a sentence or two is fine) in your readme.txt
file.
Grading
This assignment will be graded out of 100 points, as follows:
-
5 points - submit a valid
a7.zip
file with all files correctly named -
5 points - all code files contain top-level comments with file name, purpose, and author names
-
5 points - each code files’ top-level comments contain collaboration statement
-
10 points - code style enables readable programs
-
25 points -
Course
class implementation works correctly (Part 1) -
35 points -
CourseSchedule
class implementation works correctly (Part 2) -
10 points -
readScheduleFromCSV
function reads inCourse
data from a specified CSV file and returns aCourseSchedule
of those courses (Part 3) -
5 points -
readme.txt
file contains reflection
What you should submit
You should submit a single .zip file on Moodle. It should contain the following files:
readme.txt
(reflection)course.py
(Part 1)courseSchedule.py
(Parts 2+3)