First commit
This commit is contained in:
29
GUI_Lab/src/CashMachine.java
Executable file
29
GUI_Lab/src/CashMachine.java
Executable file
@@ -0,0 +1,29 @@
|
||||
import java.lang.reflect.*;
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* The main class for the CashMachine application.
|
||||
*/
|
||||
public class CashMachine implements Runnable
|
||||
{
|
||||
/**
|
||||
* The entry point of the application (which is executed in the
|
||||
* main thread of execution).
|
||||
*
|
||||
* @param args The command-line arguments
|
||||
*/
|
||||
public static void main(String[] args) throws InterruptedException, InvocationTargetException
|
||||
{
|
||||
SwingUtilities.invokeAndWait(new CashMachine());
|
||||
}
|
||||
|
||||
/**
|
||||
* The code that is executed in the event dispatch thread.
|
||||
*/
|
||||
public void run()
|
||||
{
|
||||
PINPadWindow window = new PINPadWindow();
|
||||
window.setTitle("ATM");
|
||||
window.setVisible(true);
|
||||
}
|
||||
}
|
||||
26
GUI_Lab/src/NumberPad.java
Executable file
26
GUI_Lab/src/NumberPad.java
Executable file
@@ -0,0 +1,26 @@
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* A numeric keypad
|
||||
*/
|
||||
public class NumberPad extends JPanel
|
||||
{
|
||||
/**
|
||||
* Default Constructor
|
||||
*/
|
||||
public NumberPad()
|
||||
{
|
||||
super();
|
||||
setupLayout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup and layout this NumberPad
|
||||
*/
|
||||
private void setupLayout()
|
||||
{
|
||||
// Setup and layout this NumberPad
|
||||
}
|
||||
}
|
||||
31
GUI_Lab/src/PINPadWindow.java
Executable file
31
GUI_Lab/src/PINPadWindow.java
Executable file
@@ -0,0 +1,31 @@
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* A window containing a PIN entry pad.
|
||||
*/
|
||||
public class PINPadWindow extends JFrame
|
||||
{
|
||||
/**
|
||||
* Default Constructor.
|
||||
*/
|
||||
public PINPadWindow()
|
||||
{
|
||||
super();
|
||||
setupLayout();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup and layout this PINPadWindow
|
||||
*/
|
||||
private void setupLayout()
|
||||
{
|
||||
Container contentPane;
|
||||
|
||||
setSize(300, 300);
|
||||
|
||||
contentPane = getContentPane();
|
||||
|
||||
// Layout this PINPadWindow
|
||||
}
|
||||
}
|
||||
143
Homework 1/src/app/Gradient.java
Executable file
143
Homework 1/src/app/Gradient.java
Executable file
@@ -0,0 +1,143 @@
|
||||
package app;
|
||||
|
||||
import grading.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An application for calculating the numeric grade for a course from the grades on individual
|
||||
* assignments.
|
||||
*
|
||||
* This version assumes that the course is structured as follows:
|
||||
*
|
||||
* 6 programming assignments (PAs) accounting for 40% of the course grade after the lowest grade is
|
||||
* dropped.
|
||||
*
|
||||
* 5 homework assignments (HWs) accounting for 10% of the course grade.
|
||||
*
|
||||
* 1 mid-term exam (Midterm) accounting for 20% of the course grade.
|
||||
*
|
||||
* 1 final exam (Final) accounting for 30% of the course grade.
|
||||
*
|
||||
* @version 1.0
|
||||
* @author Sagacious Media
|
||||
*
|
||||
*/
|
||||
public class Gradient
|
||||
{
|
||||
/**
|
||||
* The entry point for the application.
|
||||
*
|
||||
* @param args
|
||||
* The 13 grades (ordered as above). Missing grades can be entered as "NA".
|
||||
*/
|
||||
public static void main(final String[] args)
|
||||
{
|
||||
Filter paFilter;
|
||||
Grade courseGrade, hwGrade, paGrade;
|
||||
GradingStrategy courseStrategy, hwStrategy, paStrategy;
|
||||
List<Grade> grades, hws, pas;
|
||||
Map<String, Double> courseWeights;
|
||||
|
||||
// Early exit
|
||||
if ((args == null) || (args.length != 13))
|
||||
{
|
||||
System.err.println("You must enter exactly 13 grades. (Use NA for missing.)");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// Create the filter and strategy for PAs
|
||||
paFilter = new DropFilter(true, false);
|
||||
paStrategy = new TotalStrategy();
|
||||
|
||||
// Create the strategy for HWs
|
||||
hwStrategy = new TotalStrategy();
|
||||
|
||||
// Create the weights and strategy for the course grade
|
||||
courseWeights = new HashMap<String, Double>();
|
||||
courseWeights.put("PAs", 0.4);
|
||||
courseWeights.put("HWs", 0.1);
|
||||
courseWeights.put("Midterm", 0.2);
|
||||
courseWeights.put("Final", 0.3);
|
||||
courseStrategy = new WeightedTotalStrategy(courseWeights);
|
||||
|
||||
try
|
||||
{
|
||||
// Put the PA grades in a List
|
||||
pas = new ArrayList<Grade>();
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
pas.add(parseGrade("PA" + (i + 1), args[i]));
|
||||
}
|
||||
|
||||
// Calculate the PA grade (after filtering)
|
||||
paGrade = paStrategy.calculate("PAs", paFilter.apply(pas));
|
||||
|
||||
// Put the HW grades in a List
|
||||
hws = new ArrayList<Grade>();
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
hws.add(parseGrade("HW" + (i + 1), args[i + 6]));
|
||||
}
|
||||
|
||||
// Calculate the HW grade
|
||||
hwGrade = hwStrategy.calculate("HWs", hws);
|
||||
|
||||
// Put all of the grades in a List
|
||||
grades = new ArrayList<Grade>();
|
||||
grades.add(paGrade);
|
||||
grades.add(hwGrade);
|
||||
grades.add(parseGrade("Midterm", args[11]));
|
||||
grades.add(parseGrade("Final", args[12]));
|
||||
|
||||
// Calculate the final grade
|
||||
courseGrade = courseStrategy.calculate("Course Grade", grades);
|
||||
|
||||
// Display the final grade
|
||||
System.out.println(courseGrade.toString());
|
||||
}
|
||||
catch (SizeException se)
|
||||
{
|
||||
System.out.println("You entered too few valid grades.");
|
||||
}
|
||||
catch (IllegalArgumentException iae)
|
||||
{
|
||||
// Should never get here since all keys should be valid
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a Grade object from a key and a String representation of its value. If the String
|
||||
* representation of the value is null or not a valid double then the resulting Grade will have a
|
||||
* missing value.
|
||||
*
|
||||
* @param key
|
||||
* The key for the Grade
|
||||
* @param value
|
||||
* The String representation of the value
|
||||
* @return The corresponding Grade object
|
||||
* @throws IllegalArgumentException
|
||||
* if the key is invalid
|
||||
*/
|
||||
private static Grade parseGrade(final String key, final String value)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
Grade result;
|
||||
|
||||
try
|
||||
{
|
||||
Double v;
|
||||
if (value == null)
|
||||
v = null;
|
||||
else
|
||||
v = Double.valueOf(value);
|
||||
|
||||
result = new Grade(key, v);
|
||||
}
|
||||
catch (NumberFormatException nfe)
|
||||
{
|
||||
result = new Grade(key, null);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
79
Homework 1/src/grading/DropFilter.java
Executable file
79
Homework 1/src/grading/DropFilter.java
Executable file
@@ -0,0 +1,79 @@
|
||||
package grading;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A filter to apply to a list of grades to optionally drop the lowest or highest grades.
|
||||
*/
|
||||
public class DropFilter implements Filter
|
||||
{
|
||||
private boolean shouldDropLowest;
|
||||
private boolean shouldDropHighest;
|
||||
|
||||
/**
|
||||
* Default constructor that will drop the lowest and highest grades.
|
||||
*/
|
||||
public DropFilter()
|
||||
{
|
||||
this.shouldDropLowest = true;
|
||||
this.shouldDropHighest = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param shouldDropLowest
|
||||
* Whether or not to drop the lowest grade
|
||||
* @param shouldDropHighest
|
||||
* Whether or not to drop the highest grade
|
||||
*/
|
||||
public DropFilter(final boolean shouldDropLowest, final boolean shouldDropHighest)
|
||||
{
|
||||
this.shouldDropLowest = shouldDropLowest;
|
||||
this.shouldDropHighest = shouldDropHighest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param grades
|
||||
* The list of grades to apply the DropFilter to.
|
||||
* @return A new list containing the original grades with filter applied
|
||||
*/
|
||||
public List<Grade> apply(final List<Grade> grades) throws SizeException
|
||||
{
|
||||
int minSize = (shouldDropLowest ? 1 : 0) + (shouldDropHighest ? 1 : 0);
|
||||
|
||||
if (grades == null || grades.size() <= minSize)
|
||||
{
|
||||
throw new SizeException();
|
||||
}
|
||||
|
||||
List<Grade> droppedGrades = new ArrayList<Grade>();
|
||||
droppedGrades.addAll(grades);
|
||||
|
||||
Grade lowest = null;
|
||||
Grade highest = null;
|
||||
|
||||
for (Grade grade : grades)
|
||||
{
|
||||
if (lowest == null || grade.compareTo(lowest) < 0)
|
||||
{
|
||||
lowest = grade;
|
||||
}
|
||||
|
||||
if (highest == null || grade.compareTo(highest) > 0)
|
||||
{
|
||||
highest = grade;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldDropLowest)
|
||||
{
|
||||
droppedGrades.remove(lowest);
|
||||
}
|
||||
|
||||
if (shouldDropHighest)
|
||||
{
|
||||
droppedGrades.remove(highest);
|
||||
}
|
||||
|
||||
return droppedGrades;
|
||||
}
|
||||
}
|
||||
17
Homework 1/src/grading/Filter.java
Executable file
17
Homework 1/src/grading/Filter.java
Executable file
@@ -0,0 +1,17 @@
|
||||
package grading;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An interface for filters that can be applied to a list of grades.
|
||||
*/
|
||||
public interface Filter
|
||||
{
|
||||
/**
|
||||
* @param grades
|
||||
* The list of grades to provide the filter to
|
||||
* @return A new list contain the original grades with the filter applied
|
||||
* @throws SizeException
|
||||
*/
|
||||
public List<Grade> apply(List<Grade> grades) throws SizeException;
|
||||
}
|
||||
106
Homework 1/src/grading/Grade.java
Executable file
106
Homework 1/src/grading/Grade.java
Executable file
@@ -0,0 +1,106 @@
|
||||
package grading;
|
||||
|
||||
/**
|
||||
* A data class for storing a grade with a key and a value to store the score.
|
||||
*/
|
||||
public class Grade implements Comparable<Grade>
|
||||
{
|
||||
private String key;
|
||||
private Double value;
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The type of grade
|
||||
*/
|
||||
public Grade(final String key)
|
||||
{
|
||||
if (key == null || key.isEmpty())
|
||||
{
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
this.key = key;
|
||||
this.value = 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The type of grade
|
||||
* @param value
|
||||
* The score for the grade
|
||||
*/
|
||||
public Grade(final String key, final double value)
|
||||
{
|
||||
if (key == null || key.isEmpty())
|
||||
{
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The type of grade
|
||||
* @param value
|
||||
* The score for the grade
|
||||
*/
|
||||
public Grade(final String key, final Double value)
|
||||
{
|
||||
if (key == null || key.isEmpty())
|
||||
{
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param other
|
||||
* The grade to compare with
|
||||
* @return Either -1, 0, or 1 depending on if the grade was smaller/equal to/larger than other
|
||||
*/
|
||||
public int compareTo(final Grade other)
|
||||
{
|
||||
if (this.value == null)
|
||||
{
|
||||
return (other.value == null) ? 0 : -1;
|
||||
}
|
||||
if (other.value == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return this.value.compareTo(other.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A string representation of the grade
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return String.format("%s: NA", key);
|
||||
}
|
||||
|
||||
return String.format("%s: %5.1f", key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The key for the grade
|
||||
*/
|
||||
public String getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The value of the grade
|
||||
*/
|
||||
public Double getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
19
Homework 1/src/grading/GradingStrategy.java
Executable file
19
Homework 1/src/grading/GradingStrategy.java
Executable file
@@ -0,0 +1,19 @@
|
||||
package grading;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An interface for strategies of calculating a final grade from a list of grades.
|
||||
*/
|
||||
public interface GradingStrategy
|
||||
{
|
||||
/**
|
||||
* @param key
|
||||
* The key for the final calculated grade
|
||||
* @param grades
|
||||
* The list of grades to from which to calculate the final grade
|
||||
* @return A new grade representing the final grade calculated from grades
|
||||
* @throws SizeException
|
||||
*/
|
||||
public Grade calculate(String key, List<Grade> grades) throws SizeException;
|
||||
}
|
||||
35
Homework 1/src/grading/Missing.java
Executable file
35
Homework 1/src/grading/Missing.java
Executable file
@@ -0,0 +1,35 @@
|
||||
package grading;
|
||||
|
||||
/**
|
||||
* A utility class for supplying a default double value in the case that a provided double is null.
|
||||
*/
|
||||
public class Missing
|
||||
{
|
||||
private static double DEFAULT_MISSING_VALUE = 0.0;
|
||||
|
||||
private Missing()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param number
|
||||
* The supplied double to check for null.
|
||||
* @return Either number if it was not null, or a default value of 0.0 if it was.
|
||||
*/
|
||||
public static double doubleValue(final Double number)
|
||||
{
|
||||
return number != null ? number : DEFAULT_MISSING_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param number
|
||||
* The supplied double to check for null.
|
||||
* @param missingValue
|
||||
* The default value to return if number was null
|
||||
* @return Either number if it was not null, or missingValue if it was
|
||||
*/
|
||||
public static double doubleValue(final Double number, final double missingValue)
|
||||
{
|
||||
return number != null ? number : missingValue;
|
||||
}
|
||||
}
|
||||
19
Homework 1/src/grading/SizeException.java
Executable file
19
Homework 1/src/grading/SizeException.java
Executable file
@@ -0,0 +1,19 @@
|
||||
package grading;
|
||||
|
||||
/**
|
||||
* A custom exception for cases where a provided list does not meet a size requirement.
|
||||
*/
|
||||
public class SizeException extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* Exception identifier.
|
||||
*/
|
||||
static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates a new SizeException instance.
|
||||
*/
|
||||
public SizeException()
|
||||
{
|
||||
}
|
||||
}
|
||||
40
Homework 1/src/grading/TotalStrategy.java
Executable file
40
Homework 1/src/grading/TotalStrategy.java
Executable file
@@ -0,0 +1,40 @@
|
||||
package grading;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An implementation GradingStrategy that simply totals the scores for all grades.
|
||||
*/
|
||||
public class TotalStrategy implements GradingStrategy
|
||||
{
|
||||
/**
|
||||
* Creates a new instance of TotalStrategy.
|
||||
*/
|
||||
public TotalStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The key of the final totaled grade
|
||||
* @param grades
|
||||
* The list of grades to calculate the final total grade from
|
||||
* @return A new grade representing the total of grades
|
||||
*/
|
||||
public Grade calculate(final String key, final List<Grade> grades) throws SizeException
|
||||
{
|
||||
if (grades == null || grades.isEmpty())
|
||||
{
|
||||
throw new SizeException();
|
||||
}
|
||||
|
||||
Double total = 0.0;
|
||||
|
||||
for (Grade grade : grades)
|
||||
{
|
||||
total += Missing.doubleValue(grade.getValue());
|
||||
}
|
||||
|
||||
return new Grade(key, total);
|
||||
}
|
||||
}
|
||||
61
Homework 1/src/grading/WeightedTotalStrategy.java
Executable file
61
Homework 1/src/grading/WeightedTotalStrategy.java
Executable file
@@ -0,0 +1,61 @@
|
||||
package grading;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An implementation GradingStrategy that applies weights to specific grade keys and weighs each
|
||||
* grade before summing a total.
|
||||
*/
|
||||
public class WeightedTotalStrategy implements GradingStrategy
|
||||
{
|
||||
private Map<String, Double> weights;
|
||||
|
||||
/**
|
||||
* Creates a new instance WeightedTotalStrategy.
|
||||
*/
|
||||
public WeightedTotalStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance WeightedTotalStrategy.
|
||||
*
|
||||
* @param weights
|
||||
* A map of keys and weights to be applied to the grades during calculation.
|
||||
*/
|
||||
public WeightedTotalStrategy(final Map<String, Double> weights)
|
||||
{
|
||||
this.weights = weights;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The key of the final totaled grade
|
||||
* @param grades
|
||||
* The list of grades to calculate the final total grade from
|
||||
* @return A new grade representing the total of the weighted grades
|
||||
*/
|
||||
public Grade calculate(final String key, final List<Grade> grades) throws SizeException
|
||||
{
|
||||
if (grades == null || grades.isEmpty())
|
||||
{
|
||||
throw new SizeException();
|
||||
}
|
||||
|
||||
Double total = 0.0;
|
||||
|
||||
for (Grade grade : grades)
|
||||
{
|
||||
Double weight = 1.0;
|
||||
if (weights != null && weights.containsKey(grade.getKey()))
|
||||
{
|
||||
Double mapWeight = weights.get(grade.getKey());
|
||||
weight = Math.max(mapWeight, 0.0);
|
||||
}
|
||||
|
||||
total += Missing.doubleValue(grade.getValue()) * weight;
|
||||
}
|
||||
|
||||
return new Grade(key, total);
|
||||
}
|
||||
}
|
||||
38
Homework 1/src/testing/DropFilterTest.java
Executable file
38
Homework 1/src/testing/DropFilterTest.java
Executable file
@@ -0,0 +1,38 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import grading.Grade;
|
||||
import grading.SizeException;
|
||||
import grading.DropFilter;
|
||||
|
||||
class DropFilterTest
|
||||
{
|
||||
@Test
|
||||
void applyTest()
|
||||
{
|
||||
final Grade grade1 = new Grade("HW", 40.0);
|
||||
final Grade grade2 = new Grade("Midterm", (Double) null);
|
||||
final Grade grade3 = new Grade("Final", 100.0);
|
||||
|
||||
List<Grade> grades = List.of(grade1, grade2, grade3);
|
||||
|
||||
DropFilter defaultFilter = new DropFilter();
|
||||
DropFilter filter1 = new DropFilter(false, false);
|
||||
DropFilter filter2 = new DropFilter(false, true);
|
||||
DropFilter filter3 = new DropFilter(true, false);
|
||||
DropFilter filter4 = new DropFilter(true, true);
|
||||
|
||||
assertThrows(SizeException.class, () -> defaultFilter.apply((List<Grade>) null));
|
||||
assertThrows(SizeException.class, () -> defaultFilter.apply(new ArrayList<Grade>()));
|
||||
|
||||
assertIterableEquals(grades, filter1.apply(grades));
|
||||
assertIterableEquals(List.of(grade1, grade2), filter2.apply(grades));
|
||||
assertIterableEquals(List.of(grade1, grade3), filter3.apply(grades));
|
||||
assertIterableEquals(List.of(grade1), filter4.apply(grades));
|
||||
}
|
||||
}
|
||||
79
Homework 1/src/testing/GradeTest.java
Executable file
79
Homework 1/src/testing/GradeTest.java
Executable file
@@ -0,0 +1,79 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import grading.Grade;
|
||||
|
||||
class GradeTest
|
||||
{
|
||||
private static final String HOMEWORK_KEY = "HW";
|
||||
private static final String MIDTERM_KEY = "Midterm";
|
||||
private static final String FINAL_KEY = "Final";
|
||||
|
||||
@Test
|
||||
void defaultValueConstructorTest()
|
||||
{
|
||||
Grade grade = new Grade(FINAL_KEY);
|
||||
assertEquals(FINAL_KEY, grade.getKey());
|
||||
assertEquals(0.0, grade.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenValueConstructorTest()
|
||||
{
|
||||
Grade grade = new Grade(MIDTERM_KEY, 85.5);
|
||||
assertEquals(MIDTERM_KEY, grade.getKey());
|
||||
assertEquals(85.5, grade.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullValueConstructorTest()
|
||||
{
|
||||
assertThrows(IllegalArgumentException.class, () -> new Grade(null));
|
||||
assertThrows(IllegalArgumentException.class, () -> new Grade(null, 90.0));
|
||||
assertThrows(IllegalArgumentException.class, () -> new Grade(null, (Double) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyKeyConstructorTest()
|
||||
{
|
||||
assertThrows(IllegalArgumentException.class, () -> new Grade(""));
|
||||
assertThrows(IllegalArgumentException.class, () -> new Grade("", 90.0));
|
||||
assertThrows(IllegalArgumentException.class, () -> new Grade("", (Double) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullCompareToTest()
|
||||
{
|
||||
Grade grade1 = new Grade(HOMEWORK_KEY, (Double) null);
|
||||
Grade grade2 = new Grade(HOMEWORK_KEY, 80.0);
|
||||
Grade grade3 = new Grade(HOMEWORK_KEY, (Double) null);
|
||||
|
||||
assertTrue(grade1.compareTo(grade2) < 0);
|
||||
assertEquals(0, grade1.compareTo(grade3));
|
||||
assertTrue(grade2.compareTo(grade1) > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void compareToTest()
|
||||
{
|
||||
Grade grade1 = new Grade(HOMEWORK_KEY, 75.0);
|
||||
Grade grade2 = new Grade(HOMEWORK_KEY, 85.0);
|
||||
Grade grade3 = new Grade(HOMEWORK_KEY, 75.0);
|
||||
|
||||
assertTrue(grade1.compareTo(grade2) < 0);
|
||||
assertEquals(0, grade1.compareTo(grade3));
|
||||
assertTrue(grade2.compareTo(grade1) > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringTest()
|
||||
{
|
||||
Grade grade1 = new Grade(FINAL_KEY, 90.0);
|
||||
Grade grade2 = new Grade(MIDTERM_KEY, (Double) null);
|
||||
|
||||
assertEquals("Final: 90.0", grade1.toString());
|
||||
assertEquals("Midterm: NA", grade2.toString());
|
||||
}
|
||||
}
|
||||
23
Homework 1/src/testing/MissingTest.java
Executable file
23
Homework 1/src/testing/MissingTest.java
Executable file
@@ -0,0 +1,23 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import grading.Missing;
|
||||
|
||||
class MissingTest
|
||||
{
|
||||
@Test
|
||||
void defaultDoubleValueTest()
|
||||
{
|
||||
assertEquals(40.0, Missing.doubleValue(40.0));
|
||||
assertEquals(0.0, Missing.doubleValue((Double) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMissingDoubleValueTest()
|
||||
{
|
||||
assertEquals(40.0, Missing.doubleValue(40.0, 20.0));
|
||||
assertEquals(20.0, Missing.doubleValue((Double) null, 20.0));
|
||||
}
|
||||
}
|
||||
34
Homework 1/src/testing/TotalStrategyTest.java
Executable file
34
Homework 1/src/testing/TotalStrategyTest.java
Executable file
@@ -0,0 +1,34 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import grading.Grade;
|
||||
import grading.TotalStrategy;
|
||||
import grading.SizeException;
|
||||
|
||||
class TotalStrategyTest
|
||||
{
|
||||
private static final String TOTAL_KEY = "Total";
|
||||
|
||||
@Test
|
||||
void calculateTest()
|
||||
{
|
||||
List<Grade> grades = new ArrayList<Grade>();
|
||||
grades.add(new Grade("HW1", 40.0));
|
||||
grades.add(new Grade("HW2", (Double) null));
|
||||
grades.add(new Grade("HW3", 100.0));
|
||||
|
||||
TotalStrategy strategy = new TotalStrategy();
|
||||
|
||||
assertThrows(SizeException.class, () -> strategy.calculate(TOTAL_KEY, (List<Grade>) null));
|
||||
assertThrows(SizeException.class, () -> strategy.calculate(TOTAL_KEY, new ArrayList<Grade>()));
|
||||
|
||||
Grade total = strategy.calculate(TOTAL_KEY, grades);
|
||||
|
||||
assertEquals(TOTAL_KEY, total.getKey());
|
||||
assertEquals(140.0, total.getValue());
|
||||
}
|
||||
}
|
||||
50
Homework 1/src/testing/WeightedTotalStrategyTest.java
Executable file
50
Homework 1/src/testing/WeightedTotalStrategyTest.java
Executable file
@@ -0,0 +1,50 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import grading.Grade;
|
||||
import grading.WeightedTotalStrategy;
|
||||
import grading.SizeException;
|
||||
|
||||
class WeightedTotalStrategyTest
|
||||
{
|
||||
private static final String HOMEWORK_KEY = "HW";
|
||||
private static final String MIDTERM_KEY = "Midterm";
|
||||
private static final String FINAL_KEY = "Final";
|
||||
private static final String TOTAL_KEY = "Total";
|
||||
|
||||
@Test
|
||||
void calculateTest()
|
||||
{
|
||||
List<Grade> grades = new ArrayList<Grade>();
|
||||
grades.add(new Grade(HOMEWORK_KEY, 40.0));
|
||||
grades.add(new Grade(MIDTERM_KEY, (Double) null));
|
||||
grades.add(new Grade(FINAL_KEY, 100.0));
|
||||
|
||||
Map<String, Double> weights = new HashMap<String, Double>();
|
||||
weights.put(MIDTERM_KEY, 2.0);
|
||||
weights.put(FINAL_KEY, 3.0);
|
||||
|
||||
WeightedTotalStrategy defaultStrategy = new WeightedTotalStrategy();
|
||||
|
||||
assertThrows(SizeException.class,
|
||||
() -> defaultStrategy.calculate(TOTAL_KEY, (List<Grade>) null));
|
||||
assertThrows(SizeException.class,
|
||||
() -> defaultStrategy.calculate(TOTAL_KEY, new ArrayList<Grade>()));
|
||||
|
||||
Grade total = defaultStrategy.calculate(TOTAL_KEY, grades);
|
||||
|
||||
assertEquals(TOTAL_KEY, total.getKey());
|
||||
assertEquals(140.0, total.getValue());
|
||||
|
||||
WeightedTotalStrategy strategy = new WeightedTotalStrategy(weights);
|
||||
|
||||
Grade weightedTotal = strategy.calculate(TOTAL_KEY, grades);
|
||||
|
||||
assertEquals(TOTAL_KEY, weightedTotal.getKey());
|
||||
assertEquals(340.0, weightedTotal.getValue());
|
||||
}
|
||||
}
|
||||
BIN
Homework 2/CS345-Homework 2.vpp
Executable file
BIN
Homework 2/CS345-Homework 2.vpp
Executable file
Binary file not shown.
BIN
Homework 2/CS345-Homework 2.vpp.bak_000f
Executable file
BIN
Homework 2/CS345-Homework 2.vpp.bak_000f
Executable file
Binary file not shown.
BIN
Homework 2/Calculate Average Temperatures.pdf
Executable file
BIN
Homework 2/Calculate Average Temperatures.pdf
Executable file
Binary file not shown.
3653
Homework 2/Charlottesville.tem
Executable file
3653
Homework 2/Charlottesville.tem
Executable file
File diff suppressed because it is too large
Load Diff
2239
Homework 2/DaleEnterprise.tem
Executable file
2239
Homework 2/DaleEnterprise.tem
Executable file
File diff suppressed because it is too large
Load Diff
BIN
Homework 3/Homework 3.pdf
Executable file
BIN
Homework 3/Homework 3.pdf
Executable file
Binary file not shown.
18
Homework 4/complete_01.grd
Executable file
18
Homework 4/complete_01.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 20
|
||||
PA2 18
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5 20
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 5
|
||||
HW3 0
|
||||
HW4 10
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm 80
|
||||
Final Exam 1 0.30 false false
|
||||
Final 75
|
||||
18
Homework 4/complete_02.grd
Executable file
18
Homework 4/complete_02.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 20
|
||||
PA2 20
|
||||
PA3 20
|
||||
PA4 20
|
||||
PA5 20
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 20
|
||||
HW3 20
|
||||
HW4 20
|
||||
HW5 20
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm 100
|
||||
Final Exam 1 0.30 false false
|
||||
Final 100
|
||||
18
Homework 4/complete_03.grd
Executable file
18
Homework 4/complete_03.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 10
|
||||
PA2 10
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5 5
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 0
|
||||
HW3 0
|
||||
HW4 10
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm 60
|
||||
Final Exam 1 0.30 false false
|
||||
Final 45
|
||||
21
Homework 4/five-categories_01.grd
Executable file
21
Homework 4/five-categories_01.grd
Executable file
@@ -0,0 +1,21 @@
|
||||
5
|
||||
Homework Assignments 5 0.25 true false
|
||||
HW01 20
|
||||
HW02 5
|
||||
HW03 0
|
||||
HW04 10
|
||||
HW05 15
|
||||
Quizzes 5 0.25 true true
|
||||
Quiz01 12
|
||||
Quiz02 8
|
||||
Quiz03 20
|
||||
Quiz04 13
|
||||
Quiz05 20
|
||||
Misc 2 0.10 false false
|
||||
Attendance 40
|
||||
Participation 50
|
||||
Midterm Exams 2 0.20 false false
|
||||
Midterm01 45
|
||||
Midterm02 40
|
||||
Final Exam 1 0.20 false false
|
||||
Final 75
|
||||
18
Homework 4/missing_all.grd
Executable file
18
Homework 4/missing_all.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1
|
||||
PA2
|
||||
PA3
|
||||
PA4
|
||||
PA5
|
||||
PA6
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1
|
||||
HW2
|
||||
HW3
|
||||
HW4
|
||||
HW5
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm
|
||||
Final Exam 1 0.30 false false
|
||||
Final
|
||||
18
Homework 4/missing_multiple-in-each.grd
Executable file
18
Homework 4/missing_multiple-in-each.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1
|
||||
PA2 20
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5
|
||||
PA6
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2
|
||||
HW3 0
|
||||
HW4
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm
|
||||
Final Exam 1 0.30 false false
|
||||
Final
|
||||
18
Homework 4/missing_one-in-each.grd
Executable file
18
Homework 4/missing_one-in-each.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 20
|
||||
PA2 18
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 5
|
||||
HW3 0
|
||||
HW4
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm
|
||||
Final Exam 1 0.30 false false
|
||||
Final
|
||||
18
Homework 4/missing_one-in-one.grd
Executable file
18
Homework 4/missing_one-in-one.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 20
|
||||
PA2 18
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5 20
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 5
|
||||
HW3
|
||||
HW4 10
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm 80
|
||||
Final Exam 1 0.30 false false
|
||||
Final 75
|
||||
36
Homework 4/six-categories_01.grd
Executable file
36
Homework 4/six-categories_01.grd
Executable file
@@ -0,0 +1,36 @@
|
||||
6
|
||||
Programming Assignments 6 0.15 false false
|
||||
PA01 20
|
||||
PA02 18
|
||||
PA03 5
|
||||
PA04 15
|
||||
PA05 20
|
||||
PA06 20
|
||||
Homework Assignments 5 0.15 false false
|
||||
HW01 20
|
||||
HW02 5
|
||||
HW03 0
|
||||
HW04 10
|
||||
HW05 15
|
||||
Labs 10 0.10 false false
|
||||
Lab01 10
|
||||
Lab02 5
|
||||
Lab03 10
|
||||
Lab04 10
|
||||
Lab05 0
|
||||
Lab06 10
|
||||
Lab07 10
|
||||
Lab08 10
|
||||
Lab09 5
|
||||
Lab10 10
|
||||
Quizzes 5 0.10 false false
|
||||
Quiz01 12
|
||||
Quiz02 8
|
||||
Quiz03 20
|
||||
Quiz04 13
|
||||
Quiz05 16
|
||||
Midterm Exams 2 0.20 false false
|
||||
Midterm01 45
|
||||
Midterm02 40
|
||||
Final Exam 1 0.30 false false
|
||||
Final 75
|
||||
72
Homework 4/src/app/Gradient.java
Executable file
72
Homework 4/src/app/Gradient.java
Executable file
@@ -0,0 +1,72 @@
|
||||
package app;
|
||||
import grading.*;
|
||||
import grading.io.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
* An application for calculating the numeric grade for
|
||||
* a course from the grades on individual assignments.
|
||||
*
|
||||
* This version reads the course structure (and optionally the grades)
|
||||
* from a file. It assumes:
|
||||
*
|
||||
* The grade in each category is the total of the individual assessments.
|
||||
*
|
||||
* The course grade is the weighted total of the category grades.
|
||||
*
|
||||
* @version 2.0
|
||||
* @author Sagacious Media
|
||||
*
|
||||
*/
|
||||
public class Gradient
|
||||
{
|
||||
/**
|
||||
* The entry point for the application.
|
||||
*
|
||||
* @param args args[0] contains the path (relative or absolute) to the .grd file
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// Early exit
|
||||
if ((args == null) || (args.length < 1))
|
||||
{
|
||||
System.err.println("You must enter a file name.");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
BufferedReader in = new BufferedReader(new FileReader(args[0]));
|
||||
String line = in.readLine();
|
||||
int categories = Integer.parseInt(line);
|
||||
Course course = CourseReader.readCourse(in, categories);
|
||||
in.close();
|
||||
|
||||
ArrayList<Grade> grades = new ArrayList<Grade>();
|
||||
for (Category c: course.getCategories())
|
||||
{
|
||||
GradingStrategy categoryStrategy = c.getStrategy();
|
||||
Filter filter = c.getFilter();
|
||||
Grade grade = categoryStrategy.calculate(c.getKey(), filter.apply(c.getGrades()));
|
||||
grades.add(grade);
|
||||
}
|
||||
|
||||
GradingStrategy courseStrategy = course.getStrategy();
|
||||
Grade courseGrade = courseStrategy.calculate("Course Grade", grades);
|
||||
System.out.println(courseGrade.toString());
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
System.out.println("Unable to open file.");
|
||||
System.exit(1);
|
||||
}
|
||||
catch (SizeException se)
|
||||
{
|
||||
// Shouldn't happen
|
||||
System.out.println("Size Problem.");
|
||||
System.exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
79
Homework 4/src/grading/DropFilter.java
Executable file
79
Homework 4/src/grading/DropFilter.java
Executable file
@@ -0,0 +1,79 @@
|
||||
package grading;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A filter to apply to a list of grades to optionally drop the lowest or highest grades.
|
||||
*/
|
||||
public class DropFilter implements Filter
|
||||
{
|
||||
private boolean shouldDropLowest;
|
||||
private boolean shouldDropHighest;
|
||||
|
||||
/**
|
||||
* Default constructor that will drop the lowest and highest grades.
|
||||
*/
|
||||
public DropFilter()
|
||||
{
|
||||
this.shouldDropLowest = true;
|
||||
this.shouldDropHighest = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param shouldDropLowest
|
||||
* Whether or not to drop the lowest grade
|
||||
* @param shouldDropHighest
|
||||
* Whether or not to drop the highest grade
|
||||
*/
|
||||
public DropFilter(final boolean shouldDropLowest, final boolean shouldDropHighest)
|
||||
{
|
||||
this.shouldDropLowest = shouldDropLowest;
|
||||
this.shouldDropHighest = shouldDropHighest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param grades
|
||||
* The list of grades to apply the DropFilter to.
|
||||
* @return A new list containing the original grades with filter applied
|
||||
*/
|
||||
public List<Grade> apply(final List<Grade> grades) throws SizeException
|
||||
{
|
||||
int minSize = (shouldDropLowest ? 1 : 0) + (shouldDropHighest ? 1 : 0);
|
||||
|
||||
if (grades == null || grades.size() <= minSize)
|
||||
{
|
||||
throw new SizeException();
|
||||
}
|
||||
|
||||
List<Grade> droppedGrades = new ArrayList<Grade>();
|
||||
droppedGrades.addAll(grades);
|
||||
|
||||
Grade lowest = null;
|
||||
Grade highest = null;
|
||||
|
||||
for (Grade grade : grades)
|
||||
{
|
||||
if (lowest == null || grade.compareTo(lowest) < 0)
|
||||
{
|
||||
lowest = grade;
|
||||
}
|
||||
|
||||
if (highest == null || grade.compareTo(highest) > 0)
|
||||
{
|
||||
highest = grade;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldDropLowest)
|
||||
{
|
||||
droppedGrades.remove(lowest);
|
||||
}
|
||||
|
||||
if (shouldDropHighest)
|
||||
{
|
||||
droppedGrades.remove(highest);
|
||||
}
|
||||
|
||||
return droppedGrades;
|
||||
}
|
||||
}
|
||||
17
Homework 4/src/grading/Filter.java
Executable file
17
Homework 4/src/grading/Filter.java
Executable file
@@ -0,0 +1,17 @@
|
||||
package grading;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An interface for filters that can be applied to a list of grades.
|
||||
*/
|
||||
public interface Filter
|
||||
{
|
||||
/**
|
||||
* @param grades
|
||||
* The list of grades to provide the filter to
|
||||
* @return A new list contain the original grades with the filter applied
|
||||
* @throws SizeException
|
||||
*/
|
||||
public List<Grade> apply(List<Grade> grades) throws SizeException;
|
||||
}
|
||||
106
Homework 4/src/grading/Grade.java
Executable file
106
Homework 4/src/grading/Grade.java
Executable file
@@ -0,0 +1,106 @@
|
||||
package grading;
|
||||
|
||||
/**
|
||||
* A data class for storing a grade with a key and a value to store the score.
|
||||
*/
|
||||
public class Grade implements Comparable<Grade>
|
||||
{
|
||||
private String key;
|
||||
private Double value;
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The type of grade
|
||||
*/
|
||||
public Grade(final String key)
|
||||
{
|
||||
if (key == null || key.isEmpty())
|
||||
{
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
this.key = key;
|
||||
this.value = 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The type of grade
|
||||
* @param value
|
||||
* The score for the grade
|
||||
*/
|
||||
public Grade(final String key, final double value)
|
||||
{
|
||||
if (key == null || key.isEmpty())
|
||||
{
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The type of grade
|
||||
* @param value
|
||||
* The score for the grade
|
||||
*/
|
||||
public Grade(final String key, final Double value)
|
||||
{
|
||||
if (key == null || key.isEmpty())
|
||||
{
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param other
|
||||
* The grade to compare with
|
||||
* @return Either -1, 0, or 1 depending on if the grade was smaller/equal to/larger than other
|
||||
*/
|
||||
public int compareTo(final Grade other)
|
||||
{
|
||||
if (this.value == null)
|
||||
{
|
||||
return (other.value == null) ? 0 : -1;
|
||||
}
|
||||
if (other.value == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return this.value.compareTo(other.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A string representation of the grade
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return String.format("%s: NA", key);
|
||||
}
|
||||
|
||||
return String.format("%s: %5.1f", key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The key for the grade
|
||||
*/
|
||||
public String getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The value of the grade
|
||||
*/
|
||||
public Double getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
19
Homework 4/src/grading/GradingStrategy.java
Executable file
19
Homework 4/src/grading/GradingStrategy.java
Executable file
@@ -0,0 +1,19 @@
|
||||
package grading;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An interface for strategies of calculating a final grade from a list of grades.
|
||||
*/
|
||||
public interface GradingStrategy
|
||||
{
|
||||
/**
|
||||
* @param key
|
||||
* The key for the final calculated grade
|
||||
* @param grades
|
||||
* The list of grades to from which to calculate the final grade
|
||||
* @return A new grade representing the final grade calculated from grades
|
||||
* @throws SizeException
|
||||
*/
|
||||
public Grade calculate(String key, List<Grade> grades) throws SizeException;
|
||||
}
|
||||
35
Homework 4/src/grading/Missing.java
Executable file
35
Homework 4/src/grading/Missing.java
Executable file
@@ -0,0 +1,35 @@
|
||||
package grading;
|
||||
|
||||
/**
|
||||
* A utility class for supplying a default double value in the case that a provided double is null.
|
||||
*/
|
||||
public class Missing
|
||||
{
|
||||
private static double DEFAULT_MISSING_VALUE = 0.0;
|
||||
|
||||
private Missing()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param number
|
||||
* The supplied double to check for null.
|
||||
* @return Either number if it was not null, or a default value of 0.0 if it was.
|
||||
*/
|
||||
public static double doubleValue(final Double number)
|
||||
{
|
||||
return number != null ? number : DEFAULT_MISSING_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param number
|
||||
* The supplied double to check for null.
|
||||
* @param missingValue
|
||||
* The default value to return if number was null
|
||||
* @return Either number if it was not null, or missingValue if it was
|
||||
*/
|
||||
public static double doubleValue(final Double number, final double missingValue)
|
||||
{
|
||||
return number != null ? number : missingValue;
|
||||
}
|
||||
}
|
||||
19
Homework 4/src/grading/SizeException.java
Executable file
19
Homework 4/src/grading/SizeException.java
Executable file
@@ -0,0 +1,19 @@
|
||||
package grading;
|
||||
|
||||
/**
|
||||
* A custom exception for cases where a provided list does not meet a size requirement.
|
||||
*/
|
||||
public class SizeException extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* Exception identifier.
|
||||
*/
|
||||
static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates a new SizeException instance.
|
||||
*/
|
||||
public SizeException()
|
||||
{
|
||||
}
|
||||
}
|
||||
40
Homework 4/src/grading/TotalStrategy.java
Executable file
40
Homework 4/src/grading/TotalStrategy.java
Executable file
@@ -0,0 +1,40 @@
|
||||
package grading;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An implementation GradingStrategy that simply totals the scores for all grades.
|
||||
*/
|
||||
public class TotalStrategy implements GradingStrategy
|
||||
{
|
||||
/**
|
||||
* Creates a new instance of TotalStrategy.
|
||||
*/
|
||||
public TotalStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The key of the final totaled grade
|
||||
* @param grades
|
||||
* The list of grades to calculate the final total grade from
|
||||
* @return A new grade representing the total of grades
|
||||
*/
|
||||
public Grade calculate(final String key, final List<Grade> grades) throws SizeException
|
||||
{
|
||||
if (grades == null || grades.isEmpty())
|
||||
{
|
||||
throw new SizeException();
|
||||
}
|
||||
|
||||
Double total = 0.0;
|
||||
|
||||
for (Grade grade : grades)
|
||||
{
|
||||
total += Missing.doubleValue(grade.getValue());
|
||||
}
|
||||
|
||||
return new Grade(key, total);
|
||||
}
|
||||
}
|
||||
61
Homework 4/src/grading/WeightedTotalStrategy.java
Executable file
61
Homework 4/src/grading/WeightedTotalStrategy.java
Executable file
@@ -0,0 +1,61 @@
|
||||
package grading;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An implementation GradingStrategy that applies weights to specific grade keys and weighs each
|
||||
* grade before summing a total.
|
||||
*/
|
||||
public class WeightedTotalStrategy implements GradingStrategy
|
||||
{
|
||||
private Map<String, Double> weights;
|
||||
|
||||
/**
|
||||
* Creates a new instance WeightedTotalStrategy.
|
||||
*/
|
||||
public WeightedTotalStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance WeightedTotalStrategy.
|
||||
*
|
||||
* @param weights
|
||||
* A map of keys and weights to be applied to the grades during calculation.
|
||||
*/
|
||||
public WeightedTotalStrategy(final Map<String, Double> weights)
|
||||
{
|
||||
this.weights = weights;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The key of the final totaled grade
|
||||
* @param grades
|
||||
* The list of grades to calculate the final total grade from
|
||||
* @return A new grade representing the total of the weighted grades
|
||||
*/
|
||||
public Grade calculate(final String key, final List<Grade> grades) throws SizeException
|
||||
{
|
||||
if (grades == null || grades.isEmpty())
|
||||
{
|
||||
throw new SizeException();
|
||||
}
|
||||
|
||||
Double total = 0.0;
|
||||
|
||||
for (Grade grade : grades)
|
||||
{
|
||||
Double weight = 1.0;
|
||||
if (weights != null && weights.containsKey(grade.getKey()))
|
||||
{
|
||||
Double mapWeight = weights.get(grade.getKey());
|
||||
weight = Math.max(mapWeight, 0.0);
|
||||
}
|
||||
|
||||
total += Missing.doubleValue(grade.getValue()) * weight;
|
||||
}
|
||||
|
||||
return new Grade(key, total);
|
||||
}
|
||||
}
|
||||
70
Homework 4/src/grading/io/Category.java
Executable file
70
Homework 4/src/grading/io/Category.java
Executable file
@@ -0,0 +1,70 @@
|
||||
package grading.io;
|
||||
|
||||
import grading.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An aggregate for Grade representing a specific type of assignment with a specific Filter and
|
||||
* GradingStrategy.
|
||||
*/
|
||||
public class Category
|
||||
{
|
||||
private final String key;
|
||||
private final List<Grade> grades;
|
||||
private final Filter filter;
|
||||
private final GradingStrategy strategy;
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The key for the Category
|
||||
* @param grades
|
||||
* The Grades in the category
|
||||
* @param filter
|
||||
* The filter to apply to the collection of grades
|
||||
* @param strategy
|
||||
* The strategy used to calculate the final Category Grade
|
||||
*/
|
||||
public Category(final String key, final List<Grade> grades, final Filter filter,
|
||||
final GradingStrategy strategy)
|
||||
{
|
||||
if (key == null || key.isEmpty())
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.key = key;
|
||||
this.grades = grades;
|
||||
this.filter = filter;
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The filter for the Category
|
||||
*/
|
||||
public Filter getFilter()
|
||||
{
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The GradingStrategy for the Category
|
||||
*/
|
||||
public GradingStrategy getStrategy()
|
||||
{
|
||||
return strategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Grades making up the Category
|
||||
*/
|
||||
public List<Grade> getGrades()
|
||||
{
|
||||
return grades;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The key for the Category
|
||||
*/
|
||||
public String getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
}
|
||||
41
Homework 4/src/grading/io/Course.java
Executable file
41
Homework 4/src/grading/io/Course.java
Executable file
@@ -0,0 +1,41 @@
|
||||
package grading.io;
|
||||
|
||||
import grading.GradingStrategy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An aggregate for Categories with a specific GradingStrategy for calculating the final Course
|
||||
* Grade.
|
||||
*/
|
||||
public class Course
|
||||
{
|
||||
private final GradingStrategy strategy;
|
||||
private final List<Category> categories;
|
||||
|
||||
/**
|
||||
* @param categories The Categories making up the Course
|
||||
* @param strategy The strategy by which to calculate the final grade
|
||||
*/
|
||||
public Course(final List<Category> categories, final GradingStrategy strategy)
|
||||
{
|
||||
this.categories = categories;
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Categories making up the Course
|
||||
*/
|
||||
public List<Category> getCategories()
|
||||
{
|
||||
return categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The strategy used for calculating the final Grade for the Course
|
||||
*/
|
||||
public GradingStrategy getStrategy()
|
||||
{
|
||||
return strategy;
|
||||
}
|
||||
}
|
||||
95
Homework 4/src/grading/io/CourseReader.java
Executable file
95
Homework 4/src/grading/io/CourseReader.java
Executable file
@@ -0,0 +1,95 @@
|
||||
package grading.io;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import grading.*;
|
||||
|
||||
/**
|
||||
* A utility class for reading in Grade data from a .grd file and constructing Categories and
|
||||
* Courses.
|
||||
*/
|
||||
public class CourseReader
|
||||
{
|
||||
private static final String TAB_DELIMITER = "\t";
|
||||
|
||||
/**
|
||||
* Empty constructor so the coverage tests stop yelling at me.
|
||||
*/
|
||||
public CourseReader()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in
|
||||
* A BufferedReader for reading data from the file
|
||||
* @param size
|
||||
* The number of grade entries in a given category to read
|
||||
* @param key
|
||||
* The key for the category
|
||||
* @param filter
|
||||
* The filter to construct the Category with
|
||||
* @return A Category containing all the grades read from the file
|
||||
* @throws IOException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public static Category readCategory(final BufferedReader in, final int size, final String key,
|
||||
final Filter filter) throws IOException, IllegalArgumentException
|
||||
{
|
||||
final List<Grade> grades = new ArrayList<Grade>();
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
final String[] gradeData = in.readLine().split(TAB_DELIMITER);
|
||||
|
||||
Double gradeScore = null;
|
||||
if (gradeData.length > 1)
|
||||
{
|
||||
gradeScore = Double.parseDouble(gradeData[1]);
|
||||
}
|
||||
|
||||
grades.add(new Grade(gradeData[0], gradeScore));
|
||||
}
|
||||
|
||||
return new Category(key, grades, filter, new TotalStrategy());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in
|
||||
* A BufferedReader for reading data from the file
|
||||
* @param size
|
||||
* The number of categories in the file to read
|
||||
* @return A Course consisting of all Categories read from the file
|
||||
* @throws IOException
|
||||
*/
|
||||
public static Course readCourse(final BufferedReader in, final int size) throws IOException
|
||||
{
|
||||
|
||||
final List<Category> categories = new ArrayList<Category>();
|
||||
final Map<String, Double> weights = new HashMap<String, Double>();
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
final String[] categoryFields = in.readLine().split(TAB_DELIMITER);
|
||||
final String categoryName = categoryFields[0];
|
||||
final int gradeCount = Integer.parseInt(categoryFields[1]);
|
||||
|
||||
weights.put(categoryName, Double.parseDouble(categoryFields[2]));
|
||||
|
||||
final boolean shouldDropLowest = Boolean.parseBoolean(categoryFields[3]);
|
||||
final boolean shouldDropHighest = Boolean.parseBoolean(categoryFields[4]);
|
||||
final Filter filter = new DropFilter(shouldDropLowest, shouldDropHighest);
|
||||
|
||||
final Category category = CourseReader.readCategory(in, gradeCount, categoryName, filter);
|
||||
categories.add(category);
|
||||
}
|
||||
|
||||
final GradingStrategy strategy = new WeightedTotalStrategy(weights);
|
||||
return new Course(categories, strategy);
|
||||
}
|
||||
}
|
||||
51
Homework 4/src/testing/CategoryTest.java
Executable file
51
Homework 4/src/testing/CategoryTest.java
Executable file
@@ -0,0 +1,51 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import grading.*;
|
||||
import grading.io.Category;
|
||||
import java.util.*;
|
||||
|
||||
class CategoryTest
|
||||
{
|
||||
|
||||
private Filter filter;
|
||||
private GradingStrategy strategy;
|
||||
private List<Grade> grades;
|
||||
private String validKey;
|
||||
|
||||
@BeforeEach
|
||||
void setUp()
|
||||
{
|
||||
filter = new DropFilter();
|
||||
strategy = new TotalStrategy();
|
||||
grades = new ArrayList<Grade>();
|
||||
validKey = "math";
|
||||
}
|
||||
|
||||
@Test
|
||||
void badKeyTest()
|
||||
{
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> new Category(null, grades, filter, strategy));
|
||||
assertThrows(IllegalArgumentException.class, () -> new Category("", grades, filter, strategy));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getterTest()
|
||||
{
|
||||
Grade grade = new Grade("HW1", 95.0);
|
||||
grades.add(grade);
|
||||
Category category = new Category(validKey, grades, filter, strategy);
|
||||
|
||||
assertEquals(validKey, category.getKey());
|
||||
|
||||
assertSame(grades, category.getGrades());
|
||||
|
||||
assertEquals(filter, category.getFilter());
|
||||
|
||||
assertEquals(strategy, category.getStrategy());
|
||||
}
|
||||
}
|
||||
67
Homework 4/src/testing/CourseReaderTest.java
Executable file
67
Homework 4/src/testing/CourseReaderTest.java
Executable file
@@ -0,0 +1,67 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import grading.*;
|
||||
import grading.io.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
class CourseReaderTest
|
||||
{
|
||||
@Test
|
||||
void grdFileTests() throws IOException, SizeException
|
||||
{
|
||||
assertNotNull(new CourseReader()); // Nonsense test for coverage
|
||||
|
||||
final Grade complete01Grade = calculateCourseGradeFromFile("complete_01.grd");
|
||||
final Grade complete02Grade = calculateCourseGradeFromFile("complete_02.grd");
|
||||
final Grade complete03Grade = calculateCourseGradeFromFile("complete_03.grd");
|
||||
final Grade fiveCategories01Grade = calculateCourseGradeFromFile("five-categories_01.grd");
|
||||
final Grade missingAllGrade = calculateCourseGradeFromFile("missing_all.grd");
|
||||
final Grade missingMultipleInEachGrade = calculateCourseGradeFromFile(
|
||||
"missing_multiple-in-each.grd");
|
||||
final Grade missingOneInEachGrade = calculateCourseGradeFromFile("missing_one-in-each.grd");
|
||||
final Grade missingOneInOneGrade = calculateCourseGradeFromFile("missing_one-in-one.grd");
|
||||
final Grade sixCategories01Grade = calculateCourseGradeFromFile("six-categories_01.grd");
|
||||
|
||||
assertEquals(80.7, complete01Grade.getValue());
|
||||
assertEquals(100, complete02Grade.getValue());
|
||||
assertEquals(54.0, complete03Grade.getValue());
|
||||
assertEquals(64.75, fiveCategories01Grade.getValue());
|
||||
assertEquals(0.0, missingAllGrade.getValue());
|
||||
assertEquals(19.5, missingMultipleInEachGrade.getValue());
|
||||
assertEquals(35.2, missingOneInEachGrade.getValue());
|
||||
assertEquals(80.7, missingOneInOneGrade.getValue());
|
||||
assertEquals(76.6, sixCategories01Grade.getValue());
|
||||
}
|
||||
|
||||
private static Grade calculateCourseGradeFromFile(final String filename)
|
||||
throws IOException, SizeException
|
||||
{
|
||||
BufferedReader in = new BufferedReader(new FileReader(filename));
|
||||
String line = in.readLine();
|
||||
int categories = Integer.parseInt(line);
|
||||
Course course = CourseReader.readCourse(in, categories);
|
||||
in.close();
|
||||
|
||||
ArrayList<Grade> grades = new ArrayList<Grade>();
|
||||
for (Category c : course.getCategories())
|
||||
{
|
||||
GradingStrategy categoryStrategy = c.getStrategy();
|
||||
Filter filter = c.getFilter();
|
||||
Grade grade = categoryStrategy.calculate(c.getKey(), filter.apply(c.getGrades()));
|
||||
grades.add(grade);
|
||||
}
|
||||
|
||||
GradingStrategy courseStrategy = course.getStrategy();
|
||||
Grade courseGrade = courseStrategy.calculate("Course Grade", grades);
|
||||
|
||||
return courseGrade;
|
||||
}
|
||||
}
|
||||
37
Homework 4/src/testing/CourseTest.java
Executable file
37
Homework 4/src/testing/CourseTest.java
Executable file
@@ -0,0 +1,37 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import grading.*;
|
||||
import grading.io.Category;
|
||||
import grading.io.Course;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class CourseTest
|
||||
{
|
||||
@Test
|
||||
void testCourseInitialization()
|
||||
{
|
||||
// Arrange
|
||||
final GradingStrategy strategy = new TotalStrategy();
|
||||
final Filter filter = new DropFilter();
|
||||
final List<Category> categories = new ArrayList<Category>();
|
||||
|
||||
final List<Grade> homeworkGrades = new ArrayList<Grade>();
|
||||
homeworkGrades.add(new Grade("HW1", 20.0));
|
||||
homeworkGrades.add(new Grade("HW2", 5.0));
|
||||
|
||||
final Category hws = new Category("Homework Assignments", homeworkGrades, filter, strategy);
|
||||
categories.add(hws);
|
||||
|
||||
final Course course = new Course(categories, strategy);
|
||||
|
||||
assertEquals(categories, course.getCategories(),
|
||||
"Categories should match the initialized values");
|
||||
assertEquals(strategy, course.getStrategy(), "Strategy should match the initialized value");
|
||||
}
|
||||
}
|
||||
38
Homework 4/src/testing/DropFilterTest.java
Executable file
38
Homework 4/src/testing/DropFilterTest.java
Executable file
@@ -0,0 +1,38 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import grading.Grade;
|
||||
import grading.SizeException;
|
||||
import grading.DropFilter;
|
||||
|
||||
class DropFilterTest
|
||||
{
|
||||
@Test
|
||||
void applyTest()
|
||||
{
|
||||
final Grade grade1 = new Grade("HW", 40.0);
|
||||
final Grade grade2 = new Grade("Midterm", (Double) null);
|
||||
final Grade grade3 = new Grade("Final", 100.0);
|
||||
|
||||
List<Grade> grades = List.of(grade1, grade2, grade3);
|
||||
|
||||
DropFilter defaultFilter = new DropFilter();
|
||||
DropFilter filter1 = new DropFilter(false, false);
|
||||
DropFilter filter2 = new DropFilter(false, true);
|
||||
DropFilter filter3 = new DropFilter(true, false);
|
||||
DropFilter filter4 = new DropFilter(true, true);
|
||||
|
||||
assertThrows(SizeException.class, () -> defaultFilter.apply((List<Grade>) null));
|
||||
assertThrows(SizeException.class, () -> defaultFilter.apply(new ArrayList<Grade>()));
|
||||
|
||||
assertIterableEquals(grades, filter1.apply(grades));
|
||||
assertIterableEquals(List.of(grade1, grade2), filter2.apply(grades));
|
||||
assertIterableEquals(List.of(grade1, grade3), filter3.apply(grades));
|
||||
assertIterableEquals(List.of(grade1), filter4.apply(grades));
|
||||
}
|
||||
}
|
||||
79
Homework 4/src/testing/GradeTest.java
Executable file
79
Homework 4/src/testing/GradeTest.java
Executable file
@@ -0,0 +1,79 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import grading.Grade;
|
||||
|
||||
class GradeTest
|
||||
{
|
||||
private static final String HOMEWORK_KEY = "HW";
|
||||
private static final String MIDTERM_KEY = "Midterm";
|
||||
private static final String FINAL_KEY = "Final";
|
||||
|
||||
@Test
|
||||
void defaultValueConstructorTest()
|
||||
{
|
||||
Grade grade = new Grade(FINAL_KEY);
|
||||
assertEquals(FINAL_KEY, grade.getKey());
|
||||
assertEquals(0.0, grade.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenValueConstructorTest()
|
||||
{
|
||||
Grade grade = new Grade(MIDTERM_KEY, 85.5);
|
||||
assertEquals(MIDTERM_KEY, grade.getKey());
|
||||
assertEquals(85.5, grade.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullValueConstructorTest()
|
||||
{
|
||||
assertThrows(IllegalArgumentException.class, () -> new Grade(null));
|
||||
assertThrows(IllegalArgumentException.class, () -> new Grade(null, 90.0));
|
||||
assertThrows(IllegalArgumentException.class, () -> new Grade(null, (Double) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyKeyConstructorTest()
|
||||
{
|
||||
assertThrows(IllegalArgumentException.class, () -> new Grade(""));
|
||||
assertThrows(IllegalArgumentException.class, () -> new Grade("", 90.0));
|
||||
assertThrows(IllegalArgumentException.class, () -> new Grade("", (Double) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullCompareToTest()
|
||||
{
|
||||
Grade grade1 = new Grade(HOMEWORK_KEY, (Double) null);
|
||||
Grade grade2 = new Grade(HOMEWORK_KEY, 80.0);
|
||||
Grade grade3 = new Grade(HOMEWORK_KEY, (Double) null);
|
||||
|
||||
assertTrue(grade1.compareTo(grade2) < 0);
|
||||
assertEquals(0, grade1.compareTo(grade3));
|
||||
assertTrue(grade2.compareTo(grade1) > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void compareToTest()
|
||||
{
|
||||
Grade grade1 = new Grade(HOMEWORK_KEY, 75.0);
|
||||
Grade grade2 = new Grade(HOMEWORK_KEY, 85.0);
|
||||
Grade grade3 = new Grade(HOMEWORK_KEY, 75.0);
|
||||
|
||||
assertTrue(grade1.compareTo(grade2) < 0);
|
||||
assertEquals(0, grade1.compareTo(grade3));
|
||||
assertTrue(grade2.compareTo(grade1) > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringTest()
|
||||
{
|
||||
Grade grade1 = new Grade(FINAL_KEY, 90.0);
|
||||
Grade grade2 = new Grade(MIDTERM_KEY, (Double) null);
|
||||
|
||||
assertEquals("Final: 90.0", grade1.toString());
|
||||
assertEquals("Midterm: NA", grade2.toString());
|
||||
}
|
||||
}
|
||||
23
Homework 4/src/testing/MissingTest.java
Executable file
23
Homework 4/src/testing/MissingTest.java
Executable file
@@ -0,0 +1,23 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import grading.Missing;
|
||||
|
||||
class MissingTest
|
||||
{
|
||||
@Test
|
||||
void defaultDoubleValueTest()
|
||||
{
|
||||
assertEquals(40.0, Missing.doubleValue(40.0));
|
||||
assertEquals(0.0, Missing.doubleValue((Double) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMissingDoubleValueTest()
|
||||
{
|
||||
assertEquals(40.0, Missing.doubleValue(40.0, 20.0));
|
||||
assertEquals(20.0, Missing.doubleValue((Double) null, 20.0));
|
||||
}
|
||||
}
|
||||
34
Homework 4/src/testing/TotalStrategyTest.java
Executable file
34
Homework 4/src/testing/TotalStrategyTest.java
Executable file
@@ -0,0 +1,34 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import grading.Grade;
|
||||
import grading.TotalStrategy;
|
||||
import grading.SizeException;
|
||||
|
||||
class TotalStrategyTest
|
||||
{
|
||||
private static final String TOTAL_KEY = "Total";
|
||||
|
||||
@Test
|
||||
void calculateTest()
|
||||
{
|
||||
List<Grade> grades = new ArrayList<Grade>();
|
||||
grades.add(new Grade("HW1", 40.0));
|
||||
grades.add(new Grade("HW2", (Double) null));
|
||||
grades.add(new Grade("HW3", 100.0));
|
||||
|
||||
TotalStrategy strategy = new TotalStrategy();
|
||||
|
||||
assertThrows(SizeException.class, () -> strategy.calculate(TOTAL_KEY, (List<Grade>) null));
|
||||
assertThrows(SizeException.class, () -> strategy.calculate(TOTAL_KEY, new ArrayList<Grade>()));
|
||||
|
||||
Grade total = strategy.calculate(TOTAL_KEY, grades);
|
||||
|
||||
assertEquals(TOTAL_KEY, total.getKey());
|
||||
assertEquals(140.0, total.getValue());
|
||||
}
|
||||
}
|
||||
50
Homework 4/src/testing/WeightedTotalStrategyTest.java
Executable file
50
Homework 4/src/testing/WeightedTotalStrategyTest.java
Executable file
@@ -0,0 +1,50 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import grading.Grade;
|
||||
import grading.WeightedTotalStrategy;
|
||||
import grading.SizeException;
|
||||
|
||||
class WeightedTotalStrategyTest
|
||||
{
|
||||
private static final String HOMEWORK_KEY = "HW";
|
||||
private static final String MIDTERM_KEY = "Midterm";
|
||||
private static final String FINAL_KEY = "Final";
|
||||
private static final String TOTAL_KEY = "Total";
|
||||
|
||||
@Test
|
||||
void calculateTest()
|
||||
{
|
||||
List<Grade> grades = new ArrayList<Grade>();
|
||||
grades.add(new Grade(HOMEWORK_KEY, 40.0));
|
||||
grades.add(new Grade(MIDTERM_KEY, (Double) null));
|
||||
grades.add(new Grade(FINAL_KEY, 100.0));
|
||||
|
||||
Map<String, Double> weights = new HashMap<String, Double>();
|
||||
weights.put(MIDTERM_KEY, 2.0);
|
||||
weights.put(FINAL_KEY, 3.0);
|
||||
|
||||
WeightedTotalStrategy defaultStrategy = new WeightedTotalStrategy();
|
||||
|
||||
assertThrows(SizeException.class,
|
||||
() -> defaultStrategy.calculate(TOTAL_KEY, (List<Grade>) null));
|
||||
assertThrows(SizeException.class,
|
||||
() -> defaultStrategy.calculate(TOTAL_KEY, new ArrayList<Grade>()));
|
||||
|
||||
Grade total = defaultStrategy.calculate(TOTAL_KEY, grades);
|
||||
|
||||
assertEquals(TOTAL_KEY, total.getKey());
|
||||
assertEquals(140.0, total.getValue());
|
||||
|
||||
WeightedTotalStrategy strategy = new WeightedTotalStrategy(weights);
|
||||
|
||||
Grade weightedTotal = strategy.calculate(TOTAL_KEY, grades);
|
||||
|
||||
assertEquals(TOTAL_KEY, weightedTotal.getKey());
|
||||
assertEquals(340.0, weightedTotal.getValue());
|
||||
}
|
||||
}
|
||||
18
Homework 5/complete_01.grd
Executable file
18
Homework 5/complete_01.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 20
|
||||
PA2 18
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5 20
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 5
|
||||
HW3 0
|
||||
HW4 10
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm 80
|
||||
Final Exam 1 0.30 false false
|
||||
Final 75
|
||||
18
Homework 5/complete_02.grd
Executable file
18
Homework 5/complete_02.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 20
|
||||
PA2 20
|
||||
PA3 20
|
||||
PA4 20
|
||||
PA5 20
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 20
|
||||
HW3 20
|
||||
HW4 20
|
||||
HW5 20
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm 100
|
||||
Final Exam 1 0.30 false false
|
||||
Final 100
|
||||
18
Homework 5/complete_03.grd
Executable file
18
Homework 5/complete_03.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 10
|
||||
PA2 10
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5 5
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 0
|
||||
HW3 0
|
||||
HW4 10
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm 60
|
||||
Final Exam 1 0.30 false false
|
||||
Final 45
|
||||
21
Homework 5/five-categories_01.grd
Executable file
21
Homework 5/five-categories_01.grd
Executable file
@@ -0,0 +1,21 @@
|
||||
5
|
||||
Homework Assignments 5 0.25 true false
|
||||
HW01 20
|
||||
HW02 5
|
||||
HW03 0
|
||||
HW04 10
|
||||
HW05 15
|
||||
Quizzes 5 0.25 true true
|
||||
Quiz01 12
|
||||
Quiz02 8
|
||||
Quiz03 20
|
||||
Quiz04 13
|
||||
Quiz05 20
|
||||
Misc 2 0.10 false false
|
||||
Attendance 40
|
||||
Participation 50
|
||||
Midterm Exams 2 0.20 false false
|
||||
Midterm01 45
|
||||
Midterm02 40
|
||||
Final Exam 1 0.20 false false
|
||||
Final 75
|
||||
18
Homework 5/missing_all.grd
Executable file
18
Homework 5/missing_all.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1
|
||||
PA2
|
||||
PA3
|
||||
PA4
|
||||
PA5
|
||||
PA6
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1
|
||||
HW2
|
||||
HW3
|
||||
HW4
|
||||
HW5
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm
|
||||
Final Exam 1 0.30 false false
|
||||
Final
|
||||
18
Homework 5/missing_multiple-in-each.grd
Executable file
18
Homework 5/missing_multiple-in-each.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1
|
||||
PA2 20
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5
|
||||
PA6
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2
|
||||
HW3 0
|
||||
HW4
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm
|
||||
Final Exam 1 0.30 false false
|
||||
Final
|
||||
18
Homework 5/missing_one-in-each.grd
Executable file
18
Homework 5/missing_one-in-each.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 20
|
||||
PA2 18
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 5
|
||||
HW3 0
|
||||
HW4
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm
|
||||
Final Exam 1 0.30 false false
|
||||
Final
|
||||
18
Homework 5/missing_one-in-one.grd
Executable file
18
Homework 5/missing_one-in-one.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 20
|
||||
PA2 18
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5 20
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 5
|
||||
HW3
|
||||
HW4 10
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm 80
|
||||
Final Exam 1 0.30 false false
|
||||
Final 75
|
||||
36
Homework 5/six-categories_01.grd
Executable file
36
Homework 5/six-categories_01.grd
Executable file
@@ -0,0 +1,36 @@
|
||||
6
|
||||
Programming Assignments 6 0.15 false false
|
||||
PA01 20
|
||||
PA02 18
|
||||
PA03 5
|
||||
PA04 15
|
||||
PA05 20
|
||||
PA06 20
|
||||
Homework Assignments 5 0.15 false false
|
||||
HW01 20
|
||||
HW02 5
|
||||
HW03 0
|
||||
HW04 10
|
||||
HW05 15
|
||||
Labs 10 0.10 false false
|
||||
Lab01 10
|
||||
Lab02 5
|
||||
Lab03 10
|
||||
Lab04 10
|
||||
Lab05 0
|
||||
Lab06 10
|
||||
Lab07 10
|
||||
Lab08 10
|
||||
Lab09 5
|
||||
Lab10 10
|
||||
Quizzes 5 0.10 false false
|
||||
Quiz01 12
|
||||
Quiz02 8
|
||||
Quiz03 20
|
||||
Quiz04 13
|
||||
Quiz05 16
|
||||
Midterm Exams 2 0.20 false false
|
||||
Midterm01 45
|
||||
Midterm02 40
|
||||
Final Exam 1 0.30 false false
|
||||
Final 75
|
||||
60
Homework 5/src/app/Gradient.java
Executable file
60
Homework 5/src/app/Gradient.java
Executable file
@@ -0,0 +1,60 @@
|
||||
package app;
|
||||
|
||||
import grading.*;
|
||||
import grading.io.*;
|
||||
import java.io.*;
|
||||
|
||||
/**
|
||||
* An application for calculating the numeric grade for
|
||||
* a course from the grades on individual assignments.
|
||||
*
|
||||
* Unlike v1, this version reads the course structure (and optionally the grades)
|
||||
* from a file. It assumes:
|
||||
*
|
||||
* The grade in each category is the total of the individual assessments.
|
||||
*
|
||||
* The course grade is the weighted total of the category grades.
|
||||
*
|
||||
* Unlike v2, this version uses the LeafGrade and CompositeGrade classes.
|
||||
*
|
||||
* @version 3.0
|
||||
* @author Sagacious Media
|
||||
*
|
||||
*/
|
||||
public class Gradient
|
||||
{
|
||||
/**
|
||||
* The entry point for the application.
|
||||
*
|
||||
* @param args args[0] contains the path (relative or absolute) to the .grd file
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// Early exit
|
||||
if ((args == null) || (args.length < 1))
|
||||
{
|
||||
System.err.println("You must enter a file name.");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
BufferedReader in = new BufferedReader(new FileReader(args[0]));
|
||||
String line = in.readLine();
|
||||
int categories = Integer.parseInt(line);
|
||||
CompositeGrade courseGrade = CourseReader.readCourse(in, categories);
|
||||
in.close();
|
||||
|
||||
for (Grade g: courseGrade.getComponents())
|
||||
{
|
||||
System.out.println(g.toString());
|
||||
}
|
||||
System.out.println(courseGrade.toString());
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
System.out.println("Unable to open file.");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
72
Homework 5/src/grading/AbstractGrade.java
Executable file
72
Homework 5/src/grading/AbstractGrade.java
Executable file
@@ -0,0 +1,72 @@
|
||||
package grading;
|
||||
|
||||
/**
|
||||
* Abstract implementation of Grade meant for extension with custom getValue implementations.
|
||||
*/
|
||||
public abstract class AbstractGrade implements Grade
|
||||
{
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The key for the Grade
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public AbstractGrade(final String key) throws IllegalArgumentException
|
||||
{
|
||||
if (key == null || key.isEmpty())
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.key = key;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param other
|
||||
* Another Grade object to compare to this grade
|
||||
* @return The value 0 if other's value is equal to this Grade's value; -1 if this Grade's value
|
||||
* is less than other's; and 1 if this Grade's value is greater than other's.
|
||||
*/
|
||||
public int compareTo(final Grade other)
|
||||
{
|
||||
Double value = this.getValue();
|
||||
Double otherValue = other.getValue();
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
return (otherValue == null) ? 0 : -1;
|
||||
}
|
||||
if (otherValue == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return value.compareTo(otherValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The key of for this Grade
|
||||
*/
|
||||
public String getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The value for this Grade
|
||||
*/
|
||||
public abstract Double getValue();
|
||||
|
||||
/**
|
||||
* @return A string representation of the Grade
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
Double value = this.getValue();
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
return String.format("%s: NA", key);
|
||||
}
|
||||
|
||||
return String.format("%s: %5.1f", key, value);
|
||||
}
|
||||
}
|
||||
111
Homework 5/src/grading/CompositeGrade.java
Executable file
111
Homework 5/src/grading/CompositeGrade.java
Executable file
@@ -0,0 +1,111 @@
|
||||
package grading;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An aggregate implementation of Grade that allows for multiple grades to be treated as one.
|
||||
*/
|
||||
public class CompositeGrade extends AbstractGrade
|
||||
{
|
||||
private Filter filter;
|
||||
private GradingStrategy strategy;
|
||||
private List<Grade> components = new ArrayList<Grade>();
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The key for the CompositeGrade
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public CompositeGrade(final String key) throws IllegalArgumentException
|
||||
{
|
||||
super(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param grade
|
||||
* A sub-grade to add to the CompositeGrade
|
||||
*/
|
||||
public void add(final Grade grade)
|
||||
{
|
||||
components.add(grade);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The sub-grades that make up the CompositeGrade
|
||||
*/
|
||||
public List<Grade> getComponents()
|
||||
{
|
||||
return components;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Filter that get's applied to the components of the CompositeGrade when calculating
|
||||
* its value
|
||||
*/
|
||||
public Filter getFilter()
|
||||
{
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The GradingStrategy used on the components of the CompositeGrade to calculate its value
|
||||
*/
|
||||
public GradingStrategy getStrategy()
|
||||
{
|
||||
return strategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The calculated value of the CompositeGrade using the Filter and GradingStrategy
|
||||
* supplied
|
||||
*/
|
||||
public Double getValue()
|
||||
{
|
||||
if (strategy == null)
|
||||
return null;
|
||||
|
||||
List<Grade> componentsToCalculate = components;
|
||||
|
||||
if (filter != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
componentsToCalculate = filter.apply(components);
|
||||
}
|
||||
catch (SizeException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return strategy.calculate(getKey(), componentsToCalculate).getValue();
|
||||
}
|
||||
catch (SizeException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param filter
|
||||
* The filter to be applied to the components of the CompositeGrade when calculating its
|
||||
* value
|
||||
*/
|
||||
public void setFilter(final Filter filter)
|
||||
{
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param strategy
|
||||
* The GradingStrategy to be used on the components of the CompositeGrade to calculate
|
||||
* its value
|
||||
*/
|
||||
public void setStrategy(final GradingStrategy strategy)
|
||||
{
|
||||
this.strategy = strategy;
|
||||
}
|
||||
}
|
||||
79
Homework 5/src/grading/DropFilter.java
Executable file
79
Homework 5/src/grading/DropFilter.java
Executable file
@@ -0,0 +1,79 @@
|
||||
package grading;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* A filter to apply to a list of grades to optionally drop the lowest or highest grades.
|
||||
*/
|
||||
public class DropFilter implements Filter
|
||||
{
|
||||
private boolean shouldDropLowest;
|
||||
private boolean shouldDropHighest;
|
||||
|
||||
/**
|
||||
* Default constructor that will drop the lowest and highest grades.
|
||||
*/
|
||||
public DropFilter()
|
||||
{
|
||||
this.shouldDropLowest = true;
|
||||
this.shouldDropHighest = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param shouldDropLowest
|
||||
* Whether or not to drop the lowest grade
|
||||
* @param shouldDropHighest
|
||||
* Whether or not to drop the highest grade
|
||||
*/
|
||||
public DropFilter(final boolean shouldDropLowest, final boolean shouldDropHighest)
|
||||
{
|
||||
this.shouldDropLowest = shouldDropLowest;
|
||||
this.shouldDropHighest = shouldDropHighest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param grades
|
||||
* The list of grades to apply the DropFilter to.
|
||||
* @return A new list containing the original grades with filter applied
|
||||
*/
|
||||
public List<Grade> apply(final List<Grade> grades) throws SizeException
|
||||
{
|
||||
int minSize = (shouldDropLowest ? 1 : 0) + (shouldDropHighest ? 1 : 0);
|
||||
|
||||
if (grades == null || grades.size() <= minSize)
|
||||
{
|
||||
throw new SizeException();
|
||||
}
|
||||
|
||||
List<Grade> droppedGrades = new ArrayList<Grade>();
|
||||
droppedGrades.addAll(grades);
|
||||
|
||||
Grade lowest = null;
|
||||
Grade highest = null;
|
||||
|
||||
for (Grade grade : grades)
|
||||
{
|
||||
if (lowest == null || grade.compareTo(lowest) < 0)
|
||||
{
|
||||
lowest = grade;
|
||||
}
|
||||
|
||||
if (highest == null || grade.compareTo(highest) > 0)
|
||||
{
|
||||
highest = grade;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldDropLowest)
|
||||
{
|
||||
droppedGrades.remove(lowest);
|
||||
}
|
||||
|
||||
if (shouldDropHighest)
|
||||
{
|
||||
droppedGrades.remove(highest);
|
||||
}
|
||||
|
||||
return droppedGrades;
|
||||
}
|
||||
}
|
||||
17
Homework 5/src/grading/Filter.java
Executable file
17
Homework 5/src/grading/Filter.java
Executable file
@@ -0,0 +1,17 @@
|
||||
package grading;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An interface for filters that can be applied to a list of grades.
|
||||
*/
|
||||
public interface Filter
|
||||
{
|
||||
/**
|
||||
* @param grades
|
||||
* The list of grades to provide the filter to
|
||||
* @return A new list contain the original grades with the filter applied
|
||||
* @throws SizeException
|
||||
*/
|
||||
public List<Grade> apply(List<Grade> grades) throws SizeException;
|
||||
}
|
||||
17
Homework 5/src/grading/Grade.java
Executable file
17
Homework 5/src/grading/Grade.java
Executable file
@@ -0,0 +1,17 @@
|
||||
package grading;
|
||||
|
||||
/**
|
||||
* An interface for implementing a grade with a key and a value to store the score.
|
||||
*/
|
||||
public interface Grade extends Comparable<Grade>
|
||||
{
|
||||
/**
|
||||
* @return The key of for this Grade
|
||||
*/
|
||||
public String getKey();
|
||||
|
||||
/**
|
||||
* @return The value for this Grade
|
||||
*/
|
||||
public Double getValue();
|
||||
}
|
||||
19
Homework 5/src/grading/GradingStrategy.java
Executable file
19
Homework 5/src/grading/GradingStrategy.java
Executable file
@@ -0,0 +1,19 @@
|
||||
package grading;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An interface for strategies of calculating a final grade from a list of grades.
|
||||
*/
|
||||
public interface GradingStrategy
|
||||
{
|
||||
/**
|
||||
* @param key
|
||||
* The key for the final calculated grade
|
||||
* @param grades
|
||||
* The list of grades to from which to calculate the final grade
|
||||
* @return A new grade representing the final grade calculated from grades
|
||||
* @throws SizeException
|
||||
*/
|
||||
public Grade calculate(String key, List<Grade> grades) throws SizeException;
|
||||
}
|
||||
74
Homework 5/src/grading/LeafGrade.java
Executable file
74
Homework 5/src/grading/LeafGrade.java
Executable file
@@ -0,0 +1,74 @@
|
||||
package grading;
|
||||
|
||||
/**
|
||||
* A data class for storing a grade with a key and a value to store the score.
|
||||
*/
|
||||
public class LeafGrade extends AbstractGrade
|
||||
{
|
||||
private Double value;
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The type of grade
|
||||
*/
|
||||
public LeafGrade(final String key) throws IllegalArgumentException
|
||||
{
|
||||
this(key, 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The type of grade
|
||||
* @param value
|
||||
* The score for the grade
|
||||
*/
|
||||
public LeafGrade(final String key, final double value) throws IllegalArgumentException
|
||||
{
|
||||
this(key, Double.valueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The type of grade
|
||||
* @param value
|
||||
* The score for the grade
|
||||
*/
|
||||
public LeafGrade(final String key, final Double value) throws IllegalArgumentException
|
||||
{
|
||||
super(key);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The value of the grade
|
||||
*/
|
||||
public Double getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The key for the Grade
|
||||
* @param value
|
||||
* The string representation of the value for the Grade
|
||||
* @return A new LeafGrade object with the passed key and value
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public static LeafGrade parseLeafGrade(final String key, final String value)
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
if (value == null)
|
||||
return new LeafGrade(key, null);
|
||||
|
||||
try
|
||||
{
|
||||
Double parsedValue = Double.valueOf(value);
|
||||
return new LeafGrade(key, parsedValue);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return new LeafGrade(key, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
Homework 5/src/grading/Missing.java
Executable file
35
Homework 5/src/grading/Missing.java
Executable file
@@ -0,0 +1,35 @@
|
||||
package grading;
|
||||
|
||||
/**
|
||||
* A utility class for supplying a default double value in the case that a provided double is null.
|
||||
*/
|
||||
public class Missing
|
||||
{
|
||||
private static double DEFAULT_MISSING_VALUE = 0.0;
|
||||
|
||||
private Missing()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param number
|
||||
* The supplied double to check for null.
|
||||
* @return Either number if it was not null, or a default value of 0.0 if it was.
|
||||
*/
|
||||
public static double doubleValue(final Double number)
|
||||
{
|
||||
return number != null ? number : DEFAULT_MISSING_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param number
|
||||
* The supplied double to check for null.
|
||||
* @param missingValue
|
||||
* The default value to return if number was null
|
||||
* @return Either number if it was not null, or missingValue if it was
|
||||
*/
|
||||
public static double doubleValue(final Double number, final double missingValue)
|
||||
{
|
||||
return number != null ? number : missingValue;
|
||||
}
|
||||
}
|
||||
19
Homework 5/src/grading/SizeException.java
Executable file
19
Homework 5/src/grading/SizeException.java
Executable file
@@ -0,0 +1,19 @@
|
||||
package grading;
|
||||
|
||||
/**
|
||||
* A custom exception for cases where a provided list does not meet a size requirement.
|
||||
*/
|
||||
public class SizeException extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* Exception identifier.
|
||||
*/
|
||||
static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Creates a new SizeException instance.
|
||||
*/
|
||||
public SizeException()
|
||||
{
|
||||
}
|
||||
}
|
||||
40
Homework 5/src/grading/TotalStrategy.java
Executable file
40
Homework 5/src/grading/TotalStrategy.java
Executable file
@@ -0,0 +1,40 @@
|
||||
package grading;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An implementation GradingStrategy that simply totals the scores for all grades.
|
||||
*/
|
||||
public class TotalStrategy implements GradingStrategy
|
||||
{
|
||||
/**
|
||||
* Creates a new instance of TotalStrategy.
|
||||
*/
|
||||
public TotalStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The key of the final totaled grade
|
||||
* @param grades
|
||||
* The list of grades to calculate the final total grade from
|
||||
* @return A new grade representing the total of grades
|
||||
*/
|
||||
public Grade calculate(final String key, final List<Grade> grades) throws SizeException
|
||||
{
|
||||
if (grades == null || grades.isEmpty())
|
||||
{
|
||||
throw new SizeException();
|
||||
}
|
||||
|
||||
Double total = 0.0;
|
||||
|
||||
for (Grade grade : grades)
|
||||
{
|
||||
total += Missing.doubleValue(grade.getValue());
|
||||
}
|
||||
|
||||
return new LeafGrade(key, total);
|
||||
}
|
||||
}
|
||||
61
Homework 5/src/grading/WeightedTotalStrategy.java
Executable file
61
Homework 5/src/grading/WeightedTotalStrategy.java
Executable file
@@ -0,0 +1,61 @@
|
||||
package grading;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An implementation GradingStrategy that applies weights to specific grade keys and weighs each
|
||||
* grade before summing a total.
|
||||
*/
|
||||
public class WeightedTotalStrategy implements GradingStrategy
|
||||
{
|
||||
private Map<String, Double> weights;
|
||||
|
||||
/**
|
||||
* Creates a new instance WeightedTotalStrategy.
|
||||
*/
|
||||
public WeightedTotalStrategy()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance WeightedTotalStrategy.
|
||||
*
|
||||
* @param weights
|
||||
* A map of keys and weights to be applied to the grades during calculation.
|
||||
*/
|
||||
public WeightedTotalStrategy(final Map<String, Double> weights)
|
||||
{
|
||||
this.weights = weights;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The key of the final totaled grade
|
||||
* @param grades
|
||||
* The list of grades to calculate the final total grade from
|
||||
* @return A new grade representing the total of the weighted grades
|
||||
*/
|
||||
public Grade calculate(final String key, final List<Grade> grades) throws SizeException
|
||||
{
|
||||
if (grades == null || grades.isEmpty())
|
||||
{
|
||||
throw new SizeException();
|
||||
}
|
||||
|
||||
Double total = 0.0;
|
||||
|
||||
for (Grade grade : grades)
|
||||
{
|
||||
Double weight = 1.0;
|
||||
if (weights != null && weights.containsKey(grade.getKey()))
|
||||
{
|
||||
Double mapWeight = weights.get(grade.getKey());
|
||||
weight = Math.max(mapWeight, 0.0);
|
||||
}
|
||||
|
||||
total += Missing.doubleValue(grade.getValue()) * weight;
|
||||
}
|
||||
|
||||
return new LeafGrade(key, total);
|
||||
}
|
||||
}
|
||||
70
Homework 5/src/grading/io/Category.java
Executable file
70
Homework 5/src/grading/io/Category.java
Executable file
@@ -0,0 +1,70 @@
|
||||
package grading.io;
|
||||
|
||||
import grading.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* An aggregate for Grade representing a specific type of assignment with a specific Filter and
|
||||
* GradingStrategy.
|
||||
*/
|
||||
public class Category
|
||||
{
|
||||
private final String key;
|
||||
private final List<Grade> grades;
|
||||
private final Filter filter;
|
||||
private final GradingStrategy strategy;
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The key for the Category
|
||||
* @param grades
|
||||
* The Grades in the category
|
||||
* @param filter
|
||||
* The filter to apply to the collection of grades
|
||||
* @param strategy
|
||||
* The strategy used to calculate the final Category Grade
|
||||
*/
|
||||
public Category(final String key, final List<Grade> grades, final Filter filter,
|
||||
final GradingStrategy strategy)
|
||||
{
|
||||
if (key == null || key.isEmpty())
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.key = key;
|
||||
this.grades = grades;
|
||||
this.filter = filter;
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The filter for the Category
|
||||
*/
|
||||
public Filter getFilter()
|
||||
{
|
||||
return filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The GradingStrategy for the Category
|
||||
*/
|
||||
public GradingStrategy getStrategy()
|
||||
{
|
||||
return strategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Grades making up the Category
|
||||
*/
|
||||
public List<Grade> getGrades()
|
||||
{
|
||||
return grades;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The key for the Category
|
||||
*/
|
||||
public String getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
}
|
||||
41
Homework 5/src/grading/io/Course.java
Executable file
41
Homework 5/src/grading/io/Course.java
Executable file
@@ -0,0 +1,41 @@
|
||||
package grading.io;
|
||||
|
||||
import grading.GradingStrategy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An aggregate for Categories with a specific GradingStrategy for calculating the final Course
|
||||
* Grade.
|
||||
*/
|
||||
public class Course
|
||||
{
|
||||
private final GradingStrategy strategy;
|
||||
private final List<Category> categories;
|
||||
|
||||
/**
|
||||
* @param categories The Categories making up the Course
|
||||
* @param strategy The strategy by which to calculate the final grade
|
||||
*/
|
||||
public Course(final List<Category> categories, final GradingStrategy strategy)
|
||||
{
|
||||
this.categories = categories;
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The Categories making up the Course
|
||||
*/
|
||||
public List<Category> getCategories()
|
||||
{
|
||||
return categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The strategy used for calculating the final Grade for the Course
|
||||
*/
|
||||
public GradingStrategy getStrategy()
|
||||
{
|
||||
return strategy;
|
||||
}
|
||||
}
|
||||
103
Homework 5/src/grading/io/CourseReader.java
Executable file
103
Homework 5/src/grading/io/CourseReader.java
Executable file
@@ -0,0 +1,103 @@
|
||||
package grading.io;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import grading.*;
|
||||
|
||||
/**
|
||||
* A utility class for reading in Grade data from a .grd file and constructing Categories and
|
||||
* Courses.
|
||||
*/
|
||||
public class CourseReader
|
||||
{
|
||||
private static final String TAB_DELIMITER = "\t";
|
||||
|
||||
/**
|
||||
* Empty constructor so the coverage tests stop yelling at me.
|
||||
*/
|
||||
public CourseReader()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in
|
||||
* A BufferedReader for reading data from the file
|
||||
* @param size
|
||||
* The number of grade entries in a given category to read
|
||||
* @param key
|
||||
* The key for the category
|
||||
* @param filter
|
||||
* The filter to construct the Category with
|
||||
* @return A Category containing all the grades read from the file
|
||||
* @throws IOException
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public static CompositeGrade readCategory(final BufferedReader in, final int size,
|
||||
final String key, final Filter filter) throws IOException, IllegalArgumentException
|
||||
{
|
||||
final List<Grade> grades = new ArrayList<Grade>();
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
final String[] gradeData = in.readLine().split(TAB_DELIMITER);
|
||||
|
||||
String gradeKey = gradeData[0];
|
||||
String value = gradeData.length > 1 ? gradeData[1] : null;
|
||||
|
||||
grades.add(LeafGrade.parseLeafGrade(gradeKey, value));
|
||||
}
|
||||
|
||||
CompositeGrade compositeGrade = new CompositeGrade(key);
|
||||
compositeGrade.setFilter(filter);
|
||||
compositeGrade.setStrategy(new TotalStrategy());
|
||||
grades.forEach((grade) -> compositeGrade.add(grade));
|
||||
return compositeGrade;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in
|
||||
* A BufferedReader for reading data from the file
|
||||
* @param size
|
||||
* The number of categories in the file to read
|
||||
* @return A Course consisting of all Categories read from the file
|
||||
* @throws IOException
|
||||
*/
|
||||
public static CompositeGrade readCourse(final BufferedReader in, final int size)
|
||||
throws IOException
|
||||
{
|
||||
|
||||
final List<CompositeGrade> categories = new ArrayList<CompositeGrade>();
|
||||
final Map<String, Double> weights = new HashMap<String, Double>();
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
final String[] categoryFields = in.readLine().split(TAB_DELIMITER);
|
||||
final String categoryName = categoryFields[0];
|
||||
final int gradeCount = Integer.parseInt(categoryFields[1]);
|
||||
|
||||
weights.put(categoryName, Double.parseDouble(categoryFields[2]));
|
||||
|
||||
final boolean shouldDropLowest = Boolean.parseBoolean(categoryFields[3]);
|
||||
final boolean shouldDropHighest = Boolean.parseBoolean(categoryFields[4]);
|
||||
final Filter filter = new DropFilter(shouldDropLowest, shouldDropHighest);
|
||||
|
||||
final CompositeGrade categoryGrade = CourseReader.readCategory(in, gradeCount, categoryName,
|
||||
filter);
|
||||
categories.add(categoryGrade);
|
||||
}
|
||||
|
||||
final GradingStrategy strategy = new WeightedTotalStrategy(weights);
|
||||
|
||||
CompositeGrade courseGrade = new CompositeGrade("Course");
|
||||
courseGrade.setStrategy(strategy);
|
||||
categories.forEach((grade) -> courseGrade.add(grade));
|
||||
|
||||
return courseGrade;
|
||||
}
|
||||
}
|
||||
51
Homework 5/src/testing/CategoryTest.java
Executable file
51
Homework 5/src/testing/CategoryTest.java
Executable file
@@ -0,0 +1,51 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import grading.*;
|
||||
import grading.io.Category;
|
||||
import java.util.*;
|
||||
|
||||
class CategoryTest
|
||||
{
|
||||
|
||||
private Filter filter;
|
||||
private GradingStrategy strategy;
|
||||
private List<Grade> grades;
|
||||
private String validKey;
|
||||
|
||||
@BeforeEach
|
||||
void setUp()
|
||||
{
|
||||
filter = new DropFilter();
|
||||
strategy = new TotalStrategy();
|
||||
grades = new ArrayList<Grade>();
|
||||
validKey = "math";
|
||||
}
|
||||
|
||||
@Test
|
||||
void badKeyTest()
|
||||
{
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> new Category(null, grades, filter, strategy));
|
||||
assertThrows(IllegalArgumentException.class, () -> new Category("", grades, filter, strategy));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getterTest()
|
||||
{
|
||||
Grade grade = new LeafGrade("HW1", 95.0);
|
||||
grades.add(grade);
|
||||
Category category = new Category(validKey, grades, filter, strategy);
|
||||
|
||||
assertEquals(validKey, category.getKey());
|
||||
|
||||
assertSame(grades, category.getGrades());
|
||||
|
||||
assertEquals(filter, category.getFilter());
|
||||
|
||||
assertEquals(strategy, category.getStrategy());
|
||||
}
|
||||
}
|
||||
126
Homework 5/src/testing/CompositeGradeTest.java
Executable file
126
Homework 5/src/testing/CompositeGradeTest.java
Executable file
@@ -0,0 +1,126 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import grading.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class CompositeGradeTest
|
||||
{
|
||||
private static final String COMPOSITE_KEY = "Composite";
|
||||
|
||||
private CompositeGrade compositeGrade;
|
||||
private GradingStrategy mockStrategy;
|
||||
private Filter mockFilter;
|
||||
private List<Grade> mockGrades;
|
||||
|
||||
@BeforeEach
|
||||
void setUp()
|
||||
{
|
||||
compositeGrade = new CompositeGrade(COMPOSITE_KEY);
|
||||
mockStrategy = new TotalStrategy();
|
||||
mockFilter = new DropFilter(true, true);
|
||||
|
||||
mockGrades = new ArrayList<Grade>();
|
||||
mockGrades.add(new LeafGrade("HW1", 75.0));
|
||||
mockGrades.add(new LeafGrade("HW2", 50.0));
|
||||
mockGrades.add(new LeafGrade("HW3", 25.0));
|
||||
mockGrades.add(new LeafGrade("HW4", 100.0));
|
||||
}
|
||||
|
||||
@Test
|
||||
void constructor()
|
||||
{
|
||||
// Ensure constructor properly initializes the object
|
||||
assertEquals(compositeGrade.getKey(), COMPOSITE_KEY);
|
||||
assertEquals(compositeGrade.getValue(), null);
|
||||
}
|
||||
|
||||
@Test
|
||||
void badConstructor()
|
||||
{
|
||||
assertThrows(IllegalArgumentException.class, () -> new CompositeGrade(null));
|
||||
assertThrows(IllegalArgumentException.class, () -> new CompositeGrade(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
void addAndRetrieveComponents()
|
||||
{
|
||||
// Test that adding a grade adds it to the components list
|
||||
mockGrades.forEach((grade) -> compositeGrade.add(grade));
|
||||
assertEquals(mockGrades, compositeGrade.getComponents());
|
||||
}
|
||||
|
||||
@Test
|
||||
void setAndGetFilter()
|
||||
{
|
||||
// Test setting and getting the filter
|
||||
compositeGrade.setFilter(mockFilter);
|
||||
assertEquals(mockFilter, compositeGrade.getFilter());
|
||||
}
|
||||
|
||||
@Test
|
||||
void setAndGetStrategy()
|
||||
{
|
||||
// Test setting and getting the grading strategy
|
||||
compositeGrade.setStrategy(mockStrategy);
|
||||
assertEquals(mockStrategy, compositeGrade.getStrategy());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getValueNullIfNoStrategy()
|
||||
{
|
||||
// Test that getValue returns null when no strategy is assigned
|
||||
compositeGrade.setStrategy(null);
|
||||
assertEquals(null, compositeGrade.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getValueNullIfFilterThrowsSizeException()
|
||||
{
|
||||
// Ensure getValue handles exceptions thrown by the filter
|
||||
compositeGrade.setFilter(mockFilter);
|
||||
compositeGrade.setStrategy(mockStrategy);
|
||||
compositeGrade.add(mockGrades.getFirst());
|
||||
|
||||
assertEquals(null, compositeGrade.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getValueNullIfStrategyThrowsSizeException()
|
||||
{
|
||||
// Ensure getValue handles exceptions thrown by the strategy
|
||||
compositeGrade.setStrategy(mockStrategy);
|
||||
|
||||
assertEquals(null, compositeGrade.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getValueFilterIsNull()
|
||||
{
|
||||
// Ensure strategy calculates the value when no filter is set
|
||||
compositeGrade.setFilter(null);
|
||||
compositeGrade.setStrategy(mockStrategy);
|
||||
|
||||
mockGrades.forEach((grade) -> compositeGrade.add(grade));
|
||||
|
||||
assertEquals(250.0, compositeGrade.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getValueFilterApplies()
|
||||
{
|
||||
// Ensure filtered list is passed to strategy for calculation
|
||||
compositeGrade.setFilter(mockFilter);
|
||||
compositeGrade.setStrategy(mockStrategy);
|
||||
|
||||
mockGrades.forEach((grade) -> compositeGrade.add(grade));
|
||||
|
||||
assertEquals(125.0, compositeGrade.getValue());
|
||||
}
|
||||
}
|
||||
54
Homework 5/src/testing/CourseReaderTest.java
Executable file
54
Homework 5/src/testing/CourseReaderTest.java
Executable file
@@ -0,0 +1,54 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import grading.*;
|
||||
import grading.io.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
|
||||
class CourseReaderTest
|
||||
{
|
||||
@Test
|
||||
void grdFileTests() throws IOException, SizeException
|
||||
{
|
||||
assertNotNull(new CourseReader()); // Nonsense test for coverage
|
||||
|
||||
final Double complete01Grade = calculateCourseGradeFromFile("complete_01.grd");
|
||||
final Double complete02Grade = calculateCourseGradeFromFile("complete_02.grd");
|
||||
final Double complete03Grade = calculateCourseGradeFromFile("complete_03.grd");
|
||||
final Double fiveCategories01Grade = calculateCourseGradeFromFile("five-categories_01.grd");
|
||||
final Double missingAllGrade = calculateCourseGradeFromFile("missing_all.grd");
|
||||
final Double missingMultipleInEachGrade = calculateCourseGradeFromFile(
|
||||
"missing_multiple-in-each.grd");
|
||||
final Double missingOneInEachGrade = calculateCourseGradeFromFile("missing_one-in-each.grd");
|
||||
final Double missingOneInOneGrade = calculateCourseGradeFromFile("missing_one-in-one.grd");
|
||||
final Double sixCategories01Grade = calculateCourseGradeFromFile("six-categories_01.grd");
|
||||
|
||||
assertEquals(80.7, complete01Grade);
|
||||
assertEquals(100, complete02Grade);
|
||||
assertEquals(54.0, complete03Grade);
|
||||
assertEquals(64.75, fiveCategories01Grade);
|
||||
assertEquals(0.0, missingAllGrade);
|
||||
assertEquals(19.5, missingMultipleInEachGrade);
|
||||
assertEquals(35.2, missingOneInEachGrade);
|
||||
assertEquals(80.7, missingOneInOneGrade);
|
||||
assertEquals(76.6, sixCategories01Grade);
|
||||
}
|
||||
|
||||
private static Double calculateCourseGradeFromFile(final String filename)
|
||||
throws IOException, SizeException
|
||||
{
|
||||
BufferedReader in = new BufferedReader(new FileReader(filename));
|
||||
String line = in.readLine();
|
||||
int categories = Integer.parseInt(line);
|
||||
CompositeGrade course = CourseReader.readCourse(in, categories);
|
||||
in.close();
|
||||
|
||||
return course.getValue();
|
||||
}
|
||||
}
|
||||
37
Homework 5/src/testing/CourseTest.java
Executable file
37
Homework 5/src/testing/CourseTest.java
Executable file
@@ -0,0 +1,37 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import grading.*;
|
||||
import grading.io.Category;
|
||||
import grading.io.Course;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class CourseTest
|
||||
{
|
||||
@Test
|
||||
void testCourseInitialization()
|
||||
{
|
||||
// Arrange
|
||||
final GradingStrategy strategy = new TotalStrategy();
|
||||
final Filter filter = new DropFilter();
|
||||
final List<Category> categories = new ArrayList<Category>();
|
||||
|
||||
final List<Grade> homeworkGrades = new ArrayList<Grade>();
|
||||
homeworkGrades.add(new LeafGrade("HW1", 20.0));
|
||||
homeworkGrades.add(new LeafGrade("HW2", 5.0));
|
||||
|
||||
final Category hws = new Category("Homework Assignments", homeworkGrades, filter, strategy);
|
||||
categories.add(hws);
|
||||
|
||||
final Course course = new Course(categories, strategy);
|
||||
|
||||
assertEquals(categories, course.getCategories(),
|
||||
"Categories should match the initialized values");
|
||||
assertEquals(strategy, course.getStrategy(), "Strategy should match the initialized value");
|
||||
}
|
||||
}
|
||||
39
Homework 5/src/testing/DropFilterTest.java
Executable file
39
Homework 5/src/testing/DropFilterTest.java
Executable file
@@ -0,0 +1,39 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import grading.Grade;
|
||||
import grading.LeafGrade;
|
||||
import grading.SizeException;
|
||||
import grading.DropFilter;
|
||||
|
||||
class DropFilterTest
|
||||
{
|
||||
@Test
|
||||
void applyTest()
|
||||
{
|
||||
final Grade grade1 = new LeafGrade("HW", 40.0);
|
||||
final Grade grade2 = new LeafGrade("Midterm", (Double) null);
|
||||
final Grade grade3 = new LeafGrade("Final", 100.0);
|
||||
|
||||
List<Grade> grades = List.of(grade1, grade2, grade3);
|
||||
|
||||
DropFilter defaultFilter = new DropFilter();
|
||||
DropFilter filter1 = new DropFilter(false, false);
|
||||
DropFilter filter2 = new DropFilter(false, true);
|
||||
DropFilter filter3 = new DropFilter(true, false);
|
||||
DropFilter filter4 = new DropFilter(true, true);
|
||||
|
||||
assertThrows(SizeException.class, () -> defaultFilter.apply((List<Grade>) null));
|
||||
assertThrows(SizeException.class, () -> defaultFilter.apply(new ArrayList<Grade>()));
|
||||
|
||||
assertIterableEquals(grades, filter1.apply(grades));
|
||||
assertIterableEquals(List.of(grade1, grade2), filter2.apply(grades));
|
||||
assertIterableEquals(List.of(grade1, grade3), filter3.apply(grades));
|
||||
assertIterableEquals(List.of(grade1), filter4.apply(grades));
|
||||
}
|
||||
}
|
||||
99
Homework 5/src/testing/GradeTest.java
Executable file
99
Homework 5/src/testing/GradeTest.java
Executable file
@@ -0,0 +1,99 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import grading.LeafGrade;
|
||||
|
||||
class GradeTest
|
||||
{
|
||||
private static final String HOMEWORK_KEY = "HW";
|
||||
private static final String MIDTERM_KEY = "Midterm";
|
||||
private static final String FINAL_KEY = "Final";
|
||||
|
||||
@Test
|
||||
void defaultValueConstructorTest()
|
||||
{
|
||||
LeafGrade grade = new LeafGrade(FINAL_KEY);
|
||||
assertEquals(FINAL_KEY, grade.getKey());
|
||||
assertEquals(0.0, grade.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenValueConstructorTest()
|
||||
{
|
||||
LeafGrade grade = new LeafGrade(MIDTERM_KEY, 85.5);
|
||||
assertEquals(MIDTERM_KEY, grade.getKey());
|
||||
assertEquals(85.5, grade.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullValueConstructorTest()
|
||||
{
|
||||
assertThrows(IllegalArgumentException.class, () -> new LeafGrade(null));
|
||||
assertThrows(IllegalArgumentException.class, () -> new LeafGrade(null, 90.0));
|
||||
assertThrows(IllegalArgumentException.class, () -> new LeafGrade(null, (Double) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyKeyConstructorTest()
|
||||
{
|
||||
assertThrows(IllegalArgumentException.class, () -> new LeafGrade(""));
|
||||
assertThrows(IllegalArgumentException.class, () -> new LeafGrade("", 90.0));
|
||||
assertThrows(IllegalArgumentException.class, () -> new LeafGrade("", (Double) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void nullCompareToTest()
|
||||
{
|
||||
LeafGrade grade1 = new LeafGrade(HOMEWORK_KEY, (Double) null);
|
||||
LeafGrade grade2 = new LeafGrade(HOMEWORK_KEY, 80.0);
|
||||
LeafGrade grade3 = new LeafGrade(HOMEWORK_KEY, (Double) null);
|
||||
|
||||
assertTrue(grade1.compareTo(grade2) < 0);
|
||||
assertEquals(0, grade1.compareTo(grade3));
|
||||
assertTrue(grade2.compareTo(grade1) > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void compareToTest()
|
||||
{
|
||||
LeafGrade grade1 = new LeafGrade(HOMEWORK_KEY, 75.0);
|
||||
LeafGrade grade2 = new LeafGrade(HOMEWORK_KEY, 85.0);
|
||||
LeafGrade grade3 = new LeafGrade(HOMEWORK_KEY, 75.0);
|
||||
|
||||
assertTrue(grade1.compareTo(grade2) < 0);
|
||||
assertEquals(0, grade1.compareTo(grade3));
|
||||
assertTrue(grade2.compareTo(grade1) > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringTest()
|
||||
{
|
||||
LeafGrade grade1 = new LeafGrade(FINAL_KEY, 90.0);
|
||||
LeafGrade grade2 = new LeafGrade(MIDTERM_KEY, (Double) null);
|
||||
|
||||
assertEquals("Final: 90.0", grade1.toString());
|
||||
assertEquals("Midterm: NA", grade2.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseLeafGradeTest()
|
||||
{
|
||||
LeafGrade grade1 = LeafGrade.parseLeafGrade(FINAL_KEY, "66.0");
|
||||
assertEquals(FINAL_KEY, grade1.getKey());
|
||||
assertEquals(66.0, grade1.getValue());
|
||||
|
||||
LeafGrade grade2 = LeafGrade.parseLeafGrade(MIDTERM_KEY, (String) null);
|
||||
assertEquals(MIDTERM_KEY, grade2.getKey());
|
||||
assertEquals(null, grade2.getValue());
|
||||
|
||||
LeafGrade grade3 = LeafGrade.parseLeafGrade(HOMEWORK_KEY, "INVALID_DOUBLE");
|
||||
assertEquals(HOMEWORK_KEY, grade3.getKey());
|
||||
assertEquals(null, grade3.getValue());
|
||||
|
||||
assertThrows(IllegalArgumentException.class,
|
||||
() -> LeafGrade.parseLeafGrade((String) null, "71.0"));
|
||||
assertThrows(IllegalArgumentException.class, () -> LeafGrade.parseLeafGrade("", "31.0"));
|
||||
}
|
||||
}
|
||||
23
Homework 5/src/testing/MissingTest.java
Executable file
23
Homework 5/src/testing/MissingTest.java
Executable file
@@ -0,0 +1,23 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import grading.Missing;
|
||||
|
||||
class MissingTest
|
||||
{
|
||||
@Test
|
||||
void defaultDoubleValueTest()
|
||||
{
|
||||
assertEquals(40.0, Missing.doubleValue(40.0));
|
||||
assertEquals(0.0, Missing.doubleValue((Double) null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenMissingDoubleValueTest()
|
||||
{
|
||||
assertEquals(40.0, Missing.doubleValue(40.0, 20.0));
|
||||
assertEquals(20.0, Missing.doubleValue((Double) null, 20.0));
|
||||
}
|
||||
}
|
||||
35
Homework 5/src/testing/TotalStrategyTest.java
Executable file
35
Homework 5/src/testing/TotalStrategyTest.java
Executable file
@@ -0,0 +1,35 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import grading.Grade;
|
||||
import grading.LeafGrade;
|
||||
import grading.TotalStrategy;
|
||||
import grading.SizeException;
|
||||
|
||||
class TotalStrategyTest
|
||||
{
|
||||
private static final String TOTAL_KEY = "Total";
|
||||
|
||||
@Test
|
||||
void calculateTest()
|
||||
{
|
||||
List<Grade> grades = new ArrayList<Grade>();
|
||||
grades.add(new LeafGrade("HW1", 40.0));
|
||||
grades.add(new LeafGrade("HW2", (Double) null));
|
||||
grades.add(new LeafGrade("HW3", 100.0));
|
||||
|
||||
TotalStrategy strategy = new TotalStrategy();
|
||||
|
||||
assertThrows(SizeException.class, () -> strategy.calculate(TOTAL_KEY, (List<Grade>) null));
|
||||
assertThrows(SizeException.class, () -> strategy.calculate(TOTAL_KEY, new ArrayList<Grade>()));
|
||||
|
||||
Grade total = strategy.calculate(TOTAL_KEY, grades);
|
||||
|
||||
assertEquals(TOTAL_KEY, total.getKey());
|
||||
assertEquals(140.0, total.getValue());
|
||||
}
|
||||
}
|
||||
51
Homework 5/src/testing/WeightedTotalStrategyTest.java
Executable file
51
Homework 5/src/testing/WeightedTotalStrategyTest.java
Executable file
@@ -0,0 +1,51 @@
|
||||
package testing;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import grading.Grade;
|
||||
import grading.LeafGrade;
|
||||
import grading.WeightedTotalStrategy;
|
||||
import grading.SizeException;
|
||||
|
||||
class WeightedTotalStrategyTest
|
||||
{
|
||||
private static final String HOMEWORK_KEY = "HW";
|
||||
private static final String MIDTERM_KEY = "Midterm";
|
||||
private static final String FINAL_KEY = "Final";
|
||||
private static final String TOTAL_KEY = "Total";
|
||||
|
||||
@Test
|
||||
void calculateTest()
|
||||
{
|
||||
List<Grade> grades = new ArrayList<Grade>();
|
||||
grades.add(new LeafGrade(HOMEWORK_KEY, 40.0));
|
||||
grades.add(new LeafGrade(MIDTERM_KEY, (Double) null));
|
||||
grades.add(new LeafGrade(FINAL_KEY, 100.0));
|
||||
|
||||
Map<String, Double> weights = new HashMap<String, Double>();
|
||||
weights.put(MIDTERM_KEY, 2.0);
|
||||
weights.put(FINAL_KEY, 3.0);
|
||||
|
||||
WeightedTotalStrategy defaultStrategy = new WeightedTotalStrategy();
|
||||
|
||||
assertThrows(SizeException.class,
|
||||
() -> defaultStrategy.calculate(TOTAL_KEY, (List<Grade>) null));
|
||||
assertThrows(SizeException.class,
|
||||
() -> defaultStrategy.calculate(TOTAL_KEY, new ArrayList<Grade>()));
|
||||
|
||||
Grade total = defaultStrategy.calculate(TOTAL_KEY, grades);
|
||||
|
||||
assertEquals(TOTAL_KEY, total.getKey());
|
||||
assertEquals(140.0, total.getValue());
|
||||
|
||||
WeightedTotalStrategy strategy = new WeightedTotalStrategy(weights);
|
||||
|
||||
Grade weightedTotal = strategy.calculate(TOTAL_KEY, grades);
|
||||
|
||||
assertEquals(TOTAL_KEY, weightedTotal.getKey());
|
||||
assertEquals(340.0, weightedTotal.getValue());
|
||||
}
|
||||
}
|
||||
18
Homework 6/complete_01.grd
Executable file
18
Homework 6/complete_01.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 20
|
||||
PA2 18
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5 20
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 5
|
||||
HW3 0
|
||||
HW4 10
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm 80
|
||||
Final Exam 1 0.30 false false
|
||||
Final 75
|
||||
18
Homework 6/complete_02.grd
Executable file
18
Homework 6/complete_02.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 20
|
||||
PA2 20
|
||||
PA3 20
|
||||
PA4 20
|
||||
PA5 20
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 20
|
||||
HW3 20
|
||||
HW4 20
|
||||
HW5 20
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm 100
|
||||
Final Exam 1 0.30 false false
|
||||
Final 100
|
||||
18
Homework 6/complete_03.grd
Executable file
18
Homework 6/complete_03.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 10
|
||||
PA2 10
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5 5
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 0
|
||||
HW3 0
|
||||
HW4 10
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm 60
|
||||
Final Exam 1 0.30 false false
|
||||
Final 45
|
||||
BIN
Homework 6/cs111-screenshot.png
Executable file
BIN
Homework 6/cs111-screenshot.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
18
Homework 6/cs111.grd
Executable file
18
Homework 6/cs111.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1
|
||||
PA2
|
||||
PA3
|
||||
PA4
|
||||
PA5
|
||||
PA6
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1
|
||||
HW2
|
||||
HW3
|
||||
HW4
|
||||
HW5
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm
|
||||
Final Exam 1 0.30 false false
|
||||
Final
|
||||
21
Homework 6/five-categories_01.grd
Executable file
21
Homework 6/five-categories_01.grd
Executable file
@@ -0,0 +1,21 @@
|
||||
5
|
||||
Homework Assignments 5 0.25 true false
|
||||
HW01 20
|
||||
HW02 5
|
||||
HW03 0
|
||||
HW04 10
|
||||
HW05 15
|
||||
Quizzes 5 0.25 true true
|
||||
Quiz01 12
|
||||
Quiz02 8
|
||||
Quiz03 20
|
||||
Quiz04 13
|
||||
Quiz05 20
|
||||
Misc 2 0.10 false false
|
||||
Attendance 40
|
||||
Participation 50
|
||||
Midterm Exams 2 0.20 false false
|
||||
Midterm01 45
|
||||
Midterm02 40
|
||||
Final Exam 1 0.20 false false
|
||||
Final 75
|
||||
18
Homework 6/missing_all.grd
Executable file
18
Homework 6/missing_all.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1
|
||||
PA2
|
||||
PA3
|
||||
PA4
|
||||
PA5
|
||||
PA6
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1
|
||||
HW2
|
||||
HW3
|
||||
HW4
|
||||
HW5
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm
|
||||
Final Exam 1 0.30 false false
|
||||
Final
|
||||
18
Homework 6/missing_multiple-in-each.grd
Executable file
18
Homework 6/missing_multiple-in-each.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1
|
||||
PA2 20
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5
|
||||
PA6
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2
|
||||
HW3 0
|
||||
HW4
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm
|
||||
Final Exam 1 0.30 false false
|
||||
Final
|
||||
18
Homework 6/missing_one-in-each.grd
Executable file
18
Homework 6/missing_one-in-each.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 20
|
||||
PA2 18
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 5
|
||||
HW3 0
|
||||
HW4
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm
|
||||
Final Exam 1 0.30 false false
|
||||
Final
|
||||
18
Homework 6/missing_one-in-one.grd
Executable file
18
Homework 6/missing_one-in-one.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 20
|
||||
PA2 18
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5 20
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 5
|
||||
HW3
|
||||
HW4 10
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm 80
|
||||
Final Exam 1 0.30 false false
|
||||
Final 75
|
||||
BIN
Homework 6/potterhj-cs111-screenshot.png
Executable file
BIN
Homework 6/potterhj-cs111-screenshot.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
18
Homework 6/potterhj-cs111.grd
Executable file
18
Homework 6/potterhj-cs111.grd
Executable file
@@ -0,0 +1,18 @@
|
||||
4
|
||||
Programming Assignments 6 0.40 true false
|
||||
PA1 20
|
||||
PA2 18
|
||||
PA3 5
|
||||
PA4 15
|
||||
PA5 20
|
||||
PA6 20
|
||||
Homework Assignments 5 0.10 false false
|
||||
HW1 20
|
||||
HW2 5
|
||||
HW3 0
|
||||
HW4 10
|
||||
HW5 15
|
||||
Midterm Exam 1 0.20 false false
|
||||
Midterm 80
|
||||
Final Exam 1 0.30 false false
|
||||
Final 75
|
||||
36
Homework 6/six-categories_01.grd
Executable file
36
Homework 6/six-categories_01.grd
Executable file
@@ -0,0 +1,36 @@
|
||||
6
|
||||
Programming Assignments 6 0.15 false false
|
||||
PA01 20
|
||||
PA02 18
|
||||
PA03 5
|
||||
PA04 15
|
||||
PA05 20
|
||||
PA06 20
|
||||
Homework Assignments 5 0.15 false false
|
||||
HW01 20
|
||||
HW02 5
|
||||
HW03 0
|
||||
HW04 10
|
||||
HW05 15
|
||||
Labs 10 0.10 false false
|
||||
Lab01 10
|
||||
Lab02 5
|
||||
Lab03 10
|
||||
Lab04 10
|
||||
Lab05 0
|
||||
Lab06 10
|
||||
Lab07 10
|
||||
Lab08 10
|
||||
Lab09 5
|
||||
Lab10 10
|
||||
Quizzes 5 0.10 false false
|
||||
Quiz01 12
|
||||
Quiz02 8
|
||||
Quiz03 20
|
||||
Quiz04 13
|
||||
Quiz05 16
|
||||
Midterm Exams 2 0.20 false false
|
||||
Midterm01 45
|
||||
Midterm02 40
|
||||
Final Exam 1 0.30 false false
|
||||
Final 75
|
||||
76
Homework 6/src/app/Gradient.java
Executable file
76
Homework 6/src/app/Gradient.java
Executable file
@@ -0,0 +1,76 @@
|
||||
package app;
|
||||
|
||||
import grading.*;
|
||||
import grading.io.*;
|
||||
import gui.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
/**
|
||||
* An application for calculating the numeric grade for
|
||||
* a course from the grades on individual assignments.
|
||||
*
|
||||
* @version 4.0
|
||||
* @author Sagacious Media
|
||||
*
|
||||
*/
|
||||
public class Gradient implements Runnable
|
||||
{
|
||||
private CompositeGrade course;
|
||||
|
||||
/**
|
||||
* The entry point for the application.
|
||||
*
|
||||
* @param args args[0] contains the path (relative or absolute) to the .grd file
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// Early exit
|
||||
if ((args == null) || (args.length < 1))
|
||||
{
|
||||
System.err.println("You must enter a file name.");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
BufferedReader in = new BufferedReader(new FileReader(args[0]));
|
||||
String line = in.readLine();
|
||||
int categories = Integer.parseInt(line);
|
||||
CompositeGrade course = CourseReader.readCourse(in, categories);
|
||||
in.close();
|
||||
SwingUtilities.invokeAndWait(new Gradient(course));
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
System.out.println("Unable to open file.");
|
||||
System.exit(1);
|
||||
}
|
||||
catch (InterruptedException | InvocationTargetException ex)
|
||||
{
|
||||
System.out.println("Problem with the Event Dispatch Thread.");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Explicit Value Constructor.
|
||||
*
|
||||
* @param course The CompositeGrade to use
|
||||
*/
|
||||
public Gradient(CompositeGrade course)
|
||||
{
|
||||
this.course = course;
|
||||
}
|
||||
|
||||
/**
|
||||
* The code to run in the EventDispatchThread.
|
||||
*/
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
new GradientWindow(course);
|
||||
}
|
||||
}
|
||||
72
Homework 6/src/grading/AbstractGrade.java
Executable file
72
Homework 6/src/grading/AbstractGrade.java
Executable file
@@ -0,0 +1,72 @@
|
||||
package grading;
|
||||
|
||||
/**
|
||||
* Abstract implementation of Grade meant for extension with custom getValue implementations.
|
||||
*/
|
||||
public abstract class AbstractGrade implements Grade
|
||||
{
|
||||
private String key;
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* The key for the Grade
|
||||
* @throws IllegalArgumentException
|
||||
*/
|
||||
public AbstractGrade(final String key) throws IllegalArgumentException
|
||||
{
|
||||
if (key == null || key.isEmpty())
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
this.key = key;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param other
|
||||
* Another Grade object to compare to this grade
|
||||
* @return The value 0 if other's value is equal to this Grade's value; -1 if this Grade's value
|
||||
* is less than other's; and 1 if this Grade's value is greater than other's.
|
||||
*/
|
||||
public int compareTo(final Grade other)
|
||||
{
|
||||
Double value = this.getValue();
|
||||
Double otherValue = other.getValue();
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
return (otherValue == null) ? 0 : -1;
|
||||
}
|
||||
if (otherValue == null)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return value.compareTo(otherValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The key of for this Grade
|
||||
*/
|
||||
public String getKey()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The value for this Grade
|
||||
*/
|
||||
public abstract Double getValue();
|
||||
|
||||
/**
|
||||
* @return A string representation of the Grade
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
Double value = this.getValue();
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
return String.format("%s: NA", key);
|
||||
}
|
||||
|
||||
return String.format("%s: %5.1f", key, value);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user