lab05 : Ordered Linked Lists

num ready? description assigned due
lab05 true Ordered Linked Lists Sun 11/03 11:59PM Sun 11/10 11:59PM

In this lab, you’ll have the opportunity to practice:

Note: It is important that you start this lab early so you can utilize our office hours to seek assistance / ask clarifying questions during the week before the deadline if needed!

You will write a program that will organize Movie objects into a Movie Collection. The Movie Collection will be implemented as an Ordered Linked List with a head reference. The implementation in this lab will be different than an Unordered Linked List since you will need to organize the nodes by the Movie’s director name (last name, first name in lexicographical / alphabetical order). In the event of a tie (several movies are directed by the same person), the year the movie was released will be used to determine the Movie object’s place in the Ordered Linked List. If the director and year are the same, then the Movie’s name (lexicographical / alphabetical order) will be used to determine the Movie object’s place in the Ordered Linked List.

This lab will require you to define classes for a Movie, MovieCollection, and a MovieCollectionNode, as well as writing your own unit tests to verify the correctness of your implementation.

Instructions

You will need to create four files:

There will be no starter code for this assignment, but rather the class descriptions and required methods are defined in the specification below.

You should organize your lab work in its own directory. This way all files for a lab are located in a single folder. Also, this will be easy to import various files into your code using the import / from technique shown in lecture.

Movie.py class

The Movie.py file will contain the definition of a Movie. We will define the Movie attributes as follows:

You should write a constructor that allows the user to construct a movie object by passing in values for movieName, director, year, and rating. Your constructor should set the rating to None by default if a value is not specified. You can assume that the movieName and director will always be of type str and the year will always be of type int when your code is run.

In addition to your constructor, your class definition should also support “getter” methods that can receive the state of the Movie object:

You will implement the method

that returns a str with all of the Movie attributes. The string should contain all attributes in the following EXACT format. The director’s name should be displayed as FirstName LastName according to example output below. (Note: There is no \n character at the end of this string):

m1 = Movie("The Godfather", "Darabont, Frank", 1972, 9.4)
m2 = Movie("2001: A Space Odyssey", "Kubric, Stanley", 1968)
print(m1.getMovieDetails())
print(m2.getMovieDetails())

Output

THE GODFATHER directed by FRANK DARABONT (1972), Rating: 9.4
2001: A SPACE ODYSSEY directed by STANLEY KUBRIC (1968), Rating: None

We reviewed operator overloading in class and the textbook does discuss overloading Python operators. You can also refer to this reference on overloading various operators as well:

https://www.geeksforgeeks.org/operator-overloading-in-python/

MovieCollection.py and MovieCollectionNode.py

The MovieCollectionNode.py file will define the MovieCollectionNode class. This will be similar to the Linked List Node implementation done in lecture.

You will need to write the following methods for the MovieCollectionNode class:

The MovieCollection.py file will contain the definition of a collection of Movie objects stored in an Ordered Linked List. Your class implementation MUST have an attribute called head that refers to the node at the front of the linked list or set this value to None if the linked list is empty. This allows the autograder to properly test your code. The MovieCollection will manage an Ordered Linked List containing MovieCollectionNode objects. The MovieCollection class will be responsible for maintaining the overall structure of the Ordered Linked List. Your MovieCollection class will need to support the following methods:

m0 = Movie("Casablanca", "Curtiz, Michael", 1942, 8.8)
m1 = Movie("2001: A Space Odyssey", "Kubric, Stanley", 1968, 9.2)
m2 = Movie("The Matrix", "Wachowski, Lana", 1999, 9.1)
m3 = Movie("Modern Times", "Chaplin, Charlie", 1936, 8.9)
m4 = Movie("City Lights", "Chaplin, Charlie", 1931, 9.0)

mc = MovieCollection()
mc.insertMovie(m0)
mc.insertMovie(m1)
mc.insertMovie(m2)
mc.insertMovie(m3)
mc.insertMovie(m4)
print(bc.getAllMoviesInCollection())

Output:

CITY LIGHTS directed by CHARLIE CHAPLIN (1931), Rating: 9.0
MODERN TIMES directed by CHARLIE CHAPLIN (1936), Rating: 8.9
CASABLANCA directed by MICHAEL CURTIZ (1942), Rating: 8.8
2001: A SPACE ODYSSEY directed by STANLEY KUBRIC (1968), Rating: 9.2
THE MATRIX directed by LANA WACHOWSKI (1999), Rating: 9.1

