Assignment 2: CMSμ
Due: Thursday, September 15

Learning Objectives

Introduction

The CMSX system we are using in this class was developed by Cornell students over the past 20 years, and is still used by this class and other large classes at Cornell because it offers features and performance not available in commercially available tools like Canvas.

In this assignment, you will be designing a simple system, CMSμ (μ for “micro”), which provides a small subset of the features of CMSX. The CMSμ system will manage the enrollment of students in courses, allowing the user to interact with it through several different commands. When a user starts the system, they will be able to add new students and courses, enroll students in courses, drop students from courses, and view information about specific courses and students.

As part of the assignment, you will implement an abstraction for a mutable list of students, which we will call StudentList. This abstract data type will be used to keep track of all students in the system as well as all students enrolled in each course. Your implementation of this abstraction will use a useful data structure, the resizable array.

Academic Integrity and Collaboration Policy

You may not collaborate with anyone on the code for the classes in this assignment—this includes looking at anyone else's code or showing anyone else your code in any form. While you can talk to others, this should not be sharing code but rather discussing general strategies on how to tackle a problem. Any such discussions must be documented. You may not look at solutions to similar assignments in previous runs of 2110.

In this assignment, you will work with another student with whom you will share test cases. You and this student can work together to write test cases for testing the classes. However, you and your partner may not share any code for the classes themselves. You can choose your own partner by inviting them on CMSX. However, if you do not have a partner by Wednesday, September 7th, we will randomly assign you a partner. You may find the partner-finding social event (September 6, 4–6pm, Upson Lounge) helpful.

If you do not know where to start, are stuck, do not understand testing, or are lost, please see someone on the course staff immediately. This can be in the form of an instructor, TA, or consultant.

How to do the Assignment

Start early. This is a longer and more involved assignment than Assignment 1.

