Assignment 1: Java refresher and representation
Due dates:
Implementation: Tuesday, Jan 21 at 8:59pm
Self-evaluation: Released Wednesday January 22 at 9:00pm, Due Thursday, Jan 23 at 11:59pm
Starter files: code.zip
1 Purpose
The primary goal of this assignment is to get you writing Java (again or for the first time). A secondary goal is to understand that data representations should make behaviors easier to implement. As a tertiary goal, completing this assignment will help you ensure that you have a properly configured and working Java development environment and IDE, and that you can use the submission system.
2 Getting started
Before you start this assignment, please ensure that you have all the necessary tools to complete an assignment. They include:
Java 11 SDK
IntelliJ IDEA
Successful registration on the Handins server to submit an assignment
Successful registration on Piazza to post and get answers to common questions
Please review the directions on the course page if you need help setting up any of this, or talk to the course staff.
3 Representing expenses and expense reports
In this assignment, we will look at a possible system for representing expenses. Some organizations, like universities, reimburse, or repay, the people under them for purchases made if the purchase was for an organization’s benefit. For instance, student clubs provide a social benefit for students, so the university can reimburse the clubs’ expenses. The university requires the club to fill out an expense report before the university can reimburse them. While clubs at Northeastern create this report on paper, professors, as employees of the university, list these expenses on a website application. This application is what we will be looking at, assuming the end-users will be professors.
Throughout this assignment, we will assume all money is in US currency (dollars and cents).
An expense report has the following behaviors
Add an expense to the report
Retrieve an expense made in the report by name
Calculate the amount of money the expenses currently in the report can be reimbursed
Calculate the cost of the expenses currently in the report in total
An expense has three behaviors:
Retrieve the name of the expense
Retrieve the subtotal of the expense, which is the cost without tax applied
Retrieve the total cost of the expense, which includes the tax applied
The starter code contains two interfaces that detail the above and three classes that are all important objects of this reimbursement system:
the
TaxExemptExpenseReport
: an expense report that calculates the amount to reimburse as the subtotals of all expensesthe
TravelExpense
: a single expense for travelthe
BoardExpense
: a single expense for room and board
The Javadoc in those classes should explain what they are intended to represent.
4 Adding a method
You will add a new behavior to expenses and expense reports: pretty printing. This new behavior will return a textual representation of the expense report in a human-readable format. The method signature must be
String prettyPrint();
and must be added to both Expense
and ExpenseReport
.
The format of the output for an expense is the name of the expense, followed by a colon, a space, a dolalr sign ($
) and then the total cost of the expense (meaning with tax).
All numbers must be rounded to 2 decimal places and leading and trailing zeroes placed as necessary. So we expect numbers like "25", "24.7", and 24.07" to be printed as "25.00", 24.70", and "24.07" respectively.
As an example, suppose we had two expenses
travel expense called "United Travel to Conference" with a total cost of
$350
,$26.25
of which was taxboard expense called "Hilton Hotel Stay" for 4 nights at a rate of
$100
per night and$20
additionally paid in tax total
Then, in order, the expenses are printed as follows
United Travel to Conference: $350.00
Hilton Hotel Stay: $420.00
Hint: You will find String.format
useful. In the format string, we can use %.2f
to force a double to print as above.
The format of the output for an expense report is as follows
The word "Expenses", followed by a colon (:)
A list of the expenses in the report. Each expense must be pretty printed on its own line and start with two spaces.
The words "Grand Total" followed by a colon, space, dollar sign, and the sum cost of all the expenses in the report (including tax).
The words "Total Reimbursement" followed by a colon, space, dollar sign, and the calculated reimbursement.
Again, note that all numbers must be rounded to 2 decimal places and leading and trailing zeroes placed as necessary.
As an example, consider an expense report which had the following expenses in the following order
travel expense called "United Travel to Conference" with a total cost of
$350
,$26.25
of which was taxtravel expense called "Uber to Hotel" with a total cost of
$35
,$7
of which was taxboard expense called "Hilton Hotel Stay" for 4 nights at a rate of
$100
per night and$20
additionally paid in tax totaltravel expense called "Lyft to Airport" with a total cost of
$25
,$5
of which was taxtravel expense called "Spirit Travel from Conference" with a total cost of
$500
,$37.50
of which was tax
The pretty print of such an expense report will be as follows
Expenses:
United Travel to Conference: $350.00
Uber to Hotel: $35.00
Hilton Hotel Stay: $420.00
Lyft to Airport: $25.00
Spirit Travel from Conference: $500.00
Grand Total: $1330.00
Total Reimbursement: $1234.25
If there are no expenses in the report, then the total and reimbursement are 0 and the list of expenses is empty, like below:
Expenses:
Grand Total: $0.00
Total Reimbursement: $0.00
You must NOT change the implementation of the classes in starter code given to you except to add the new method and any helper methods related to that method.
Additionally, write a JUnit 4 test class, ExpenseReportTests
, that includes the
tests you add for this method.
5 Adding a class: Conference Expenses
Professors go to conferences often to keep up on the latest research and technology. Therefore, this too can be reimbursed by the university. You will design and implement a class to represent this type of expense called ConferenceExpense
that implements the Expense
interface. You may design additional classes to help you with this task.
A ConferenceExpense
is an expense for a conference. This must have a name and is comprised of one or more different workshop registrations.
Technically, workshops are different than conferences. In a conference, you passively absorb information from various technical talks. In a workshop, you may be more active, interacting with the speaker, engaging with discussion with participants, or learning some new technology. This means technically, a conference is made up of both conferences and workshops. In lieu of a more general term and knowing both have the same behaviors in this context, I will use workshop to avoid confusion in our data definitions.
A workshop registration is the name of a workshop and the cost of registering at that workshop. An important detail is that the cost has no tax at all! Two workshops are different if they have different names.
As an example, take the Programming Languages Design and Implementation Conference, abbreviated PLDI, specifically PLDI 2024. If you click on Organization, you will see a list of workshops to the right of the drop-down menu. For our example, we will be pulling from this list. An example conference expense called "PLDI 2024" for the conference PLDI is 3 workshop registrations: PLDI itself (which we will call a workshop for convenience) for $685
, ARRAY for $100
, and ISMM (which we will also call a workshop for convenience) for $200
.
The constructor for a ConferenceExpense
is defined as follows
public ConferenceExpense(String name, List<String> workshopNames, List<Double> workshopCosts)
The workshop registration is stored in both lists. The two lists are aligned by index. For example, workshopNames.get(4)
and workshopCosts.get(4)
are one workshop registration. This implies the lists must be the same length.
If either list is empty or null, the constructor should throw a IllegalArgumentException
. If either list contains a null object, the constructor should throw a IllegalArgumentException
. If the two lists are not the same length, the constructor should throw a IllegalArgumentException
. If a workshop name appears more than once in the list of workshop names, the constructor should throw a IllegalArgumentException
. Finally, if the name is empty or null, the constructor should throw a IllegalArgumentException
.
Hint: You will want to refresh yourselves on try-catch blocks and exception for throwing and catching exceptions. You may also want to refresh yourself on the java List interface and any of the classes that implement it.
When a ConferenceExpense
is asked for its name, it should return the name supplied.}
When a ConferenceExpense
is asked to calculate its subtotal, it should calculate the sum of all registration fees for the conferences.
When a ConferenceExpense
is asked to calculate its total cost, it should return the subtotal as all of these registrations do not have tax applied to them.
When a ConferenceExpense
is asked to pretty print its expense, it should create a formatted text representation of the expense. The format is as follows
the name of the expense followed by the word "Workshops" in a single line
each workshop registration on their own line. Each registration starts with two spaces, then the name of the workshop, followed by a colon, space, dollar sign, and the registration cost.
The word "Total", a colon, space, and dollar sign, followed by the total cost of the expense.
For our "PLDI 2024" expense example, the pretty print is as follows
PLDI 2024 Workshops
PLDI: $685.00
ARRAY: $100.00
ISMM: $200.00
Total: $985.00
Consider how this printing changes when put in an expense report. As an example, say we added this conference expense to the expense form example above, before all of the other expenses. The pretty print output changes to the following
Expenses:
PLDI 2024 Workshops
PLDI: $685.00
ARRAY: $100.00
ISMM: $200.00
Total: $985.00
United Travel to Conference: $350.00
Uber to Hotel: $35.00
Hilton Hotel Stay: $400.00
Lyft to Airport: $25.00
Spirit Travel from Conference: $500.00
Grand Total: $2315.00
Total Reimbursement: $2219.25
Notice how the workshops are further indented, two spaces from ConferenceExpense
and two more spaces from ExpenseReport
.
Additionally, in the ExpenseReportTests
test class, include new tests you add for this class
to ensure the above behavior works as intended. Note that the prettyPrint
method must also work for these kind of expenses.
6 Grading standards
For this assignment, you will be graded on
whether your code compiles,
whether your code implements the specification (functional correctness),
whether you thoroughly test every method that you write
how well you follow the style guide.
whether your program is suitably commented
whether you’ve kept each implementation method to 50 lines or less
6.1 The style guide
Coding style is important. For this class we follow Google’s Java style guide. It’s comprehensive but not very long, so I suggest reading the whole thing and then referring to it as needed.
While it can’t yet take on full responsibility for formatting code—
For IntelliJ IDEA, download
intellij-java-google-style.xml
and save it in theconfig/codestyles/
subdirectory of your IntelliJ configuration folder. Then from within IntelliJ, go to File > Other Settings > Default Settings..., then in the dialog that pops up, go to Editor / Code Style, and select it in the Scheme dropdown, where it should have appeared as an option. If you’ve already created a project, then you’ll additionally need to set this as the project style, using File > Settings.Check here for more info.
7 Submission
Ready to submit? Look at the Design Principles Master List first! (Not all items there may apply to this assignment)
7.1 Deliverables
For your implementation: submit a zip file containing
the code files defining your classes in the
cs3500.expenses
packageany test files
any files you had to create in order to implement and test your
ConferenceExpense
class, andprettyPrint
method.
Please ensure that your submission is a zip file. This zip file should contain your
src/
andtest/
folders from your project, and only those folders. These folders should mimic the folder structure required for your packages. Please do not put these folders within another folder before submitting, as the grader will not find your files:A properly-formatted zip file:
A improperly-formatted zip file:
my-submission.zip +-src/ | +-cs3500/ | +-expenses/ | +-Java files for expenses +-test/ +-ExpenseReportTests.java +-whatever other tests you wrote... possibly in packages...
my-submission.zip +-My Awesome Homework 1/ +-src/ | +-cs3500/ | +-expenses/ | +-Java files for expenses +-test/ +-ExpenseReportTests.java +-whatever other tests you wrote... possibly in packages...
7.2 Instructions
You will submit the assignment on the Handins server. Follow these instructions:
Log in to the server using the link above, using your Khoury account (not your Northeastern account). Follow directions on the course page if you do not have a Khoury account or have forgotten your password.
You must be registered as a student to CS 3500 for Spring 2025 on the handin server. Follow directions on the course page if you have not applied for registration.
Submit the zip file you made above to the relevant assignment (“HW1 - Expenses”) on the submission server. Note that for the autograded portions, it may take some time to see feedback. This time increases as we get closer to the deadline, because many more students tend to submit. Please be patient!
You have two submissions for this assignment: the implementation submission, and the self-eval. Make sure to submit to each of them by their respective deadlines.