m0 = Movie("Casablanca", "Curtiz, Michael", 1942, 8.8)
m1 = Movie("2001: A Space Odyssey", "Kubric, Stanley", 1968, 9.2)
m2 = Movie("The Matrix", "Wachowski, Lana", 1999, 9.1)
m3 = Movie("Work", "Chaplin, Charlie", 1915, 6.2)
m4 = Movie("Modern Times", "Chaplin, Charlie", 1936, 8.9)
m5 = Movie("City Lights", "Chaplin, Charlie", 1931, 9.0)
m6 = Movie("The Champion", "Chaplin, Charlie", 1915, 6.7)

mc = MovieCollection()
mc.insertMovie(m0)
mc.insertMovie(m1)
mc.insertMovie(m2)
mc.insertMovie(m3)
mc.insertMovie(m4)
mc.insertMovie(m5)
mc.insertMovie(m6)
print(mc.getMoviesByDirector("Chaplin, Charlie"))

Output:

THE CHAMPION directed by CHARLIE CHAPLIN (1915), Rating: 6.7
WORK directed by CHARLIE CHAPLIN (1915), Rating: 6.2
CITY LIGHTS directed by CHARLIE CHAPLIN (1931), Rating: 9.0
MODERN TIMES directed by CHARLIE CHAPLIN (1936), Rating: 8.9

m0 = Movie("Casablanca", "Curtiz, Michael", 1942, 8.8)
m1 = Movie("Modern Times", "Chaplin, Charlie", 1936, 8.9)
m2 = Movie("The Matrix", "Wachowski, Lana", 1999, 9.1)
m3 = Movie("City Lights", "Chaplin, Charlie", 1931, 9.0)

mc = MovieCollection()
mc.insertMovie(m0)
mc.insertMovie(m1)
mc.insertMovie(m2)
mc.insertMovie(m3)
print(mc.avgDirectorRating("Chaplin, Charlie"))
print(mc.avgDirectorRating("Curtiz, Michael"))

Output:

8.95
8.8
m0 = Movie("Casablanca", "Curtiz, Michael", 1942, 8.8)
m1 = Movie("2001: A Space Odyssey", "Kubric, Stanley", 1968, 9.2)
m2 = Movie("Modern Times", "Chaplin, Charlie", 1936, 8.9)
m3 = Movie("City Lights", "Chaplin, Charlie", 1931, 9.8)

mc = MovieCollection()
mc.insertMovie(m0)
mc.insertMovie(m1)
mc.insertMovie(m2)
mc.insertMovie(m3)
assert mc.recursiveSearchMovie("Modern times", mc.head) == True
assert mc.recursiveSearchMovie("The Matrix", mc.head) == False
* You can then recursively search through the `MovieCollection` sub parts by recursively referring to the next `MovieCollectionNode` in `MovieCollection` that needs to be searched if the Movie in `movieNode` does not have the movie name we're looking for.
* **Note:** the input parameter `movieName` may be in a different case than the case of the movie name that the Movie was constructed with - your solution must account for these situations (see assert statement above).

testFile.py pytest

This file should import your Movie, MovieCollection, and MovieCollectionNode classes so you can write unit tests using pytest to test your functionality is correct. Think of various scenarios and edge cases when testing your code. Write your tests first in order to check the correctness of the Movie, MovieCollection and MovieCollectionNode methods. Gradescope requires testfile.py to be submitted before running any autograded tests. You should write at least one test for each method in each of these classes (but more tests can help you debug various cases!).

Submission

Once you’re done with writing your class definitions and tests, submit your Movie.py and MovieCollection.py, MovieCollectionNode.py, and testFile.py files to the Lab05 assignment on Gradescope. Remember to remove any print statements in your code since this may confuse the autograder. There will be various unit tests Gradescope will run to ensure your code is working correctly based on the specifications given in this lab.

If the tests don’t pass, you may get some error message that may or may not be obvious. Don’t worry - if the tests didn’t pass, take a minute to think about what may have caused the error, and try writing more comprehensive tests for various cases. If your tests didn’t pass and you’re still not sure why you’re getting the error, feel free to ask your TAs or Learning Assistants.

* Lab05 created by Sanjay Chandrasekaran and Qiucheng Wu, and adapted / updated by Richert Wang (F24)