diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/CT326 - Assignment 1.pdf b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326 - Assignment 1.pdf
new file mode 100644
index 00000000..eced3c33
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326 - Assignment 1.pdf differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.gitignore b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.gitignore
new file mode 100644
index 00000000..5ff6309b
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.gitignore
@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.idea/.gitignore b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.idea/.gitignore
new file mode 100644
index 00000000..26d33521
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.idea/encodings.xml b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.idea/encodings.xml
new file mode 100644
index 00000000..aa00ffab
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.idea/misc.xml b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.idea/misc.xml
new file mode 100644
index 00000000..c3f3b0ab
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.idea/misc.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.idea/uiDesigner.xml b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.idea/uiDesigner.xml
new file mode 100644
index 00000000..2b63946d
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/Test Results.png b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/Test Results.png
new file mode 100644
index 00000000..0a2abde4
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/Test Results.png differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/pom.xml b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/pom.xml
new file mode 100644
index 00000000..c55ddb2f
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/pom.xml
@@ -0,0 +1,25 @@
+
+
+ 4.0.0
+
+ org.example
+ CT326-Assignment01
+ 1.0-SNAPSHOT
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ RELEASE
+ test
+
+
+
+
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/main/java/DateInPastException.java b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/main/java/DateInPastException.java
new file mode 100644
index 00000000..3e692549
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/main/java/DateInPastException.java
@@ -0,0 +1,6 @@
+// Andrew Hayes, ID: 21321503
+public class DateInPastException extends RuntimeException {
+ public DateInPastException(String s) {
+ super(s);
+ }
+}
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/main/java/NCTBooking.java b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/main/java/NCTBooking.java
new file mode 100644
index 00000000..e0dd6d9f
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/main/java/NCTBooking.java
@@ -0,0 +1,62 @@
+// Andrew Hayes, ID: 21321503
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.concurrent.atomic.AtomicLong;
+
+public class NCTBooking {
+ private static final AtomicLong NEXT_ID = new AtomicLong(0);
+
+ private String vehicleRegistrationNumber;
+ private TestCentre testCentre;
+ private LocalDateTime datetime;
+ private final long bookingID = NEXT_ID.getAndIncrement();
+
+ public NCTBooking(String vehicleRegistrationNumber, TestCentre testCentre, LocalDateTime datetime) throws DateInPastException {
+ // if datetime is in the future, initialising NCTBooking, otherwise throwing DateInPastException
+ if (datetime.isAfter(LocalDateTime.now())) {
+ this.vehicleRegistrationNumber = vehicleRegistrationNumber;
+ this.testCentre = testCentre;
+ this.datetime = datetime;
+ }
+ else {
+ throw new DateInPastException("Passed datetime is in the past!");
+ }
+ }
+
+ public NCTBooking(String vehicleRegistrationNumber, TestCentre testCentre) {
+ this.vehicleRegistrationNumber = vehicleRegistrationNumber;
+ this.testCentre = testCentre;
+ }
+
+ public TestCentre getTestCentre() { return testCentre; }
+
+ public String getVehicleRegistrationNumber() { return vehicleRegistrationNumber; }
+
+ public void setVehicleRegistrationNumber(String vehicleRegistrationNumber) { this.vehicleRegistrationNumber = vehicleRegistrationNumber; }
+
+ public long getBookingID() { return bookingID; }
+
+ @Override
+ public String toString() {
+ DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("EEEE, d MMMM yyyy");
+ DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
+
+ return "Booking ID Number: " + bookingID + "\n" +
+ "Registration Number: " + vehicleRegistrationNumber + "\n" +
+ "Centre: " + testCentre.getName() + "\n" +
+ "Address: " + testCentre.getAddress() + "\n" +
+ "Date & Time: On " + datetime.format(dateFormatter) + " at " + datetime.format(timeFormatter);
+ }
+
+ public void setDatetime(LocalDateTime datetime) throws DateInPastException {
+ // if datetime is in the future, setting datetime, otherwise throwing exception
+ if (datetime.isAfter(LocalDateTime.now())) {
+ this.datetime = datetime;
+ }
+ else {
+ throw new DateInPastException(datetime.toString() + "is in the past!");
+ }
+ }
+
+ public LocalDateTime getDatetime() { return datetime; }
+}
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/main/java/NCTBookingSlotWebservice.java b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/main/java/NCTBookingSlotWebservice.java
new file mode 100644
index 00000000..3cdf993b
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/main/java/NCTBookingSlotWebservice.java
@@ -0,0 +1,6 @@
+// Andrew Hayes, ID: 21321503
+import java.time.LocalDateTime;
+
+public interface NCTBookingSlotWebservice {
+ public LocalDateTime getBookingDateTime(TestCentre testCentre);
+}
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/main/java/TestCentre.java b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/main/java/TestCentre.java
new file mode 100644
index 00000000..1d623170
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/main/java/TestCentre.java
@@ -0,0 +1,13 @@
+// Andrew Hayes, ID: 21321503
+public class TestCentre {
+ private String name;
+ private String address;
+
+ public TestCentre(String name, String address) {
+ this.name = name;
+ this.address = address;
+ }
+
+ public String getName() { return name; }
+ public String getAddress() { return address; }
+}
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/test/java/NCTBookingTest.java b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/test/java/NCTBookingTest.java
new file mode 100644
index 00000000..6079b7f9
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/test/java/NCTBookingTest.java
@@ -0,0 +1,165 @@
+// Andrew Hayes, ID: 21321503
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+import java.time.LocalDateTime;
+
+class NCTBookingTest {
+ // tests ability to instantiate an NCTBooking
+ @Test
+ void testCreateNCTBooking() {
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+ NCTBooking booking = new NCTBooking("221-RN-1234", testCentre, LocalDateTime.of(2024, 1, 1, 9, 0, 0));
+ assertNotNull(booking);
+ }
+
+ // tests ability to query the test centre of a booking
+ @Test
+ void testGetTestCentre() {
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+ NCTBooking booking = new NCTBooking("221-RN-1234", testCentre, LocalDateTime.of(2024, 1, 1, 9, 0, 0));
+
+ // value returned by getTestCentre() should be the value set when the booking was created
+ assertEquals(testCentre, booking.getTestCentre());
+ }
+
+ // tests ability to query the vehicle registration for a booking
+ @Test
+ void testGetVehicleRegistrationNumber() {
+ String vehicleRegistrationNumber = "221-RN-1234";
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+ NCTBooking booking = new NCTBooking(vehicleRegistrationNumber, testCentre, LocalDateTime.of(2024, 1, 1, 9, 0, 0));
+
+ // value returned by getVehicleRegistrationNumber() should be the value that was set when the booking was created (in this case)
+ assertEquals(vehicleRegistrationNumber, booking.getVehicleRegistrationNumber());
+ }
+
+ // tests ability to edit the vehicle registration number of a booking
+ @Test
+ void testSetVehicleRegistrationNumber() {
+ String vehicleRegistrationNumber = "221-RN-1234";
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+ NCTBooking booking = new NCTBooking(vehicleRegistrationNumber, testCentre, LocalDateTime.of(2024, 1, 1, 9, 0, 0));
+
+ // changing the value of vehicleRegistrationNumber and testing that the value returned by getVehicleRegistrationNumber is equal to the updated value
+ String newVehicleRegistrationNumber = "00-D-4321";
+ booking.setVehicleRegistrationNumber(newVehicleRegistrationNumber);
+
+ // value returned by getVehicleRegistrationNumber() should be the value that was set in the last edit
+ assertEquals(newVehicleRegistrationNumber, booking.getVehicleRegistrationNumber());
+ }
+
+ // tests ability to instantiate an NCTBooking without specifying a date
+ @Test
+ void testCreateNCTBookingWithoutDate() {
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+ NCTBooking booking = new NCTBooking("221-RN-123", testCentre);
+ assertNotNull(booking);
+ }
+
+ // tests ability to query the date and time of a booking
+ @Test
+ void testGetDatetime() {
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+ LocalDateTime datetime = LocalDateTime.of(2024, 1, 1, 9, 0, 0);
+ NCTBooking booking = new NCTBooking("221-RN-1234", testCentre, datetime);
+
+ // queried datetime should be equal to the datetime set on initialisation
+ assertEquals(datetime, booking.getDatetime());
+ }
+
+ // tests ability to set the date and time of a booking via an external API
+ @Test
+ void testSetDatetime() {
+ // stub implementation of the NCTBookingSlotWebservice for testing purposes
+ NCTBookingSlotWebservice testService = new NCTBookingSlotWebservice() {
+ @Override
+ public LocalDateTime getBookingDateTime(TestCentre testCentre) {
+ return LocalDateTime.of(2024, 1, 1, 9, 0, 0);
+ }
+ };
+
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+ NCTBooking booking = new NCTBooking("221-RN-123", testCentre);
+ LocalDateTime datetime = testService.getBookingDateTime(testCentre);
+ booking.setDatetime(datetime);
+
+ assertEquals(datetime, booking.getDatetime());
+ }
+
+ // tests that bookings with a date and time in the past throw a user-defined exception
+ @Test
+ void testCreateNCTBookingWithDataInThePast() {
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+ assertThrows(
+ DateInPastException.class,
+ () -> new NCTBooking("221-RN-123", testCentre, LocalDateTime.of(1970, 1, 1, 9, 0, 0))
+ );
+ }
+
+ // tests that attempting to set the datetime of a booking to a time in the past throws a user-defined exception
+ @Test
+ void testSetDatetimeInPast() {
+ // stub implementation of the NCTBookingSlotWebservice for testing purposes
+ NCTBookingSlotWebservice testService = new NCTBookingSlotWebservice() {
+ @Override
+ public LocalDateTime getBookingDateTime(TestCentre testCentre) {
+ return LocalDateTime.of(1970, 1, 1, 9, 0, 0);
+ }
+ };
+
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+ NCTBooking booking = new NCTBooking("221-RN-123", testCentre);
+ LocalDateTime datetime = testService.getBookingDateTime(testCentre);
+
+ assertThrows(
+ DateInPastException.class,
+ () -> booking.setDatetime(datetime)
+ );
+
+ }
+
+ // tests that bookings have a unique booking ID number generated when they're created
+ @Test
+ void testUniqueIDGenerated() {
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+ NCTBooking booking = new NCTBooking("221-RN-123", testCentre, LocalDateTime.of(2024, 1, 1, 9, 0, 0));
+ assertNotNull(booking.getBookingID());
+ }
+
+ // attempts to test if booking IDs are not unique by comparing 10,000 of them (note that this does not prove uniqueness, just will disprove it in certain situations)
+ @Test
+ void testBookingIDsUnique() {
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+
+ NCTBooking[] bookings = new NCTBooking[10_000];
+ for (int i = 0; i < 10_000; i ++) {
+ bookings[i] = new NCTBooking("221-RN-123", testCentre, LocalDateTime.of(2024, 1, 1, 9, 0, 0));
+ }
+
+ // looping over the bookings and comparing each one to every other one
+ for (int i = 0; i < 10_000; i ++) {
+ for (int j = 0; j < 10_000; j ++) {
+ if (i != j) {
+ assertNotEquals(bookings[i].getBookingID(), bookings[j].getBookingID());
+ }
+ }
+ }
+ }
+
+ // tests that output from toString() method matches a regex for the expected output
+ @Test
+ void testToString() {
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+ NCTBooking booking = new NCTBooking("221-RN-123", testCentre, LocalDateTime.of(2024, 1, 1, 9, 0, 0));
+
+ // the only "regular-expressiony" part of the below regex is "[0-9]+" which just matches one or more decimal digits
+ assertTrue(booking.toString().matches(
+ """
+ Booking ID Number: [0-9]+
+ Registration Number: 221-RN-123
+ Centre: Test Centre 1
+ Address: 10 Downing Street
+ Date & Time: On Monday, 1 January 2024 at 09:00"""
+ ));
+ }
+}
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/test/java/TestCentreTest.java b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/test/java/TestCentreTest.java
new file mode 100644
index 00000000..ee3a7766
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment1/CT326-Assignment01/src/test/java/TestCentreTest.java
@@ -0,0 +1,27 @@
+// Andrew Hayes, ID: 21321503
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+import java.time.LocalDateTime;
+
+class TestCentreTest {
+ // tests ability to instantiate a TestCentre
+ @Test
+ void testCreateTestCentre() {
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+ assertNotNull(testCentre);
+ }
+
+ // tests the getter for "name" in TestCentre class
+ @Test
+ void testGetName() {
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+ assertEquals("Test Centre 1", testCentre.getName());
+ }
+
+ // tests the getter for "address" in TestCentre class
+ @Test
+ void testGetAddress() {
+ TestCentre testCentre = new TestCentre("Test Centre 1", "10 Downing Street");
+ assertEquals("10 Downing Street", testCentre.getAddress());
+ }
+}
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment1/assignment1_Andrew_Hayes.zip b/third/semester1/CT326_Programming_III/assignments/assignment1/assignment1_Andrew_Hayes.zip
new file mode 100644
index 00000000..4f1ebfca
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment1/assignment1_Andrew_Hayes.zip differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/CT326 - Assignment 2.pdf b/third/semester1/CT326_Programming_III/assignments/assignment2/CT326 - Assignment 2.pdf
new file mode 100644
index 00000000..aa2b76b9
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment2/CT326 - Assignment 2.pdf differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.gitignore b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.gitignore
new file mode 100644
index 00000000..5ff6309b
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.gitignore
@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.idea/.gitignore b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.idea/.gitignore
new file mode 100644
index 00000000..26d33521
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.idea/.name b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.idea/.name
new file mode 100644
index 00000000..cadd1315
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.idea/.name
@@ -0,0 +1 @@
+assignment2
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.idea/encodings.xml b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.idea/encodings.xml
new file mode 100644
index 00000000..aa00ffab
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.idea/misc.xml b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.idea/misc.xml
new file mode 100644
index 00000000..c3f3b0ab
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/.idea/misc.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/Console Output.png b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/Console Output.png
new file mode 100644
index 00000000..12c5e48b
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/Console Output.png differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/lib/joda-money-1.0.3.jar b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/lib/joda-money-1.0.3.jar
new file mode 100644
index 00000000..23941144
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/lib/joda-money-1.0.3.jar differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/pom.xml b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/pom.xml
new file mode 100644
index 00000000..75055300
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/pom.xml
@@ -0,0 +1,17 @@
+
+
+ 4.0.0
+
+ org.example
+ assignment2
+ 1.0-SNAPSHOT
+
+
+ 17
+ 17
+ UTF-8
+
+
+
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/Expense.java b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/Expense.java
new file mode 100644
index 00000000..2fdede9c
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/Expense.java
@@ -0,0 +1,138 @@
+// Name: Andrew Hayes
+// ID Number: 21321503
+import java.time.LocalDate;
+
+import org.joda.money.CurrencyUnit;
+import org.joda.money.Money;
+
+public class Expense {
+ private LocalDate date;
+ private String description;
+ private ExpenseCategory category;
+ private Money amount;
+ private boolean approved; // defaults to false
+
+ /**
+ * constructor that does not take the boolean "approved" - this should be set later
+ * @param date
+ * @param description
+ * @param category
+ * @param amount
+ */
+ public Expense(LocalDate date, String description, ExpenseCategory category, Money amount) {
+ this.date = date;
+ this.description = description;
+ this.category = category;
+ this.amount = amount;
+ }
+
+ /**
+ * constructor that takes the boolean "approved" in case you want to override it defaulting to false
+ * @param date
+ * @param description
+ * @param category
+ * @param amount
+ * @param approved
+ */
+ public Expense(LocalDate date, String description, ExpenseCategory category, Money amount, boolean approved) {
+ this.date = date;
+ this.description = description;
+ this.category = category;
+ this.amount = amount;
+ this.approved = approved;
+ }
+
+ /**
+ *
+ * @return date
+ */
+ public LocalDate getDate() {
+ return date;
+ }
+
+ /**
+ *
+ * @param date
+ */
+ public void setDate(LocalDate date) {
+ this.date = date;
+ }
+
+ /**
+ *
+ * @return description
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ *
+ * @param description
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ *
+ * @return category
+ */
+ public ExpenseCategory getCategory() {
+ return category;
+ }
+
+ /**
+ *
+ * @param category
+ */
+ public void setCategory(ExpenseCategory category) {
+ this.category = category;
+ }
+
+ /**
+ *
+ * @return amount
+ */
+ public Money getAmount() {
+ return amount;
+ }
+
+ /**
+ *
+ * @param amount
+ */
+ public void setAmount(Money amount) {
+ this.amount = amount;
+ }
+
+
+ /**
+ * method to return the currency unit of the amount
+ * @return the CurrencyUnit of the amount
+ */
+ public CurrencyUnit getAmountCurrency() { return amount.getCurrencyUnit(); }
+
+ /**
+ *
+ * @return isApproved
+ */
+ public boolean isApproved() {
+ return approved;
+ }
+
+ /**
+ *
+ * @param approved
+ */
+ public void setApproved(boolean approved) {
+ this.approved = approved;
+ }
+
+ @Override
+ public String toString() {
+ return String.format(
+ "%s: %s - %s - %s %.2f", date.toString(), description, category, amount.getCurrencyUnit(), amount.getAmount().doubleValue()
+ );
+ }
+}
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/ExpenseCategory.java b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/ExpenseCategory.java
new file mode 100644
index 00000000..eb1674e0
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/ExpenseCategory.java
@@ -0,0 +1,9 @@
+// Name: Andrew Hayes
+// ID Number: 21321503
+public enum ExpenseCategory {
+ TRAVEL_AND_SUBSISTENCE,
+ SUPPLIES,
+ ENTERTAINMENT,
+ EQUIPMENT,
+ OTHER
+}
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/ExpensePrinter.java b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/ExpensePrinter.java
new file mode 100644
index 00000000..1d4a7adf
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/ExpensePrinter.java
@@ -0,0 +1,12 @@
+// Name: Andrew Hayes
+// ID Number: 21321503
+import java.util.ArrayList;
+
+public interface ExpensePrinter {
+
+ /**
+ * method to print the expenses
+ * @param expenses
+ */
+ public void print(ArrayList expenses);
+}
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/ExpensesPortal.java b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/ExpensesPortal.java
new file mode 100644
index 00000000..e3bdf5e6
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/ExpensesPortal.java
@@ -0,0 +1,99 @@
+// Name: Andrew Hayes
+// ID Number: 21321503
+import org.joda.money.CurrencyUnit;
+import org.joda.money.IllegalCurrencyException;
+import org.joda.money.Money;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDate;
+import java.util.ArrayList;
+
+public class ExpensesPortal {
+ private ArrayList expenses = new ArrayList();
+
+ /**
+ * main method
+ * @param args
+ */
+ public static void main(String[] args) {
+ ExpensesPortal ep = new ExpensesPortal();
+
+ // create sample expenses
+ ep.addExpense(new Expense(LocalDate.of(2022, 9, 23), "FLight to Glasgow", ExpenseCategory.TRAVEL_AND_SUBSISTENCE, Money.parse("EUR 270.59")));
+ ep.addExpense(new Expense(LocalDate.of(2022, 9, 23), "FLight to Dublin", ExpenseCategory.TRAVEL_AND_SUBSISTENCE, Money.parse("EUR 271.59")));
+ ep.addExpense(new Expense(LocalDate.of(2022, 9, 20), "Dell 17-inch monitor", ExpenseCategory.EQUIPMENT, Money.parse("USD 540.00")));
+ ep.addExpense(new Expense(LocalDate.of(2022, 9, 20), "Logitech Mouse", ExpenseCategory.EQUIPMENT, Money.parse("USD 40.00")));
+ ep.addExpense(new Expense(LocalDate.of(2022, 9, 21), "Java for Dummies", ExpenseCategory.OTHER, Money.parse("EUR 17.99")));
+ ep.addExpense(new Expense(LocalDate.of(2022, 9, 21), "Dinner", ExpenseCategory.OTHER, Money.parse("EUR 20.99")));
+ ep.addExpense(new Expense(LocalDate.of(2022, 9, 21), "Whiteboard Marker", ExpenseCategory.SUPPLIES, Money.parse("EUR 4.99")));
+
+ // call the printExpenses method using a lambda expression to implement the ExpensePrinter parameter
+ ep.printExpenses(expenses -> {
+ for (Expense expense : expenses) {
+ System.out.println(expense);
+ }
+ });
+ System.out.printf("%n");
+
+ // call the printExpenses method using an anonymous inner class to implement the ExpensePrinter parameter
+ ep.printExpenses(new ExpensePrinter() {
+ /**
+ * method to print a summary of the expenses
+ * @param expenses
+ */
+ @Override
+ public void print(ArrayList expenses) {
+ System.out.println("There are " + expenses.toArray().length + " expenses in the system totalling to a value of " + sumExpenses(expenses));
+ }
+ });
+ System.out.printf("%n");
+
+ // call the printExpense method using a PrinterByLabel instance as a parameter
+ ep.printExpenses(new PrinterByLabel());
+ }
+
+ /**
+ * method to submit a new expense
+ * @param expense
+ */
+ public void addExpense(Expense expense) {
+ expenses.add(expense);
+ }
+
+ /**
+ * method to print expenses
+ * @param printer
+ */
+ public void printExpenses(ExpensePrinter printer) {
+ printer.print(expenses);
+ }
+
+
+ /**
+ * method for summing the expenses that supports both EUR & USD
+ * @param expenses
+ * @return
+ * @throws IllegalCurrencyException
+ */
+ public static Money sumExpenses(ArrayList expenses) throws IllegalCurrencyException {
+ Money total = Money.parse("EUR 0");
+ BigDecimal USDToEURConversionRate = BigDecimal.valueOf(0.95); // hardcoded conversion rate as of 2023-10-04 - clearly not ideal, but as a proof of concept
+
+ for (Expense expense : expenses) {
+ // if currency is usd, converting to euro and adding to total
+ if (expense.getAmountCurrency().equals(CurrencyUnit.of("USD"))) {
+ total = total.plus(expense.getAmount().convertedTo(CurrencyUnit.EUR, USDToEURConversionRate, RoundingMode.HALF_UP));
+ }
+ // checking that the currency is of type euro before adding to total
+ else if (expense.getAmountCurrency().equals(CurrencyUnit.of("EUR"))) {
+ total = total.plus(expense.getAmount());
+ }
+ else {
+ throw new IllegalCurrencyException("CurrencyUnity " + expense.getAmountCurrency() + " is not supported! USD or EUR only");
+ }
+ }
+
+ return total;
+ }
+}
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/PrinterByLabel.java b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/PrinterByLabel.java
new file mode 100644
index 00000000..56ecf7ff
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2/src/main/java/PrinterByLabel.java
@@ -0,0 +1,48 @@
+// Name: Andrew Hayes
+// ID Number: 21321503
+import java.util.ArrayList;
+//import java.util.Collections; // for use in commented out algorithm -- see below
+//import java.util.Comparator;
+
+public class PrinterByLabel implements ExpensePrinter {
+ /**
+ * method to print all the expenses, grouped by category
+ * @param expenses
+ */
+ @Override
+ public void print(ArrayList expenses) {
+ ExpenseCategory[] categories = ExpenseCategory.values();
+
+ for (ExpenseCategory category : categories) {
+ System.out.println(category + ":");
+
+ for (Expense expense : expenses) {
+ // printing out expense only if it's in the current category
+ if (expense.getCategory().equals(category)) {
+ System.out.println(expense);
+ }
+ }
+ System.out.printf("%n");
+ }
+
+ // below is a commented-out alternative to the above algorithm that doesn't match the output in the design spec
+ // it doesn't print out every expense category as a title, just the ones that have an existing expense in the system
+ // this allows the sorting to be done nicely using the enum, and allows the enum to be expanded or contracted without changing other code
+ // this allows for slightly nicer sorting and does not print out categories which do not have extant expenses in them, which may or may not be desirable
+
+// // sorting the ArrayList by category
+// Collections.sort(expenses, Comparator.comparing(Expense::getCategory));
+//
+// // variable to keep track of what category the last printed expense was so that a heading can be printed once and only once for each category
+// ExpenseCategory lastCategory = null;
+//
+// for (Expense expense : expenses) {
+// // if the current expense's category is different to the last, print it out as a heading
+// if (expense.getCategory() != lastCategory) {
+// System.out.println(expense.getCategory());
+// lastCategory = expense.getCategory();
+// }
+// System.out.println(expense);
+// }
+ }
+}
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2_Andrew_Hayes.zip b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2_Andrew_Hayes.zip
new file mode 100644
index 00000000..7d8fc4a6
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment2/assignment2_Andrew_Hayes.zip differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/CT326 - Assignment 3.pdf b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326 - Assignment 3.pdf
new file mode 100644
index 00000000..3809d008
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326 - Assignment 3.pdf differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.gitignore b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.gitignore
new file mode 100644
index 00000000..5ff6309b
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.gitignore
@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.idea/.gitignore b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.idea/.gitignore
new file mode 100644
index 00000000..26d33521
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.idea/encodings.xml b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.idea/encodings.xml
new file mode 100644
index 00000000..aa00ffab
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.idea/misc.xml b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.idea/misc.xml
new file mode 100644
index 00000000..82dbec8a
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.idea/uiDesigner.xml b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.idea/uiDesigner.xml
new file mode 100644
index 00000000..2b63946d
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/players.ser b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/players.ser
new file mode 100644
index 00000000..c9de9bab
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/players.ser differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/pom.xml b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/pom.xml
new file mode 100644
index 00000000..fc95f9db
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/pom.xml
@@ -0,0 +1,24 @@
+
+
+ 4.0.0
+
+ org.example
+ CT326-Assignment3
+ 1.0-SNAPSHOT
+
+
+ 17
+ 17
+ UTF-8
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ 5.10.0
+
+
+
+
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/src/main/java/Achievement.java b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/src/main/java/Achievement.java
new file mode 100644
index 00000000..98944216
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/src/main/java/Achievement.java
@@ -0,0 +1,81 @@
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.time.LocalDate;
+
+/**
+ * class representing a player's achievement
+ */
+public class Achievement {
+ private String achievementName;
+ private String description;
+ private LocalDate dateOfAward;
+
+ /**
+ * constructor for the Achievement class
+ * @param achievementName a String representation of the name of the Achievement
+ * @param description a String describing the Achievement
+ * @param dateOfAward a LocalDate representing the date that the Achievement was awarded
+ */
+ public Achievement(String achievementName, String description, LocalDate dateOfAward) {
+ this.achievementName = achievementName;
+ this.description = description;
+ this.dateOfAward = dateOfAward;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof Achievement) {
+ Achievement toCompare = (Achievement) obj;
+
+ if (!achievementName.equals(toCompare.achievementName)) {
+ return false;
+ }
+ if (!description.equals(toCompare.description)) {
+ return false;
+ }
+ if (!dateOfAward.equals(toCompare.dateOfAward)) {
+ return false;
+ }
+
+ return true;
+ }
+ else { return false; }
+ }
+
+ /**
+ * getter method for the achievementName field
+ * @return a String representation of the name of the Achievement
+ */
+ public String getAchievementName() { return achievementName; }
+
+ /**
+ * setter method for the achievementName field
+ * @param achievementName a String representation of the name of the Achievement
+ */
+ public void setAchievementName(String achievementName) { this.achievementName = achievementName; }
+
+ /**
+ * getter method for the description field
+ * @return a String describing the Achievement
+ */
+ public String getDescription() { return description; }
+
+ /**
+ * setter method for the description field
+ * @param description a String describing the Achievement
+ */
+ public void setDescription(String description) { this.description = description; }
+
+ /**
+ * getter method for the dateOfAward field
+ * @return a LocalDate representing the date that the Achievement was awarded
+ */
+ public LocalDate getDateOfAward() { return dateOfAward; }
+
+ /**
+ * setter method for the dateOfAward field
+ * @param dateOfAward a LocalDate representing the date that the Achievement was awarded
+ */
+ public void setDateOfAward(LocalDate dateOfAward) { this.dateOfAward = dateOfAward; }
+}
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/src/main/java/Country.java b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/src/main/java/Country.java
new file mode 100644
index 00000000..3660b127
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/src/main/java/Country.java
@@ -0,0 +1,260 @@
+/**
+ * enum for each ISO 3166 Alpha-2 country Code
+ */
+public enum Country {
+ // Explanation of how this data was sourced:
+ // the following ISO 3166 Alpha-2 Codes were taken from the CSV file found here: https://pkgstore.datahub.io/core/country-list/data_csv/data/d7c9d7cfb42cb69f4422dec222dbbaa8/data_csv.csv
+ // the CSV file was cleaned to have UNIX line endings (as it had Windows line endings, and I am on GNU/Linux) with the command `tr -d '\r' < data_csv.csv > clean_data.csv `
+ // they were then parsed & read into this Java source file with the Vim / GNU AWK command `:read !awk -F',' '{gsub(/\"/, ""); print $NF ",\t// " $1}' clean_data.csv`
+ // finally, the block was indented in Vim and a `;` appended to the last value
+
+ AF, // Afghanistan
+ AX, // Ã…land Islands
+ AL, // Albania
+ DZ, // Algeria
+ AS, // American Samoa
+ AD, // Andorra
+ AO, // Angola
+ AI, // Anguilla
+ AQ, // Antarctica
+ AG, // Antigua and Barbuda
+ AR, // Argentina
+ AM, // Armenia
+ AW, // Aruba
+ AU, // Australia
+ AT, // Austria
+ AZ, // Azerbaijan
+ BS, // Bahamas
+ BH, // Bahrain
+ BD, // Bangladesh
+ BB, // Barbados
+ BY, // Belarus
+ BE, // Belgium
+ BZ, // Belize
+ BJ, // Benin
+ BM, // Bermuda
+ BT, // Bhutan
+ BO, // Bolivia
+ BQ, // Bonaire
+ BA, // Bosnia and Herzegovina
+ BW, // Botswana
+ BV, // Bouvet Island
+ BR, // Brazil
+ IO, // British Indian Ocean Territory
+ BN, // Brunei Darussalam
+ BG, // Bulgaria
+ BF, // Burkina Faso
+ BI, // Burundi
+ KH, // Cambodia
+ CM, // Cameroon
+ CA, // Canada
+ CV, // Cape Verde
+ KY, // Cayman Islands
+ CF, // Central African Republic
+ TD, // Chad
+ CL, // Chile
+ CN, // China
+ CX, // Christmas Island
+ CC, // Cocos (Keeling) Islands
+ CO, // Colombia
+ KM, // Comoros
+ CG, // Congo
+ CD, // Congo
+ CK, // Cook Islands
+ CR, // Costa Rica
+ CI, // Côte d'Ivoire
+ HR, // Croatia
+ CU, // Cuba
+ CW, // Curaçao
+ CY, // Cyprus
+ CZ, // Czech Republic
+ DK, // Denmark
+ DJ, // Djibouti
+ DM, // Dominica
+ DO, // Dominican Republic
+ EC, // Ecuador
+ EG, // Egypt
+ SV, // El Salvador
+ GQ, // Equatorial Guinea
+ ER, // Eritrea
+ EE, // Estonia
+ ET, // Ethiopia
+ FK, // Falkland Islands (Malvinas)
+ FO, // Faroe Islands
+ FJ, // Fiji
+ FI, // Finland
+ FR, // France
+ GF, // French Guiana
+ PF, // French Polynesia
+ TF, // French Southern Territories
+ GA, // Gabon
+ GM, // Gambia
+ GE, // Georgia
+ DE, // Germany
+ GH, // Ghana
+ GI, // Gibraltar
+ GR, // Greece
+ GL, // Greenland
+ GD, // Grenada
+ GP, // Guadeloupe
+ GU, // Guam
+ GT, // Guatemala
+ GG, // Guernsey
+ GN, // Guinea
+ GW, // Guinea-Bissau
+ GY, // Guyana
+ HT, // Haiti
+ HM, // Heard Island and McDonald Islands
+ VA, // Holy See (Vatican City State)
+ HN, // Honduras
+ HK, // Hong Kong
+ HU, // Hungary
+ IS, // Iceland
+ IN, // India
+ ID, // Indonesia
+ IR, // Iran
+ IQ, // Iraq
+ IE, // Ireland
+ IM, // Isle of Man
+ IL, // Israel
+ IT, // Italy
+ JM, // Jamaica
+ JP, // Japan
+ JE, // Jersey
+ JO, // Jordan
+ KZ, // Kazakhstan
+ KE, // Kenya
+ KI, // Kiribati
+ KP, // Korea
+ KR, // Korea
+ KW, // Kuwait
+ KG, // Kyrgyzstan
+ LA, // Lao People's Democratic Republic
+ LV, // Latvia
+ LB, // Lebanon
+ LS, // Lesotho
+ LR, // Liberia
+ LY, // Libya
+ LI, // Liechtenstein
+ LT, // Lithuania
+ LU, // Luxembourg
+ MO, // Macao
+ MK, // Macedonia
+ MG, // Madagascar
+ MW, // Malawi
+ MY, // Malaysia
+ MV, // Maldives
+ ML, // Mali
+ MT, // Malta
+ MH, // Marshall Islands
+ MQ, // Martinique
+ MR, // Mauritania
+ MU, // Mauritius
+ YT, // Mayotte
+ MX, // Mexico
+ FM, // Micronesia
+ MD, // Moldova
+ MC, // Monaco
+ MN, // Mongolia
+ ME, // Montenegro
+ MS, // Montserrat
+ MA, // Morocco
+ MZ, // Mozambique
+ MM, // Myanmar
+ NA, // Namibia
+ NR, // Nauru
+ NP, // Nepal
+ NL, // Netherlands
+ NC, // New Caledonia
+ NZ, // New Zealand
+ NI, // Nicaragua
+ NE, // Niger
+ NG, // Nigeria
+ NU, // Niue
+ NF, // Norfolk Island
+ MP, // Northern Mariana Islands
+ NO, // Norway
+ OM, // Oman
+ PK, // Pakistan
+ PW, // Palau
+ PS, // Palestine
+ PA, // Panama
+ PG, // Papua New Guinea
+ PY, // Paraguay
+ PE, // Peru
+ PH, // Philippines
+ PN, // Pitcairn
+ PL, // Poland
+ PT, // Portugal
+ PR, // Puerto Rico
+ QA, // Qatar
+ RE, // Réunion
+ RO, // Romania
+ RU, // Russian Federation
+ RW, // Rwanda
+ BL, // Saint Barthélemy
+ SH, // Saint Helena
+ KN, // Saint Kitts and Nevis
+ LC, // Saint Lucia
+ MF, // Saint Martin (French part)
+ PM, // Saint Pierre and Miquelon
+ VC, // Saint Vincent and the Grenadines
+ WS, // Samoa
+ SM, // San Marino
+ ST, // Sao Tome and Principe
+ SA, // Saudi Arabia
+ SN, // Senegal
+ RS, // Serbia
+ SC, // Seychelles
+ SL, // Sierra Leone
+ SG, // Singapore
+ SX, // Sint Maarten (Dutch part)
+ SK, // Slovakia
+ SI, // Slovenia
+ SB, // Solomon Islands
+ SO, // Somalia
+ ZA, // South Africa
+ GS, // South Georgia and the South Sandwich Islands
+ SS, // South Sudan
+ ES, // Spain
+ LK, // Sri Lanka
+ SD, // Sudan
+ SR, // Suriname
+ SJ, // Svalbard and Jan Mayen
+ SZ, // Swaziland
+ SE, // Sweden
+ CH, // Switzerland
+ SY, // Syrian Arab Republic
+ TW, // Taiwan
+ TJ, // Tajikistan
+ TZ, // Tanzania
+ TH, // Thailand
+ TL, // Timor-Leste
+ TG, // Togo
+ TK, // Tokelau
+ TO, // Tonga
+ TT, // Trinidad and Tobago
+ TN, // Tunisia
+ TR, // Turkey
+ TM, // Turkmenistan
+ TC, // Turks and Caicos Islands
+ TV, // Tuvalu
+ UG, // Uganda
+ UA, // Ukraine
+ AE, // United Arab Emirates
+ GB, // United Kingdom
+ US, // United States
+ UM, // United States Minor Outlying Islands
+ UY, // Uruguay
+ UZ, // Uzbekistan
+ VU, // Vanuatu
+ VE, // Venezuela
+ VN, // Viet Nam
+ VG, // Virgin Islands
+ VI, // Virgin Islands
+ WF, // Wallis and Futuna
+ EH, // Western Sahara
+ YE, // Yemen
+ ZM, // Zambia
+ ZW; // Zimbabwe
+}
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/src/main/java/Player.java b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/src/main/java/Player.java
new file mode 100644
index 00000000..e734d5ca
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/src/main/java/Player.java
@@ -0,0 +1,184 @@
+import java.io.*;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * class to represent a player
+ */
+public class Player implements Serializable {
+ private String id;
+ private String username;
+ private Country country;
+ private LocalDate joinDate;
+ private List achievements;
+ private static final String serializeAchievementsTo = "achievements.csv";
+
+ /**
+ * constructor for the Player class
+ * @param id a String representing the player's ID
+ * @param username a String representing the player's username
+ * @param country a Country object representing the country to which the player belongs
+ * @param joinDate a LocalDate object representing the date that the player joined the team
+ * @param achievements a List of Achievement objects awarded to the player
+ */
+ public Player(String id, String username, Country country, LocalDate joinDate, List achievements) {
+ this.id = id;
+ this.username = username;
+ this.country = country;
+ this.joinDate = joinDate;
+ this.achievements = achievements;
+ }
+
+ /**
+ * overridden method to compare two objects for equality
+ * @param obj the object to be compared
+ * @return boolean - true if the objects have all the same fields equals, false otherwise
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof Player) {
+ Player toCompare = (Player) obj;
+
+ if (!id.equals(toCompare.id)) {
+ return false;
+ }
+ if (!username.equals(toCompare.username)) {
+ return false;
+ }
+ if (!country.equals(toCompare.country)) {
+ return false;
+ }
+ if (!joinDate.equals(toCompare.joinDate)) {
+ return false;
+ }
+ if (!achievements.equals(toCompare.achievements)) {
+ return false;
+ } // note that if the lists are in different orders, this will return false
+
+ return true;
+ }
+ else { return false; }
+ }
+
+ /**
+ * method to deserialize the Player object and to read in its achievements from a CSV file
+ * @param out ObjectOutputStream
+ * @throws IOException
+ */
+ @Serial
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ // would be inappropriate to catch IOExceptions here - should be caught in the code attempting to serialize the object
+ out.writeObject(id);
+ out.writeObject(username);
+ out.writeObject(country);
+ out.writeObject(joinDate);
+
+ // deliberate design choice here to not use the writeObject method of the Achievement class
+ // serializing Achievements in the context of a Player's list of Achievements should be treated differently to serializing, say, a single, isolated Achievement
+ // there may be times when we want to serialize an Achievement without reference to a Player, without a CSV file
+
+ // writing out Achievements to CSV file
+ FileWriter writer = new FileWriter(serializeAchievementsTo, true); // append set to true
+ for (Achievement achievement : achievements) {
+ writer.write(id + "," + achievement.getAchievementName() + "," + achievement.getDescription() + "," + achievement.getDateOfAward().toString() + "\n");
+ }
+ writer.close();
+ }
+
+ /**
+ * method to serialize the Player object and to write out its achievements to a CSV file
+ * @param in ObjectInputStream
+ * @throws IOException
+ * @throws ClassNotFoundException
+ */
+ @Serial
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ // would be inappropriate to catch exceptions here - should be caught in the code attempting to de-serialize the object
+ id = (String) in.readObject();
+ username = (String) in.readObject();
+ country = (Country) in.readObject();
+ joinDate = (LocalDate) in.readObject();
+
+ achievements = new ArrayList<>();
+
+ FileReader fileReader = new FileReader(serializeAchievementsTo);
+ BufferedReader bufferedReader = new BufferedReader(fileReader);
+
+ String line;
+ while ((line = bufferedReader.readLine()) != null) {
+ String[] cols = line.split(",");
+
+ // only adding to list of achievements if the player ids match
+ if (cols[0].equals(id)) {
+ achievements.add(new Achievement(cols[1], cols[2], LocalDate.parse(cols[3], DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
+ }
+ }
+ bufferedReader.close();
+
+ }
+
+
+ /**
+ * getter method for the ID field
+ * @return a String representing the player's ID
+ */
+ public String getId() { return id; }
+
+ /**
+ * setter method for the id field
+ * @param id String representing the player's ID
+ */
+ public void setId(String id) { this.id = id; }
+
+
+ /**
+ * getter method for the username field
+ * @return a String representing the player's username
+ */
+ public String getUsername() { return username; }
+
+ /**
+ * setter method for the username field
+ * @param username String representing the player's username
+ */
+ public void setUsername(String username) { this.username = username; }
+
+ /**
+ * getter method for the country field
+ * @return a Country object
+ */
+ public Country getCountry() { return country; }
+
+ /**
+ * setter method for the country field
+ * @param country a Country object
+ */
+ public void setCountry(Country country) { this.country = country; }
+
+ /**
+ * getter method for the joinDate field
+ * @return a LocalDate representing the date when the player joined the team
+ */
+ public LocalDate getJoinDate() { return joinDate; }
+
+ /**
+ * setter method for the joinDate field
+ * @param joinDate LocalDate representing the date when the player joined the team
+ */
+ public void setJoinDate(LocalDate joinDate) { this.joinDate = joinDate; }
+
+ /**
+ * getter method for the achievements field
+ * @return a list of Achievement objects
+ */
+ public List getAchievements() { return achievements; }
+
+ /**
+ * setter method for the achievements field
+ * @param achievements a list of Achievement objects
+ */
+ public void setAchievements(List achievements) { this.achievements = achievements; }
+}
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/src/test/java/TestSerialization.java b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/src/test/java/TestSerialization.java
new file mode 100644
index 00000000..86d446a5
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment3/CT326-Assignment3/src/test/java/TestSerialization.java
@@ -0,0 +1,155 @@
+import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.*;
+import java.io.*;
+import java.time.LocalDate;
+import java.util.ArrayList;
+
+/**
+ * JUnit tests to test the serialization ability of the Player class
+ */
+public class TestSerialization {
+ // assuming that the instruction "Use a test-driven development approach to implement the serialization of Player objects" only applies to the serialization, and not the other functionality
+
+ /**
+ * method that runs after each test and deletes the achievements.csv and players.ser files
+ */
+ @AfterEach
+ void deleteFiles() {
+ File achievementsFile = new File("achievements.csv");
+ achievementsFile.delete();
+
+ File playersFile = new File("player.ser");
+ playersFile.delete();
+ }
+
+
+ /**
+ * test that creates 5 player objects, serializes them, and compares them to the deserialized objects
+ * @throws IOException
+ * @throws ClassNotFoundException
+ */
+ @Test
+ void serializeFivePlayers() throws IOException, ClassNotFoundException {
+ // deliberately not catching potential IOExceptions - we want the tests to fail if these are thrown
+ FileOutputStream players_file = new FileOutputStream("players.ser");
+ ObjectOutputStream players_out = new ObjectOutputStream(players_file);
+ ObjectInputStream players_in = new ObjectInputStream(new FileInputStream("players.ser"));
+
+ ArrayList players = new ArrayList<>(); // array of players to be serialized
+
+ // creating some unique players
+ // player 0
+ players.add(new Player("0", "player0", Country.IE, LocalDate.now(),
+ new ArrayList<>() {{
+ add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6)));
+ }}
+ ));
+
+ // player 1
+ players.add(new Player("1", "player1", Country.JP, LocalDate.now(),
+ new ArrayList<>() {{
+ add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6)));
+ add(new Achievement("Another Award", "An award for something else", LocalDate.of(1996, 7, 6)));
+ }}
+ ));
+
+ // player 2
+ players.add(new Player("2", "player2", Country.UA, LocalDate.now(),
+ new ArrayList<>() {{
+ add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6)));
+ add(new Achievement("Another Award", "An award for something else", LocalDate.of(1996, 7, 6)));
+ add(new Achievement("Yet Another Award", "An award for something else entirely", LocalDate.of(2023, 8, 6)));
+ }}
+ ));
+
+ // player 3
+ players.add(new Player("3", "player3", Country.AD, LocalDate.now(),
+ new ArrayList<>() {{
+ add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6)));
+ add(new Achievement("Another Award", "An award for something else", LocalDate.of(1996, 7, 6)));
+ add(new Achievement("Yet Another Award", "An award for something else entirely", LocalDate.of(2023, 8, 6)));
+ add(new Achievement("A fourth award", "An award that comes after three previous awards", LocalDate.of(2022, 8, 3)));
+ }}
+ ));
+
+ // player 4
+ players.add(new Player("4", "player4", Country.DE, LocalDate.now(),
+ new ArrayList<>() {{
+ add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6)));
+ add(new Achievement("Another Award", "An award for something else", LocalDate.of(1996, 7, 6)));
+ add(new Achievement("Yet Another Award", "An award for something else entirely", LocalDate.of(2023, 8, 6)));
+ add(new Achievement("A fourth award", "An award that comes after three previous awards", LocalDate.of(2022, 8, 3)));
+ add(new Achievement("The final award", "The last award anyone will ever get", LocalDate.of(2030, 12, 25)));
+ }}
+ ));
+
+ for (Player player : players) {
+ players_out.writeObject(player);
+ }
+
+ // looping over each player and comparing it to the de-serialized player
+ // doing this in a separate loop to separate writing and reading
+ for (Player player : players) {
+ // deliberately not catching exceptions here - we want the test to fail if exceptions are thrown
+ Player dplayer = (Player) players_in.readObject();
+ assertEquals(player, dplayer);
+ }
+
+ players_out.close();
+ players_file.close();
+ }
+
+ /**
+ * test the equals() method of the Player class
+ */
+ @Test
+ void testPlayerDotEquals() {
+ // creating two identical players
+ Player player1 = new Player("0", "player0", Country.IE, LocalDate.now(),
+ new ArrayList<>(){{ add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6))); }}
+ );
+ Player player2 = new Player("0", "player0", Country.IE, LocalDate.now(),
+ new ArrayList<>(){{ add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6))); }}
+ );
+
+ // assertEquals uses the objects equals() method, so it suffices for this test
+ assertEquals(player1, player2);
+ }
+
+ /**
+ * test the equals() method of the Achievement class
+ */
+ @Test
+ void testAchievementDotEquals() {
+ Achievement achievement1 = new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6));
+ Achievement achievement2 = new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6));
+
+ assertEquals(achievement1, achievement2);
+ }
+
+ /**
+ * test serializing & de-serializing just one player
+ * @throws IOException
+ * @throws ClassNotFoundException
+ */
+ @Test
+ void testSerializePlayer() throws IOException, ClassNotFoundException {
+ // deliberately not catching potential IOExceptions - we want the tests to fail if these are thrown
+ FileOutputStream players_file = new FileOutputStream("players.ser");
+ ObjectOutputStream players_out = new ObjectOutputStream(players_file);
+ ObjectInputStream players_in = new ObjectInputStream(new FileInputStream("players.ser"));
+
+ Player player = new Player("0", "player0", Country.IE, LocalDate.now(),
+ new ArrayList<>(){{ add(new Achievement("Something Award", "An award for something that was especially something", LocalDate.of(2004, 7, 6))); }}
+ );
+
+ // serializing player object, de-serializing it, and comparing them
+ players_out.writeObject(player);
+ Player dplayer = (Player) players_in.readObject();
+ players_out.close();
+ players_file.close();
+
+ assertEquals(player, dplayer);
+ }
+}
+
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/assignment3_Andrew_Hayes.zip b/third/semester1/CT326_Programming_III/assignments/assignment3/assignment3_Andrew_Hayes.zip
new file mode 100644
index 00000000..e40d79fb
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment3/assignment3_Andrew_Hayes.zip differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/clean_data.csv b/third/semester1/CT326_Programming_III/assignments/assignment3/clean_data.csv
new file mode 100644
index 00000000..47881c60
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment3/clean_data.csv
@@ -0,0 +1,250 @@
+Name,Code
+Afghanistan,AF
+Ã…land Islands,AX
+Albania,AL
+Algeria,DZ
+American Samoa,AS
+Andorra,AD
+Angola,AO
+Anguilla,AI
+Antarctica,AQ
+Antigua and Barbuda,AG
+Argentina,AR
+Armenia,AM
+Aruba,AW
+Australia,AU
+Austria,AT
+Azerbaijan,AZ
+Bahamas,BS
+Bahrain,BH
+Bangladesh,BD
+Barbados,BB
+Belarus,BY
+Belgium,BE
+Belize,BZ
+Benin,BJ
+Bermuda,BM
+Bhutan,BT
+"Bolivia, Plurinational State of",BO
+"Bonaire, Sint Eustatius and Saba",BQ
+Bosnia and Herzegovina,BA
+Botswana,BW
+Bouvet Island,BV
+Brazil,BR
+British Indian Ocean Territory,IO
+Brunei Darussalam,BN
+Bulgaria,BG
+Burkina Faso,BF
+Burundi,BI
+Cambodia,KH
+Cameroon,CM
+Canada,CA
+Cape Verde,CV
+Cayman Islands,KY
+Central African Republic,CF
+Chad,TD
+Chile,CL
+China,CN
+Christmas Island,CX
+Cocos (Keeling) Islands,CC
+Colombia,CO
+Comoros,KM
+Congo,CG
+"Congo, the Democratic Republic of the",CD
+Cook Islands,CK
+Costa Rica,CR
+Côte d'Ivoire,CI
+Croatia,HR
+Cuba,CU
+Curaçao,CW
+Cyprus,CY
+Czech Republic,CZ
+Denmark,DK
+Djibouti,DJ
+Dominica,DM
+Dominican Republic,DO
+Ecuador,EC
+Egypt,EG
+El Salvador,SV
+Equatorial Guinea,GQ
+Eritrea,ER
+Estonia,EE
+Ethiopia,ET
+Falkland Islands (Malvinas),FK
+Faroe Islands,FO
+Fiji,FJ
+Finland,FI
+France,FR
+French Guiana,GF
+French Polynesia,PF
+French Southern Territories,TF
+Gabon,GA
+Gambia,GM
+Georgia,GE
+Germany,DE
+Ghana,GH
+Gibraltar,GI
+Greece,GR
+Greenland,GL
+Grenada,GD
+Guadeloupe,GP
+Guam,GU
+Guatemala,GT
+Guernsey,GG
+Guinea,GN
+Guinea-Bissau,GW
+Guyana,GY
+Haiti,HT
+Heard Island and McDonald Islands,HM
+Holy See (Vatican City State),VA
+Honduras,HN
+Hong Kong,HK
+Hungary,HU
+Iceland,IS
+India,IN
+Indonesia,ID
+"Iran, Islamic Republic of",IR
+Iraq,IQ
+Ireland,IE
+Isle of Man,IM
+Israel,IL
+Italy,IT
+Jamaica,JM
+Japan,JP
+Jersey,JE
+Jordan,JO
+Kazakhstan,KZ
+Kenya,KE
+Kiribati,KI
+"Korea, Democratic People's Republic of",KP
+"Korea, Republic of",KR
+Kuwait,KW
+Kyrgyzstan,KG
+Lao People's Democratic Republic,LA
+Latvia,LV
+Lebanon,LB
+Lesotho,LS
+Liberia,LR
+Libya,LY
+Liechtenstein,LI
+Lithuania,LT
+Luxembourg,LU
+Macao,MO
+"Macedonia, the Former Yugoslav Republic of",MK
+Madagascar,MG
+Malawi,MW
+Malaysia,MY
+Maldives,MV
+Mali,ML
+Malta,MT
+Marshall Islands,MH
+Martinique,MQ
+Mauritania,MR
+Mauritius,MU
+Mayotte,YT
+Mexico,MX
+"Micronesia, Federated States of",FM
+"Moldova, Republic of",MD
+Monaco,MC
+Mongolia,MN
+Montenegro,ME
+Montserrat,MS
+Morocco,MA
+Mozambique,MZ
+Myanmar,MM
+Namibia,NA
+Nauru,NR
+Nepal,NP
+Netherlands,NL
+New Caledonia,NC
+New Zealand,NZ
+Nicaragua,NI
+Niger,NE
+Nigeria,NG
+Niue,NU
+Norfolk Island,NF
+Northern Mariana Islands,MP
+Norway,NO
+Oman,OM
+Pakistan,PK
+Palau,PW
+"Palestine, State of",PS
+Panama,PA
+Papua New Guinea,PG
+Paraguay,PY
+Peru,PE
+Philippines,PH
+Pitcairn,PN
+Poland,PL
+Portugal,PT
+Puerto Rico,PR
+Qatar,QA
+Réunion,RE
+Romania,RO
+Russian Federation,RU
+Rwanda,RW
+Saint Barthélemy,BL
+"Saint Helena, Ascension and Tristan da Cunha",SH
+Saint Kitts and Nevis,KN
+Saint Lucia,LC
+Saint Martin (French part),MF
+Saint Pierre and Miquelon,PM
+Saint Vincent and the Grenadines,VC
+Samoa,WS
+San Marino,SM
+Sao Tome and Principe,ST
+Saudi Arabia,SA
+Senegal,SN
+Serbia,RS
+Seychelles,SC
+Sierra Leone,SL
+Singapore,SG
+Sint Maarten (Dutch part),SX
+Slovakia,SK
+Slovenia,SI
+Solomon Islands,SB
+Somalia,SO
+South Africa,ZA
+South Georgia and the South Sandwich Islands,GS
+South Sudan,SS
+Spain,ES
+Sri Lanka,LK
+Sudan,SD
+Suriname,SR
+Svalbard and Jan Mayen,SJ
+Swaziland,SZ
+Sweden,SE
+Switzerland,CH
+Syrian Arab Republic,SY
+"Taiwan, Province of China",TW
+Tajikistan,TJ
+"Tanzania, United Republic of",TZ
+Thailand,TH
+Timor-Leste,TL
+Togo,TG
+Tokelau,TK
+Tonga,TO
+Trinidad and Tobago,TT
+Tunisia,TN
+Turkey,TR
+Turkmenistan,TM
+Turks and Caicos Islands,TC
+Tuvalu,TV
+Uganda,UG
+Ukraine,UA
+United Arab Emirates,AE
+United Kingdom,GB
+United States,US
+United States Minor Outlying Islands,UM
+Uruguay,UY
+Uzbekistan,UZ
+Vanuatu,VU
+"Venezuela, Bolivarian Republic of",VE
+Viet Nam,VN
+"Virgin Islands, British",VG
+"Virgin Islands, U.S.",VI
+Wallis and Futuna,WF
+Western Sahara,EH
+Yemen,YE
+Zambia,ZM
+Zimbabwe,ZW
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment3/data_csv.csv b/third/semester1/CT326_Programming_III/assignments/assignment3/data_csv.csv
new file mode 100644
index 00000000..16c718a3
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment3/data_csv.csv
@@ -0,0 +1,250 @@
+Name,Code
+Afghanistan,AF
+Ã…land Islands,AX
+Albania,AL
+Algeria,DZ
+American Samoa,AS
+Andorra,AD
+Angola,AO
+Anguilla,AI
+Antarctica,AQ
+Antigua and Barbuda,AG
+Argentina,AR
+Armenia,AM
+Aruba,AW
+Australia,AU
+Austria,AT
+Azerbaijan,AZ
+Bahamas,BS
+Bahrain,BH
+Bangladesh,BD
+Barbados,BB
+Belarus,BY
+Belgium,BE
+Belize,BZ
+Benin,BJ
+Bermuda,BM
+Bhutan,BT
+"Bolivia, Plurinational State of",BO
+"Bonaire, Sint Eustatius and Saba",BQ
+Bosnia and Herzegovina,BA
+Botswana,BW
+Bouvet Island,BV
+Brazil,BR
+British Indian Ocean Territory,IO
+Brunei Darussalam,BN
+Bulgaria,BG
+Burkina Faso,BF
+Burundi,BI
+Cambodia,KH
+Cameroon,CM
+Canada,CA
+Cape Verde,CV
+Cayman Islands,KY
+Central African Republic,CF
+Chad,TD
+Chile,CL
+China,CN
+Christmas Island,CX
+Cocos (Keeling) Islands,CC
+Colombia,CO
+Comoros,KM
+Congo,CG
+"Congo, the Democratic Republic of the",CD
+Cook Islands,CK
+Costa Rica,CR
+Côte d'Ivoire,CI
+Croatia,HR
+Cuba,CU
+Curaçao,CW
+Cyprus,CY
+Czech Republic,CZ
+Denmark,DK
+Djibouti,DJ
+Dominica,DM
+Dominican Republic,DO
+Ecuador,EC
+Egypt,EG
+El Salvador,SV
+Equatorial Guinea,GQ
+Eritrea,ER
+Estonia,EE
+Ethiopia,ET
+Falkland Islands (Malvinas),FK
+Faroe Islands,FO
+Fiji,FJ
+Finland,FI
+France,FR
+French Guiana,GF
+French Polynesia,PF
+French Southern Territories,TF
+Gabon,GA
+Gambia,GM
+Georgia,GE
+Germany,DE
+Ghana,GH
+Gibraltar,GI
+Greece,GR
+Greenland,GL
+Grenada,GD
+Guadeloupe,GP
+Guam,GU
+Guatemala,GT
+Guernsey,GG
+Guinea,GN
+Guinea-Bissau,GW
+Guyana,GY
+Haiti,HT
+Heard Island and McDonald Islands,HM
+Holy See (Vatican City State),VA
+Honduras,HN
+Hong Kong,HK
+Hungary,HU
+Iceland,IS
+India,IN
+Indonesia,ID
+"Iran, Islamic Republic of",IR
+Iraq,IQ
+Ireland,IE
+Isle of Man,IM
+Israel,IL
+Italy,IT
+Jamaica,JM
+Japan,JP
+Jersey,JE
+Jordan,JO
+Kazakhstan,KZ
+Kenya,KE
+Kiribati,KI
+"Korea, Democratic People's Republic of",KP
+"Korea, Republic of",KR
+Kuwait,KW
+Kyrgyzstan,KG
+Lao People's Democratic Republic,LA
+Latvia,LV
+Lebanon,LB
+Lesotho,LS
+Liberia,LR
+Libya,LY
+Liechtenstein,LI
+Lithuania,LT
+Luxembourg,LU
+Macao,MO
+"Macedonia, the Former Yugoslav Republic of",MK
+Madagascar,MG
+Malawi,MW
+Malaysia,MY
+Maldives,MV
+Mali,ML
+Malta,MT
+Marshall Islands,MH
+Martinique,MQ
+Mauritania,MR
+Mauritius,MU
+Mayotte,YT
+Mexico,MX
+"Micronesia, Federated States of",FM
+"Moldova, Republic of",MD
+Monaco,MC
+Mongolia,MN
+Montenegro,ME
+Montserrat,MS
+Morocco,MA
+Mozambique,MZ
+Myanmar,MM
+Namibia,NA
+Nauru,NR
+Nepal,NP
+Netherlands,NL
+New Caledonia,NC
+New Zealand,NZ
+Nicaragua,NI
+Niger,NE
+Nigeria,NG
+Niue,NU
+Norfolk Island,NF
+Northern Mariana Islands,MP
+Norway,NO
+Oman,OM
+Pakistan,PK
+Palau,PW
+"Palestine, State of",PS
+Panama,PA
+Papua New Guinea,PG
+Paraguay,PY
+Peru,PE
+Philippines,PH
+Pitcairn,PN
+Poland,PL
+Portugal,PT
+Puerto Rico,PR
+Qatar,QA
+Réunion,RE
+Romania,RO
+Russian Federation,RU
+Rwanda,RW
+Saint Barthélemy,BL
+"Saint Helena, Ascension and Tristan da Cunha",SH
+Saint Kitts and Nevis,KN
+Saint Lucia,LC
+Saint Martin (French part),MF
+Saint Pierre and Miquelon,PM
+Saint Vincent and the Grenadines,VC
+Samoa,WS
+San Marino,SM
+Sao Tome and Principe,ST
+Saudi Arabia,SA
+Senegal,SN
+Serbia,RS
+Seychelles,SC
+Sierra Leone,SL
+Singapore,SG
+Sint Maarten (Dutch part),SX
+Slovakia,SK
+Slovenia,SI
+Solomon Islands,SB
+Somalia,SO
+South Africa,ZA
+South Georgia and the South Sandwich Islands,GS
+South Sudan,SS
+Spain,ES
+Sri Lanka,LK
+Sudan,SD
+Suriname,SR
+Svalbard and Jan Mayen,SJ
+Swaziland,SZ
+Sweden,SE
+Switzerland,CH
+Syrian Arab Republic,SY
+"Taiwan, Province of China",TW
+Tajikistan,TJ
+"Tanzania, United Republic of",TZ
+Thailand,TH
+Timor-Leste,TL
+Togo,TG
+Tokelau,TK
+Tonga,TO
+Trinidad and Tobago,TT
+Tunisia,TN
+Turkey,TR
+Turkmenistan,TM
+Turks and Caicos Islands,TC
+Tuvalu,TV
+Uganda,UG
+Ukraine,UA
+United Arab Emirates,AE
+United Kingdom,GB
+United States,US
+United States Minor Outlying Islands,UM
+Uruguay,UY
+Uzbekistan,UZ
+Vanuatu,VU
+"Venezuela, Bolivarian Republic of",VE
+Viet Nam,VN
+"Virgin Islands, British",VG
+"Virgin Islands, U.S.",VI
+Wallis and Futuna,WF
+Western Sahara,EH
+Yemen,YE
+Zambia,ZM
+Zimbabwe,ZW
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/CT326 - Assignment 4-1.pdf b/third/semester1/CT326_Programming_III/assignments/assignment4/CT326 - Assignment 4-1.pdf
new file mode 100644
index 00000000..0bce2e09
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment4/CT326 - Assignment 4-1.pdf differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/.gitignore b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/.gitignore
new file mode 100644
index 00000000..5ff6309b
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/.gitignore
@@ -0,0 +1,38 @@
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/.idea/.gitignore b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/.idea/.gitignore
new file mode 100644
index 00000000..26d33521
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/.idea/encodings.xml b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/.idea/encodings.xml
new file mode 100644
index 00000000..aa00ffab
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/.idea/encodings.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/.idea/misc.xml b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/.idea/misc.xml
new file mode 100644
index 00000000..82dbec8a
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/library_view_screenshot.png b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/library_view_screenshot.png
new file mode 100644
index 00000000..a69b6d1f
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/library_view_screenshot.png differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/pom.xml b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/pom.xml
new file mode 100644
index 00000000..b720bd8b
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/pom.xml
@@ -0,0 +1,17 @@
+
+
+ 4.0.0
+
+ org.example
+ assignment4
+ 1.0-SNAPSHOT
+
+
+ 17
+ 17
+ UTF-8
+
+
+
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/Beatles_-_Abbey_Road.jpg b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/Beatles_-_Abbey_Road.jpg
new file mode 100644
index 00000000..1b066450
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/Beatles_-_Abbey_Road.jpg differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/Damien_Dempsey_-_Seize_the_Day.jpg b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/Damien_Dempsey_-_Seize_the_Day.jpg
new file mode 100644
index 00000000..49b611c8
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/Damien_Dempsey_-_Seize_the_Day.jpg differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/Katebushneverforever.png b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/Katebushneverforever.png
new file mode 100644
index 00000000..19f2d535
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/Katebushneverforever.png differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/Razorblade_suitcase.jpg b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/Razorblade_suitcase.jpg
new file mode 100644
index 00000000..643e93f6
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/Razorblade_suitcase.jpg differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/polyphia_new_levels_new_devils.jpeg b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/polyphia_new_levels_new_devils.jpeg
new file mode 100644
index 00000000..812e2a2c
Binary files /dev/null and b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/covers/polyphia_new_levels_new_devils.jpeg differ
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/bush_razorblade_suitcase.txt b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/bush_razorblade_suitcase.txt
new file mode 100644
index 00000000..47e31219
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/bush_razorblade_suitcase.txt
@@ -0,0 +1,13 @@
+1., "Personal Holloway", 3:23
+2., "Greedy Fly", 4:30
+3., "Swallowed", 4:51
+4., "Insect Kin", 4:27
+5., "Cold Contagious", 6:00
+6., "A Tendency to Start Fires", 4:04
+7., "Mouth", 5:45
+8., "Straight No Chaser", 4:02
+9., "History", 4:17
+10., "Synapse", 4:52
+11., "Communicator", 4:25
+12., "Bonedriven", 4:32
+13., "Distant Voices", 6:39
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/damien_dempsey_seize_the_day.txt b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/damien_dempsey_seize_the_day.txt
new file mode 100644
index 00000000..d442d9db
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/damien_dempsey_seize_the_day.txt
@@ -0,0 +1,11 @@
+1., "Negative Vibes", 4:44
+2., "Ghosts of Overdoses", 4:41
+3., "It's All Good", 4:21
+4., "Factories", 5:17
+5., "Jar Song", 5:03
+6., "Celtic Tiger", 5:13
+7., "Apple of My Eye", 3:43
+8., "Industrial School", 5:27
+9., "Great Gaels of Ireland", 5:21
+10., "Marching Season Siege", 3:24
+11., "Seize the Day" (hidden track), 4:12
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/kate_bush_never_for_ever.txt b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/kate_bush_never_for_ever.txt
new file mode 100644
index 00000000..8e543f85
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/kate_bush_never_for_ever.txt
@@ -0,0 +1,11 @@
+1., "Babooshka", 3:20
+2., "Delius (Song of Summer)", 2:51
+3., "Blow Away (For Bill)", 3:33
+4., "All We Ever Look For", 3:47
+5., "Egypt", 4:10
+6., "The Wedding List", 4:15
+7., "Violin", 3:15
+8., "The Infant Kiss", 2:50
+9., "Night Scented Stock", 0:51
+10., "Army Dreamers", 2:55
+11., "Breathing", 5:29
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/new_levels_new_devils.txt b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/new_levels_new_devils.txt
new file mode 100644
index 00000000..94d8c6c3
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/new_levels_new_devils.txt
@@ -0,0 +1,10 @@
+1, Nasty, 4:40
+2, O.D., 3:22
+3, Death Note, 3:40
+4, Bad, 3:55
+5, Drown, 3:54
+6, Saucy, 3:04
+7, Yas, 3:22
+8, So Strange, 4:00
+9, Rich Kids, 3:21
+10, G.O.A.T., 3:35
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/the_beatles_abbey_road.txt b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/the_beatles_abbey_road.txt
new file mode 100644
index 00000000..ec4bf7d9
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/library/the_beatles_abbey_road.txt
@@ -0,0 +1,11 @@
+1., "Here Comes the Sun", 3:05
+2., "Because", 2:45
+3., "You Never Give Me Your Money", 4:03
+4., "Sun King", 2:26
+5., "Mean Mr. Mustard", 1:06
+6., "Polythene Pam", 1:13
+7., "She Came In Through the Bathroom Window", 1:58
+8., "Golden Slumbers", 1:31
+9., "Carry That Weight", 1:36
+10., "The End", 2:05
+11., "Her Majesty", 0:23
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/music_library.txt b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/music_library.txt
new file mode 100644
index 00000000..12387aff
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/resources/music_library.txt
@@ -0,0 +1,5 @@
+Bush, Razorblade Suitcase, covers/Razorblade_suitcase.jpg, library/bush_razorblade_suitcase.txt
+Kate Bush, Never for Ever, covers/Katebushneverforever.png, library/kate_bush_never_for_ever.txt
+Damien Dempsey, Seize the Day, covers/Damien_Dempsey_-_Seize_the_Day.jpg, library/damien_dempsey_seize_the_day.txt
+Beatles, Abbey Road, covers/Beatles_-_Abbey_Road.jpg, library/the_beatles_abbey_road.txt
+Polyphia, New Levels New Devils, covers/polyphia_new_levels_new_devils.jpeg, library/new_levels_new_devils.txt
\ No newline at end of file
diff --git a/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/src/main/java/Album.java b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/src/main/java/Album.java
new file mode 100644
index 00000000..7d49eead
--- /dev/null
+++ b/third/semester1/CT326_Programming_III/assignments/assignment4/assignment4/src/main/java/Album.java
@@ -0,0 +1,120 @@
+// Name: Andrew Hayes
+// Student ID: 21321503
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * class to represent an Album object and its tracks
+ */
+public class Album {
+ private String artist; // the name of the artist
+ private String title; // the title of the album
+ private String pathToCover; // the path to the cover image of the album
+ private String pathToTrackList; // the path to the track list text file for the album
+ private ArrayList