Scan the entire assignment handout before starting. The three assignment classes are commented with various TODO statements numbered 1 through 25. Please design your classes and tests in this order to avoid confusion. An important part of design is to develop your classes and test them incrementally. This means you should test each part of the code you write before continuing to write the next step. We will pin a post on Ed with FAQs about this assignment. This post will be updated regularly with answers to questions including notes about what you can or can't use in your solution. Please read this post regularly to stay up to date on this information.

  1. At this point, you should have all of the release code classes in your project. The first step is to create your test class and also develop the Student class. To start, open the A2Test class in the a2 package. Here you and your testing partner will write unit tests primarily to test the methods of your StudentList class. You can write these tests using a similar format to those you wrote in A1.

  2. In class Student, declare the fields listed in the release code and write their class invariant.

    The class invariant. Comments must accompany the declarations of all fields to describe what the fields mean, what legal values they may contain, and what constraints hold for them. For example, for firstName, state in a comment that the field contains the Student's first name and must be a String of at least 1 character. The collection of the comments on these fields is called the class invariant.

    Use Javadoc comments for both the class invariant and method specifications. A Javadoc comment is a multiline comment that starts with /** instead of /*. You can find examples of this in the StudentList and Course classes.

    For this assignment you should also implement a method classInv() that implements the class invariant check as described in class. The method should be package-visible to help us test it. You will likely find it help to insert calls to classInv() in your method code to catch bugs.

  3. For each method in the Student class you must do the following:

    1. Read the Javadoc specification for the method describing what the method does as well as its preconditions.
    2. Write the method body, implementing what the method specifications say the method should do.
    3. Write a test procedure in your testing class that tests this method.
    4. Test the method thoroughly.


    Method specs do not mention fields because the user may not know what the fields are, or even if there are fields. The fields are private.

    How to test the Constructor. Based on its specification. figure out what values all the fields should be to make the class invariant true. Then in A2Test, write a test procedure that tests the constructor by calling the constructor and using the observer methods to determine if all the fields have the correct values. This also tests all the observer methods!

  4. Next you will fill in the methods in the StudentList class. The methods you need to fill in will all be marked with a TODO comment.

    It is important you also write tests in A2Test to test each of the methods you write as you write them. We highly recommend you write and test each method before continuing to write the next method!

  5. The next step is to write the Course class. Similar to the StudentList class, all the methods that you have to write have a TODO comment. Some of these TODO comments have additional information that you should read. This information is very important.

  6. Main.java is a harness class containing code that processes some commands. Once you complete implementing the Student, Course, and StudentList classes, you can run the code in Main.java successfully and use various commands to add students and courses to your CMSμ program. Additionally, you can enroll and drop students from courses and list all students and available courses. There is a help command that lists all the commands available and how to use them to get you started. You should not change any of the code in Main.java.

Commands

The system provides several different commands a user can run to manage the courses and students. Below are all the commands you will be implementing and their expected behavior. We provide a sample test script and the expected output when running that set of commands. You will also work with your testing partner to create your own test scripts to test your code. Command arguments must be separated by spaces.

Resizable Arrays

The most technically demanding part of the assignment is to implement the StudentList class. This class is an abstract data type representing a list of students. We are expecting you to implement it as a resizable array data structure. Ordinary arrays in Java have a fixed length, so they are not sufficient to store a list of students that can grow to an arbitrarily large size. The Java standard libraries do have existing classes that can keep track of such a list, such as java.util.ArrayList, but we are asking you to implement your own class without relying on any classes from the java.util package.

A resizable array is a simple, common data structure that acts like an array whose size can change, for example by adding new elements to the end of the array. A resizable array is implemented on top of fixed-length arrays. The data structure is backed by an underlying, fixed-length array that contains all of the elements of the resizable array. However, the underlying array is typically longer than necessary to store the elements it contains: up to half of the elements of the underlying array are logically “empty” and do not contain useful information. For example, a resizable array might have an underlying array of length 100 but only contain 70 elements at indices from 0 to 69. The contents of the remaining locations are not important. For example, they might contain null. A new element can then be added efficiently by simply storing it at index 70, and updating the data structure to record that the number of elements has increased. Thus, there is a difference between the capacity of the backing array and the number of elements in the resizable array. Viewed through the abstraction, the client should not be able to tell how big the backing array is.

If the capacity of the backing array is exceeded, a new, larger backing array is created and the resizable array data structure is changed to refer to the new backing array. It is conventional to double the size of the backing array when its capacity is exceeded, so that it is not more than 50% empty unless elements are removed.

How to Run CMSμ with a Test Script

In order to run CMSμ with a test script, first create a tests directory in your project by right clicking on the project name and selecting New ⇒ Directory. Name this directory tests. If you name it something else, it will not work. Then create a new text file inside the tests directory and put your test script in this file.

Next, go to Run → Edit Configurations. You should see a run configuration for Main.java. Then go to the Program Arguments field in the popup window and enter the name of your test script text file. For example, if my file is called script1.txt, I would enter script1.txt in the program arguments. Then click Ok and run the main method in Main.java. This will read the commands in the test script file and run them in order. We will provide one example test script for you to use, but we strongly suggest that you work with your test partner to write more test scripts.


Submission

Please make sure to fill in the time you spent using the timeSpent field in the StudentList class. Additionally, be sure to fill in your NetID and other information in the comment at the top of the StudentList class. Please also provide your testing partner's NetID after your own. Then upload your files StudentList.java, Course.java, Student.java, and A2Test.java to CMSX before the deadline. Additionally, use zip to compress your tests folder containing all the test scripts you used and submit it as tests.zip to CMSX before the deadline. To locate these files on your computer, you can right click on any of the classes and select "Open In" and then select your file explorer. For Windows, that may be "Explorer" and for Mac, that may be "Finder." Do not submit any files with different extensions at the end. To check if you submitted the correct files, download the files from CMSX after you have submitted them.