From 8bd093e9de90f3983171f603ef158e3c3e211416 Mon Sep 17 00:00:00 2001 From: mudabbir-ahmad Date: Sun, 25 Jan 2026 14:25:04 +0000 Subject: [PATCH] Programming 3 Question 2 --- .gitignore | 39 +++++++++++++ .idea/.gitignore | 8 +++ .idea/copilot.data.migration.ask2agent.xml | 6 ++ .idea/encodings.xml | 7 +++ .idea/misc.xml | 14 +++++ .idea/vcs.xml | 6 ++ pom.xml | 9 +++ .../resources/META-INF/maven/archetype.xml | 9 +++ .../resources/archetype-resources/pom.xml | 15 +++++ .../src/main/java/App.java | 55 ++++++++++++++++++ .../src/main/java/Employee.java | 42 ++++++++++++++ .../src/main/java/PasswordService.java | 25 ++++++++ .../src/main/java/User.java | 24 ++++++++ .../src/test/java/AppTest.java | 38 ++++++++++++ .../src/test/java/EmployeeTaxTest.java | 58 +++++++++++++++++++ .../src/test/java/PasswordServiceTest.java | 15 +++++ 16 files changed, 370 insertions(+) create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/copilot.data.migration.ask2agent.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/vcs.xml create mode 100644 pom.xml create mode 100644 src/main/resources/META-INF/maven/archetype.xml create mode 100644 src/main/resources/archetype-resources/pom.xml create mode 100644 src/main/resources/archetype-resources/src/main/java/App.java create mode 100644 src/main/resources/archetype-resources/src/main/java/Employee.java create mode 100644 src/main/resources/archetype-resources/src/main/java/PasswordService.java create mode 100644 src/main/resources/archetype-resources/src/main/java/User.java create mode 100644 src/main/resources/archetype-resources/src/test/java/AppTest.java create mode 100644 src/main/resources/archetype-resources/src/test/java/EmployeeTaxTest.java create mode 100644 src/main/resources/archetype-resources/src/test/java/PasswordServiceTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..480bdf5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ +.kotlin + +### 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/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..9a897b6 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/copilot.data.migration.ask2agent.xml b/.idea/copilot.data.migration.ask2agent.xml new file mode 100644 index 0000000..1f2ea11 --- /dev/null +++ b/.idea/copilot.data.migration.ask2agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..fdc35ea --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..0b9cec7 --- /dev/null +++ b/pom.xml @@ -0,0 +1,9 @@ + + 4.0.0 + org.example + Prog3-AssignmentQ2 + 1.0-SNAPSHOT + Archetype - Prog3-AssignmentQ2 + http://maven.apache.org + diff --git a/src/main/resources/META-INF/maven/archetype.xml b/src/main/resources/META-INF/maven/archetype.xml new file mode 100644 index 0000000..cec5756 --- /dev/null +++ b/src/main/resources/META-INF/maven/archetype.xml @@ -0,0 +1,9 @@ + + Prog3-AssignmentQ2 + + src/main/java/App.java + + + src/test/java/AppTest.java + + diff --git a/src/main/resources/archetype-resources/pom.xml b/src/main/resources/archetype-resources/pom.xml new file mode 100644 index 0000000..2ea6439 --- /dev/null +++ b/src/main/resources/archetype-resources/pom.xml @@ -0,0 +1,15 @@ + + 4.0.0 + $org.example + $Prog3-AssignmentQ2 + $1.0-SNAPSHOT + + + junit + junit + 3.8.1 + test + + + diff --git a/src/main/resources/archetype-resources/src/main/java/App.java b/src/main/resources/archetype-resources/src/main/java/App.java new file mode 100644 index 0000000..1c83d1c --- /dev/null +++ b/src/main/resources/archetype-resources/src/main/java/App.java @@ -0,0 +1,55 @@ +package $org.example; + +/** + * Taxables Question for Programming 3 + * + */ +import java.util.*; +import java.util.stream.*; + +public class App { + + public static void main(String[] args) { + + TaxCalculator taxCalculator = (income) -> { + if (income <= 12_570) { + return 0; + } else if (income <= 50_270) { + return (income - 12_570) * 0.20; + } else { + return (50_270 - 12_570) * 0.20 + + (income - 50_270) * 0.40; + } + }; + + // Create Employee objects + List employees = new ArrayList<>(); + employees.add(new Employee("u1", "pass123", "Alice", "London", 30_000)); + employees.add(new Employee("u2", "password", "Bob", "Leeds", 55_000)); + employees.add(new Employee("u3", "hello", "Charlie", "Manchester", 12_000)); + employees.add(new Employee("u4", "secure1234", "Daisy", "Bristol", 80_000)); + + // Apply tax calculation to all employees (Lambda + Stream) + employees.forEach(e -> + e.setTaxToPay(taxCalculator.calculate(e.getIncome())) + ); + + // Sort employees by income (ascending) + List sortedByIncome = employees.stream() + .sorted(Comparator.comparingDouble(Employee::getIncome)) + .toList(); + + // Filter employees who pay tax (income above personal allowance) + List taxableEmployees = employees.stream() + .filter(e -> e.getIncome() > 12_570) + .toList(); + + // Optional output to demonstrate integration + sortedByIncome.forEach(e -> + System.out.println(e.getName() + + " | Income: £" + e.getIncome() + + " | Tax: £" + e.getTaxToPay()) + ); + } +} + diff --git a/src/main/resources/archetype-resources/src/main/java/Employee.java b/src/main/resources/archetype-resources/src/main/java/Employee.java new file mode 100644 index 0000000..e40fda9 --- /dev/null +++ b/src/main/resources/archetype-resources/src/main/java/Employee.java @@ -0,0 +1,42 @@ +package $org.example; + +/** + * Employee class for Taxables Question + * + */ + +public class Employee extends User { + + private String name; + private String address; + private double income; + private double taxToPay; + + public Employee(String username, String password, + String name, String address, double income) { + super(username, password); + this.name = name; + this.address = address; + this.income = income; + } + + public String getName() { + return name; + } + + public String getAddress() { + return address; + } + + public double getIncome() { + return income; + } + + public double getTaxToPay() { + return taxToPay; + } + + public void setTaxToPay(double taxToPay) { + this.taxToPay = taxToPay; + } +} diff --git a/src/main/resources/archetype-resources/src/main/java/PasswordService.java b/src/main/resources/archetype-resources/src/main/java/PasswordService.java new file mode 100644 index 0000000..2e5ef6b --- /dev/null +++ b/src/main/resources/archetype-resources/src/main/java/PasswordService.java @@ -0,0 +1,25 @@ +package $org.example; + +/** + * Password Service for Taxables Question + * + */ + +import java.util.*; +import java.util.stream.*; + +public class PasswordService { + + private List passwords = new ArrayList<>(); + + public void addPassword(String password) { + passwords.add(password); + } + + public double getAveragePasswordLength() { + return passwords.stream() + .mapToInt(String::length) + .average() + .orElse(0); + } +} diff --git a/src/main/resources/archetype-resources/src/main/java/User.java b/src/main/resources/archetype-resources/src/main/java/User.java new file mode 100644 index 0000000..5318c91 --- /dev/null +++ b/src/main/resources/archetype-resources/src/main/java/User.java @@ -0,0 +1,24 @@ +package $org.example; + +/** + * User class for Taxables Question + * + */ + +public class User { + protected String username; + protected String password; + + public User(String username, String password) { + this.username = username; + this.password = password; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } +} diff --git a/src/main/resources/archetype-resources/src/test/java/AppTest.java b/src/main/resources/archetype-resources/src/test/java/AppTest.java new file mode 100644 index 0000000..65be417 --- /dev/null +++ b/src/main/resources/archetype-resources/src/test/java/AppTest.java @@ -0,0 +1,38 @@ +package $org.example; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/src/main/resources/archetype-resources/src/test/java/EmployeeTaxTest.java b/src/main/resources/archetype-resources/src/test/java/EmployeeTaxTest.java new file mode 100644 index 0000000..512fb23 --- /dev/null +++ b/src/main/resources/archetype-resources/src/test/java/EmployeeTaxTest.java @@ -0,0 +1,58 @@ +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import java.util.*; + +public class EmployeeTaxTest { + + TaxCalculator taxCalculator = (income) -> { + if (income <= 12_570) return 0; + else if (income <= 50_270) + return (income - 12_570) * 0.20; + else + return (50_270 - 12_570) * 0.20 + + (income - 50_270) * 0.40; + }; + + @Test + void testPersonalAllowanceBand() { + assertEquals(0, taxCalculator.calculate(10_000)); + } + + @Test + void testBasicRateBand() { + assertEquals(3_486, taxCalculator.calculate(30_000), 0.01); + } + + @Test + void testHigherRateBand() { + assertEquals(19_432, taxCalculator.calculate(80_000), 0.01); + } + + @Test + void testSortingByIncome() { + List employees = List.of( + new Employee("u1", "p1", "A", "X", 40_000), + new Employee("u2", "p2", "B", "Y", 20_000) + ); + + List sorted = employees.stream() + .sorted(Comparator.comparingDouble(Employee::getIncome)) + .toList(); + + assertEquals(20_000, sorted.get(0).getIncome()); + } + + @Test + void testFilteringHighEarners() { + List employees = List.of( + new Employee("u1", "p1", "A", "X", 60_000), + new Employee("u2", "p2", "B", "Y", 30_000) + ); + + List result = employees.stream() + .filter(e -> e.getIncome() > 50_000) + .toList(); + + assertEquals(1, result.size()); + } +} diff --git a/src/main/resources/archetype-resources/src/test/java/PasswordServiceTest.java b/src/main/resources/archetype-resources/src/test/java/PasswordServiceTest.java new file mode 100644 index 0000000..ba23c3d --- /dev/null +++ b/src/main/resources/archetype-resources/src/test/java/PasswordServiceTest.java @@ -0,0 +1,15 @@ +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + +public class PasswordServiceTest { + + @Test + void testAveragePasswordLength() { + PasswordService service = new PasswordService(); + service.addPassword("abc"); // 3 + service.addPassword("password"); // 8 + service.addPassword("hello"); // 5 + + assertEquals(5.33, service.getAveragePasswordLength(), 0.01); + } +}