From 76a31f8db0ebcc9d7611bb704265a523c507f0d6 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi <111232955+ParthGandhiNUS@users.noreply.github.com> Date: Thu, 7 Mar 2024 13:20:42 +0800 Subject: [PATCH 001/503] Update README.md --- README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/README.md b/README.md index f82e2494b7..89a5451b6c 100644 --- a/README.md +++ b/README.md @@ -62,3 +62,36 @@ Steps for publishing documentation to the public: 1. Scroll down to the `GitHub Pages` section. 1. Set the `source` as `master branch /docs folder`. 1. Optionally, use the `choose a theme` button to choose a theme for your documentation. + + + +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣠⣤⣴⠶⠶⣦⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⡾⠟⠋⠉⠀⠀⠀⠀⠀⠀⠈⠉⠛⠿⣶⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣾⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⢿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣧⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⠋⠀⠀⠀⠀⠀⠀⠀⢀⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣷⡀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⢸⡏⠀⠀⠀⠀⠀⣠⣾⠟⠛⠛⠛⠻⢶⣄⠀⠀⠀⠀⠀⠀⣴⡾⠛⠛⢿⣧⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⣾⠁⠀⠀⠀⢀⣾⠏⠀⠀⠀⠀⠀⠀⠀⠙⣷⡀⠀⠀⠀⢸⡟⠀⠀⠀⠈⣿⡆⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀⣼⠏⠀⠀⠀⠀⠀⣠⣤⡀⠀⠘⣷⣤⣶⢶⣿⣇⠀⣖⣶⡆⠘⣿⡀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⢠⣿⠀⠀⠀⠀⠀⠸⣧⣿⣿⠀⣼⠏⠁⠀⠀⠀⠹⣧⠙⠛⠁⠀⣿⣧⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠈⣿⠀⠀⠀⠀⠀⠀⠈⠉⠀⠀⢻⣿⣶⠶⣶⣶⣿⠏⠀⠀⠀⣰⣿⡏⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⢰⡟⠀⠀⠀⠀⠹⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠛⠋⠉⠀⠀⠀⣠⣾⠋⢹⡆⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⢀⣿⠃⠀⠀⠀⠀⠀⠙⢷⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⠟⠻⢷⣄⢻⣦⠀⠀⠀ +⠀⠀⠀⠀⠀⢠⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⣻⣶⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠻⣷⡙⢷⣄⠀ +⠀⠀⠀⠀⢠⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣴⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⠃⠈⢻⣆ +⠀⠀⠀⢠⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠻⣦⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⠏⠀⠀⠀⣿ +⠀⠀⠀⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⡟⠀⠀⠀⢠⣿ +⠀⠀⢰⡟⠀⠀⠀⠀⠀⠀⠠⣤⣄⠀⠀⠀⠀⠀⠀⠀⠀⠹⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⡇⠀⠀⠀⣾⠃ +⠀⠀⢸⣷⠀⠀⠀⠀⠀⠀⠀⠈⠙⢿⣦⣀⠀⠀⠀⠀⠀⠀⢹⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢿⡇⠀⣠⣾⠏⠀ +⢀⣴⡿⣿⡀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡿⠻⢷⣄⡀⠀⠀⠀⢸⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠿⠿⣿⠃⠀⠀ +⣿⡏⠀⢹⣧⠀⠀⠀⠀⠀⠀⠀⠀⢸⡇⠀⠀⠙⠿⣦⣤⣤⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⢿⣦⠀⠀ +⠙⢿⣦⣀⠻⣧⡀⠀⠀⠀⠀⠀⢠⣼⣷⣄⠀⣀⣀⡀⠈⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⠏⢰⡿⢶⡆ +⠀⠀⠉⠙⠛⠿⠿⣦⣀⢠⣶⣶⡿⠁⠀⠹⣿⠋⠉⢿⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⡿⠃⠀⠀⣠⡾⠃ +⠀⠀⠀⠀⠀⠀⠀⠈⠻⢿⣿⡦⠀⠀⠀⠀⠀⠀⠀⢸⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⣿⣋⣀⣤⣴⠟⠋⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣦⣀⠀⠀⠀⠀⣰⡿⠁⠀⠀⠀⠀⠀⢀⣀⣠⣴⠿⠛⠉⠙⠛⠉⠉⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⠻⠶⠶⠟⠛⠛⠛⠛⠛⠛⠛⠛⠋⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠘⠦⣠⠀⠀⠠⠀⡀⠀⠀⣘⢦⠀⢤⡄⠀⠈⠡⡄⡀⠀⡀⣄⠈⠀⠀⠐⠀⠀⠀⠈⠀⠀⠀⠀ +⠀⠀⠀⠀⠐⠶⠠⠄⠠⠀⠀⠤⠀⠤⠄⠀⡰⡉⠈⠱⠘⠀⡄⣀⠀⠀⠀⠠⠀⠭⠰⠶⠤⠆⠰⡶⠘⢤⠄⠀⢀⠀ + From 00b83012154e1c936a21c59c1298d08097e9d581 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Thu, 7 Mar 2024 13:43:01 +0800 Subject: [PATCH 002/503] Update About Us --- docs/AboutUs.md | 2 +- src/main/java/seedu/duke/Duke.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..061f985018 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,7 +1,7 @@ # About us Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: +-----1234---|:----:|:--------------:|:---------: ![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 5c74e68d59..9f8063ee94 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -18,4 +18,4 @@ public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("Hello " + in.nextLine()); } -} +} \ No newline at end of file From 532b0c57c5f1fc80cb866ccacd2004785d16e2f5 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Thu, 7 Mar 2024 13:43:38 +0800 Subject: [PATCH 003/503] Add Joe --- docs/AboutUs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..69776fb612 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,9 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +Display | Name | Github Profile | Portfolio +--------|:--------:|:--------------:|:---------: +![](https://via.placeholder.com/100.png?text=Photo) | joe joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) From 0a72c23315cd2d13b0340c25f839e637e08e48dc Mon Sep 17 00:00:00 2001 From: tayponghee Date: Thu, 7 Mar 2024 13:43:56 +0800 Subject: [PATCH 004/503] Change AboutUs.md --- docs/AboutUs.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..cbb0247bd8 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,9 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +Display | Name | Github Profile | Portfolio +--------|:---------:|:--------------:|:---------: +![](https://via.placeholder.com/100.png?text=Photo) | Bing Bong | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) From a653dc502676543b9a5eba546c3c10d0aafec08d Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Thu, 7 Mar 2024 13:44:59 +0800 Subject: [PATCH 005/503] Update about us for project --- docs/AboutUs.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..b89b06e1d1 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,9 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +Display | Name | Github Profile | Portfolio +--------|:---------:|:--------------:|:---------: +![](https://via.placeholder.com/100.png?text=Photo) | John Yeet | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) From 94d1c8d3e8eae1199c8b030dc64741a4f43e84f8 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Thu, 7 Mar 2024 13:45:02 +0800 Subject: [PATCH 006/503] Update AboutUs.md with my name --- docs/AboutUs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0f072953ea..65dc7098d7 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,9 +1,9 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | John Doe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +Display | Name | Github Profile | Portfolio +--------|:--------:|:--------------:|:---------: +![](https://via.placeholder.com/100.png?text=Photo) | Parth Gandhi | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) ![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) +![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) From 2d0d7d970d0cbc3ae26a6d44a9a8e6a14314bc37 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Thu, 7 Mar 2024 13:50:20 +0800 Subject: [PATCH 007/503] Add scanner close --- src/main/java/seedu/duke/Duke.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index 9f8063ee94..d7deee7b25 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -17,5 +17,6 @@ public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("Hello " + in.nextLine()); + in.close(); } } \ No newline at end of file From 5ef1a6b83928f9001f3893e62a49b78450533d89 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Thu, 7 Mar 2024 13:54:49 +0800 Subject: [PATCH 008/503] Fix Newline ending --- src/main/java/seedu/duke/Duke.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/seedu/duke/Duke.java index d7deee7b25..30e57c6944 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/seedu/duke/Duke.java @@ -19,4 +19,5 @@ public static void main(String[] args) { System.out.println("Hello " + in.nextLine()); in.close(); } -} \ No newline at end of file +} + From 3afaf84f525caab2dca7de24f4d536ceace219e4 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 8 Mar 2024 15:41:45 +0800 Subject: [PATCH 009/503] Add student and class classes --- .../duke/Duke.java => classify/Classify.java} | 4 +- src/main/java/classify/classgroup/Class.java | 42 +++++++++++++ .../java/classify/classgroup/ClassList.java | 26 ++++++++ src/main/java/classify/student/Details.java | 59 +++++++++++++++++++ src/main/java/classify/student/Student.java | 25 ++++++++ .../java/classify/student/StudentList.java | 31 ++++++++++ 6 files changed, 185 insertions(+), 2 deletions(-) rename src/main/java/{seedu/duke/Duke.java => classify/Classify.java} (93%) create mode 100644 src/main/java/classify/classgroup/Class.java create mode 100644 src/main/java/classify/classgroup/ClassList.java create mode 100644 src/main/java/classify/student/Details.java create mode 100644 src/main/java/classify/student/Student.java create mode 100644 src/main/java/classify/student/StudentList.java diff --git a/src/main/java/seedu/duke/Duke.java b/src/main/java/classify/Classify.java similarity index 93% rename from src/main/java/seedu/duke/Duke.java rename to src/main/java/classify/Classify.java index 30e57c6944..88197128a6 100644 --- a/src/main/java/seedu/duke/Duke.java +++ b/src/main/java/classify/Classify.java @@ -1,8 +1,8 @@ -package seedu.duke; +package classify; import java.util.Scanner; -public class Duke { +public class Classify { /** * Main entry-point for the java.duke.Duke application. */ diff --git a/src/main/java/classify/classgroup/Class.java b/src/main/java/classify/classgroup/Class.java new file mode 100644 index 0000000000..11a66f5e5a --- /dev/null +++ b/src/main/java/classify/classgroup/Class.java @@ -0,0 +1,42 @@ +package classify.classgroup; + +import classify.student.StudentList; +import classify.student.Student; + +public class Class { + + //@@author Cryolian + public int year; + public String className; + public StudentList studentList; + + public Class(int year, String className) { + this.year = year; + this.className = className; + } + + public void addStudent(Student s) { + this.studentList.addStudent(s); + } + + public int getYear() { + return year; + } + + public void setYear(int year) { + this.year = year; + } + + public String getClassName() { + return className; + } + + public void setClassName(String className) { + this.className = className; + } + + @Override + public String toString() { + return this.className; + } +} diff --git a/src/main/java/classify/classgroup/ClassList.java b/src/main/java/classify/classgroup/ClassList.java new file mode 100644 index 0000000000..f94f57bff8 --- /dev/null +++ b/src/main/java/classify/classgroup/ClassList.java @@ -0,0 +1,26 @@ +package classify.classgroup; + +import java.util.ArrayList; + +public class ClassList { + + //@@author Cryolian + public ArrayList classList; + + public ClassList() { + this.classList = new ArrayList<>(); + } + + public void addClass(Class classToAdd) { + classList.add(classToAdd); + } + + public void removeClass(int id) { + classList.remove(id); + } + + public void removeClass(Class classToRemove) { + classList.remove(classToRemove); + } + +} diff --git a/src/main/java/classify/student/Details.java b/src/main/java/classify/student/Details.java new file mode 100644 index 0000000000..67cd068df0 --- /dev/null +++ b/src/main/java/classify/student/Details.java @@ -0,0 +1,59 @@ +package classify.student; + +import classify.classgroup.Class; +import java.util.ArrayList; + +public class Details { + + //@@author Cryolian + public String gender; + public int phoneNumber; + public Class currentClass; + public ArrayList subjects; + public String lastPaymentDate; + public String remarks; + + public String getGender() { + return gender; + } + + public int getPhoneNumber() { + return phoneNumber; + } + + public Class getCurrentClass() { + return currentClass; + } + + public ArrayList getSubjects() { + return subjects; + } + + public String getLastPaymentDate() { + return lastPaymentDate; + } + + public String getRemarks() { + return remarks; + } + + public void setGender(String gender) { + this.gender = gender; + } + + public void setPhoneNumber(int phoneNumber) { + this.phoneNumber = phoneNumber; + } + + public void setLastPaymentDate(String lastPaymentDate) { + this.lastPaymentDate = lastPaymentDate; + } + + public void setRemarks(String remarks) { + this.remarks = remarks; + } + + public void setCurrentClass(Class currentClass) { + this.currentClass = currentClass; + } +} diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java new file mode 100644 index 0000000000..4a39ac9fd5 --- /dev/null +++ b/src/main/java/classify/student/Student.java @@ -0,0 +1,25 @@ +package classify.student; + +public class Student { + + //@@author Cryolian + public String name; + public Details details = new Details(); + + public Student(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.name; + } +} diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java new file mode 100644 index 0000000000..3d01a9fad6 --- /dev/null +++ b/src/main/java/classify/student/StudentList.java @@ -0,0 +1,31 @@ +package classify.student; + +import java.util.ArrayList; + +public class StudentList { + + //@@author Cryolian + public ArrayList studentList; + + public StudentList() { + this.studentList = new ArrayList<>(); + } + + public void addStudent(Student s) { + this.studentList.add(s); + } + + public void removeStudent(int id) { + this.studentList.remove(id); + } + + public void removeStudent(String name) { + for (Student s: studentList) { + if (s.getName().equals(name)) { + studentList.remove(s); + return; + } + } + } + +} From 6506031c6dec7ca1a87659480ed4eb45c6961064 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 8 Mar 2024 15:51:13 +0800 Subject: [PATCH 010/503] Update gradle variables for new name --- build.gradle | 4 ++-- .../{seedu/duke/DukeTest.java => classify/ClassifyTest.java} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/test/java/{seedu/duke/DukeTest.java => classify/ClassifyTest.java} (81%) diff --git a/build.gradle b/build.gradle index ea82051fab..9a1f9a7d66 100644 --- a/build.gradle +++ b/build.gradle @@ -29,11 +29,11 @@ test { } application { - mainClass.set("seedu.duke.Duke") + mainClass.set("classify.Classify") } shadowJar { - archiveBaseName.set("duke") + archiveBaseName.set("classify") archiveClassifier.set("") } diff --git a/src/test/java/seedu/duke/DukeTest.java b/src/test/java/classify/ClassifyTest.java similarity index 81% rename from src/test/java/seedu/duke/DukeTest.java rename to src/test/java/classify/ClassifyTest.java index 2dda5fd651..1b6498f4a3 100644 --- a/src/test/java/seedu/duke/DukeTest.java +++ b/src/test/java/classify/ClassifyTest.java @@ -1,10 +1,10 @@ -package seedu.duke; +package classify; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -class DukeTest { +class ClassifyTest { @Test public void sampleTest() { assertTrue(true); From 7ac124bb303cfc885f49d5d4b0089149238c98d3 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 8 Mar 2024 16:06:10 +0800 Subject: [PATCH 011/503] Add javadoc and some student/class functions --- src/main/java/classify/classgroup/Class.java | 41 +++++++++++++++---- src/main/java/classify/student/Details.java | 20 ++++----- src/main/java/classify/student/Student.java | 10 +++++ .../java/classify/student/StudentList.java | 17 ++++++++ 4 files changed, 70 insertions(+), 18 deletions(-) diff --git a/src/main/java/classify/classgroup/Class.java b/src/main/java/classify/classgroup/Class.java index 11a66f5e5a..75157fb0fe 100644 --- a/src/main/java/classify/classgroup/Class.java +++ b/src/main/java/classify/classgroup/Class.java @@ -3,28 +3,45 @@ import classify.student.StudentList; import classify.student.Student; +/** + * Class meant to represent a class for students. + */ public class Class { //@@author Cryolian - public int year; + public int ageOfStudents; public String className; - public StudentList studentList; + public String subject; + public StudentList studentList = new StudentList(); - public Class(int year, String className) { - this.year = year; + /** + * Constructor for a class of Students. + * @param ageOfStudents Age of the students in the class. + * @param className Name of the class. + */ + public Class(int ageOfStudents, String className) { + this.ageOfStudents = ageOfStudents; this.className = className; } + /** + * Add a student as attending this class. + * @param s Student to add to the class. + */ public void addStudent(Student s) { this.studentList.addStudent(s); } - public int getYear() { - return year; + /** + * Get the age of the students attending the class. + * @return the age of the students as an integer. + */ + public int getAgeOfStudents() { + return ageOfStudents; } - public void setYear(int year) { - this.year = year; + public void setAgeOfStudents(int ageOfStudents) { + this.ageOfStudents = ageOfStudents; } public String getClassName() { @@ -35,6 +52,14 @@ public void setClassName(String className) { this.className = className; } + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + @Override public String toString() { return this.className; diff --git a/src/main/java/classify/student/Details.java b/src/main/java/classify/student/Details.java index 67cd068df0..f13cd47a67 100644 --- a/src/main/java/classify/student/Details.java +++ b/src/main/java/classify/student/Details.java @@ -3,15 +3,19 @@ import classify.classgroup.Class; import java.util.ArrayList; +/** + * Important details of a student the tuition centre + * has to keep track of. + */ public class Details { //@@author Cryolian - public String gender; - public int phoneNumber; - public Class currentClass; - public ArrayList subjects; - public String lastPaymentDate; - public String remarks; + public String gender = "unknown"; + public int phoneNumber = 0; + public Class currentClass = new Class(0, "Unknown"); + public ArrayList subjects = new ArrayList<>(); + public String lastPaymentDate = "unknown"; + public String remarks = "NA"; public String getGender() { return gender; @@ -25,10 +29,6 @@ public Class getCurrentClass() { return currentClass; } - public ArrayList getSubjects() { - return subjects; - } - public String getLastPaymentDate() { return lastPaymentDate; } diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 4a39ac9fd5..deb04907f3 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -1,5 +1,10 @@ package classify.student; +/** + * Meant to represent a particular student of the tuition centre. + * The student can first be declared with a only a name, and the subsequent details + * added later. + */ public class Student { //@@author Cryolian @@ -9,6 +14,11 @@ public class Student { public Student(String name) { this.name = name; } + + public Student(String name, Details details) { + this.name = name; + this.details = details; + } public String getName() { return name; diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 3d01a9fad6..3b8756fe77 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -2,6 +2,9 @@ import java.util.ArrayList; +/** + * Class to represent a list of Students. + */ public class StudentList { //@@author Cryolian @@ -11,14 +14,28 @@ public StudentList() { this.studentList = new ArrayList<>(); } + /** + * Adds in an instance of a student to the student list. + * @param s The student to add to the list. + */ public void addStudent(Student s) { this.studentList.add(s); } + /** + * Removes a student of a certain id from the student list. + * @param id The id of the student to remove. + */ public void removeStudent(int id) { this.studentList.remove(id); } + /** + * Removes the first student in the list with a name matching + * the given string. + * @param name The string to search among the names of the student + * to remove. + */ public void removeStudent(String name) { for (Student s: studentList) { if (s.getName().equals(name)) { From ffc3a95f1a1bdd8c49438fbb7a775d03465e10e6 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 8 Mar 2024 16:10:30 +0800 Subject: [PATCH 012/503] Fix javadoc line indentation --- src/main/java/classify/student/StudentList.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 3b8756fe77..76ac38e080 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -33,8 +33,7 @@ public void removeStudent(int id) { /** * Removes the first student in the list with a name matching * the given string. - * @param name The string to search among the names of the student - * to remove. + * @param name The string to search among the names of the student to remove. */ public void removeStudent(String name) { for (Student s: studentList) { From 1686a0895224ce231c44f272444c121445fad40e Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 9 Mar 2024 12:50:44 +0800 Subject: [PATCH 013/503] Add Master Class for setting up masterStudentList in future --- src/main/java/classify/student/Master.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/main/java/classify/student/Master.java diff --git a/src/main/java/classify/student/Master.java b/src/main/java/classify/student/Master.java new file mode 100644 index 0000000000..6a9bc7e2ee --- /dev/null +++ b/src/main/java/classify/student/Master.java @@ -0,0 +1,10 @@ +package classify.student; + +//This class is a master arraylist for all the students in our system. to be explored ig +public class Master { + public static StudentList masterStudentList = new StudentList(); + + public Master() { + + } +} From 6906b9d11394e6024e202224a200c287d2a9a618 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 9 Mar 2024 12:51:42 +0800 Subject: [PATCH 014/503] Add UserInput Class to process User Inputs --- src/main/java/classify/commands/UserInput.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/java/classify/commands/UserInput.java diff --git a/src/main/java/classify/commands/UserInput.java b/src/main/java/classify/commands/UserInput.java new file mode 100644 index 0000000000..6a23a34172 --- /dev/null +++ b/src/main/java/classify/commands/UserInput.java @@ -0,0 +1,12 @@ +package classify; + +public class UserInput { + /** + * Used to process the different variations of the users inputs + * @param userInput : String which the user inputs + * @return String which is in lowercase and clear of any unnecessary whitespace + */ + public static String processInput(String userInput){ + return (userInput.trim()).toLowerCase(); + } +} From 317589e981630e75b991fd477284072ca954a518 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 9 Mar 2024 12:52:08 +0800 Subject: [PATCH 015/503] Add Ui class to streamline printing processes --- src/main/java/classify/commands/Ui.java | 34 +++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/main/java/classify/commands/Ui.java diff --git a/src/main/java/classify/commands/Ui.java b/src/main/java/classify/commands/Ui.java new file mode 100644 index 0000000000..450ced1dea --- /dev/null +++ b/src/main/java/classify/commands/Ui.java @@ -0,0 +1,34 @@ +package classify.commands; + +public class Ui { + //@@author ParthGandhiNUS + private static final String DIVIDER = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; + private static final String WELCOME_TO_CLASSIFY = "Welcome to Classify!"; + private static final String WHAT_CAN_I_DO_FOR_YOU_TODAY = "What can I do for you today?"; + private static final String CLASSIFY_GOODBYE_MESSAGE = "Hope you've had a productive day. See you again! Goodbye!"; + + /** + * Prints a dividing line between statements for added clarity + */ + public static void printDivider(){ + System.out.println(DIVIDER); + } + + /** + * Prints out the welcome message to introduce the user to Classify + */ + public static void printWelcomeMessage(){ + printDivider(); + System.out.println(WELCOME_TO_CLASSIFY); + System.out.println(WHAT_CAN_I_DO_FOR_YOU_TODAY); + printDivider(); + } + + /** + * Prints out the message to end conversation with the user + */ + public static void printEndConversation() { + System.out.println(CLASSIFY_GOODBYE_MESSAGE); + printDivider(); + } +} From 20d0dfafe42098e126518e1871865de9a3b384e8 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 9 Mar 2024 12:52:43 +0800 Subject: [PATCH 016/503] Add UserParsing Class to parse Users' inputs --- .../java/classify/commands/InputParsing.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 src/main/java/classify/commands/InputParsing.java diff --git a/src/main/java/classify/commands/InputParsing.java b/src/main/java/classify/commands/InputParsing.java new file mode 100644 index 0000000000..7ed08c44fe --- /dev/null +++ b/src/main/java/classify/commands/InputParsing.java @@ -0,0 +1,35 @@ +package classify; + +import classify.commands.Ui; +import classify.student.Student; +import classify.student.StudentList; + +import java.util.ArrayList; +import java.util.Scanner; + +public class InputParsing { + private static final String BYE = "bye"; + private static final String LIST = "list"; + private static final String ADD = "add"; + private static final String DELETE = "delete"; + private static final String WRONG_INPUT_MESSAGE = "Wrong Input! Please try again!"; + + public static void parseUserCommand(String userCommand, ArrayListmasterStudentList, Scanner in){ + switch (userCommand) { + case BYE: + break; + + case LIST: + StudentList.printCurrentArrayList(masterStudentList); + Ui.printDivider(); + break; + + default: + System.out.println(WRONG_INPUT_MESSAGE); + Ui.printDivider(); + break; + } + } + + +} From e0b1a998b5fd9f5b19e7fe072cced649d90376a5 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 9 Mar 2024 12:53:36 +0800 Subject: [PATCH 017/503] update StudentList class with masterStudentList --- src/main/java/classify/student/StudentList.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 76ac38e080..47dad0cee5 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -10,6 +10,11 @@ public class StudentList { //@@author Cryolian public ArrayList studentList; + //@@author ParthGandhiNUS + public static ArrayList masterStudentList = new ArrayList<>(); + public static final String DOT = "."; + + //@@author Cryolian public StudentList() { this.studentList = new ArrayList<>(); } @@ -30,6 +35,17 @@ public void removeStudent(int id) { this.studentList.remove(id); } + //@@author ParthGandhiNUS + /** + * Used in the "list" command to print all the Current Tasks in the proper format + */ + public static void printCurrentArrayList(ArrayListcurrentList){ + for (int i = 1; i <= currentList.size(); i++){ + System.out.println(i + DOT + currentList.get(i-1)); + } + } + + //@@author Cryolian /** * Removes the first student in the list with a name matching * the given string. From fa606d0b97ac3656165edb17440ee36fd181f4f4 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 9 Mar 2024 12:54:08 +0800 Subject: [PATCH 018/503] Edit mistake in comment --- src/main/java/classify/student/Student.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index deb04907f3..18f186d6db 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -2,7 +2,7 @@ /** * Meant to represent a particular student of the tuition centre. - * The student can first be declared with a only a name, and the subsequent details + * The student can first be declared with only a name, and the subsequent details * added later. */ public class Student { From 3d6cff400ec758cf466ea8e25475e470495e4acf Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 9 Mar 2024 12:55:38 +0800 Subject: [PATCH 019/503] Add fallenCode to keep track of deleted code --- src/main/java/classify/fallenCode.java | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/main/java/classify/fallenCode.java diff --git a/src/main/java/classify/fallenCode.java b/src/main/java/classify/fallenCode.java new file mode 100644 index 0000000000..286d26b2fd --- /dev/null +++ b/src/main/java/classify/fallenCode.java @@ -0,0 +1,30 @@ +package classify; +//import classify.student.StudentList; + +//import classify.Commands.Ui; +//import classify.student.Master; + +//import java.util.Scanner; + +//@@author ParthGandhiNUS +public class fallenCode { +// while (!(userCommand.equals("bye"))){ +// InputParsing.parseUserCommand(UserInput.processInput(userCommand), StudentList.masterStudentList, in); +// } +// +// //for master class +// while (!(userCommand.equals("bye"))){ +// InputParsing.parseUserCommand(UserInput.processInput(userCommand), masterStudentList, in); +// } + +// public static void parseUserCommand(String UserCommand, Master studentList, Scanner in){ +// switch (UserCommand) { +// case BYE: +// break; +// +// case LIST: +// Ui.printDivider(); +// break; +// } +// } +} From 5741e98b517cebb4e27bac4bcb0b4193352cf15f Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 9 Mar 2024 13:07:34 +0800 Subject: [PATCH 020/503] Update file location and packages --- src/main/java/classify/{commands => }/Ui.java | 2 +- src/main/java/classify/commands/InputParsing.java | 4 ++-- src/main/java/classify/commands/UserInput.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename src/main/java/classify/{commands => }/Ui.java (97%) diff --git a/src/main/java/classify/commands/Ui.java b/src/main/java/classify/Ui.java similarity index 97% rename from src/main/java/classify/commands/Ui.java rename to src/main/java/classify/Ui.java index 450ced1dea..c277c08726 100644 --- a/src/main/java/classify/commands/Ui.java +++ b/src/main/java/classify/Ui.java @@ -1,4 +1,4 @@ -package classify.commands; +package classify; public class Ui { //@@author ParthGandhiNUS diff --git a/src/main/java/classify/commands/InputParsing.java b/src/main/java/classify/commands/InputParsing.java index 7ed08c44fe..7cca246f74 100644 --- a/src/main/java/classify/commands/InputParsing.java +++ b/src/main/java/classify/commands/InputParsing.java @@ -1,6 +1,6 @@ -package classify; +package classify.commands; -import classify.commands.Ui; +import classify.Ui; import classify.student.Student; import classify.student.StudentList; diff --git a/src/main/java/classify/commands/UserInput.java b/src/main/java/classify/commands/UserInput.java index 6a23a34172..8fed55ab25 100644 --- a/src/main/java/classify/commands/UserInput.java +++ b/src/main/java/classify/commands/UserInput.java @@ -1,4 +1,4 @@ -package classify; +package classify.commands; public class UserInput { /** From a5ed70f87489466c7f3fd3167622103aea779d6a Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 9 Mar 2024 13:07:48 +0800 Subject: [PATCH 021/503] Update Main with new Implementation --- src/main/java/classify/Classify.java | 29 ++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 88197128a6..82cb7aae54 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -1,23 +1,32 @@ package classify; +import classify.commands.InputParsing; +import classify.commands.UserInput; +import classify.student.StudentList; + import java.util.Scanner; public class Classify { + public static Scanner in = new Scanner(System.in); + /** * Main entry-point for the java.duke.Duke application. */ public static void main(String[] args) { - String logo = " ____ _ \n" - + "| _ \\ _ _| | _____ \n" - + "| | | | | | | |/ / _ \\\n" - + "| |_| | |_| | < __/\n" - + "|____/ \\__,_|_|\\_\\___|\n"; - System.out.println("Hello from\n" + logo); - System.out.println("What is your name?"); + // @@author ParthGandhiNUS + // CAA: 9 March 2024 1pm + Ui.printWelcomeMessage(); + // Takes in only the first word input by the user + String userCommand = UserInput.processInput(in.next()); + + //Set up polling for the first word input by the user. + // If user's first word is "bye", will exit the while loop. + while (!(userCommand.equals("bye"))){ + InputParsing.parseUserCommand(UserInput.processInput(userCommand), StudentList.masterStudentList, in); + userCommand = in.next(); + } - Scanner in = new Scanner(System.in); - System.out.println("Hello " + in.nextLine()); - in.close(); + Ui.printEndConversation(); } } From 6c3df34c6e68cf4eee0dfd4f2675c64c15ff7057 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 9 Mar 2024 13:35:21 +0800 Subject: [PATCH 022/503] Reorganise code to make it work --- src/main/java/classify/Classify.java | 2 -- .../classify/{commands => }/InputParsing.java | 5 ++-- .../classify/{commands => }/UserInput.java | 2 +- .../java/classify/student/StudentList.java | 29 ++++++++++--------- 4 files changed, 19 insertions(+), 19 deletions(-) rename src/main/java/classify/{commands => }/InputParsing.java (94%) rename src/main/java/classify/{commands => }/UserInput.java (93%) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 82cb7aae54..a7d27b13a7 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -1,7 +1,5 @@ package classify; -import classify.commands.InputParsing; -import classify.commands.UserInput; import classify.student.StudentList; import java.util.Scanner; diff --git a/src/main/java/classify/commands/InputParsing.java b/src/main/java/classify/InputParsing.java similarity index 94% rename from src/main/java/classify/commands/InputParsing.java rename to src/main/java/classify/InputParsing.java index 7cca246f74..5a51575ebf 100644 --- a/src/main/java/classify/commands/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -1,6 +1,7 @@ -package classify.commands; +package classify; + + -import classify.Ui; import classify.student.Student; import classify.student.StudentList; diff --git a/src/main/java/classify/commands/UserInput.java b/src/main/java/classify/UserInput.java similarity index 93% rename from src/main/java/classify/commands/UserInput.java rename to src/main/java/classify/UserInput.java index 8fed55ab25..6a23a34172 100644 --- a/src/main/java/classify/commands/UserInput.java +++ b/src/main/java/classify/UserInput.java @@ -1,4 +1,4 @@ -package classify.commands; +package classify; public class UserInput { /** diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 47dad0cee5..9506b8e627 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -6,19 +6,29 @@ * Class to represent a list of Students. */ public class StudentList { + //@@ParthGandhiNUS + public static final String DOT = "."; + public static ArrayList masterStudentList = new ArrayList<>(); //@@author Cryolian public ArrayList studentList; - //@@author ParthGandhiNUS - public static ArrayList masterStudentList = new ArrayList<>(); - public static final String DOT = "."; - //@@author Cryolian public StudentList() { this.studentList = new ArrayList<>(); - } + } + //@@author ParthGandhiNUS + /** + * Used in the "list" command to print all the Current Tasks in the proper format + */ + public static void printCurrentArrayList(ArrayListcurrentList){ + for (int i = 1; i <= currentList.size(); i++){ + System.out.println(i + DOT + currentList.get(i-1)); + } + } + + //@@author Cryolian /** * Adds in an instance of a student to the student list. * @param s The student to add to the list. @@ -35,15 +45,6 @@ public void removeStudent(int id) { this.studentList.remove(id); } - //@@author ParthGandhiNUS - /** - * Used in the "list" command to print all the Current Tasks in the proper format - */ - public static void printCurrentArrayList(ArrayListcurrentList){ - for (int i = 1; i <= currentList.size(); i++){ - System.out.println(i + DOT + currentList.get(i-1)); - } - } //@@author Cryolian /** From fc96e12fb06cbd70cb643848d82354de8e404f1d Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 9 Mar 2024 13:53:35 +0800 Subject: [PATCH 023/503] Update test cases --- text-ui-test/EXPECTED.TXT | 15 ++++++--------- text-ui-test/input.txt | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 892cb6cae7..6156a7ed33 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,9 +1,6 @@ -Hello from - ____ _ -| _ \ _ _| | _____ -| | | | | | | |/ / _ \ -| |_| | |_| | < __/ -|____/ \__,_|_|\_\___| - -What is your name? -Hello James Gosling +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Welcome to Classify! +What can I do for you today? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Hope you've had a productive day. See you again! Goodbye! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index f6ec2e9f95..0abaeaa993 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1 +1 @@ -James Gosling \ No newline at end of file +bye \ No newline at end of file From d9393f0007248811ab5bd956490c051a89a61dad Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 15 Mar 2024 20:19:35 +0800 Subject: [PATCH 024/503] Add JUnit tests --- src/main/java/classify/classgroup/Class.java | 16 +++++++------- src/main/java/classify/student/Details.java | 20 +++++++++++------- .../classify/classgroup/ClassListTest.java | 5 +++++ .../java/classify/classgroup/ClassTest.java | 5 +++++ .../java/classify/student/StudentTest.java | 21 +++++++++++++++++++ 5 files changed, 51 insertions(+), 16 deletions(-) create mode 100644 src/test/java/classify/classgroup/ClassListTest.java create mode 100644 src/test/java/classify/classgroup/ClassTest.java create mode 100644 src/test/java/classify/student/StudentTest.java diff --git a/src/main/java/classify/classgroup/Class.java b/src/main/java/classify/classgroup/Class.java index 75157fb0fe..5c87268a1d 100644 --- a/src/main/java/classify/classgroup/Class.java +++ b/src/main/java/classify/classgroup/Class.java @@ -12,7 +12,7 @@ public class Class { public int ageOfStudents; public String className; public String subject; - public StudentList studentList = new StudentList(); + // public StudentList studentList = new StudentList(); /** * Constructor for a class of Students. @@ -24,13 +24,13 @@ public Class(int ageOfStudents, String className) { this.className = className; } - /** - * Add a student as attending this class. - * @param s Student to add to the class. - */ - public void addStudent(Student s) { - this.studentList.addStudent(s); - } + // /** + // * Add a student as attending this class. + // * @param s Student to add to the class. + // */ + // public void addStudent(Student s) { + // this.studentList.addStudent(s); + // } /** * Get the age of the students attending the class. diff --git a/src/main/java/classify/student/Details.java b/src/main/java/classify/student/Details.java index f13cd47a67..07250bc54d 100644 --- a/src/main/java/classify/student/Details.java +++ b/src/main/java/classify/student/Details.java @@ -12,11 +12,15 @@ public class Details { //@@author Cryolian public String gender = "unknown"; public int phoneNumber = 0; - public Class currentClass = new Class(0, "Unknown"); + // public Class currentClass = new Class(0, "Unknown"); public ArrayList subjects = new ArrayList<>(); public String lastPaymentDate = "unknown"; public String remarks = "NA"; - + + public Details() { + + } + public String getGender() { return gender; } @@ -25,9 +29,9 @@ public int getPhoneNumber() { return phoneNumber; } - public Class getCurrentClass() { - return currentClass; - } + // public Class getCurrentClass() { + // return currentClass; + // } public String getLastPaymentDate() { return lastPaymentDate; @@ -53,7 +57,7 @@ public void setRemarks(String remarks) { this.remarks = remarks; } - public void setCurrentClass(Class currentClass) { - this.currentClass = currentClass; - } + // public void setCurrentClass(Class currentClass) { + // this.currentClass = currentClass; + // } } diff --git a/src/test/java/classify/classgroup/ClassListTest.java b/src/test/java/classify/classgroup/ClassListTest.java new file mode 100644 index 0000000000..092d1fb325 --- /dev/null +++ b/src/test/java/classify/classgroup/ClassListTest.java @@ -0,0 +1,5 @@ +package classify.classgroup; + +public class ClassListTest { + +} diff --git a/src/test/java/classify/classgroup/ClassTest.java b/src/test/java/classify/classgroup/ClassTest.java new file mode 100644 index 0000000000..29b95d3da0 --- /dev/null +++ b/src/test/java/classify/classgroup/ClassTest.java @@ -0,0 +1,5 @@ +package classify.classgroup; + +public class ClassTest { + +} diff --git a/src/test/java/classify/student/StudentTest.java b/src/test/java/classify/student/StudentTest.java new file mode 100644 index 0000000000..eb09bc57d0 --- /dev/null +++ b/src/test/java/classify/student/StudentTest.java @@ -0,0 +1,21 @@ +package classify.student; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +// import static org.junit.jupiter.api.Assertions.fail; + +public class StudentTest { + + @Test + public void student_name_constructor_test() { + assertEquals("James", new Student("James").getName()); + } + + @Test + public void student_details_constructor_test() { + + Student jack = new Student("jack"); + Student jack2 = new Student(jack.name, jack.details); + assertEquals(jack, jack2); + } +} From b65a6adae397056f0993afdc91ea546e4623aac1 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 15 Mar 2024 20:22:43 +0800 Subject: [PATCH 025/503] Remove Class Attribute from Student --- src/main/java/classify/fallenCode.java | 16 ++++++++++++++++ src/main/java/classify/student/Details.java | 9 +-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/main/java/classify/fallenCode.java b/src/main/java/classify/fallenCode.java index 286d26b2fd..d6304cf75e 100644 --- a/src/main/java/classify/fallenCode.java +++ b/src/main/java/classify/fallenCode.java @@ -27,4 +27,20 @@ public class fallenCode { // break; // } // } + + //@@author Cryolian + // public Class getCurrentClass() { + // return currentClass; + // } + // public void setCurrentClass(Class currentClass) { + // this.currentClass = currentClass; + // } + + // /** + // * Add a student as attending this class. + // * @param s Student to add to the class. + // */ + // public void addStudent(Student s) { + // this.studentList.addStudent(s); + // } } diff --git a/src/main/java/classify/student/Details.java b/src/main/java/classify/student/Details.java index 07250bc54d..fcb5c8360a 100644 --- a/src/main/java/classify/student/Details.java +++ b/src/main/java/classify/student/Details.java @@ -1,6 +1,6 @@ package classify.student; -import classify.classgroup.Class; +// import classify.classgroup.Class; import java.util.ArrayList; /** @@ -29,10 +29,6 @@ public int getPhoneNumber() { return phoneNumber; } - // public Class getCurrentClass() { - // return currentClass; - // } - public String getLastPaymentDate() { return lastPaymentDate; } @@ -57,7 +53,4 @@ public void setRemarks(String remarks) { this.remarks = remarks; } - // public void setCurrentClass(Class currentClass) { - // this.currentClass = currentClass; - // } } From 2cf484d05dc998a0139fa7b1d69aed532aaca0b5 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 15 Mar 2024 20:26:06 +0800 Subject: [PATCH 026/503] Remove unused imports --- src/main/java/classify/classgroup/Class.java | 12 ++---------- src/test/java/classify/student/StudentTest.java | 14 +++++++------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/main/java/classify/classgroup/Class.java b/src/main/java/classify/classgroup/Class.java index 5c87268a1d..963055d37d 100644 --- a/src/main/java/classify/classgroup/Class.java +++ b/src/main/java/classify/classgroup/Class.java @@ -1,7 +1,7 @@ package classify.classgroup; -import classify.student.StudentList; -import classify.student.Student; +// import classify.student.StudentList; +// import classify.student.Student; /** * Class meant to represent a class for students. @@ -24,14 +24,6 @@ public Class(int ageOfStudents, String className) { this.className = className; } - // /** - // * Add a student as attending this class. - // * @param s Student to add to the class. - // */ - // public void addStudent(Student s) { - // this.studentList.addStudent(s); - // } - /** * Get the age of the students attending the class. * @return the age of the students as an integer. diff --git a/src/test/java/classify/student/StudentTest.java b/src/test/java/classify/student/StudentTest.java index eb09bc57d0..9c034ed5cc 100644 --- a/src/test/java/classify/student/StudentTest.java +++ b/src/test/java/classify/student/StudentTest.java @@ -7,15 +7,15 @@ public class StudentTest { @Test - public void student_name_constructor_test() { + public void studentNameConstructorTest() { assertEquals("James", new Student("James").getName()); } - @Test - public void student_details_constructor_test() { + // @Test + // public void studentDetailsConstructorTest() { - Student jack = new Student("jack"); - Student jack2 = new Student(jack.name, jack.details); - assertEquals(jack, jack2); - } + // Student jack = new Student("jack"); + // Student jack2 = new Student(jack.name, jack.details); + // assertEquals(jack, jack2); + // } } From e72fd0ecf6da4bccb28bfde176805c149748f328 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sat, 16 Mar 2024 15:24:53 +0800 Subject: [PATCH 027/503] Add Junit test --- src/main/java/classify/InputParsing.java | 15 ++++++---- src/test/java/classify/InputParsingTest.java | 30 ++++++++++++++++++++ 2 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 src/test/java/classify/InputParsingTest.java diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 5a51575ebf..381f9f27dc 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -1,7 +1,5 @@ package classify; - - import classify.student.Student; import classify.student.StudentList; @@ -15,13 +13,20 @@ public class InputParsing { private static final String DELETE = "delete"; private static final String WRONG_INPUT_MESSAGE = "Wrong Input! Please try again!"; - public static void parseUserCommand(String userCommand, ArrayListmasterStudentList, Scanner in){ + //@@author tayponghee + public static void parseUserCommand(String userCommand, ArrayList masterStudentList, Scanner in){ switch (userCommand) { case BYE: + Ui.printEndConversation(); break; + //@@author ParthGandhiNUS case LIST: - StudentList.printCurrentArrayList(masterStudentList); + if (masterStudentList != null) { + StudentList.printCurrentArrayList(masterStudentList); + } else { + System.out.println("Student list is null."); + } Ui.printDivider(); break; @@ -31,6 +36,4 @@ public static void parseUserCommand(String userCommand, ArrayListmaster break; } } - - } diff --git a/src/test/java/classify/InputParsingTest.java b/src/test/java/classify/InputParsingTest.java new file mode 100644 index 0000000000..45674d0b88 --- /dev/null +++ b/src/test/java/classify/InputParsingTest.java @@ -0,0 +1,30 @@ +package classify; + +import classify.student.Student; +import org.junit.jupiter.api.Test; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Scanner; +import static org.junit.jupiter.api.Assertions.assertEquals; + +//@@author tayponghee +public class InputParsingTest { + + @Test + public void testByeCommand() { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outputStream)); + + ArrayList masterStudentList = new ArrayList<>(); + InputParsing.parseUserCommand("bye", masterStudentList, new Scanner(System.in)); + + System.setOut(System.out); + + String printedOutput = outputStream.toString().trim(); + String expectedOutput = "Hope you've had a productive day. See you again! Goodbye!" + + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; + + assertEquals(expectedOutput.trim(), printedOutput); + } +} From 639705a5b75acb706e601e1799ad4ae3a142ae7a Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sat, 16 Mar 2024 16:01:21 +0800 Subject: [PATCH 028/503] Add view and add student functionalities --- src/main/java/classify/InputParsing.java | 85 ++++++++++++++++++- src/main/java/classify/student/Student.java | 20 ++++- .../classify/student/StudentAttributes.java | 48 +++++++++++ 3 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 src/main/java/classify/student/StudentAttributes.java diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 381f9f27dc..64bb9daa11 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -1,6 +1,7 @@ package classify; import classify.student.Student; +import classify.student.StudentAttributes; import classify.student.StudentList; import java.util.ArrayList; @@ -10,16 +11,36 @@ public class InputParsing { private static final String BYE = "bye"; private static final String LIST = "list"; private static final String ADD = "add"; + private static final String VIEW = "view"; private static final String DELETE = "delete"; private static final String WRONG_INPUT_MESSAGE = "Wrong Input! Please try again!"; //@@author tayponghee + public static final String ENTER_STUDENT_NAME = "Enter student name: "; + public static final String STUDENT_DETAILS = "Student details:"; + public static final String NAME = "Name: "; + public static final String GRADE = "Grade: "; + public static final String CLASSES_ATTENDED = "Classes Attended: "; + public static final String STUDENT_NOT_FOUND = "Student not found!"; + public static final String STUDENT_ADDED_SUCCESSFULLY = "Student added successfully!"; + public static void parseUserCommand(String userCommand, ArrayList masterStudentList, Scanner in){ switch (userCommand) { case BYE: Ui.printEndConversation(); break; + case ADD: + in.nextLine(); + addStudent(masterStudentList, in); + break; + + case VIEW: + in.nextLine(); + viewStudent(masterStudentList, in); + Ui.printDivider(); + break; + //@@author ParthGandhiNUS case LIST: if (masterStudentList != null) { @@ -36,4 +57,66 @@ public static void parseUserCommand(String userCommand, ArrayList maste break; } } -} + + //@@author tayponghee + private static void viewStudent(ArrayList masterStudentList, Scanner in) { + System.out.print(ENTER_STUDENT_NAME); + String studentName = in.nextLine(); + Student foundStudent = findStudentByName(masterStudentList, studentName); + if (foundStudent != null) { + System.out.println(STUDENT_DETAILS); + System.out.println(NAME + foundStudent.getName()); + System.out.println(GRADE + foundStudent.getAttributes().getGrade()); + System.out.println(CLASSES_ATTENDED + foundStudent.getAttributes().getClassesAttended()); + } else { + System.out.println(STUDENT_NOT_FOUND); + } + } + + private static void addStudent(ArrayList masterStudentList, Scanner in) { + System.out.println(ENTER_STUDENT_NAME); + + System.out.print(NAME); + String name = in.nextLine().trim(); + + System.out.print(GRADE); + double grade = parseDoubleInput(in.nextLine()); + + System.out.print(CLASSES_ATTENDED); + int classesAttended = parseIntegerInput(in.nextLine()); + + StudentAttributes attributes = new StudentAttributes(name, grade, classesAttended); + Student student = new Student(name, attributes); + masterStudentList.add(student); + + System.out.println(STUDENT_ADDED_SUCCESSFULLY); + Ui.printDivider(); + } + + private static double parseDoubleInput(String input) { + try { + return Double.parseDouble(input); + } catch (NumberFormatException e) { + System.out.println("Invalid input for grade. Please enter a valid number."); + return 0; + } + } + + private static int parseIntegerInput(String input) { + try { + return Integer.parseInt(input); + } catch (NumberFormatException e) { + System.out.println("Invalid input for classes attended. Please enter a valid number."); + return 0; + } + } + + private static Student findStudentByName(ArrayList masterStudentList, String name) { + for (Student student : masterStudentList) { + if (student.getName().equalsIgnoreCase(name)) { + return student; + } + } + return null; + } +} \ No newline at end of file diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 18f186d6db..671dba9197 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -7,6 +7,9 @@ */ public class Student { + //@@author tayponghee + private StudentAttributes attributes; + //@@author Cryolian public String name; public Details details = new Details(); @@ -19,7 +22,22 @@ public Student(String name, Details details) { this.name = name; this.details = details; } - + + //@@ tayponghee + public Student(String name, StudentAttributes attributes) { + this.name = name; + this.attributes = attributes; + } + + public StudentAttributes getAttributes() { + return attributes; + } + + public void setAttributes(StudentAttributes attributes) { + this.attributes = attributes; + } + + //@@ Cryolian public String getName() { return name; } diff --git a/src/main/java/classify/student/StudentAttributes.java b/src/main/java/classify/student/StudentAttributes.java new file mode 100644 index 0000000000..7962f9b1b5 --- /dev/null +++ b/src/main/java/classify/student/StudentAttributes.java @@ -0,0 +1,48 @@ +package classify.student; + +public class StudentAttributes { + private String name; + private double grade; + private int classesAttended; + + public StudentAttributes(String name, double grade, int classesAttended) { + this.name = name; + this.grade = grade; + this.classesAttended = classesAttended; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getGrade() { + return grade; + } + + public void setGrade(double grade) { + this.grade = grade; + } + + public int getClassesAttended() { + return classesAttended; + } + + public void setClassesAttended(int classesAttended) { + this.classesAttended = classesAttended; + } + + + @Override + public String toString() { + return "StudentAttributes{" + + "name='" + name + '\'' + + ", grade=" + grade + + ", classesAttended=" + classesAttended + + '}'; + } +} + From eb07673fd30665b1afd90415c99ab5c5e1e17e1f Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sat, 16 Mar 2024 16:04:19 +0800 Subject: [PATCH 029/503] Add author tag --- src/main/java/classify/InputParsing.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 64bb9daa11..631ed5ebc9 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -26,10 +26,6 @@ public class InputParsing { public static void parseUserCommand(String userCommand, ArrayList masterStudentList, Scanner in){ switch (userCommand) { - case BYE: - Ui.printEndConversation(); - break; - case ADD: in.nextLine(); addStudent(masterStudentList, in); @@ -42,6 +38,10 @@ public static void parseUserCommand(String userCommand, ArrayList maste break; //@@author ParthGandhiNUS + case BYE: + Ui.printEndConversation(); + break; + case LIST: if (masterStudentList != null) { StudentList.printCurrentArrayList(masterStudentList); From e29143183c59d68bf529a7ca5f70e328ee535aa0 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sat, 16 Mar 2024 16:19:19 +0800 Subject: [PATCH 030/503] Fix gradle coding style convention --- src/main/java/classify/InputParsing.java | 17 ++++++++--------- src/main/java/classify/student/Student.java | 6 ++++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 631ed5ebc9..4110211a91 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -14,15 +14,14 @@ public class InputParsing { private static final String VIEW = "view"; private static final String DELETE = "delete"; private static final String WRONG_INPUT_MESSAGE = "Wrong Input! Please try again!"; - //@@author tayponghee - public static final String ENTER_STUDENT_NAME = "Enter student name: "; - public static final String STUDENT_DETAILS = "Student details:"; - public static final String NAME = "Name: "; - public static final String GRADE = "Grade: "; - public static final String CLASSES_ATTENDED = "Classes Attended: "; - public static final String STUDENT_NOT_FOUND = "Student not found!"; - public static final String STUDENT_ADDED_SUCCESSFULLY = "Student added successfully!"; + private static final String ENTER_STUDENT_NAME = "Enter student name: "; + private static final String STUDENT_DETAILS = "Student details:"; + private static final String NAME = "Name: "; + private static final String GRADE = "Grade: "; + private static final String CLASSES_ATTENDED = "Classes Attended: "; + private static final String STUDENT_NOT_FOUND = "Student not found!"; + private static final String STUDENT_ADDED_SUCCESSFULLY = "Student added successfully!"; public static void parseUserCommand(String userCommand, ArrayList masterStudentList, Scanner in){ switch (userCommand) { @@ -119,4 +118,4 @@ private static Student findStudentByName(ArrayList masterStudentList, S } return null; } -} \ No newline at end of file +} diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 671dba9197..4867f49496 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -7,12 +7,14 @@ */ public class Student { + //@@author Cryolian + public String name; + public Details details = new Details(); + //@@author tayponghee private StudentAttributes attributes; //@@author Cryolian - public String name; - public Details details = new Details(); public Student(String name) { this.name = name; From d12d7b1fddfddc2e06ebcfc52471dbc52ccc9c2f Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Sat, 16 Mar 2024 23:13:00 +0800 Subject: [PATCH 031/503] Add JUnit test --- src/test/java/classify/InputParsingTest.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/test/java/classify/InputParsingTest.java b/src/test/java/classify/InputParsingTest.java index 45674d0b88..2bcd4fd23a 100644 --- a/src/test/java/classify/InputParsingTest.java +++ b/src/test/java/classify/InputParsingTest.java @@ -1,6 +1,7 @@ package classify; import classify.student.Student; +import classify.student.StudentAttributes; import org.junit.jupiter.api.Test; import java.io.ByteArrayOutputStream; import java.io.PrintStream; @@ -8,9 +9,10 @@ import java.util.Scanner; import static org.junit.jupiter.api.Assertions.assertEquals; -//@@author tayponghee + public class InputParsingTest { + //@@author tayponghee @Test public void testByeCommand() { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); @@ -27,4 +29,18 @@ public void testByeCommand() { assertEquals(expectedOutput.trim(), printedOutput); } + + //@author blackmirag3 + @Test + public void testUnknownCommand() { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outputStream)); + ArrayList students = new ArrayList<>(); + InputParsing.parseUserCommand("yeet", students, new Scanner(System.in)); + System.setOut(System.out); + String printedOutput = outputStream.toString().trim(); + String expectedOutput = "Wrong Input! Please try again!" + + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; + assertEquals(expectedOutput.trim(), printedOutput); + } } From 5ff2cb1e9d2f6e26720dfed53c9dd8ffadaf298f Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Sat, 16 Mar 2024 23:18:52 +0800 Subject: [PATCH 032/503] Fix coding style violation for InputParsingTest class --- src/test/java/classify/InputParsingTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/classify/InputParsingTest.java b/src/test/java/classify/InputParsingTest.java index 2bcd4fd23a..85d82a5e8b 100644 --- a/src/test/java/classify/InputParsingTest.java +++ b/src/test/java/classify/InputParsingTest.java @@ -1,7 +1,6 @@ package classify; import classify.student.Student; -import classify.student.StudentAttributes; import org.junit.jupiter.api.Test; import java.io.ByteArrayOutputStream; import java.io.PrintStream; From c07cf42746e465eb300f3f62b4f389d60aa357b3 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sat, 16 Mar 2024 23:34:41 +0800 Subject: [PATCH 033/503] Implement delete feature and help feature --- src/main/java/classify/InputParsing.java | 38 ++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 4110211a91..2195acf179 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -22,6 +22,8 @@ public class InputParsing { private static final String CLASSES_ATTENDED = "Classes Attended: "; private static final String STUDENT_NOT_FOUND = "Student not found!"; private static final String STUDENT_ADDED_SUCCESSFULLY = "Student added successfully!"; + private static final String STUDENT_DELETED_SUCCESSFULLY = "Student removed successfully!"; + private static final String HELP = "help"; public static void parseUserCommand(String userCommand, ArrayList masterStudentList, Scanner in){ switch (userCommand) { @@ -36,6 +38,17 @@ public static void parseUserCommand(String userCommand, ArrayList maste Ui.printDivider(); break; + //@@author alalal47 + case DELETE: + in.nextLine(); + deleteStudent(masterStudentList, in); + break; + + case HELP: + printHelpMessage(); + Ui.printDivider(); + break; + //@@author ParthGandhiNUS case BYE: Ui.printEndConversation(); @@ -57,6 +70,31 @@ public static void parseUserCommand(String userCommand, ArrayList maste } } + //@@author alalal47 + private static void deleteStudent(ArrayList masterStudentList, Scanner in) { + System.out.print(ENTER_STUDENT_NAME); + String studentName = in.nextLine().trim(); + Student foundStudent = findStudentByName(masterStudentList, studentName); + if (foundStudent != null) { + System.out.println(NAME + foundStudent.getName()); + System.out.println(STUDENT_DELETED_SUCCESSFULLY); + } else { + System.out.println(STUDENT_NOT_FOUND); + } + Ui.printDivider(); + masterStudentList.remove(foundStudent); + } + + private static void printHelpMessage() { + System.out.println("add Adds a student to the student list, " + + "expects a name, grade and lessons attended"); + System.out.println("view Views a students details, expects a name"); + System.out.println("delete Deletes a student from the student list, expects a name"); + System.out.println("list Displays the list of all students"); + System.out.println("bye Exits Classify"); + System.out.println("help Prints this help message"); + } + //@@author tayponghee private static void viewStudent(ArrayList masterStudentList, Scanner in) { System.out.print(ENTER_STUDENT_NAME); From 7c782d29cf47af5a81d5f5d4770a71a9edfe5d19 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sun, 17 Mar 2024 00:05:55 +0800 Subject: [PATCH 034/503] Add JUnit test --- src/test/java/classify/InputParsingTest.java | 32 +++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/test/java/classify/InputParsingTest.java b/src/test/java/classify/InputParsingTest.java index 85d82a5e8b..126f3cbb84 100644 --- a/src/test/java/classify/InputParsingTest.java +++ b/src/test/java/classify/InputParsingTest.java @@ -29,7 +29,7 @@ public void testByeCommand() { assertEquals(expectedOutput.trim(), printedOutput); } - //@author blackmirag3 + //@@author blackmirag3 @Test public void testUnknownCommand() { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); @@ -42,4 +42,34 @@ public void testUnknownCommand() { System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; assertEquals(expectedOutput.trim(), printedOutput); } + + //@@author alalal47 + @Test + public void testHelpCommand() { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outputStream)); + + ArrayList masterStudentList = new ArrayList<>(); + InputParsing.parseUserCommand("help", masterStudentList, new Scanner(System.in)); + + System.setOut(System.out); + + String printedOutput = outputStream.toString().trim(); + String expectedOutput = + "add Adds a student to the student list, expects a name," + + " grade and lessons attended" + + System.lineSeparator() + + "view Views a students details, expects a name" + + System.lineSeparator() + + "delete Deletes a student from the student list, expects a name" + + System.lineSeparator() + + "list Displays the list of all students" + + System.lineSeparator() + + "bye Exits Classify" + + System.lineSeparator() + + "help Prints this help message" + + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; + + assertEquals(expectedOutput.trim(), printedOutput); + } } From 9e141e40e19f8a7db1c8baa915302c70c1debb2f Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 17 Mar 2024 13:53:48 +0800 Subject: [PATCH 035/503] Add support for multiple subjects and grades, with corresponding classes attended --- src/main/java/classify/InputParsing.java | 143 +++++++++++++++--- src/main/java/classify/student/Student.java | 5 +- .../classify/student/StudentAttributes.java | 49 +++--- .../java/classify/student/SubjectGrade.java | 25 +++ 4 files changed, 172 insertions(+), 50 deletions(-) create mode 100644 src/main/java/classify/student/SubjectGrade.java diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 2195acf179..c97a50c23a 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -3,8 +3,10 @@ import classify.student.Student; import classify.student.StudentAttributes; import classify.student.StudentList; +import classify.student.SubjectGrade; import java.util.ArrayList; +import java.util.List; import java.util.Scanner; public class InputParsing { @@ -15,6 +17,7 @@ public class InputParsing { private static final String DELETE = "delete"; private static final String WRONG_INPUT_MESSAGE = "Wrong Input! Please try again!"; //@@author tayponghee + private static final String ENTER_STUDENT_DETAILS = "Enter student details: "; private static final String ENTER_STUDENT_NAME = "Enter student name: "; private static final String STUDENT_DETAILS = "Student details:"; private static final String NAME = "Name: "; @@ -26,7 +29,7 @@ public class InputParsing { private static final String HELP = "help"; public static void parseUserCommand(String userCommand, ArrayList masterStudentList, Scanner in){ - switch (userCommand) { + switch (userCommand.toLowerCase()) { case ADD: in.nextLine(); addStudent(masterStudentList, in); @@ -96,6 +99,12 @@ private static void printHelpMessage() { } //@@author tayponghee + /** + * Displays the details of a specific student. + * + * @param masterStudentList The list of all students. + * @param in The scanner object to read user input. + */ private static void viewStudent(ArrayList masterStudentList, Scanner in) { System.out.print(ENTER_STUDENT_NAME); String studentName = in.nextLine(); @@ -103,26 +112,52 @@ private static void viewStudent(ArrayList masterStudentList, Scanner in if (foundStudent != null) { System.out.println(STUDENT_DETAILS); System.out.println(NAME + foundStudent.getName()); - System.out.println(GRADE + foundStudent.getAttributes().getGrade()); - System.out.println(CLASSES_ATTENDED + foundStudent.getAttributes().getClassesAttended()); + StudentAttributes attributes = foundStudent.getAttributes(); + if (attributes != null) { + List subjectGrades = attributes.getSubjectGrades(); + if (!subjectGrades.isEmpty()) { + for (SubjectGrade subjectGrade : subjectGrades) { + System.out.println("Subject: " + subjectGrade.getSubject()); + System.out.println("Grade: " + subjectGrade.getGrade()); + System.out.println("Classes Attended: " + subjectGrade.getClassesAttended()); + System.out.println(); + } + } else { + System.out.println("No subjects and grades found for this student."); + } + } else { + System.out.println("No attributes found for this student."); + } } else { System.out.println(STUDENT_NOT_FOUND); } } + /** + * Adds a new student to the list of students. + * Does not allow for students of the same name to be added. + * Checks if attributes added are in the correct format. + * Allows for multiple subjects to be added, along with their grades and classes + * attended. + * + * @param masterStudentList The list of all students. + * @param in The scanner object to read user input. + */ private static void addStudent(ArrayList masterStudentList, Scanner in) { - System.out.println(ENTER_STUDENT_NAME); - + System.out.println(ENTER_STUDENT_DETAILS); System.out.print(NAME); String name = in.nextLine().trim(); - System.out.print(GRADE); - double grade = parseDoubleInput(in.nextLine()); + if (findStudentByName(masterStudentList, name) != null) { + System.out.println("Student with the same name already exists. Please enter a different name."); + Ui.printDivider(); + return; + } + + StudentAttributes attributes = new StudentAttributes(name); - System.out.print(CLASSES_ATTENDED); - int classesAttended = parseIntegerInput(in.nextLine()); + attributeInput(in, attributes); - StudentAttributes attributes = new StudentAttributes(name, grade, classesAttended); Student student = new Student(name, attributes); masterStudentList.add(student); @@ -130,24 +165,88 @@ private static void addStudent(ArrayList masterStudentList, Scanner in) Ui.printDivider(); } - private static double parseDoubleInput(String input) { - try { - return Double.parseDouble(input); - } catch (NumberFormatException e) { - System.out.println("Invalid input for grade. Please enter a valid number."); - return 0; + private static void attributeInput(Scanner in, StudentAttributes attributes) { + while (true) { + System.out.print("Subject: "); + String subject = in.nextLine().trim(); + double grade = checkForGradeFormat(in); + int classesAttended = checkForClassesAttendedFormat(in); + + SubjectGrade subjectGrade = new SubjectGrade(subject, grade, classesAttended); + + attributes.addSubjectGrade(subjectGrade); + + System.out.println("Do you want to add another subject and grade? (yes/no)"); + String response = in.nextLine().trim().toLowerCase(); + if (!response.equals("yes")) { + break; + } } } - private static int parseIntegerInput(String input) { - try { - return Integer.parseInt(input); - } catch (NumberFormatException e) { - System.out.println("Invalid input for classes attended. Please enter a valid number."); - return 0; + /** + * Checks the format of the input for the number of classes attended. + * Prompts the user to enter a valid integer until one is provided. + * + * @param in The scanner object to read user input. + * @return The valid number of classes attended. + */ + private static int checkForClassesAttendedFormat(Scanner in) { + int classesAttended; + while (true) { + System.out.print(CLASSES_ATTENDED); + String classesAttendedInput = in.nextLine(); + try { + classesAttended = Integer.parseInt(classesAttendedInput); + if (classesAttended < 0) { + System.out.println("Classes attended must be 0 or more."); + Ui.printDivider(); + continue; + } + break; + } catch (NumberFormatException e) { + System.out.println("Invalid input for classes attended. Please enter a valid whole number."); + Ui.printDivider(); + } + } + return classesAttended; + } + + /** + * Checks the format of the input for the grade. + * Prompts the user to enter a valid double within the range [0, 100] until one is provided. + * + * @param in The scanner object to read user input. + * @return The valid grade. + */ + private static double checkForGradeFormat(Scanner in) { + double grade; + while (true) { + System.out.print(GRADE); + String gradeInput = in.nextLine(); + try { + grade = Double.parseDouble(gradeInput); + if (grade < 0 || grade > 100) { + System.out.println("Grade must be between 0 and 100. Please enter a valid number."); + Ui.printDivider(); + continue; + } + break; + } catch (NumberFormatException e) { + System.out.println("Invalid input for grade. Please enter a valid number."); + Ui.printDivider(); + } } + return grade; } + /** + * Finds a student in the list by their name. + * + * @param masterStudentList The list of all students. + * @param name The name of the student to search for. + * @return The student object if found, null otherwise. + */ private static Student findStudentByName(ArrayList masterStudentList, String name) { for (Student student : masterStudentList) { if (student.getName().equalsIgnoreCase(name)) { diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 4867f49496..6664575b35 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -25,7 +25,7 @@ public Student(String name, Details details) { this.details = details; } - //@@ tayponghee + //@@author tayponghee public Student(String name, StudentAttributes attributes) { this.name = name; this.attributes = attributes; @@ -38,6 +38,9 @@ public StudentAttributes getAttributes() { public void setAttributes(StudentAttributes attributes) { this.attributes = attributes; } + public StudentAttributes getAttributesList() { + return attributes; + } //@@ Cryolian public String getName() { diff --git a/src/main/java/classify/student/StudentAttributes.java b/src/main/java/classify/student/StudentAttributes.java index 7962f9b1b5..c785a847ab 100644 --- a/src/main/java/classify/student/StudentAttributes.java +++ b/src/main/java/classify/student/StudentAttributes.java @@ -1,48 +1,43 @@ package classify.student; +import java.util.ArrayList; +import java.util.List; + public class StudentAttributes { private String name; - private double grade; - private int classesAttended; + private List subjectGrades; - public StudentAttributes(String name, double grade, int classesAttended) { + public StudentAttributes(String name) { this.name = name; - this.grade = grade; - this.classesAttended = classesAttended; - } - - public String getName() { - return name; + this.subjectGrades = new ArrayList<>(); } - public void setName(String name) { - this.name = name; + public void addSubjectGrade(SubjectGrade subjectGrade) { + subjectGrades.add(subjectGrade); } - public double getGrade() { - return grade; + public List getSubjectGrades() { + return subjectGrades; } - public void setGrade(double grade) { - this.grade = grade; - } - - public int getClassesAttended() { - return classesAttended; + public String getName() { + return name; } - public void setClassesAttended(int classesAttended) { - this.classesAttended = classesAttended; + public void setName(String name) { + this.name = name; } - @Override public String toString() { - return "StudentAttributes{" + + StringBuilder sb = new StringBuilder(); + sb.append("StudentAttributes{" + "name='" + name + '\'' + - ", grade=" + grade + - ", classesAttended=" + classesAttended + - '}'; + ", subjectGrades=["); + for (SubjectGrade subjectGrade : subjectGrades) { + sb.append(subjectGrade.toString()).append(", "); + } + sb.append("]}"); + return sb.toString(); } } - diff --git a/src/main/java/classify/student/SubjectGrade.java b/src/main/java/classify/student/SubjectGrade.java new file mode 100644 index 0000000000..bf8a4c4d38 --- /dev/null +++ b/src/main/java/classify/student/SubjectGrade.java @@ -0,0 +1,25 @@ +package classify.student; + +public class SubjectGrade { + private String subject; + private double grade; + private int classesAttended; + + public SubjectGrade(String subject, double grade, int classesAttended) { + this.subject = subject; + this.grade = grade; + this.classesAttended = classesAttended; + } + + public String getSubject() { + return subject; + } + + public double getGrade() { + return grade; + } + + public int getClassesAttended() { + return classesAttended; + } +} From d56f89d73b94c5abd29e815f458b9381a97d0c62 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Mon, 18 Mar 2024 14:19:52 +0800 Subject: [PATCH 036/503] Add logging for View [Student] method, refactor method --- src/main/java/classify/InputParsing.java | 41 ++++++++++++++++-------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index c97a50c23a..07d2d6b048 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -8,6 +8,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; public class InputParsing { private static final String BYE = "bye"; @@ -27,6 +29,8 @@ public class InputParsing { private static final String STUDENT_ADDED_SUCCESSFULLY = "Student added successfully!"; private static final String STUDENT_DELETED_SUCCESSFULLY = "Student removed successfully!"; private static final String HELP = "help"; + private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); + public static void parseUserCommand(String userCommand, ArrayList masterStudentList, Scanner in){ switch (userCommand.toLowerCase()) { @@ -110,26 +114,37 @@ private static void viewStudent(ArrayList masterStudentList, Scanner in String studentName = in.nextLine(); Student foundStudent = findStudentByName(masterStudentList, studentName); if (foundStudent != null) { + logger.log(Level.INFO, "Viewing student details: " + studentName); System.out.println(STUDENT_DETAILS); System.out.println(NAME + foundStudent.getName()); StudentAttributes attributes = foundStudent.getAttributes(); - if (attributes != null) { - List subjectGrades = attributes.getSubjectGrades(); - if (!subjectGrades.isEmpty()) { - for (SubjectGrade subjectGrade : subjectGrades) { - System.out.println("Subject: " + subjectGrade.getSubject()); - System.out.println("Grade: " + subjectGrade.getGrade()); - System.out.println("Classes Attended: " + subjectGrade.getClassesAttended()); - System.out.println(); - } - } else { - System.out.println("No subjects and grades found for this student."); + showAttributes(attributes); + } else { + logger.log(Level.WARNING, "Student not found: " + studentName); + System.out.println(STUDENT_NOT_FOUND); + } + } + + /** + * Displays the attributes of a student. + * + * @param attributes The attributes of the student to display. + */ + private static void showAttributes(StudentAttributes attributes) { + if (attributes != null) { + List subjectGrades = attributes.getSubjectGrades(); + if (!subjectGrades.isEmpty()) { + for (SubjectGrade subjectGrade : subjectGrades) { + System.out.println("Subject: " + subjectGrade.getSubject()); + System.out.println("Grade: " + subjectGrade.getGrade()); + System.out.println("Classes Attended: " + subjectGrade.getClassesAttended()); + System.out.println(); } } else { - System.out.println("No attributes found for this student."); + System.out.println("No subjects and grades found for this student."); } } else { - System.out.println(STUDENT_NOT_FOUND); + System.out.println("No attributes found for this student."); } } From df86abc0bf32fe39495dd3cf405f15a32f2945e8 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Mon, 18 Mar 2024 14:37:23 +0800 Subject: [PATCH 037/503] Add logging for Add student method --- src/main/java/classify/InputParsing.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 07d2d6b048..9f0b226cc6 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -23,13 +23,14 @@ public class InputParsing { private static final String ENTER_STUDENT_NAME = "Enter student name: "; private static final String STUDENT_DETAILS = "Student details:"; private static final String NAME = "Name: "; - private static final String GRADE = "Grade: "; private static final String CLASSES_ATTENDED = "Classes Attended: "; private static final String STUDENT_NOT_FOUND = "Student not found!"; private static final String STUDENT_ADDED_SUCCESSFULLY = "Student added successfully!"; private static final String STUDENT_DELETED_SUCCESSFULLY = "Student removed successfully!"; private static final String HELP = "help"; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); + public static final String SUBJECT = "Subject: "; + public static final String CURRENT_MARKS_OUT_OF_100 = "Current marks out of 100: "; public static void parseUserCommand(String userCommand, ArrayList masterStudentList, Scanner in){ @@ -94,7 +95,7 @@ private static void deleteStudent(ArrayList masterStudentList, Scanner private static void printHelpMessage() { System.out.println("add Adds a student to the student list, " + - "expects a name, grade and lessons attended"); + "expects a name, grades and lessons attended"); System.out.println("view Views a students details, expects a name"); System.out.println("delete Deletes a student from the student list, expects a name"); System.out.println("list Displays the list of all students"); @@ -135,8 +136,8 @@ private static void showAttributes(StudentAttributes attributes) { List subjectGrades = attributes.getSubjectGrades(); if (!subjectGrades.isEmpty()) { for (SubjectGrade subjectGrade : subjectGrades) { - System.out.println("Subject: " + subjectGrade.getSubject()); - System.out.println("Grade: " + subjectGrade.getGrade()); + System.out.println(SUBJECT + subjectGrade.getSubject()); + System.out.println(CURRENT_MARKS_OUT_OF_100 + subjectGrade.getGrade()); System.out.println("Classes Attended: " + subjectGrade.getClassesAttended()); System.out.println(); } @@ -164,18 +165,18 @@ private static void addStudent(ArrayList masterStudentList, Scanner in) String name = in.nextLine().trim(); if (findStudentByName(masterStudentList, name) != null) { + logger.log(Level.WARNING, "Student with the same name already exists."); System.out.println("Student with the same name already exists. Please enter a different name."); Ui.printDivider(); return; } StudentAttributes attributes = new StudentAttributes(name); - attributeInput(in, attributes); - Student student = new Student(name, attributes); masterStudentList.add(student); + logger.log(Level.INFO, "Student added successfully."); System.out.println(STUDENT_ADDED_SUCCESSFULLY); Ui.printDivider(); } @@ -220,6 +221,7 @@ private static int checkForClassesAttendedFormat(Scanner in) { } break; } catch (NumberFormatException e) { + logger.log(Level.WARNING, "Invalid input for classes attended: " + classesAttendedInput, e); System.out.println("Invalid input for classes attended. Please enter a valid whole number."); Ui.printDivider(); } @@ -237,7 +239,7 @@ private static int checkForClassesAttendedFormat(Scanner in) { private static double checkForGradeFormat(Scanner in) { double grade; while (true) { - System.out.print(GRADE); + System.out.print(CURRENT_MARKS_OUT_OF_100); String gradeInput = in.nextLine(); try { grade = Double.parseDouble(gradeInput); @@ -248,6 +250,7 @@ private static double checkForGradeFormat(Scanner in) { } break; } catch (NumberFormatException e) { + logger.log(Level.WARNING, "Invalid input for grade: " + gradeInput, e); System.out.println("Invalid input for grade. Please enter a valid number."); Ui.printDivider(); } From 366a5c4b15a111a9743e2cb97ca96cd3b8dda7fd Mon Sep 17 00:00:00 2001 From: tayponghee Date: Mon, 18 Mar 2024 14:39:15 +0800 Subject: [PATCH 038/503] Fix checkstyle errors --- src/main/java/classify/InputParsing.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 9f0b226cc6..d01ec1d3b5 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -29,8 +29,8 @@ public class InputParsing { private static final String STUDENT_DELETED_SUCCESSFULLY = "Student removed successfully!"; private static final String HELP = "help"; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); - public static final String SUBJECT = "Subject: "; - public static final String CURRENT_MARKS_OUT_OF_100 = "Current marks out of 100: "; + private static final String SUBJECT = "Subject: "; + private static final String CURRENT_MARKS_OUT_OF_100 = "Current marks out of 100: "; public static void parseUserCommand(String userCommand, ArrayList masterStudentList, Scanner in){ @@ -95,7 +95,7 @@ private static void deleteStudent(ArrayList masterStudentList, Scanner private static void printHelpMessage() { System.out.println("add Adds a student to the student list, " + - "expects a name, grades and lessons attended"); + "expects a name, grade and lessons attended"); System.out.println("view Views a students details, expects a name"); System.out.println("delete Deletes a student from the student list, expects a name"); System.out.println("list Displays the list of all students"); From e9abab943498b247bede36c3a6ef704661b4f11b Mon Sep 17 00:00:00 2001 From: tayponghee Date: Mon, 18 Mar 2024 15:28:49 +0800 Subject: [PATCH 039/503] Add assertions for view and add student. Fix bug for add student. --- src/main/java/classify/InputParsing.java | 62 ++++++++++++++++++++---- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index d01ec1d3b5..cd4c0fc36c 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -113,6 +113,9 @@ private static void printHelpMessage() { private static void viewStudent(ArrayList masterStudentList, Scanner in) { System.out.print(ENTER_STUDENT_NAME); String studentName = in.nextLine(); + + assert studentName != null : "Student name cannot be null"; + Student foundStudent = findStudentByName(masterStudentList, studentName); if (foundStudent != null) { logger.log(Level.INFO, "Viewing student details: " + studentName); @@ -161,18 +164,20 @@ private static void showAttributes(StudentAttributes attributes) { */ private static void addStudent(ArrayList masterStudentList, Scanner in) { System.out.println(ENTER_STUDENT_DETAILS); - System.out.print(NAME); - String name = in.nextLine().trim(); + String name; + name = checkForEmptyName(masterStudentList, in); + assert name != null : "Student name cannot be empty"; + StudentAttributes attributes = new StudentAttributes(name); + attributeInput(in, attributes); - if (findStudentByName(masterStudentList, name) != null) { - logger.log(Level.WARNING, "Student with the same name already exists."); - System.out.println("Student with the same name already exists. Please enter a different name."); + if (attributes.getSubjectGrades().isEmpty()) { + System.out.println("At least one subject must be provided. Please add subjects and grades."); Ui.printDivider(); - return; + attributeInput(in, attributes); } - StudentAttributes attributes = new StudentAttributes(name); - attributeInput(in, attributes); + assert attributes.getSubjectGrades() != null : "Subject cannot be empty"; + Student student = new Student(name, attributes); masterStudentList.add(student); @@ -181,15 +186,54 @@ private static void addStudent(ArrayList masterStudentList, Scanner in) Ui.printDivider(); } + /** + * Prompts the user to enter a non-empty name for a student and checks if it already exists in the list. + * If the name is empty or already exists, prompts the user again until valid input is provided. + * + * @param masterStudentList The list of all students. + * @param in The scanner object to read user input. + * @return The valid non-empty name entered by the user. + */ + private static String checkForEmptyName(ArrayList masterStudentList, Scanner in) { + String name; + while (true) { + System.out.print(NAME); + name = in.nextLine().trim(); + if (name.isEmpty()) { + System.out.println("Student name cannot be empty. Please enter a valid name."); + Ui.printDivider(); + } else if (findStudentByName(masterStudentList, name) != null) { + logger.log(Level.WARNING, "Student with the same name already exists."); + System.out.println("Student with the same name already exists. Please enter a different name."); + Ui.printDivider(); + } else { + break; + } + } + return name; + } + + /** + * Prompts the user to enter attributes for a student, including subject, grade, and classes attended. + * Continues to prompt the user until at least one subject and grade are provided. + * + * @param in The scanner object to read user input. + * @param attributes The StudentAttributes object to store the attributes of the student. + */ private static void attributeInput(Scanner in, StudentAttributes attributes) { while (true) { System.out.print("Subject: "); String subject = in.nextLine().trim(); + if (subject.isEmpty()) { + logger.log(Level.WARNING, "Empty subject provided."); + System.out.println("Subject cannot be empty. Please enter a valid subject."); + Ui.printDivider(); + continue; + } double grade = checkForGradeFormat(in); int classesAttended = checkForClassesAttendedFormat(in); SubjectGrade subjectGrade = new SubjectGrade(subject, grade, classesAttended); - attributes.addSubjectGrade(subjectGrade); System.out.println("Do you want to add another subject and grade? (yes/no)"); From cfbed2f140e8b191fbe54cfc0a04c2b6d9e268cc Mon Sep 17 00:00:00 2001 From: Cryolian Date: Mon, 18 Mar 2024 18:37:53 +0800 Subject: [PATCH 040/503] Add minor assertions --- src/main/java/classify/classgroup/Class.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/classify/classgroup/Class.java b/src/main/java/classify/classgroup/Class.java index 963055d37d..c8d59578c5 100644 --- a/src/main/java/classify/classgroup/Class.java +++ b/src/main/java/classify/classgroup/Class.java @@ -22,6 +22,8 @@ public class Class { public Class(int ageOfStudents, String className) { this.ageOfStudents = ageOfStudents; this.className = className; + assert this.ageOfStudents == ageOfStudents : "class attribute should be equal to constructor"; + assert this.className == className : "class attribute should be equal to constructor"; } /** From d590b94f1ea4a47dae1a320c3d003082fcaeb508 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Tue, 19 Mar 2024 18:04:30 +0800 Subject: [PATCH 041/503] Implement functionality for using add, delete and view functions by invoking them with a name parameter as well as the ability to use them without a name parameter and fill it in after --- src/main/java/classify/Classify.java | 8 +- src/main/java/classify/InputParsing.java | 92 ++++++++++++++------ src/main/java/classify/UserInput.java | 14 ++- src/test/java/classify/InputParsingTest.java | 25 ++++-- 4 files changed, 95 insertions(+), 44 deletions(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index a7d27b13a7..3724b9fbe7 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -15,13 +15,13 @@ public static void main(String[] args) { // CAA: 9 March 2024 1pm Ui.printWelcomeMessage(); // Takes in only the first word input by the user - String userCommand = UserInput.processInput(in.next()); + String[] userCommand = UserInput.processInput(in.nextLine()); //Set up polling for the first word input by the user. // If user's first word is "bye", will exit the while loop. - while (!(userCommand.equals("bye"))){ - InputParsing.parseUserCommand(UserInput.processInput(userCommand), StudentList.masterStudentList, in); - userCommand = in.next(); + while (!(userCommand[0].equals("bye"))){ + InputParsing.parseUserCommand(userCommand, StudentList.masterStudentList, in); + userCommand = UserInput.processInput(in.nextLine()); } Ui.printEndConversation(); diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index cd4c0fc36c..2858c515c8 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -12,12 +12,13 @@ import java.util.logging.Logger; public class InputParsing { + private static final String NOTEMPTY = "THIS STRING IS NOT EMPTY"; private static final String BYE = "bye"; private static final String LIST = "list"; private static final String ADD = "add"; private static final String VIEW = "view"; private static final String DELETE = "delete"; - private static final String WRONG_INPUT_MESSAGE = "Wrong Input! Please try again!"; + private static final String WRONG_INPUT_MESSAGE = "No such command, type \"help\" to view all commands"; //@@author tayponghee private static final String ENTER_STUDENT_DETAILS = "Enter student details: "; private static final String ENTER_STUDENT_NAME = "Enter student name: "; @@ -33,23 +34,20 @@ public class InputParsing { private static final String CURRENT_MARKS_OUT_OF_100 = "Current marks out of 100: "; - public static void parseUserCommand(String userCommand, ArrayList masterStudentList, Scanner in){ - switch (userCommand.toLowerCase()) { + public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, Scanner in){ + switch (userCommand[0]) { case ADD: - in.nextLine(); - addStudent(masterStudentList, in); + addStudent(masterStudentList, in, userCommand[1]); break; case VIEW: - in.nextLine(); - viewStudent(masterStudentList, in); + viewStudent(masterStudentList, in, userCommand[1]); Ui.printDivider(); break; //@@author alalal47 case DELETE: - in.nextLine(); - deleteStudent(masterStudentList, in); + deleteStudent(masterStudentList, in, userCommand[1]); break; case HELP: @@ -79,10 +77,23 @@ public static void parseUserCommand(String userCommand, ArrayList maste } //@@author alalal47 - private static void deleteStudent(ArrayList masterStudentList, Scanner in) { - System.out.print(ENTER_STUDENT_NAME); - String studentName = in.nextLine().trim(); - Student foundStudent = findStudentByName(masterStudentList, studentName); + /** + * Removes a student from the list. + * + * @param masterStudentList The list of all students. + * @param in The scanner object to read user input. + * @param studentName The name of the student if the user had entered it before being prompted + */ + private static void deleteStudent(ArrayList masterStudentList, Scanner in, String studentName) { + String name; + if (studentName == null) { + System.out.print(ENTER_STUDENT_NAME); + name = in.nextLine().trim(); + } else { + name = studentName; + } + + Student foundStudent = findStudentByName(masterStudentList, name); if (foundStudent != null) { System.out.println(NAME + foundStudent.getName()); System.out.println(STUDENT_DELETED_SUCCESSFULLY); @@ -93,11 +104,17 @@ private static void deleteStudent(ArrayList masterStudentList, Scanner masterStudentList.remove(foundStudent); } + /** + * Displays the help message to teach users how to use Classify. + */ private static void printHelpMessage() { System.out.println("add Adds a student to the student list, " + - "expects a name, grade and lessons attended"); - System.out.println("view Views a students details, expects a name"); - System.out.println("delete Deletes a student from the student list, expects a name"); + "expects a name, grade and lessons attended" + + ", can be used directly with a name e.g. add [name]"); + System.out.println("view Views a students details, expects a name" + + ", can be used directly with a name e.g. add [name]"); + System.out.println("delete Deletes a student from the student list, expects a name" + + ", can be used directly with a name e.g. add [name]"); System.out.println("list Displays the list of all students"); System.out.println("bye Exits Classify"); System.out.println("help Prints this help message"); @@ -109,22 +126,28 @@ private static void printHelpMessage() { * * @param masterStudentList The list of all students. * @param in The scanner object to read user input. + * @param studentName The name of the student if the user had entered it before being prompted */ - private static void viewStudent(ArrayList masterStudentList, Scanner in) { - System.out.print(ENTER_STUDENT_NAME); - String studentName = in.nextLine(); + private static void viewStudent(ArrayList masterStudentList, Scanner in, String studentName) { + String name; + if (studentName == null) { + System.out.print(ENTER_STUDENT_NAME); + name = in.nextLine(); + } else { + name = studentName; + } - assert studentName != null : "Student name cannot be null"; + assert name != null : "Student name cannot be null"; - Student foundStudent = findStudentByName(masterStudentList, studentName); + Student foundStudent = findStudentByName(masterStudentList, name); if (foundStudent != null) { - logger.log(Level.INFO, "Viewing student details: " + studentName); + logger.log(Level.INFO, "Viewing student details: " + name); System.out.println(STUDENT_DETAILS); System.out.println(NAME + foundStudent.getName()); StudentAttributes attributes = foundStudent.getAttributes(); showAttributes(attributes); } else { - logger.log(Level.WARNING, "Student not found: " + studentName); + logger.log(Level.WARNING, "Student not found: " + name); System.out.println(STUDENT_NOT_FOUND); } } @@ -161,11 +184,16 @@ private static void showAttributes(StudentAttributes attributes) { * * @param masterStudentList The list of all students. * @param in The scanner object to read user input. + * @param studentName The name of the student if the user had entered it before being prompted */ - private static void addStudent(ArrayList masterStudentList, Scanner in) { - System.out.println(ENTER_STUDENT_DETAILS); + private static void addStudent(ArrayList masterStudentList, Scanner in, String studentName) { String name; - name = checkForEmptyName(masterStudentList, in); + if (studentName == null) { + System.out.println(ENTER_STUDENT_DETAILS); + name = checkForEmptyName(masterStudentList, in, studentName); + } else { + name = checkForEmptyName(masterStudentList,in, studentName); + } assert name != null : "Student name cannot be empty"; StudentAttributes attributes = new StudentAttributes(name); attributeInput(in, attributes); @@ -192,13 +220,19 @@ private static void addStudent(ArrayList masterStudentList, Scanner in) * * @param masterStudentList The list of all students. * @param in The scanner object to read user input. + * @param studentName The name of the student if the user had entered it before being prompted * @return The valid non-empty name entered by the user. */ - private static String checkForEmptyName(ArrayList masterStudentList, Scanner in) { + private static String checkForEmptyName(ArrayList masterStudentList, Scanner in, String studentName) { String name; while (true) { - System.out.print(NAME); - name = in.nextLine().trim(); + if (studentName == null) { + System.out.print(NAME); + name = in.nextLine().trim(); + } else { + name = studentName.trim(); + studentName = NOTEMPTY; + } if (name.isEmpty()) { System.out.println("Student name cannot be empty. Please enter a valid name."); Ui.printDivider(); diff --git a/src/main/java/classify/UserInput.java b/src/main/java/classify/UserInput.java index 6a23a34172..16064c3514 100644 --- a/src/main/java/classify/UserInput.java +++ b/src/main/java/classify/UserInput.java @@ -1,12 +1,20 @@ package classify; public class UserInput { + //@@author alalal47 /** * Used to process the different variations of the users inputs * @param userInput : String which the user inputs - * @return String which is in lowercase and clear of any unnecessary whitespace + * @return String[] which contains the command in [0] and name in [1] if the user chose to input it */ - public static String processInput(String userInput){ - return (userInput.trim()).toLowerCase(); + public static String[] processInput(String userInput){ + String[] commandWithName = new String[2]; + if (userInput.trim().contains(" ")) { + commandWithName = userInput.split(" ", 2); + } else { + commandWithName[0] = userInput; + } + commandWithName[0] = commandWithName[0].toLowerCase(); + return commandWithName; } } diff --git a/src/test/java/classify/InputParsingTest.java b/src/test/java/classify/InputParsingTest.java index 126f3cbb84..9fa4545a82 100644 --- a/src/test/java/classify/InputParsingTest.java +++ b/src/test/java/classify/InputParsingTest.java @@ -18,7 +18,9 @@ public void testByeCommand() { System.setOut(new PrintStream(outputStream)); ArrayList masterStudentList = new ArrayList<>(); - InputParsing.parseUserCommand("bye", masterStudentList, new Scanner(System.in)); + String [] commands = new String[2]; + commands[0] = "bye"; + InputParsing.parseUserCommand(commands, masterStudentList, new Scanner(System.in)); System.setOut(System.out); @@ -35,10 +37,12 @@ public void testUnknownCommand() { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); System.setOut(new PrintStream(outputStream)); ArrayList students = new ArrayList<>(); - InputParsing.parseUserCommand("yeet", students, new Scanner(System.in)); + String [] commands = new String[2]; + commands[0] = "yeet"; + InputParsing.parseUserCommand(commands, students, new Scanner(System.in)); System.setOut(System.out); String printedOutput = outputStream.toString().trim(); - String expectedOutput = "Wrong Input! Please try again!" + + String expectedOutput = "No such command, type \"help\" to view all commands" + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; assertEquals(expectedOutput.trim(), printedOutput); } @@ -50,18 +54,23 @@ public void testHelpCommand() { System.setOut(new PrintStream(outputStream)); ArrayList masterStudentList = new ArrayList<>(); - InputParsing.parseUserCommand("help", masterStudentList, new Scanner(System.in)); + String [] commands = new String[2]; + commands[0] = "help"; + InputParsing.parseUserCommand(commands, masterStudentList, new Scanner(System.in)); System.setOut(System.out); String printedOutput = outputStream.toString().trim(); String expectedOutput = - "add Adds a student to the student list, expects a name," + - " grade and lessons attended" + "add Adds a student to the student list, expects a name" + + ", grade and lessons attended," + + " can be used directly with a name e.g. add [name]" + System.lineSeparator() + - "view Views a students details, expects a name" + "view Views a students details, expects a name" + + ", can be used directly with a name e.g. add [name]" + System.lineSeparator() + - "delete Deletes a student from the student list, expects a name" + "delete Deletes a student from the student list, expects a name" + + ", can be used directly with a name e.g. add [name]" + System.lineSeparator() + "list Displays the list of all students" + System.lineSeparator() + From 8816cb5713c32ae6b0e9803bfa58bc149dcac441 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Tue, 19 Mar 2024 20:34:00 +0800 Subject: [PATCH 042/503] Make student attributes optional when adding student --- src/main/java/classify/InputParsing.java | 43 ++++++++----------- src/main/java/classify/fallenCode.java | 8 ++++ .../java/classify/student/SubjectGrade.java | 6 +++ 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 2858c515c8..5d6c044154 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -197,18 +197,8 @@ private static void addStudent(ArrayList masterStudentList, Scanner in, assert name != null : "Student name cannot be empty"; StudentAttributes attributes = new StudentAttributes(name); attributeInput(in, attributes); - - if (attributes.getSubjectGrades().isEmpty()) { - System.out.println("At least one subject must be provided. Please add subjects and grades."); - Ui.printDivider(); - attributeInput(in, attributes); - } - - assert attributes.getSubjectGrades() != null : "Subject cannot be empty"; - Student student = new Student(name, attributes); masterStudentList.add(student); - logger.log(Level.INFO, "Student added successfully."); System.out.println(STUDENT_ADDED_SUCCESSFULLY); Ui.printDivider(); @@ -256,25 +246,26 @@ private static String checkForEmptyName(ArrayList masterStudentList, Sc */ private static void attributeInput(Scanner in, StudentAttributes attributes) { while (true) { - System.out.print("Subject: "); + System.out.print("Subject (enter nothing to skip): "); String subject = in.nextLine().trim(); - if (subject.isEmpty()) { - logger.log(Level.WARNING, "Empty subject provided."); - System.out.println("Subject cannot be empty. Please enter a valid subject."); - Ui.printDivider(); - continue; - } - double grade = checkForGradeFormat(in); - int classesAttended = checkForClassesAttendedFormat(in); - - SubjectGrade subjectGrade = new SubjectGrade(subject, grade, classesAttended); - attributes.addSubjectGrade(subjectGrade); - - System.out.println("Do you want to add another subject and grade? (yes/no)"); - String response = in.nextLine().trim().toLowerCase(); - if (!response.equals("yes")) { + //@author blackmirag3 + if (subject.isBlank()) { + SubjectGrade subjectGrade = new SubjectGrade(); + attributes.addSubjectGrade(subjectGrade); break; } + //@author tayponghee + else { + double grade = checkForGradeFormat(in); + int classesAttended = checkForClassesAttendedFormat(in); + SubjectGrade subjectGrade = new SubjectGrade(subject, grade, classesAttended); + attributes.addSubjectGrade(subjectGrade); + System.out.println("Do you want to add another subject and grade? (yes/no)"); + String response = in.nextLine().trim().toLowerCase(); + if (!response.equals("yes")) { + break; + } + } } } diff --git a/src/main/java/classify/fallenCode.java b/src/main/java/classify/fallenCode.java index d6304cf75e..7b402cb683 100644 --- a/src/main/java/classify/fallenCode.java +++ b/src/main/java/classify/fallenCode.java @@ -43,4 +43,12 @@ public class fallenCode { // public void addStudent(Student s) { // this.studentList.addStudent(s); // } + + /* + //@author tayponghee + if (attributes.getSubjectGrades().isEmpty()) { + System.out.println("At least one subject must be provided. Please add subjects and grades."); + Ui.printDivider(); + attributeInput(in, attributes); + }*/ } diff --git a/src/main/java/classify/student/SubjectGrade.java b/src/main/java/classify/student/SubjectGrade.java index bf8a4c4d38..8358509e3a 100644 --- a/src/main/java/classify/student/SubjectGrade.java +++ b/src/main/java/classify/student/SubjectGrade.java @@ -5,6 +5,12 @@ public class SubjectGrade { private double grade; private int classesAttended; + private final String EMPTY = "unspecified"; + + public SubjectGrade() { + this.subject = EMPTY; + } + public SubjectGrade(String subject, double grade, int classesAttended) { this.subject = subject; this.grade = grade; From a3c48b895c507f69729d3986c7cc6274785f9c6b Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Tue, 19 Mar 2024 21:41:26 +0800 Subject: [PATCH 043/503] Add JUnit Test --- src/test/java/classify/classgroup/ClassTest.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/test/java/classify/classgroup/ClassTest.java b/src/test/java/classify/classgroup/ClassTest.java index 29b95d3da0..ad2a3c1eba 100644 --- a/src/test/java/classify/classgroup/ClassTest.java +++ b/src/test/java/classify/classgroup/ClassTest.java @@ -1,5 +1,12 @@ package classify.classgroup; -public class ClassTest { +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class ClassTest { + public void classConstructorTest() { + Class newClass = new Class(17,"J1 Physics"); + assertEquals(17, newClass.getAgeOfStudents()); + assertEquals("J1 Physics",newClass.getClassName()); + } } From 624abdb2a7a4d92e6b4e248dee7b0ba66ee81b12 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Wed, 20 Mar 2024 00:10:05 +0800 Subject: [PATCH 044/503] Update Ui output --- src/main/java/classify/InputParsing.java | 170 ++++++++++++++++-- src/main/java/classify/fallenCode.java | 2 +- src/main/java/classify/student/Student.java | 3 - .../classify/student/StudentAttributes.java | 21 +++ .../java/classify/student/StudentList.java | 1 - .../java/classify/student/SubjectGrade.java | 12 ++ 6 files changed, 187 insertions(+), 22 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 5d6c044154..1c1a951ea3 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -18,23 +18,30 @@ public class InputParsing { private static final String ADD = "add"; private static final String VIEW = "view"; private static final String DELETE = "delete"; + //@@author blackmirag3 + private static final String EDIT = "edit"; private static final String WRONG_INPUT_MESSAGE = "No such command, type \"help\" to view all commands"; //@@author tayponghee private static final String ENTER_STUDENT_DETAILS = "Enter student details: "; private static final String ENTER_STUDENT_NAME = "Enter student name: "; - private static final String STUDENT_DETAILS = "Student details:"; + private static final String STUDENT_DETAILS = "Student details: "; private static final String NAME = "Name: "; - private static final String CLASSES_ATTENDED = "Classes Attended: "; + private static final String CLASSES_ATTENDED = "Classes Attended (blank to skip): "; private static final String STUDENT_NOT_FOUND = "Student not found!"; private static final String STUDENT_ADDED_SUCCESSFULLY = "Student added successfully!"; private static final String STUDENT_DELETED_SUCCESSFULLY = "Student removed successfully!"; private static final String HELP = "help"; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); private static final String SUBJECT = "Subject: "; - private static final String CURRENT_MARKS_OUT_OF_100 = "Current marks out of 100: "; + private static final String CURRENT_MARKS_OUT_OF_100 = "Current marks out of 100 (blank to skip) : "; public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, Scanner in){ + //@@author blackmirag3 + if (masterStudentList == null) { + System.out.println("Student list is null."); + } + //@@author tayponghee switch (userCommand[0]) { case ADD: addStudent(masterStudentList, in, userCommand[1]); @@ -61,12 +68,11 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas break; case LIST: - if (masterStudentList != null) { - StudentList.printCurrentArrayList(masterStudentList); - } else { - System.out.println("Student list is null."); - } - Ui.printDivider(); + listStudents(masterStudentList); + break; + + case EDIT: + editStudent(masterStudentList, in, userCommand[1]); break; default: @@ -75,6 +81,82 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas break; } } + //@@author blackmirag3 + private static void listStudents(ArrayList list) { + if (list.isEmpty()) { + System.out.println("Currently no students in list."); + } + else { + StudentList.printCurrentArrayList(list); + } + Ui.printDivider(); + } + + private static void editStudent(ArrayList list, Scanner in, String name) { + if (list.isEmpty()) { + System.out.println("Currently no students in list."); + return; + } + Student student = null; + if (name != null) { + student = findStudentByName(list, name); + if (student == null) { + System.out.println(STUDENT_NOT_FOUND); + } + } + while (student == null) { + System.out.println("Name of student to edit (enter blank to exit):"); + name = in.nextLine().trim(); + if (name.isBlank()) { + return; + } + student = findStudentByName(list, name); + if (student == null) { + System.out.println(STUDENT_NOT_FOUND); + } else { + break; + } + } + StudentAttributes attributes = student.getAttributes(); + showAttributes(attributes); + //edits only StudentAttribute. (Not Name or Details) + System.out.println("Add or edit? (enter blank to exit)"); + String command = in.nextLine().trim(); + switch (command) { + case ADD: + addAttribute(in, attributes); + student.setAttributes(attributes); + break; + + case EDIT: +// while (true) { +// System.out.println("Subject to edit (enter blank to exit)"); +// String subjectToEdit = in.nextLine().trim(); +// SubjectGrade currentSubjectGrade = attributes.findSubject(subjectToEdit); +// if (currentSubjectGrade == null) { +// System.out.println("subject not found."); +// } +// else { +// System.out.println("New subject name (enter blank to skip):"); +// } +// +// String attribute = in.nextLine().trim(); + break; + + case DELETE: + System.out.println("Subject to delete (enter blank to exit)"); + String subjectToDelete = in.nextLine().trim(); + if (attributes.findSubject(subjectToDelete) != null) { + attributes.deleteSubject(subjectToDelete); + System.out.println("Subject deleted"); + } + else { + System.out.println("subject not found"); + } + break; + } + //if done overwrite student + } //@@author alalal47 /** @@ -190,13 +272,11 @@ private static void addStudent(ArrayList masterStudentList, Scanner in, String name; if (studentName == null) { System.out.println(ENTER_STUDENT_DETAILS); - name = checkForEmptyName(masterStudentList, in, studentName); - } else { - name = checkForEmptyName(masterStudentList,in, studentName); } + name = checkForEmptyName(masterStudentList, in, studentName); assert name != null : "Student name cannot be empty"; StudentAttributes attributes = new StudentAttributes(name); - attributeInput(in, attributes); + addAttribute(in, attributes); Student student = new Student(name, attributes); masterStudentList.add(student); logger.log(Level.INFO, "Student added successfully."); @@ -237,24 +317,74 @@ private static String checkForEmptyName(ArrayList masterStudentList, Sc return name; } + //@@author blackmirag3 + /** + * Prompts the user to edit subject, grade, and classes attended for student. + * Continues to prompt the user until user enters blank to exit. + * + * @param in The scanner object to read user input. + * @param attributes The StudentAttributes object to store the attributes of the student. + */ +// private static void editAttribute(Scanner in, StudentAttributes attributes) { +// while (true) { +// System.out.print("Subject to edit (enter nothing to exit): "); +// String subjectToFind = in.nextLine().trim(); +// if (subjectToFind.isBlank()) { +// return; +// } +// SubjectGrade currentSubject = attributes.findSubject(subjectToFind); +// if (currentSubject != null) { +// System.out.print("New subject name (enter nothing to skip): "); +// String newName = in.nextLine().trim(); +// if (!newName.isBlank()) { +// currentSubject.setSubject(newName); +// } +// System.out.print("New grade name (enter nothing to skip): "); +// String newGradeString = in.nextLine().trim(); +// double newGrade = newGrade.Par +// if (!newGrade.isBlank()) { +// currentSubject.setGrade(newGrade); +// } +// double grade = checkForGradeFormat(in); +// int classesAttended = checkForClassesAttendedFormat(in); +// SubjectGrade subjectGrade = new SubjectGrade(subject, grade, classesAttended); +// attributes.addSubjectGrade(subjectGrade); +// System.out.println("Do you want to add another subject and grade? (yes/no)"); +// String response = in.nextLine().trim().toLowerCase(); +// if (!response.equals("yes")) { +// break; +// } +// } +// else { +// System.out.println("Subject not found."); +// } +// } +// } + + //@@author tayponghee /** * Prompts the user to enter attributes for a student, including subject, grade, and classes attended. - * Continues to prompt the user until at least one subject and grade are provided. + * Continues to prompt the user until user enters blank to exit. * * @param in The scanner object to read user input. * @param attributes The StudentAttributes object to store the attributes of the student. */ - private static void attributeInput(Scanner in, StudentAttributes attributes) { + private static void addAttribute(Scanner in, StudentAttributes attributes) { while (true) { + //@@author blackmirag3 System.out.print("Subject (enter nothing to skip): "); String subject = in.nextLine().trim(); - //@author blackmirag3 if (subject.isBlank()) { SubjectGrade subjectGrade = new SubjectGrade(); attributes.addSubjectGrade(subjectGrade); break; } - //@author tayponghee + //rejects subject if existing subject of same name exists in students' attributes + else if (attributes.findSubject(subject) != null) { + System.out.println("Subject already exists."); + break; + } + //@@author tayponghee else { double grade = checkForGradeFormat(in); int classesAttended = checkForClassesAttendedFormat(in); @@ -281,6 +411,9 @@ private static int checkForClassesAttendedFormat(Scanner in) { while (true) { System.out.print(CLASSES_ATTENDED); String classesAttendedInput = in.nextLine(); + if (classesAttendedInput.isBlank()) { + return 0; + } try { classesAttended = Integer.parseInt(classesAttendedInput); if (classesAttended < 0) { @@ -310,6 +443,9 @@ private static double checkForGradeFormat(Scanner in) { while (true) { System.out.print(CURRENT_MARKS_OUT_OF_100); String gradeInput = in.nextLine(); + if (gradeInput.isBlank()) { + return 0; + } try { grade = Double.parseDouble(gradeInput); if (grade < 0 || grade > 100) { diff --git a/src/main/java/classify/fallenCode.java b/src/main/java/classify/fallenCode.java index 7b402cb683..438998708b 100644 --- a/src/main/java/classify/fallenCode.java +++ b/src/main/java/classify/fallenCode.java @@ -45,7 +45,7 @@ public class fallenCode { // } /* - //@author tayponghee + //@@author tayponghee if (attributes.getSubjectGrades().isEmpty()) { System.out.println("At least one subject must be provided. Please add subjects and grades."); Ui.printDivider(); diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 6664575b35..d07e1a2ba8 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -38,9 +38,6 @@ public StudentAttributes getAttributes() { public void setAttributes(StudentAttributes attributes) { this.attributes = attributes; } - public StudentAttributes getAttributesList() { - return attributes; - } //@@ Cryolian public String getName() { diff --git a/src/main/java/classify/student/StudentAttributes.java b/src/main/java/classify/student/StudentAttributes.java index c785a847ab..4ca8af8acd 100644 --- a/src/main/java/classify/student/StudentAttributes.java +++ b/src/main/java/classify/student/StudentAttributes.java @@ -40,4 +40,25 @@ public String toString() { sb.append("]}"); return sb.toString(); } + + //@@author blackmirag3 + public SubjectGrade findSubject(String subjectName) { + for (SubjectGrade subjectGrade : subjectGrades) { + String currentSubjectName = subjectGrade.getSubject(); + if (currentSubjectName.equals(subjectName)) { + return subjectGrade; + } + } + return null; + } + + public void deleteSubject(String subjectName) { + for (SubjectGrade subjectGrade : subjectGrades) { + String currentSubjectName = subjectGrade.getSubject(); + if (currentSubjectName.equals(subjectName)) { + subjectGrades.remove(subjectGrade); + return; + } + } + } } diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 9506b8e627..6296484f9c 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -60,5 +60,4 @@ public void removeStudent(String name) { } } } - } diff --git a/src/main/java/classify/student/SubjectGrade.java b/src/main/java/classify/student/SubjectGrade.java index 8358509e3a..563bbecbf0 100644 --- a/src/main/java/classify/student/SubjectGrade.java +++ b/src/main/java/classify/student/SubjectGrade.java @@ -28,4 +28,16 @@ public double getGrade() { public int getClassesAttended() { return classesAttended; } + + public void setSubject(String subject) { + this.subject = subject; + } + + public void setGrade(double grade) { + this.grade = grade; + } + + public void setClassesAttended(int classesAttended) { + this.classesAttended = classesAttended; + } } From 23f3ac553d243b9d31d80fdd05ff2ac3b3a2d57e Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Wed, 20 Mar 2024 01:22:14 +0800 Subject: [PATCH 045/503] Refactor format checker for grade and attendance --- src/main/java/classify/InputParsing.java | 220 ++++++++++++----------- 1 file changed, 112 insertions(+), 108 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 1c1a951ea3..dcbd06faa1 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -85,8 +85,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas private static void listStudents(ArrayList list) { if (list.isEmpty()) { System.out.println("Currently no students in list."); - } - else { + } else { StudentList.printCurrentArrayList(list); } Ui.printDivider(); @@ -120,40 +119,30 @@ private static void editStudent(ArrayList list, Scanner in, String name StudentAttributes attributes = student.getAttributes(); showAttributes(attributes); //edits only StudentAttribute. (Not Name or Details) - System.out.println("Add or edit? (enter blank to exit)"); + while (true) { + System.out.println("How would you like to update student's subject? (enter blank to exit)"); String command = in.nextLine().trim(); + if (command.isBlank()) { + return; + } switch (command) { - case ADD: - addAttribute(in, attributes); - student.setAttributes(attributes); - break; + case ADD: + addAttribute(in, attributes); + student.setAttributes(attributes); + break; - case EDIT: -// while (true) { -// System.out.println("Subject to edit (enter blank to exit)"); -// String subjectToEdit = in.nextLine().trim(); -// SubjectGrade currentSubjectGrade = attributes.findSubject(subjectToEdit); -// if (currentSubjectGrade == null) { -// System.out.println("subject not found."); -// } -// else { -// System.out.println("New subject name (enter blank to skip):"); -// } -// -// String attribute = in.nextLine().trim(); - break; + case EDIT: + editAttribute(in, attributes); + break; - case DELETE: - System.out.println("Subject to delete (enter blank to exit)"); - String subjectToDelete = in.nextLine().trim(); - if (attributes.findSubject(subjectToDelete) != null) { - attributes.deleteSubject(subjectToDelete); - System.out.println("Subject deleted"); - } - else { - System.out.println("subject not found"); - } - break; + case DELETE: + deleteAttribute(in, attributes); + break; + + default: + System.out.println("invalid input"); + break; + } } //if done overwrite student } @@ -325,41 +314,48 @@ private static String checkForEmptyName(ArrayList masterStudentList, Sc * @param in The scanner object to read user input. * @param attributes The StudentAttributes object to store the attributes of the student. */ -// private static void editAttribute(Scanner in, StudentAttributes attributes) { -// while (true) { -// System.out.print("Subject to edit (enter nothing to exit): "); -// String subjectToFind = in.nextLine().trim(); -// if (subjectToFind.isBlank()) { -// return; -// } -// SubjectGrade currentSubject = attributes.findSubject(subjectToFind); -// if (currentSubject != null) { -// System.out.print("New subject name (enter nothing to skip): "); -// String newName = in.nextLine().trim(); -// if (!newName.isBlank()) { -// currentSubject.setSubject(newName); -// } -// System.out.print("New grade name (enter nothing to skip): "); -// String newGradeString = in.nextLine().trim(); -// double newGrade = newGrade.Par -// if (!newGrade.isBlank()) { -// currentSubject.setGrade(newGrade); -// } -// double grade = checkForGradeFormat(in); -// int classesAttended = checkForClassesAttendedFormat(in); -// SubjectGrade subjectGrade = new SubjectGrade(subject, grade, classesAttended); -// attributes.addSubjectGrade(subjectGrade); -// System.out.println("Do you want to add another subject and grade? (yes/no)"); -// String response = in.nextLine().trim().toLowerCase(); -// if (!response.equals("yes")) { -// break; -// } -// } -// else { -// System.out.println("Subject not found."); -// } -// } -// } + private static void editAttribute(Scanner in, StudentAttributes attributes) { + while (true) { + System.out.print("Subject to edit (enter nothing to exit): "); + String subjectToFind = in.nextLine().trim(); + if (subjectToFind.isBlank()) { + System.out.println("no subject edited"); + return; + } + SubjectGrade currentSubject = attributes.findSubject(subjectToFind); + if (currentSubject != null) { + System.out.print("New subject name (enter nothing to skip): "); + String newName = in.nextLine().trim(); + if (!newName.isBlank()) { + currentSubject.setSubject(newName); + } + double newGrade = promptForGrade(in); + currentSubject.setGrade(newGrade); + int newClassesAttended = promptForClassesAttended(in); + currentSubject.setClassesAttended(newClassesAttended); + System.out.println("Subject updated."); + } else { + System.out.println("Subject not found."); + } + } + } + + private static void deleteAttribute(Scanner in, StudentAttributes attributes) { + while (true) { + System.out.println("Subject to delete (enter blank to exit)"); + String subjectToDelete = in.nextLine().trim(); + if (subjectToDelete.isBlank()) { + System.out.println("no subject deleted"); + return; + } + if (attributes.findSubject(subjectToDelete) != null) { + attributes.deleteSubject(subjectToDelete); + System.out.println("Subject deleted"); + } else { + System.out.println("subject not found"); + } + } + } //@@author tayponghee /** @@ -375,19 +371,16 @@ private static void addAttribute(Scanner in, StudentAttributes attributes) { System.out.print("Subject (enter nothing to skip): "); String subject = in.nextLine().trim(); if (subject.isBlank()) { - SubjectGrade subjectGrade = new SubjectGrade(); - attributes.addSubjectGrade(subjectGrade); + System.out.println("No subjects added."); break; - } - //rejects subject if existing subject of same name exists in students' attributes - else if (attributes.findSubject(subject) != null) { + } else if (attributes.findSubject(subject) != null) { + //rejects subject if existing subject of same name exists in students' attributes System.out.println("Subject already exists."); break; - } - //@@author tayponghee - else { - double grade = checkForGradeFormat(in); - int classesAttended = checkForClassesAttendedFormat(in); + } else { + //@@author tayponghee + double grade = promptForGrade(in); + int classesAttended = promptForClassesAttended(in); SubjectGrade subjectGrade = new SubjectGrade(subject, grade, classesAttended); attributes.addSubjectGrade(subjectGrade); System.out.println("Do you want to add another subject and grade? (yes/no)"); @@ -406,61 +399,39 @@ else if (attributes.findSubject(subject) != null) { * @param in The scanner object to read user input. * @return The valid number of classes attended. */ - private static int checkForClassesAttendedFormat(Scanner in) { - int classesAttended; + private static int promptForClassesAttended(Scanner in) { while (true) { System.out.print(CLASSES_ATTENDED); String classesAttendedInput = in.nextLine(); if (classesAttendedInput.isBlank()) { return 0; } - try { - classesAttended = Integer.parseInt(classesAttendedInput); - if (classesAttended < 0) { - System.out.println("Classes attended must be 0 or more."); - Ui.printDivider(); - continue; - } - break; - } catch (NumberFormatException e) { - logger.log(Level.WARNING, "Invalid input for classes attended: " + classesAttendedInput, e); - System.out.println("Invalid input for classes attended. Please enter a valid whole number."); - Ui.printDivider(); + int classesAttended = Integer.parseInt(classesAttendedInput); + if (isValidClassesAttended(classesAttended)) { + return classesAttended; } } - return classesAttended; } /** - * Checks the format of the input for the grade. + * Prompts for grade from user input and checks format * Prompts the user to enter a valid double within the range [0, 100] until one is provided. * * @param in The scanner object to read user input. * @return The valid grade. */ - private static double checkForGradeFormat(Scanner in) { - double grade; + private static double promptForGrade(Scanner in) { while (true) { System.out.print(CURRENT_MARKS_OUT_OF_100); String gradeInput = in.nextLine(); if (gradeInput.isBlank()) { return 0; } - try { - grade = Double.parseDouble(gradeInput); - if (grade < 0 || grade > 100) { - System.out.println("Grade must be between 0 and 100. Please enter a valid number."); - Ui.printDivider(); - continue; - } - break; - } catch (NumberFormatException e) { - logger.log(Level.WARNING, "Invalid input for grade: " + gradeInput, e); - System.out.println("Invalid input for grade. Please enter a valid number."); - Ui.printDivider(); + double grade = Double.parseDouble(gradeInput); + if (isValidGrade(grade)) { + return grade; } } - return grade; } /** @@ -478,4 +449,37 @@ private static Student findStudentByName(ArrayList masterStudentList, S } return null; } + + //@@author blackmirag3 + private static boolean isValidClassesAttended(int classesAttended) { + try { + if (classesAttended < 0) { + System.out.println("Classes attended must be 0 or more."); + Ui.printDivider(); + return false; + } + return true; + } catch (NumberFormatException e) { + logger.log(Level.WARNING, "Invalid input for classes attended: " + classesAttended, e); + System.out.println("Invalid input for classes attended. Please enter a valid whole number."); + Ui.printDivider(); + return false; + } + } + + private static boolean isValidGrade(double grade) { + try { + if (grade < 0 || grade > 100) { + System.out.println("Grade must be between 0 and 100. Please enter a valid number."); + Ui.printDivider(); + return false; + } + return true; + } catch (NumberFormatException e) { + logger.log(Level.WARNING, "Invalid input for grade: " + grade, e); + System.out.println("Invalid input for grade. Please enter a valid number."); + Ui.printDivider(); + return false; + } + } } From 491168afbc0adf9399aba2f5eda4bb31925b649a Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Wed, 20 Mar 2024 01:32:50 +0800 Subject: [PATCH 046/503] Update formatting for checkStyle test --- src/main/java/classify/InputParsing.java | 40 ++++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index dcbd06faa1..62f76ec596 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -120,29 +120,29 @@ private static void editStudent(ArrayList list, Scanner in, String name showAttributes(attributes); //edits only StudentAttribute. (Not Name or Details) while (true) { - System.out.println("How would you like to update student's subject? (enter blank to exit)"); - String command = in.nextLine().trim(); - if (command.isBlank()) { - return; - } - switch (command) { - case ADD: - addAttribute(in, attributes); - student.setAttributes(attributes); - break; + System.out.println("How would you like to update student's subject? (enter blank to exit)"); + String command = in.nextLine().trim(); + if (command.isBlank()) { + return; + } + switch (command) { + case ADD: + addAttribute(in, attributes); + student.setAttributes(attributes); + break; - case EDIT: - editAttribute(in, attributes); - break; + case EDIT: + editAttribute(in, attributes); + break; - case DELETE: - deleteAttribute(in, attributes); - break; + case DELETE: + deleteAttribute(in, attributes); + break; - default: - System.out.println("invalid input"); - break; - } + default: + System.out.println("invalid input"); + break; + } } //if done overwrite student } From 2dccd7ff564934c84dbb2a497b427830409e46ee Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Wed, 20 Mar 2024 11:39:25 +0800 Subject: [PATCH 047/503] Refactor Ui printer methods --- .../{fallenCode.java => FallenCode.java} | 2 +- src/main/java/classify/InputParsing.java | 88 +++++++----------- src/main/java/classify/Ui.java | 90 ++++++++++++++++++- .../java/classify/student/SubjectGrade.java | 6 -- 4 files changed, 120 insertions(+), 66 deletions(-) rename src/main/java/classify/{fallenCode.java => FallenCode.java} (98%) diff --git a/src/main/java/classify/fallenCode.java b/src/main/java/classify/FallenCode.java similarity index 98% rename from src/main/java/classify/fallenCode.java rename to src/main/java/classify/FallenCode.java index 438998708b..e4eeedbd1b 100644 --- a/src/main/java/classify/fallenCode.java +++ b/src/main/java/classify/FallenCode.java @@ -7,7 +7,7 @@ //import java.util.Scanner; //@@author ParthGandhiNUS -public class fallenCode { +public class FallenCode { // while (!(userCommand.equals("bye"))){ // InputParsing.parseUserCommand(UserInput.processInput(userCommand), StudentList.masterStudentList, in); // } diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 62f76ec596..7b5c52e32b 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -18,23 +18,9 @@ public class InputParsing { private static final String ADD = "add"; private static final String VIEW = "view"; private static final String DELETE = "delete"; - //@@author blackmirag3 private static final String EDIT = "edit"; - private static final String WRONG_INPUT_MESSAGE = "No such command, type \"help\" to view all commands"; - //@@author tayponghee - private static final String ENTER_STUDENT_DETAILS = "Enter student details: "; - private static final String ENTER_STUDENT_NAME = "Enter student name: "; - private static final String STUDENT_DETAILS = "Student details: "; - private static final String NAME = "Name: "; - private static final String CLASSES_ATTENDED = "Classes Attended (blank to skip): "; - private static final String STUDENT_NOT_FOUND = "Student not found!"; - private static final String STUDENT_ADDED_SUCCESSFULLY = "Student added successfully!"; - private static final String STUDENT_DELETED_SUCCESSFULLY = "Student removed successfully!"; private static final String HELP = "help"; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); - private static final String SUBJECT = "Subject: "; - private static final String CURRENT_MARKS_OUT_OF_100 = "Current marks out of 100 (blank to skip) : "; - public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, Scanner in){ //@@author blackmirag3 @@ -58,7 +44,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas break; case HELP: - printHelpMessage(); + Ui.printHelp(); Ui.printDivider(); break; @@ -76,8 +62,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas break; default: - System.out.println(WRONG_INPUT_MESSAGE); - Ui.printDivider(); + Ui.printWrongInput(); break; } } @@ -100,7 +85,7 @@ private static void editStudent(ArrayList list, Scanner in, String name if (name != null) { student = findStudentByName(list, name); if (student == null) { - System.out.println(STUDENT_NOT_FOUND); + Ui.printStudentNotFound(); } } while (student == null) { @@ -110,12 +95,16 @@ private static void editStudent(ArrayList list, Scanner in, String name return; } student = findStudentByName(list, name); - if (student == null) { - System.out.println(STUDENT_NOT_FOUND); - } else { + if (student != null) { break; + } else { + Ui.printStudentNotFound(); } } + editStudentAttributes(in, student); + } + + private static void editStudentAttributes(Scanner in, Student student) { StudentAttributes attributes = student.getAttributes(); showAttributes(attributes); //edits only StudentAttribute. (Not Name or Details) @@ -140,11 +129,10 @@ private static void editStudent(ArrayList list, Scanner in, String name break; default: - System.out.println("invalid input"); + Ui.printWrongInput(); break; } } - //if done overwrite student } //@@author alalal47 @@ -158,7 +146,7 @@ private static void editStudent(ArrayList list, Scanner in, String name private static void deleteStudent(ArrayList masterStudentList, Scanner in, String studentName) { String name; if (studentName == null) { - System.out.print(ENTER_STUDENT_NAME); + Ui.printStudentNamePrompt(); name = in.nextLine().trim(); } else { name = studentName; @@ -166,30 +154,15 @@ private static void deleteStudent(ArrayList masterStudentList, Scanner Student foundStudent = findStudentByName(masterStudentList, name); if (foundStudent != null) { - System.out.println(NAME + foundStudent.getName()); - System.out.println(STUDENT_DELETED_SUCCESSFULLY); + Ui.printStudentDeleted(); } else { - System.out.println(STUDENT_NOT_FOUND); + Ui.printStudentNotFound(); } Ui.printDivider(); masterStudentList.remove(foundStudent); } - /** - * Displays the help message to teach users how to use Classify. - */ - private static void printHelpMessage() { - System.out.println("add Adds a student to the student list, " + - "expects a name, grade and lessons attended" + - ", can be used directly with a name e.g. add [name]"); - System.out.println("view Views a students details, expects a name" + - ", can be used directly with a name e.g. add [name]"); - System.out.println("delete Deletes a student from the student list, expects a name" + - ", can be used directly with a name e.g. add [name]"); - System.out.println("list Displays the list of all students"); - System.out.println("bye Exits Classify"); - System.out.println("help Prints this help message"); - } + //@@author tayponghee /** @@ -202,24 +175,24 @@ private static void printHelpMessage() { private static void viewStudent(ArrayList masterStudentList, Scanner in, String studentName) { String name; if (studentName == null) { - System.out.print(ENTER_STUDENT_NAME); + Ui.printStudentNamePrompt(); name = in.nextLine(); } else { name = studentName; } - + //@author blackmirag3 assert name != null : "Student name cannot be null"; - + //@author tayponghee Student foundStudent = findStudentByName(masterStudentList, name); if (foundStudent != null) { logger.log(Level.INFO, "Viewing student details: " + name); - System.out.println(STUDENT_DETAILS); - System.out.println(NAME + foundStudent.getName()); + Ui.printStudentDetails(); + Ui.printStudentName(name); StudentAttributes attributes = foundStudent.getAttributes(); showAttributes(attributes); } else { logger.log(Level.WARNING, "Student not found: " + name); - System.out.println(STUDENT_NOT_FOUND); + Ui.printStudentNotFound(); } } @@ -233,10 +206,11 @@ private static void showAttributes(StudentAttributes attributes) { List subjectGrades = attributes.getSubjectGrades(); if (!subjectGrades.isEmpty()) { for (SubjectGrade subjectGrade : subjectGrades) { - System.out.println(SUBJECT + subjectGrade.getSubject()); - System.out.println(CURRENT_MARKS_OUT_OF_100 + subjectGrade.getGrade()); - System.out.println("Classes Attended: " + subjectGrade.getClassesAttended()); - System.out.println(); + assert subjectGrade != null : "subjectGrade cannot be null"; + Ui.printSubjectName(subjectGrade.getSubject()); + Ui.printStudentGrades(subjectGrade.getGrade()); + Ui.printClassesAttended(subjectGrade.getClassesAttended()); + Ui.printDivider(); } } else { System.out.println("No subjects and grades found for this student."); @@ -260,7 +234,7 @@ private static void showAttributes(StudentAttributes attributes) { private static void addStudent(ArrayList masterStudentList, Scanner in, String studentName) { String name; if (studentName == null) { - System.out.println(ENTER_STUDENT_DETAILS); + Ui.printStudentNamePrompt(); } name = checkForEmptyName(masterStudentList, in, studentName); assert name != null : "Student name cannot be empty"; @@ -269,7 +243,7 @@ private static void addStudent(ArrayList masterStudentList, Scanner in, Student student = new Student(name, attributes); masterStudentList.add(student); logger.log(Level.INFO, "Student added successfully."); - System.out.println(STUDENT_ADDED_SUCCESSFULLY); + Ui.printStudentAdded(); Ui.printDivider(); } @@ -286,7 +260,7 @@ private static String checkForEmptyName(ArrayList masterStudentList, Sc String name; while (true) { if (studentName == null) { - System.out.print(NAME); + Ui.printStudentNamePrompt(); name = in.nextLine().trim(); } else { name = studentName.trim(); @@ -401,7 +375,7 @@ private static void addAttribute(Scanner in, StudentAttributes attributes) { */ private static int promptForClassesAttended(Scanner in) { while (true) { - System.out.print(CLASSES_ATTENDED); + Ui.printClassesAttendedPrompt(); String classesAttendedInput = in.nextLine(); if (classesAttendedInput.isBlank()) { return 0; @@ -422,7 +396,7 @@ private static int promptForClassesAttended(Scanner in) { */ private static double promptForGrade(Scanner in) { while (true) { - System.out.print(CURRENT_MARKS_OUT_OF_100); + Ui.printStudentGradesPrompt(); String gradeInput = in.nextLine(); if (gradeInput.isBlank()) { return 0; diff --git a/src/main/java/classify/Ui.java b/src/main/java/classify/Ui.java index c277c08726..3819552e17 100644 --- a/src/main/java/classify/Ui.java +++ b/src/main/java/classify/Ui.java @@ -6,18 +6,50 @@ public class Ui { private static final String WELCOME_TO_CLASSIFY = "Welcome to Classify!"; private static final String WHAT_CAN_I_DO_FOR_YOU_TODAY = "What can I do for you today?"; private static final String CLASSIFY_GOODBYE_MESSAGE = "Hope you've had a productive day. See you again! Goodbye!"; + private static final String WRONG_INPUT_MESSAGE = "No such command, type \"help\" to view all commands"; + //@@author blackmirag3 + private static final String STUDENT_DETAILS_PROMPT = "Enter student details: "; + private static final String STUDENT_NAME_PROMPT = "Enter student name: "; + private static final String STUDENT_DETAILS_MESSAGE = "Student details: "; + private static final String STUDENT_NAME_MESSAGE = "Name: "; + private static final String CLASSES_ATTENDED_PROMPT = "Enter Classes Attended (blank to skip): "; + private static final String CLASSES_ATTENDED_MESSAGE = "Classes Attended: "; + private static final String STUDENT_NOT_FOUND_MESSAGE = "Student not found!"; + private static final String STUDENT_ADDED_MESSAGE = "Student added successfully!"; + private static final String STUDENT_DELETED_MESSAGE = "Student removed successfully!"; + private static final String SUBJECT_MESSAGE = "Subject: "; + private static final String STUDENT_GRADES_PROMPT = "Current marks out of 100 (blank to skip) : "; + private static final String STUDENT_GRADES_MESSAGE = "Current marks out of 100: "; + //@author alalal47 + /** + * Displays the help message to teach users how to use Classify. + */ + public static void printHelp() { + System.out.println("add Adds a student to the student list, " + + "expects a name, grade and lessons attended" + + ", can be used directly with a name e.g. add [name]"); + System.out.println("view Views a students details, expects a name" + + ", can be used directly with a name e.g. add [name]"); + System.out.println("delete Deletes a student from the student list, expects a name" + + ", can be used directly with a name e.g. add [name]"); + System.out.println("list Displays the list of all students"); + System.out.println("bye Exits Classify"); + System.out.println("help Prints this help message"); + } + + //@@author ParthGandhiNUS /** * Prints a dividing line between statements for added clarity */ - public static void printDivider(){ + public static void printDivider() { System.out.println(DIVIDER); } /** * Prints out the welcome message to introduce the user to Classify */ - public static void printWelcomeMessage(){ + public static void printWelcomeMessage() { printDivider(); System.out.println(WELCOME_TO_CLASSIFY); System.out.println(WHAT_CAN_I_DO_FOR_YOU_TODAY); @@ -31,4 +63,58 @@ public static void printEndConversation() { System.out.println(CLASSIFY_GOODBYE_MESSAGE); printDivider(); } + + //@@author blackmirag3 + public static void printWrongInput() { + System.out.println(WRONG_INPUT_MESSAGE); + printDivider(); + } + + public static void printStudentDetailsPrompt() { + System.out.println(STUDENT_DETAILS_PROMPT); + } + + public static void printStudentNamePrompt() { + System.out.println(STUDENT_NAME_PROMPT); + } + + public static void printStudentDetails() { + System.out.println(STUDENT_DETAILS_MESSAGE); + } + + public static void printStudentName(String name) { + System.out.println(STUDENT_NAME_MESSAGE + name); + } + + public static void printClassesAttendedPrompt() { + System.out.println(CLASSES_ATTENDED_PROMPT); + } + + public static void printClassesAttended(int attendance) { + System.out.println(CLASSES_ATTENDED_MESSAGE + attendance); + } + + public static void printStudentNotFound() { + System.out.println(STUDENT_NOT_FOUND_MESSAGE); + } + + public static void printStudentAdded() { + System.out.println(STUDENT_ADDED_MESSAGE); + } + + public static void printStudentDeleted() { + System.out.println(STUDENT_DELETED_MESSAGE); + } + + public static void printSubjectName(String name) { + System.out.println(SUBJECT_MESSAGE + name); + } + + public static void printStudentGrades(Double grades) { + System.out.println(STUDENT_GRADES_MESSAGE + grades); + } + + public static void printStudentGradesPrompt() { + System.out.println(STUDENT_GRADES_PROMPT); + } } diff --git a/src/main/java/classify/student/SubjectGrade.java b/src/main/java/classify/student/SubjectGrade.java index 563bbecbf0..cebbcff584 100644 --- a/src/main/java/classify/student/SubjectGrade.java +++ b/src/main/java/classify/student/SubjectGrade.java @@ -5,12 +5,6 @@ public class SubjectGrade { private double grade; private int classesAttended; - private final String EMPTY = "unspecified"; - - public SubjectGrade() { - this.subject = EMPTY; - } - public SubjectGrade(String subject, double grade, int classesAttended) { this.subject = subject; this.grade = grade; From 9b80758131b6ab5576fd096a2ba91efbb0248e42 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 20 Mar 2024 12:07:53 +0800 Subject: [PATCH 048/503] Add new ClassifyExceptions Class --- src/main/java/classify/ClassifyExceptions.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/java/classify/ClassifyExceptions.java diff --git a/src/main/java/classify/ClassifyExceptions.java b/src/main/java/classify/ClassifyExceptions.java new file mode 100644 index 0000000000..cec542f3ae --- /dev/null +++ b/src/main/java/classify/ClassifyExceptions.java @@ -0,0 +1,4 @@ +package classify; + +public class ClassifyExceptions extends Exception{ +} From d095c8e87613678991f931570d5bfb119c88221f Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 20 Mar 2024 12:10:58 +0800 Subject: [PATCH 049/503] Add new printCurrentArrayMessage method --- .../java/classify/student/StudentList.java | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 6296484f9c..1b05ccbdd6 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -6,8 +6,12 @@ * Class to represent a list of Students. */ public class StudentList { - //@@ParthGandhiNUS + //@@authorParthGandhiNUS public static final String DOT = "."; + public static final String ZERO_STUDENT_MESSAGE = "Currently, there are 0 students in the list."; + public static final String ONE_STUDENT_MESSAGE = "Currently, there is 1 student in the list."; + public static final String CURRENTLY_THERE_ARE = "Currently, there are "; + public static final String STUDENTS_IN_THE_LIST = " students in the list."; public static ArrayList masterStudentList = new ArrayList<>(); //@@author Cryolian @@ -21,13 +25,37 @@ public StudentList() { //@@author ParthGandhiNUS /** * Used in the "list" command to print all the Current Tasks in the proper format + * @param currentList takes in an array to print out the name and other attributes of the Student */ public static void printCurrentArrayList(ArrayListcurrentList){ + assert currentList.size() >= 0; for (int i = 1; i <= currentList.size(); i++){ System.out.println(i + DOT + currentList.get(i-1)); } } + //@@author ParthGandhiNUS + /** + * Prints a statement displaying the number of students in the Student List + * @param currentList takes in a Student list to get its size + */ + public static void printCurrentArrayMessage(ArrayListcurrentList){ + int numberOfStudents = currentList.size(); + assert numberOfStudents >= 0; + switch (numberOfStudents){ + case 0: + System.out.println(ZERO_STUDENT_MESSAGE); + break; + case 1: + System.out.println(ONE_STUDENT_MESSAGE); + break; + default: + System.out.println(CURRENTLY_THERE_ARE + numberOfStudents + STUDENTS_IN_THE_LIST); + break; + } + + } + //@@author Cryolian /** * Adds in an instance of a student to the student list. From 21c2ad8ab0e07e5ed36d4650eb2caf6de33bca04 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 20 Mar 2024 12:11:29 +0800 Subject: [PATCH 050/503] Edit "list" command functionalities --- src/main/java/classify/InputParsing.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 62f76ec596..b69245891e 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -83,11 +83,9 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas } //@@author blackmirag3 private static void listStudents(ArrayList list) { - if (list.isEmpty()) { - System.out.println("Currently no students in list."); - } else { - StudentList.printCurrentArrayList(list); - } + StudentList.printCurrentArrayList(list); + //@@author ParthGandhiNUS + StudentList.printCurrentArrayMessage(list); Ui.printDivider(); } From 6c7d010e4528184fe3c52595680c4a25a00ff56e Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 20 Mar 2024 14:47:40 +0800 Subject: [PATCH 051/503] Add exception catching and resolution for grade prompt --- src/main/java/classify/InputParsing.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index b69245891e..87eabadc0b 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -425,7 +425,14 @@ private static double promptForGrade(Scanner in) { if (gradeInput.isBlank()) { return 0; } - double grade = Double.parseDouble(gradeInput); + //@@author ParthGandhiNUS + double grade = 0; + try { + grade = Double.parseDouble(gradeInput); + } catch (NumberFormatException e) { + System.out.println("Wrong number format! Please try again! "); + grade = promptForGrade(in); + } if (isValidGrade(grade)) { return grade; } From cb5c5c6fb67dceec91638c0c9387dd0062f6731f Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 20 Mar 2024 16:07:18 +0800 Subject: [PATCH 052/503] Add exception catching and resolution for classes attended method --- src/main/java/classify/InputParsing.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 87eabadc0b..8cf4dc5d7c 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -404,7 +404,14 @@ private static int promptForClassesAttended(Scanner in) { if (classesAttendedInput.isBlank()) { return 0; } - int classesAttended = Integer.parseInt(classesAttendedInput); + //@@author ParthGandhiNUS + int classesAttended; + try { + classesAttended = Integer.parseInt(classesAttendedInput); + } catch (NumberFormatException e){ + System.out.println("Wrong number format! Please try again! "); + classesAttended = promptForClassesAttended(in); + } if (isValidClassesAttended(classesAttended)) { return classesAttended; } @@ -426,7 +433,7 @@ private static double promptForGrade(Scanner in) { return 0; } //@@author ParthGandhiNUS - double grade = 0; + double grade; try { grade = Double.parseDouble(gradeInput); } catch (NumberFormatException e) { From 17e5eece4907682dbb56380abe5a36c32ee99112 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 20 Mar 2024 16:21:47 +0800 Subject: [PATCH 053/503] Edit the print message for the users when encountered with an exception --- src/main/java/classify/InputParsing.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 8cf4dc5d7c..7c32af2d2f 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -409,7 +409,8 @@ private static int promptForClassesAttended(Scanner in) { try { classesAttended = Integer.parseInt(classesAttendedInput); } catch (NumberFormatException e){ - System.out.println("Wrong number format! Please try again! "); + System.out.println("Wrong number format! Please try again! e.g. 12 "); + Ui.printDivider(); classesAttended = promptForClassesAttended(in); } if (isValidClassesAttended(classesAttended)) { @@ -437,7 +438,8 @@ private static double promptForGrade(Scanner in) { try { grade = Double.parseDouble(gradeInput); } catch (NumberFormatException e) { - System.out.println("Wrong number format! Please try again! "); + System.out.println("Wrong number format! Please try again! e.g. 75 "); + Ui.printDivider(); grade = promptForGrade(in); } if (isValidGrade(grade)) { From 8527ec231559e17be27f7eec55f4bbb786d3b117 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 20 Mar 2024 16:22:19 +0800 Subject: [PATCH 054/503] Add relevant assertions in printCurrentArrayMessage Method --- src/main/java/classify/student/StudentList.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 1b05ccbdd6..fc1516dc48 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -41,15 +41,18 @@ public static void printCurrentArrayList(ArrayListcurrentList){ */ public static void printCurrentArrayMessage(ArrayListcurrentList){ int numberOfStudents = currentList.size(); - assert numberOfStudents >= 0; + switch (numberOfStudents){ case 0: + assert numberOfStudents == 0 : "Number of Students equal to zero!"; System.out.println(ZERO_STUDENT_MESSAGE); break; case 1: + assert numberOfStudents == 1 : "Number of Students equal to one!"; System.out.println(ONE_STUDENT_MESSAGE); break; default: + assert numberOfStudents > 1 : "Number of Students more than one!"; System.out.println(CURRENTLY_THERE_ARE + numberOfStudents + STUDENTS_IN_THE_LIST); break; } From bbd13564d0091884c2f2f25db899f0bd4578b652 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Wed, 20 Mar 2024 16:30:15 +0800 Subject: [PATCH 055/503] Implement assert and modify help message to include edit --- src/main/java/classify/InputParsing.java | 2 +- src/main/java/classify/Ui.java | 2 ++ src/test/java/classify/InputParsingTest.java | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 7b5c52e32b..8a4e5e4bdd 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -151,7 +151,7 @@ private static void deleteStudent(ArrayList masterStudentList, Scanner } else { name = studentName; } - + assert name != null : "Student name cannot be null"; Student foundStudent = findStudentByName(masterStudentList, name); if (foundStudent != null) { Ui.printStudentDeleted(); diff --git a/src/main/java/classify/Ui.java b/src/main/java/classify/Ui.java index 3819552e17..dad0f1bcaf 100644 --- a/src/main/java/classify/Ui.java +++ b/src/main/java/classify/Ui.java @@ -29,6 +29,8 @@ public static void printHelp() { System.out.println("add Adds a student to the student list, " + "expects a name, grade and lessons attended" + ", can be used directly with a name e.g. add [name]"); + System.out.println("edit Edits a students details, expects a name" + + " , can be used directly with a name e.g. edit [name]"); System.out.println("view Views a students details, expects a name" + ", can be used directly with a name e.g. add [name]"); System.out.println("delete Deletes a student from the student list, expects a name" + diff --git a/src/test/java/classify/InputParsingTest.java b/src/test/java/classify/InputParsingTest.java index 9fa4545a82..162a8aa458 100644 --- a/src/test/java/classify/InputParsingTest.java +++ b/src/test/java/classify/InputParsingTest.java @@ -66,6 +66,9 @@ public void testHelpCommand() { ", grade and lessons attended," + " can be used directly with a name e.g. add [name]" + System.lineSeparator() + + "edit Edits a students details, expects a name" + + " , can be used directly with a name e.g. edit [name]" + + System.lineSeparator() + "view Views a students details, expects a name" + ", can be used directly with a name e.g. add [name]" + System.lineSeparator() + From f072eb892fc86ea8149a17b844d4326c4c3282eb Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 20 Mar 2024 16:49:22 +0800 Subject: [PATCH 056/503] Add required datacommand Classes --- src/main/java/classify/datacommands/DataHandler.java | 5 +++++ src/main/java/classify/datacommands/DataReader.java | 5 +++++ src/main/java/classify/datacommands/DataStorage.java | 5 +++++ 3 files changed, 15 insertions(+) create mode 100644 src/main/java/classify/datacommands/DataHandler.java create mode 100644 src/main/java/classify/datacommands/DataReader.java create mode 100644 src/main/java/classify/datacommands/DataStorage.java diff --git a/src/main/java/classify/datacommands/DataHandler.java b/src/main/java/classify/datacommands/DataHandler.java new file mode 100644 index 0000000000..a06cc1ec1e --- /dev/null +++ b/src/main/java/classify/datacommands/DataHandler.java @@ -0,0 +1,5 @@ +package classify.datacommands; + +public class DataHandler { + +} diff --git a/src/main/java/classify/datacommands/DataReader.java b/src/main/java/classify/datacommands/DataReader.java new file mode 100644 index 0000000000..c8b7c1530f --- /dev/null +++ b/src/main/java/classify/datacommands/DataReader.java @@ -0,0 +1,5 @@ +package classify.datacommands; + +public class DataReader { + +} diff --git a/src/main/java/classify/datacommands/DataStorage.java b/src/main/java/classify/datacommands/DataStorage.java new file mode 100644 index 0000000000..e0a23fb905 --- /dev/null +++ b/src/main/java/classify/datacommands/DataStorage.java @@ -0,0 +1,5 @@ +package classify.datacommands; + +public class DataStorage { + +} From 81093f7bd8ba3a96b01dba12cf0b5144aed8d779 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Wed, 20 Mar 2024 16:51:44 +0800 Subject: [PATCH 057/503] Edit assertion to not be always true --- src/main/java/classify/InputParsing.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index 8ccc7493a2..b25c148fc5 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -149,7 +149,6 @@ private static void deleteStudent(ArrayList masterStudentList, Scanner } else { name = studentName; } - assert name != null : "Student name cannot be null"; Student foundStudent = findStudentByName(masterStudentList, name); if (foundStudent != null) { Ui.printStudentDeleted(); @@ -158,10 +157,9 @@ private static void deleteStudent(ArrayList masterStudentList, Scanner } Ui.printDivider(); masterStudentList.remove(foundStudent); + assert foundStudent == null : "Student should be deleted"; } - - //@@author tayponghee /** * Displays the details of a specific student. From f69c44444d49bb02f5a532bcad33b394a563bde4 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Wed, 20 Mar 2024 16:56:28 +0800 Subject: [PATCH 058/503] Add printing of user prompt for each main user command iteration --- src/main/java/classify/Classify.java | 1 + src/main/java/classify/Ui.java | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 3724b9fbe7..6c61f8fd61 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -20,6 +20,7 @@ public static void main(String[] args) { //Set up polling for the first word input by the user. // If user's first word is "bye", will exit the while loop. while (!(userCommand[0].equals("bye"))){ + Ui.printUserPrompt(); InputParsing.parseUserCommand(userCommand, StudentList.masterStudentList, in); userCommand = UserInput.processInput(in.nextLine()); } diff --git a/src/main/java/classify/Ui.java b/src/main/java/classify/Ui.java index dad0f1bcaf..7b0c07ac9f 100644 --- a/src/main/java/classify/Ui.java +++ b/src/main/java/classify/Ui.java @@ -54,8 +54,6 @@ public static void printDivider() { public static void printWelcomeMessage() { printDivider(); System.out.println(WELCOME_TO_CLASSIFY); - System.out.println(WHAT_CAN_I_DO_FOR_YOU_TODAY); - printDivider(); } /** @@ -67,6 +65,10 @@ public static void printEndConversation() { } //@@author blackmirag3 + public static void printUserPrompt() { + System.out.println(WHAT_CAN_I_DO_FOR_YOU_TODAY); + printDivider(); + } public static void printWrongInput() { System.out.println(WRONG_INPUT_MESSAGE); printDivider(); From 46864de5c58ac30e0f2ff8dc41c680e7d8185a8f Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 20 Mar 2024 17:22:19 +0800 Subject: [PATCH 059/503] Edit assertions --- src/main/java/classify/InputParsing.java | 5 +++++ src/main/java/classify/student/StudentList.java | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index fe1a94d8a3..d0af35bf2c 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -257,6 +257,7 @@ private static void addStudent(ArrayList masterStudentList, Scanner in, private static String checkForEmptyName(ArrayList masterStudentList, Scanner in, String studentName) { String name; while (true) { + if (studentName == null) { Ui.printStudentNamePrompt(); name = in.nextLine().trim(); @@ -264,10 +265,14 @@ private static String checkForEmptyName(ArrayList masterStudentList, Sc name = studentName.trim(); studentName = NOTEMPTY; } + + assert studentName != null : + if (name.isEmpty()) { System.out.println("Student name cannot be empty. Please enter a valid name."); Ui.printDivider(); } else if (findStudentByName(masterStudentList, name) != null) { + assert findStudentByName(masterStudentList, name) != null; logger.log(Level.WARNING, "Student with the same name already exists."); System.out.println("Student with the same name already exists. Please enter a different name."); Ui.printDivider(); diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index fc1516dc48..2cb12cf153 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -28,7 +28,6 @@ public StudentList() { * @param currentList takes in an array to print out the name and other attributes of the Student */ public static void printCurrentArrayList(ArrayListcurrentList){ - assert currentList.size() >= 0; for (int i = 1; i <= currentList.size(); i++){ System.out.println(i + DOT + currentList.get(i-1)); } @@ -44,15 +43,12 @@ public static void printCurrentArrayMessage(ArrayListcurrentList){ switch (numberOfStudents){ case 0: - assert numberOfStudents == 0 : "Number of Students equal to zero!"; System.out.println(ZERO_STUDENT_MESSAGE); break; case 1: - assert numberOfStudents == 1 : "Number of Students equal to one!"; System.out.println(ONE_STUDENT_MESSAGE); break; default: - assert numberOfStudents > 1 : "Number of Students more than one!"; System.out.println(CURRENTLY_THERE_ARE + numberOfStudents + STUDENTS_IN_THE_LIST); break; } From 812e0ce9a7a5b2774e5e96ae6e32a9975c92331b Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 20 Mar 2024 17:28:33 +0800 Subject: [PATCH 060/503] Add semicolon instead of colon for assertion --- src/main/java/classify/InputParsing.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/InputParsing.java index d0af35bf2c..39d4f06ed7 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/InputParsing.java @@ -266,7 +266,7 @@ private static String checkForEmptyName(ArrayList masterStudentList, Sc studentName = NOTEMPTY; } - assert studentName != null : + assert studentName != null; if (name.isEmpty()) { System.out.println("Student name cannot be empty. Please enter a valid name."); From 58d89554d301717ce38d3d5bb5feba578ead679a Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 20 Mar 2024 17:39:52 +0800 Subject: [PATCH 061/503] Edit Expected.txt for teammate --- text-ui-test/EXPECTED.TXT | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 6156a7ed33..5800f80283 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,6 +1,4 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Welcome to Classify! -What can I do for you today? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Hope you've had a productive day. See you again! Goodbye! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \ No newline at end of file From 41d446d84e355fdc10fb79ce0d119fc5fb631991 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 20 Mar 2024 17:43:26 +0800 Subject: [PATCH 062/503] Add newLine for teammate --- text-ui-test/EXPECTED.TXT | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 5800f80283..ee9b049e1f 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,4 +1,4 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Welcome to Classify! Hope you've had a productive day. See you again! Goodbye! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \ No newline at end of file +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 78c1b6cf93a5a9304208ebd28af794fc48de82c9 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 20 Mar 2024 18:29:33 +0800 Subject: [PATCH 063/503] Add student details input --- src/main/java/classify/Classify.java | 5 + src/main/java/classify/student/Details.java | 15 +- src/main/java/classify/student/Master.java | 10 - src/main/java/classify/student/Student.java | 13 +- .../classify/student/StudentAttributes.java | 25 ++- .../java/classify/student/StudentList.java | 4 + .../{ => user}/ClassifyExceptions.java | 3 +- .../classify/{ => user}/InputParsing.java | 209 ++++++++++++++---- src/main/java/classify/{ => user}/Ui.java | 16 +- .../java/classify/{ => user}/UserInput.java | 5 +- .../classify/{ => user}/InputParsingTest.java | 3 +- 11 files changed, 218 insertions(+), 90 deletions(-) delete mode 100644 src/main/java/classify/student/Master.java rename src/main/java/classify/{ => user}/ClassifyExceptions.java (65%) rename src/main/java/classify/{ => user}/InputParsing.java (80%) rename src/main/java/classify/{ => user}/Ui.java (86%) rename src/main/java/classify/{ => user}/UserInput.java (96%) rename src/test/java/classify/{ => user}/InputParsingTest.java (99%) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 6c61f8fd61..4a95f1041b 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -1,6 +1,9 @@ package classify; import classify.student.StudentList; +import classify.user.InputParsing; +import classify.user.Ui; +import classify.user.UserInput; import java.util.Scanner; @@ -11,9 +14,11 @@ public class Classify { * Main entry-point for the java.duke.Duke application. */ public static void main(String[] args) { + // @@author ParthGandhiNUS // CAA: 9 March 2024 1pm Ui.printWelcomeMessage(); + // Takes in only the first word input by the user String[] userCommand = UserInput.processInput(in.nextLine()); diff --git a/src/main/java/classify/student/Details.java b/src/main/java/classify/student/Details.java index fcb5c8360a..bd650528a6 100644 --- a/src/main/java/classify/student/Details.java +++ b/src/main/java/classify/student/Details.java @@ -1,21 +1,16 @@ package classify.student; -// import classify.classgroup.Class; -import java.util.ArrayList; - /** * Important details of a student the tuition centre * has to keep track of. */ -public class Details { +public abstract class Details { //@@author Cryolian - public String gender = "unknown"; - public int phoneNumber = 0; - // public Class currentClass = new Class(0, "Unknown"); - public ArrayList subjects = new ArrayList<>(); - public String lastPaymentDate = "unknown"; - public String remarks = "NA"; + protected String gender; + protected int phoneNumber = 0; + protected String lastPaymentDate = "unknown"; + protected String remarks = "NA"; public Details() { diff --git a/src/main/java/classify/student/Master.java b/src/main/java/classify/student/Master.java deleted file mode 100644 index 6a9bc7e2ee..0000000000 --- a/src/main/java/classify/student/Master.java +++ /dev/null @@ -1,10 +0,0 @@ -package classify.student; - -//This class is a master arraylist for all the students in our system. to be explored ig -public class Master { - public static StudentList masterStudentList = new StudentList(); - - public Master() { - - } -} diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index d07e1a2ba8..49a194c3ef 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -9,7 +9,6 @@ public class Student { //@@author Cryolian public String name; - public Details details = new Details(); //@@author tayponghee private StudentAttributes attributes; @@ -18,17 +17,7 @@ public class Student { public Student(String name) { this.name = name; - } - - public Student(String name, Details details) { - this.name = name; - this.details = details; - } - - //@@author tayponghee - public Student(String name, StudentAttributes attributes) { - this.name = name; - this.attributes = attributes; + this.attributes = new StudentAttributes(this); } public StudentAttributes getAttributes() { diff --git a/src/main/java/classify/student/StudentAttributes.java b/src/main/java/classify/student/StudentAttributes.java index 4ca8af8acd..f2608f0f29 100644 --- a/src/main/java/classify/student/StudentAttributes.java +++ b/src/main/java/classify/student/StudentAttributes.java @@ -3,12 +3,12 @@ import java.util.ArrayList; import java.util.List; -public class StudentAttributes { - private String name; +public class StudentAttributes extends Details { + private Student student; private List subjectGrades; - public StudentAttributes(String name) { - this.name = name; + public StudentAttributes(Student student) { + this.student = student; this.subjectGrades = new ArrayList<>(); } @@ -21,30 +21,38 @@ public List getSubjectGrades() { } public String getName() { - return name; + return student.getName(); } public void setName(String name) { - this.name = name; + student.setName(name); } @Override public String toString() { StringBuilder sb = new StringBuilder(); + sb.append("StudentAttributes{" + - "name='" + name + '\'' + + "name: '" + student.getName() + '\'' + + ", H/P: " + String.valueOf(phoneNumber) + '\'' + + ", Gender: " + gender + '\'' + + ", Remarks: " + remarks + '\'' + ", subjectGrades=["); + for (SubjectGrade subjectGrade : subjectGrades) { sb.append(subjectGrade.toString()).append(", "); } + sb.append("]}"); return sb.toString(); } //@@author blackmirag3 public SubjectGrade findSubject(String subjectName) { + for (SubjectGrade subjectGrade : subjectGrades) { String currentSubjectName = subjectGrade.getSubject(); + if (currentSubjectName.equals(subjectName)) { return subjectGrade; } @@ -53,12 +61,15 @@ public SubjectGrade findSubject(String subjectName) { } public void deleteSubject(String subjectName) { + for (SubjectGrade subjectGrade : subjectGrades) { String currentSubjectName = subjectGrade.getSubject(); + if (currentSubjectName.equals(subjectName)) { subjectGrades.remove(subjectGrade); return; } } } + } diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 2cb12cf153..a1fb2b4ed0 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -45,9 +45,11 @@ public static void printCurrentArrayMessage(ArrayListcurrentList){ case 0: System.out.println(ZERO_STUDENT_MESSAGE); break; + case 1: System.out.println(ONE_STUDENT_MESSAGE); break; + default: System.out.println(CURRENTLY_THERE_ARE + numberOfStudents + STUDENTS_IN_THE_LIST); break; @@ -80,7 +82,9 @@ public void removeStudent(int id) { * @param name The string to search among the names of the student to remove. */ public void removeStudent(String name) { + for (Student s: studentList) { + if (s.getName().equals(name)) { studentList.remove(s); return; diff --git a/src/main/java/classify/ClassifyExceptions.java b/src/main/java/classify/user/ClassifyExceptions.java similarity index 65% rename from src/main/java/classify/ClassifyExceptions.java rename to src/main/java/classify/user/ClassifyExceptions.java index cec542f3ae..7e6de811da 100644 --- a/src/main/java/classify/ClassifyExceptions.java +++ b/src/main/java/classify/user/ClassifyExceptions.java @@ -1,4 +1,5 @@ -package classify; +package classify.user; public class ClassifyExceptions extends Exception{ + } diff --git a/src/main/java/classify/InputParsing.java b/src/main/java/classify/user/InputParsing.java similarity index 80% rename from src/main/java/classify/InputParsing.java rename to src/main/java/classify/user/InputParsing.java index 501e5a6ff9..455efd9f71 100644 --- a/src/main/java/classify/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -1,4 +1,4 @@ -package classify; +package classify.user; import classify.student.Student; import classify.student.StudentAttributes; @@ -22,12 +22,12 @@ public class InputParsing { private static final String HELP = "help"; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); - public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, Scanner in){ - //@@author blackmirag3 + public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, Scanner in) { + // @@author blackmirag3 if (masterStudentList == null) { System.out.println("Student list is null."); } - //@@author tayponghee + // @@author tayponghee switch (userCommand[0]) { case ADD: addStudent(masterStudentList, in, userCommand[1]); @@ -38,7 +38,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas Ui.printDivider(); break; - //@@author alalal47 + // @@author alalal47 case DELETE: deleteStudent(masterStudentList, in, userCommand[1]); break; @@ -48,7 +48,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas Ui.printDivider(); break; - //@@author ParthGandhiNUS + // @@author ParthGandhiNUS case BYE: Ui.printEndConversation(); break; @@ -66,10 +66,11 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas break; } } - //@@author blackmirag3 + + // @@author blackmirag3 private static void listStudents(ArrayList list) { StudentList.printCurrentArrayList(list); - //@@author ParthGandhiNUS + // @@author ParthGandhiNUS StudentList.printCurrentArrayMessage(list); Ui.printDivider(); } @@ -79,13 +80,16 @@ private static void editStudent(ArrayList list, Scanner in, String name System.out.println("Currently no students in list."); return; } + Student student = null; + if (name != null) { student = findStudentByName(list, name); if (student == null) { Ui.printStudentNotFound(); } } + while (student == null) { System.out.println("Name of student to edit (enter blank to exit):"); name = in.nextLine().trim(); @@ -99,20 +103,23 @@ private static void editStudent(ArrayList list, Scanner in, String name Ui.printStudentNotFound(); } } + editStudentAttributes(in, student); } private static void editStudentAttributes(Scanner in, Student student) { StudentAttributes attributes = student.getAttributes(); showAttributes(attributes); - //edits only StudentAttribute. (Not Name or Details) + while (true) { System.out.println("How would you like to update student's subject? (enter blank to exit)"); String command = in.nextLine().trim(); if (command.isBlank()) { return; } + switch (command) { + case ADD: addAttribute(in, attributes); student.setAttributes(attributes); @@ -133,28 +140,34 @@ private static void editStudentAttributes(Scanner in, Student student) { } } - //@@author alalal47 + // @@author alalal47 /** * Removes a student from the list. * * @param masterStudentList The list of all students. * @param in The scanner object to read user input. - * @param studentName The name of the student if the user had entered it before being prompted + * @param studentName The name of the student if the user had entered it + * before being prompted */ private static void deleteStudent(ArrayList masterStudentList, Scanner in, String studentName) { + String name; + if (studentName == null) { Ui.printStudentNamePrompt(); name = in.nextLine().trim(); } else { name = studentName; } + Student foundStudent = findStudentByName(masterStudentList, name); + if (foundStudent != null) { Ui.printStudentDeleted(); } else { Ui.printStudentNotFound(); } + Ui.printDivider(); masterStudentList.remove(foundStudent); assert foundStudent == null : "Student should be deleted"; @@ -166,24 +179,30 @@ private static void deleteStudent(ArrayList masterStudentList, Scanner * * @param masterStudentList The list of all students. * @param in The scanner object to read user input. - * @param studentName The name of the student if the user had entered it before being prompted + * @param studentName The name of the student if the user had entered it + * before being prompted */ private static void viewStudent(ArrayList masterStudentList, Scanner in, String studentName) { + String name; + if (studentName == null) { Ui.printStudentNamePrompt(); name = in.nextLine(); } else { name = studentName; } - //@author blackmirag3 + + // @author blackmirag3 assert name != null : "Student name cannot be null"; - //@author tayponghee + // @author tayponghee Student foundStudent = findStudentByName(masterStudentList, name); + if (foundStudent != null) { logger.log(Level.INFO, "Viewing student details: " + name); Ui.printStudentDetails(); Ui.printStudentName(name); + Ui.printStudentDetails(foundStudent); StudentAttributes attributes = foundStudent.getAttributes(); showAttributes(attributes); } else { @@ -199,8 +218,11 @@ private static void viewStudent(ArrayList masterStudentList, Scanner in */ private static void showAttributes(StudentAttributes attributes) { if (attributes != null) { + List subjectGrades = attributes.getSubjectGrades(); + if (!subjectGrades.isEmpty()) { + for (SubjectGrade subjectGrade : subjectGrades) { assert subjectGrade != null : "subjectGrade cannot be null"; Ui.printSubjectName(subjectGrade.getSubject()); @@ -208,9 +230,11 @@ private static void showAttributes(StudentAttributes attributes) { Ui.printClassesAttended(subjectGrade.getClassesAttended()); Ui.printDivider(); } + } else { System.out.println("No subjects and grades found for this student."); } + } else { System.out.println("No attributes found for this student."); } @@ -225,18 +249,44 @@ private static void showAttributes(StudentAttributes attributes) { * * @param masterStudentList The list of all students. * @param in The scanner object to read user input. - * @param studentName The name of the student if the user had entered it before being prompted + * @param studentName The name of the student if the user had entered it + * before being prompted */ private static void addStudent(ArrayList masterStudentList, Scanner in, String studentName) { String name; - if (studentName == null) { - Ui.printStudentNamePrompt(); - } + name = checkForEmptyName(masterStudentList, in, studentName); - assert name != null : "Student name cannot be empty"; - StudentAttributes attributes = new StudentAttributes(name); - addAttribute(in, attributes); - Student student = new Student(name, attributes); + + if (findStudentByName(masterStudentList, name) != null) { + assert findStudentByName(masterStudentList, name) != null; + logger.log(Level.WARNING, "Student with the same name already exists."); + System.out.println("Student with the same name already exists. Please enter a different name."); + Ui.printDivider(); + return; + } + + Student student = new Student(name); + addAttribute(in, student.getAttributes()); + + // @@author Cryolian + int number = promptForPhoneNumber(in); + + while (number < 0) { + number = promptForPhoneNumber(in); + } + + student.getAttributes().setPhoneNumber(number); + + System.out.println("Please input the student's gender: "); + student.getAttributes().setGender(promptString(in)); + + System.out.println("Please input their last payment date: "); + student.getAttributes().setLastPaymentDate(promptString(in)); + + System.out.println("Please input any remarks: "); + student.getAttributes().setRemarks(promptString(in)); + + //@@author tayponghee masterStudentList.add(student); logger.log(Level.INFO, "Student added successfully."); Ui.printStudentAdded(); @@ -244,12 +294,15 @@ private static void addStudent(ArrayList masterStudentList, Scanner in, } /** - * Prompts the user to enter a non-empty name for a student and checks if it already exists in the list. - * If the name is empty or already exists, prompts the user again until valid input is provided. + * Prompts the user to enter a non-empty name for a student and checks if it + * already exists in the list. + * If the name is empty or already exists, prompts the user again until valid + * input is provided. * * @param masterStudentList The list of all students. * @param in The scanner object to read user input. - * @param studentName The name of the student if the user had entered it before being prompted + * @param studentName The name of the student if the user had entered it + * before being prompted * @return The valid non-empty name entered by the user. */ private static String checkForEmptyName(ArrayList masterStudentList, Scanner in, String studentName) { @@ -269,11 +322,6 @@ private static String checkForEmptyName(ArrayList masterStudentList, Sc if (name.isEmpty()) { System.out.println("Student name cannot be empty. Please enter a valid name."); Ui.printDivider(); - } else if (findStudentByName(masterStudentList, name) != null) { - assert findStudentByName(masterStudentList, name) != null; - logger.log(Level.WARNING, "Student with the same name already exists."); - System.out.println("Student with the same name already exists. Please enter a different name."); - Ui.printDivider(); } else { break; } @@ -281,48 +329,64 @@ private static String checkForEmptyName(ArrayList masterStudentList, Sc return name; } - //@@author blackmirag3 + // @@author blackmirag3 /** * Prompts the user to edit subject, grade, and classes attended for student. * Continues to prompt the user until user enters blank to exit. * * @param in The scanner object to read user input. - * @param attributes The StudentAttributes object to store the attributes of the student. + * @param attributes The StudentAttributes object to store the attributes of the + * student. */ private static void editAttribute(Scanner in, StudentAttributes attributes) { while (true) { + System.out.print("Subject to edit (enter nothing to exit): "); String subjectToFind = in.nextLine().trim(); + if (subjectToFind.isBlank()) { System.out.println("no subject edited"); return; } + SubjectGrade currentSubject = attributes.findSubject(subjectToFind); + if (currentSubject != null) { System.out.print("New subject name (enter nothing to skip): "); String newName = in.nextLine().trim(); + if (!newName.isBlank()) { currentSubject.setSubject(newName); } + double newGrade = promptForGrade(in); - currentSubject.setGrade(newGrade); + + if (newGrade != -1) { + currentSubject.setGrade(newGrade); + } + int newClassesAttended = promptForClassesAttended(in); currentSubject.setClassesAttended(newClassesAttended); System.out.println("Subject updated."); + } else { System.out.println("Subject not found."); } + } } private static void deleteAttribute(Scanner in, StudentAttributes attributes) { while (true) { + System.out.println("Subject to delete (enter blank to exit)"); String subjectToDelete = in.nextLine().trim(); + if (subjectToDelete.isBlank()) { System.out.println("no subject deleted"); return; } + if (attributes.findSubject(subjectToDelete) != null) { attributes.deleteSubject(subjectToDelete); System.out.println("Subject deleted"); @@ -332,29 +396,36 @@ private static void deleteAttribute(Scanner in, StudentAttributes attributes) { } } - //@@author tayponghee + // @@author tayponghee /** - * Prompts the user to enter attributes for a student, including subject, grade, and classes attended. + * Prompts the user to enter attributes for a student, including subject, grade, + * and classes attended. * Continues to prompt the user until user enters blank to exit. * * @param in The scanner object to read user input. - * @param attributes The StudentAttributes object to store the attributes of the student. + * @param attributes The StudentAttributes object to store the attributes of the + * student. */ private static void addAttribute(Scanner in, StudentAttributes attributes) { while (true) { - //@@author blackmirag3 + // @@author blackmirag3 System.out.print("Subject (enter nothing to skip): "); String subject = in.nextLine().trim(); + if (subject.isBlank()) { System.out.println("No subjects added."); break; + } else if (attributes.findSubject(subject) != null) { - //rejects subject if existing subject of same name exists in students' attributes + // rejects subject if existing subject of same name exists in students' + // attributes System.out.println("Subject already exists."); break; + } else { - //@@author tayponghee - double grade = promptForGrade(in); + + // @@author tayponghee + double grade = Math.max(promptForGrade(in), 0); int classesAttended = promptForClassesAttended(in); SubjectGrade subjectGrade = new SubjectGrade(subject, grade, classesAttended); attributes.addSubjectGrade(subjectGrade); @@ -378,18 +449,21 @@ private static int promptForClassesAttended(Scanner in) { while (true) { Ui.printClassesAttendedPrompt(); String classesAttendedInput = in.nextLine(); + if (classesAttendedInput.isBlank()) { - return 0; + return -1; } - //@@author ParthGandhiNUS + + // @@author ParthGandhiNUS int classesAttended; try { classesAttended = Integer.parseInt(classesAttendedInput); - } catch (NumberFormatException e){ + } catch (NumberFormatException e) { System.out.println("Wrong number format! Please try again! e.g. 12 "); Ui.printDivider(); classesAttended = promptForClassesAttended(in); } + if (isValidClassesAttended(classesAttended)) { return classesAttended; } @@ -398,7 +472,8 @@ private static int promptForClassesAttended(Scanner in) { /** * Prompts for grade from user input and checks format - * Prompts the user to enter a valid double within the range [0, 100] until one is provided. + * Prompts the user to enter a valid double within the range [0, 100] until one + * is provided. * * @param in The scanner object to read user input. * @return The valid grade. @@ -407,10 +482,12 @@ private static double promptForGrade(Scanner in) { while (true) { Ui.printStudentGradesPrompt(); String gradeInput = in.nextLine(); + if (gradeInput.isBlank()) { - return 0; + return -1; } - //@@author ParthGandhiNUS + + // @@author ParthGandhiNUS double grade; try { grade = Double.parseDouble(gradeInput); @@ -419,6 +496,7 @@ private static double promptForGrade(Scanner in) { Ui.printDivider(); grade = promptForGrade(in); } + if (isValidGrade(grade)) { return grade; } @@ -441,7 +519,7 @@ private static Student findStudentByName(ArrayList masterStudentList, S return null; } - //@@author blackmirag3 + // @@author blackmirag3 private static boolean isValidClassesAttended(int classesAttended) { try { if (classesAttended < 0) { @@ -473,4 +551,41 @@ private static boolean isValidGrade(double grade) { return false; } } + + private static int promptForPhoneNumber(Scanner in) { + + System.out.println("Please input a valid Phone number: "); + + try { + + int number = Integer.parseInt(in.nextLine()); + while (!checkNumberValidity(number)) { + System.out.println("Please input a valid number"); + number = Integer.parseInt(in.nextLine()); + } + + return number; + + } catch (NumberFormatException e) { + System.out.println("A number was not inputted. "); + } + + return -1; + } + + private static boolean checkNumberValidity(int number) { + return String.valueOf(number).length() == 8 || String.valueOf(number).length() == 10; + } + + private static String promptString(Scanner in) { + + String string = in.nextLine(); + if (string.isBlank()) { + return "Unknown"; + } + + return string; + + } + } diff --git a/src/main/java/classify/Ui.java b/src/main/java/classify/user/Ui.java similarity index 86% rename from src/main/java/classify/Ui.java rename to src/main/java/classify/user/Ui.java index 7b0c07ac9f..bf19d431b6 100644 --- a/src/main/java/classify/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -1,4 +1,6 @@ -package classify; +package classify.user; + +import classify.student.Student; public class Ui { //@@author ParthGandhiNUS @@ -20,6 +22,10 @@ public class Ui { private static final String SUBJECT_MESSAGE = "Subject: "; private static final String STUDENT_GRADES_PROMPT = "Current marks out of 100 (blank to skip) : "; private static final String STUDENT_GRADES_MESSAGE = "Current marks out of 100: "; + private static final String STUDENT_PHONE_MESSAGE = "Phone Number: "; + private static final String STUDENT_GENDER_MESSAGE = "Gender: "; + private static final String STUDENT_PAYMENT_MESSAGE = "Last Payment Date: "; + private static final String STUDENT_REMARKS_MESSAGE = "Remarks: "; //@author alalal47 /** @@ -86,6 +92,13 @@ public static void printStudentDetails() { System.out.println(STUDENT_DETAILS_MESSAGE); } + public static void printStudentDetails(Student student) { + System.out.println(STUDENT_PHONE_MESSAGE + student.getAttributes().getPhoneNumber()); + System.out.println(STUDENT_GENDER_MESSAGE + student.getAttributes().getGender()); + System.out.println(STUDENT_PAYMENT_MESSAGE + student.getAttributes().getLastPaymentDate()); + System.out.println(STUDENT_REMARKS_MESSAGE + student.getAttributes().getRemarks()); + } + public static void printStudentName(String name) { System.out.println(STUDENT_NAME_MESSAGE + name); } @@ -121,4 +134,5 @@ public static void printStudentGrades(Double grades) { public static void printStudentGradesPrompt() { System.out.println(STUDENT_GRADES_PROMPT); } + } diff --git a/src/main/java/classify/UserInput.java b/src/main/java/classify/user/UserInput.java similarity index 96% rename from src/main/java/classify/UserInput.java rename to src/main/java/classify/user/UserInput.java index 16064c3514..41c26c52e8 100644 --- a/src/main/java/classify/UserInput.java +++ b/src/main/java/classify/user/UserInput.java @@ -1,4 +1,4 @@ -package classify; +package classify.user; public class UserInput { //@@author alalal47 @@ -8,12 +8,15 @@ public class UserInput { * @return String[] which contains the command in [0] and name in [1] if the user chose to input it */ public static String[] processInput(String userInput){ + String[] commandWithName = new String[2]; + if (userInput.trim().contains(" ")) { commandWithName = userInput.split(" ", 2); } else { commandWithName[0] = userInput; } + commandWithName[0] = commandWithName[0].toLowerCase(); return commandWithName; } diff --git a/src/test/java/classify/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java similarity index 99% rename from src/test/java/classify/InputParsingTest.java rename to src/test/java/classify/user/InputParsingTest.java index 162a8aa458..c071c979cc 100644 --- a/src/test/java/classify/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -1,6 +1,7 @@ -package classify; +package classify.user; import classify.student.Student; + import org.junit.jupiter.api.Test; import java.io.ByteArrayOutputStream; import java.io.PrintStream; From a78283fdde763520571fe545079ba2a6bc018736 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Wed, 20 Mar 2024 18:49:46 +0800 Subject: [PATCH 064/503] Split help message print into multiple methods to allow for individual calls in the future --- src/main/java/classify/user/InputParsing.java | 2 +- src/main/java/classify/user/Ui.java | 40 +++++++++++++++---- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 455efd9f71..dfc4670019 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -168,7 +168,7 @@ private static void deleteStudent(ArrayList masterStudentList, Scanner Ui.printStudentNotFound(); } - Ui.printDivider(); +ffffffffffffffffffffffff Ui.printDivider(); masterStudentList.remove(foundStudent); assert foundStudent == null : "Student should be deleted"; } diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index bf19d431b6..2eb9ac4e3b 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -32,18 +32,42 @@ public class Ui { * Displays the help message to teach users how to use Classify. */ public static void printHelp() { - System.out.println("add Adds a student to the student list, " + - "expects a name, grade and lessons attended" + + printAddHelpMessage(); + printEditHelpMessage(); + printViewHelpMessage(); + printDeleteHelpMessage(); + printListHelpMessage(); + printByeHelpMessage(); + System.out.println("help Prints this help message"); + } + + private static void printByeHelpMessage() { + System.out.println("bye Exits Classify"); + } + + private static void printListHelpMessage() { + System.out.println("list Displays the list of all students"); + } + + private static void printDeleteHelpMessage() { + System.out.println("delete Deletes a student from the student list, expects a name" + ", can be used directly with a name e.g. add [name]"); - System.out.println("edit Edits a students details, expects a name" + - " , can be used directly with a name e.g. edit [name]"); + } + + private static void printViewHelpMessage() { System.out.println("view Views a students details, expects a name" + ", can be used directly with a name e.g. add [name]"); - System.out.println("delete Deletes a student from the student list, expects a name" + + } + + private static void printEditHelpMessage() { + System.out.println("edit Edits a students details, expects a name" + + " , can be used directly with a name e.g. edit [name]"); + } + + private static void printAddHelpMessage() { + System.out.println("add Adds a student to the student list, " + + "expects a name, grade and lessons attended" + ", can be used directly with a name e.g. add [name]"); - System.out.println("list Displays the list of all students"); - System.out.println("bye Exits Classify"); - System.out.println("help Prints this help message"); } //@@author ParthGandhiNUS From c3f421cb315798098912df62de423ca34db53699 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 20 Mar 2024 18:53:23 +0800 Subject: [PATCH 065/503] Add exiting edit bugfix --- src/main/java/classify/Classify.java | 3 ++- src/main/java/classify/user/InputParsing.java | 5 ++++- text-ui-test/EXPECTED.TXT | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 4a95f1041b..7e3a5f40e6 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -18,6 +18,7 @@ public static void main(String[] args) { // @@author ParthGandhiNUS // CAA: 9 March 2024 1pm Ui.printWelcomeMessage(); + Ui.printUserPrompt(); // Takes in only the first word input by the user String[] userCommand = UserInput.processInput(in.nextLine()); @@ -25,9 +26,9 @@ public static void main(String[] args) { //Set up polling for the first word input by the user. // If user's first word is "bye", will exit the while loop. while (!(userCommand[0].equals("bye"))){ - Ui.printUserPrompt(); InputParsing.parseUserCommand(userCommand, StudentList.masterStudentList, in); userCommand = UserInput.processInput(in.nextLine()); + } Ui.printEndConversation(); diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 455efd9f71..827223593a 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -115,6 +115,8 @@ private static void editStudentAttributes(Scanner in, Student student) { System.out.println("How would you like to update student's subject? (enter blank to exit)"); String command = in.nextLine().trim(); if (command.isBlank()) { + System.out.println("Exiting edit"); + Ui.printDivider(); return; } @@ -339,13 +341,14 @@ private static String checkForEmptyName(ArrayList masterStudentList, Sc * student. */ private static void editAttribute(Scanner in, StudentAttributes attributes) { + while (true) { System.out.print("Subject to edit (enter nothing to exit): "); String subjectToFind = in.nextLine().trim(); if (subjectToFind.isBlank()) { - System.out.println("no subject edited"); + System.out.println("No subject edited."); return; } diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index ee9b049e1f..6156a7ed33 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,4 +1,6 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Welcome to Classify! +What can I do for you today? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Hope you've had a productive day. See you again! Goodbye! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From d25a9bdb973fa71da7f8514b2ae4cffe1c5efa7e Mon Sep 17 00:00:00 2001 From: alalal47 Date: Wed, 20 Mar 2024 18:54:51 +0800 Subject: [PATCH 066/503] Split help message to multiple methods --- src/main/java/classify/user/InputParsing.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index dfc4670019..455efd9f71 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -168,7 +168,7 @@ private static void deleteStudent(ArrayList masterStudentList, Scanner Ui.printStudentNotFound(); } -ffffffffffffffffffffffff Ui.printDivider(); + Ui.printDivider(); masterStudentList.remove(foundStudent); assert foundStudent == null : "Student should be deleted"; } From 4802dc48313a6b12eb93d0be9a6fc22c7e9be532 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 20 Mar 2024 19:10:39 +0800 Subject: [PATCH 067/503] Fix UI bug with spaces --- .gitignore | 2 ++ src/main/java/classify/user/InputParsing.java | 1 + src/main/java/classify/user/UserInput.java | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2873e189e1..e80bf5aa50 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ bin/ /text-ui-test/ACTUAL.TXT text-ui-test/EXPECTED-UNIX.TXT + +/tp.jar diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 827223593a..829e481dc5 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -94,6 +94,7 @@ private static void editStudent(ArrayList list, Scanner in, String name System.out.println("Name of student to edit (enter blank to exit):"); name = in.nextLine().trim(); if (name.isBlank()) { + System.out.println("Exiting edit."); return; } student = findStudentByName(list, name); diff --git a/src/main/java/classify/user/UserInput.java b/src/main/java/classify/user/UserInput.java index 41c26c52e8..b16c8b20fc 100644 --- a/src/main/java/classify/user/UserInput.java +++ b/src/main/java/classify/user/UserInput.java @@ -14,7 +14,7 @@ public static String[] processInput(String userInput){ if (userInput.trim().contains(" ")) { commandWithName = userInput.split(" ", 2); } else { - commandWithName[0] = userInput; + commandWithName[0] = userInput.trim(); } commandWithName[0] = commandWithName[0].toLowerCase(); From 23ac1dc84bd55274eb30c5bef45bd7d3e5e10e29 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 20 Mar 2024 19:11:19 +0800 Subject: [PATCH 068/503] Change javadoc --- src/main/java/classify/Classify.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 7e3a5f40e6..3b80c5e7e7 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -11,7 +11,7 @@ public class Classify { public static Scanner in = new Scanner(System.in); /** - * Main entry-point for the java.duke.Duke application. + * Main entry-point for the the Classify application. */ public static void main(String[] args) { From ee462a7a67114d69d700d35f935c664cafa7666d Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 20 Mar 2024 19:15:37 +0800 Subject: [PATCH 069/503] Change more javadoc --- src/main/java/classify/classgroup/Class.java | 6 +++--- src/main/java/classify/user/InputParsing.java | 3 +-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/classify/classgroup/Class.java b/src/main/java/classify/classgroup/Class.java index c8d59578c5..ccfe60ccb7 100644 --- a/src/main/java/classify/classgroup/Class.java +++ b/src/main/java/classify/classgroup/Class.java @@ -16,8 +16,8 @@ public class Class { /** * Constructor for a class of Students. - * @param ageOfStudents Age of the students in the class. - * @param className Name of the class. + * @param ageOfStudents Age of the students in the class. + * @param className Name of the class. */ public Class(int ageOfStudents, String className) { this.ageOfStudents = ageOfStudents; @@ -28,7 +28,7 @@ public Class(int ageOfStudents, String className) { /** * Get the age of the students attending the class. - * @return the age of the students as an integer. + * @return The age of the students as an integer. */ public int getAgeOfStudents() { return ageOfStudents; diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 829e481dc5..e04d00578e 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -586,8 +586,7 @@ private static String promptString(Scanner in) { String string = in.nextLine(); if (string.isBlank()) { return "Unknown"; - } - + } return string; } From d4b9998852bcd873b1cc92d518f07406b3201a8a Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 20 Mar 2024 19:25:21 +0800 Subject: [PATCH 070/503] Fix excess spacing --- src/main/java/classify/user/Ui.java | 40 +++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index bf19d431b6..238fd73786 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -32,18 +32,42 @@ public class Ui { * Displays the help message to teach users how to use Classify. */ public static void printHelp() { - System.out.println("add Adds a student to the student list, " + - "expects a name, grade and lessons attended" + + printAddHelpMessage(); + printEditHelpMessage(); + printViewHelpMessage(); + printDeleteHelpMessage(); + printListHelpMessage(); + printByeHelpMessage(); + System.out.println("help Prints this help message"); + } + + private static void printByeHelpMessage() { + System.out.println("bye Exits Classify"); + } + + private static void printListHelpMessage() { + System.out.println("list Displays the list of all students"); + } + + private static void printDeleteHelpMessage() { + System.out.println("delete Deletes a student from the student list, expects a name" + ", can be used directly with a name e.g. add [name]"); - System.out.println("edit Edits a students details, expects a name" + - " , can be used directly with a name e.g. edit [name]"); + } + + private static void printViewHelpMessage() { System.out.println("view Views a students details, expects a name" + ", can be used directly with a name e.g. add [name]"); - System.out.println("delete Deletes a student from the student list, expects a name" + + } + + private static void printEditHelpMessage() { + System.out.println("edit Edits a students details, expects a name" + + ", can be used directly with a name e.g. edit [name]"); + } + + private static void printAddHelpMessage() { + System.out.println("add Adds a student to the student list, " + + "expects a name, grade and lessons attended" + ", can be used directly with a name e.g. add [name]"); - System.out.println("list Displays the list of all students"); - System.out.println("bye Exits Classify"); - System.out.println("help Prints this help message"); } //@@author ParthGandhiNUS From 08353231ba1226c80b0a01d4062e81c1dcf37aa4 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 20 Mar 2024 19:30:02 +0800 Subject: [PATCH 071/503] Fix input test --- src/test/java/classify/user/InputParsingTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index c071c979cc..451e6b5d51 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -68,7 +68,7 @@ public void testHelpCommand() { " can be used directly with a name e.g. add [name]" + System.lineSeparator() + "edit Edits a students details, expects a name" + - " , can be used directly with a name e.g. edit [name]" + ", can be used directly with a name e.g. edit [name]" + System.lineSeparator() + "view Views a students details, expects a name" + ", can be used directly with a name e.g. add [name]" From a6bf754c843d04255dddc4a216eb4d64890220c3 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 20 Mar 2024 20:41:05 +0800 Subject: [PATCH 072/503] Add check for yes or no --- src/main/java/classify/user/InputParsing.java | 40 ++++++++++++++----- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index e04d00578e..032150ba2b 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -426,20 +426,38 @@ private static void addAttribute(Scanner in, StudentAttributes attributes) { System.out.println("Subject already exists."); break; + } else if (checkForValidSubjectResponse(in, attributes, subject)) { + //@@author tayponghee + return; + } + } + } + + /** + * Checks for a valid response from the user when prompted to add another subject and grade. + * + * @param in The scanner object to read user input. + * @param attributes The attributes of the student. + * @param subject The subject to be added. + * @return True if the user chooses not to add another subject and grade, false otherwise. + */ + private static boolean checkForValidSubjectResponse(Scanner in, StudentAttributes attributes, String subject) { + double grade = Math.max(promptForGrade(in), 0); + int classesAttended = promptForClassesAttended(in); + SubjectGrade subjectGrade = new SubjectGrade(subject, grade, classesAttended); + attributes.addSubjectGrade(subjectGrade); + while (true) { + System.out.println("Do you want to add another subject and grade? (yes/no)"); + String response = in.nextLine().trim().toLowerCase(); + if (response.equals("yes")) { + break; + } else if (response.equals("no")) { + return true; } else { - - // @@author tayponghee - double grade = Math.max(promptForGrade(in), 0); - int classesAttended = promptForClassesAttended(in); - SubjectGrade subjectGrade = new SubjectGrade(subject, grade, classesAttended); - attributes.addSubjectGrade(subjectGrade); - System.out.println("Do you want to add another subject and grade? (yes/no)"); - String response = in.nextLine().trim().toLowerCase(); - if (!response.equals("yes")) { - break; - } + System.out.println("Invalid response. Please type 'yes' or 'no'."); } } + return false; } /** From d360303dcf8f19091a60e86fadb91c0d34fc4de3 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 20 Mar 2024 23:20:11 +0800 Subject: [PATCH 073/503] Add javadoc for Input Parsing class --- src/main/java/classify/user/InputParsing.java | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 032150ba2b..63ba0b5043 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -12,6 +12,8 @@ import java.util.logging.Logger; public class InputParsing { + private static final int UPPER_LIMIT_PHONE_NUMBER = 10; + private static final int LOWER_LIMIT_PHONE_NUMBER = 8; private static final String NOTEMPTY = "THIS STRING IS NOT EMPTY"; private static final String BYE = "bye"; private static final String LIST = "list"; @@ -574,6 +576,18 @@ private static boolean isValidGrade(double grade) { } } + //@@author Cryolian + /** + * Creates a looping prompt asking for a phone number. + * Only exits the loop when either an exception is thrown, + * or when the number is either 8 or 10 digits to account for + * the length of a Singaporean number, with or without + * the country code. + * + * @param in The scanner class to read inputs from. + * @return -1 if an exception was thrown. An 8 + * or 10 digit number if not. + */ private static int promptForPhoneNumber(Scanner in) { System.out.println("Please input a valid Phone number: "); @@ -589,23 +603,30 @@ private static int promptForPhoneNumber(Scanner in) { return number; } catch (NumberFormatException e) { - System.out.println("A number was not inputted. "); + System.out.println("A valid number was not inputted. "); } return -1; } private static boolean checkNumberValidity(int number) { - return String.valueOf(number).length() == 8 || String.valueOf(number).length() == 10; + return String.valueOf(number).length() == LOWER_LIMIT_PHONE_NUMBER || String.valueOf(number).length() == UPPER_LIMIT_PHONE_NUMBER; } + /** + * A prompting input to scan in a string from the user input. + * + * @param in The scanner class to scan inputs from. + * @return "Unknown" if blank was inputted, or the + * trimmed string inputted by the user. + */ private static String promptString(Scanner in) { String string = in.nextLine(); if (string.isBlank()) { return "Unknown"; } - return string; + return string.trim(); } From 18aeff81e2730066ed6101dee3d4115309fece46 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 20 Mar 2024 23:23:54 +0800 Subject: [PATCH 074/503] Fix line wrapping --- src/main/java/classify/user/InputParsing.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 63ba0b5043..da24d8d4fa 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -610,7 +610,8 @@ private static int promptForPhoneNumber(Scanner in) { } private static boolean checkNumberValidity(int number) { - return String.valueOf(number).length() == LOWER_LIMIT_PHONE_NUMBER || String.valueOf(number).length() == UPPER_LIMIT_PHONE_NUMBER; + return String.valueOf(number).length() == LOWER_LIMIT_PHONE_NUMBER + || String.valueOf(number).length() == UPPER_LIMIT_PHONE_NUMBER; } /** From 31be9930293e0a25e52b2ac230a507166fa75ac5 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Thu, 21 Mar 2024 15:44:15 +0800 Subject: [PATCH 075/503] Edit comments in Classify.java to more accurately describe how we are processing inputs now, and add author tags to my code. --- src/main/java/classify/Classify.java | 4 ++-- src/main/java/classify/user/InputParsing.java | 15 ++++++++------- src/main/java/classify/user/Ui.java | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 3b80c5e7e7..bbbdb7af6a 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -20,10 +20,10 @@ public static void main(String[] args) { Ui.printWelcomeMessage(); Ui.printUserPrompt(); - // Takes in only the first word input by the user + // Takes in input from the user, and processes input to determine if it contains a command and a name String[] userCommand = UserInput.processInput(in.nextLine()); - //Set up polling for the first word input by the user. + // Set up polling for the first word input by the user. // If user's first word is "bye", will exit the while loop. while (!(userCommand[0].equals("bye"))){ InputParsing.parseUserCommand(userCommand, StudentList.masterStudentList, in); diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index da24d8d4fa..95808b9e3f 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -40,7 +40,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas Ui.printDivider(); break; - // @@author alalal47 + //@@author alalal47 case DELETE: deleteStudent(masterStudentList, in, userCommand[1]); break; @@ -145,7 +145,7 @@ private static void editStudentAttributes(Scanner in, Student student) { } } - // @@author alalal47 + //@@author alalal47 /** * Removes a student from the list. * @@ -155,9 +155,7 @@ private static void editStudentAttributes(Scanner in, Student student) { * before being prompted */ private static void deleteStudent(ArrayList masterStudentList, Scanner in, String studentName) { - String name; - if (studentName == null) { Ui.printStudentNamePrompt(); name = in.nextLine().trim(); @@ -190,7 +188,8 @@ private static void deleteStudent(ArrayList masterStudentList, Scanner private static void viewStudent(ArrayList masterStudentList, Scanner in, String studentName) { String name; - + + //@@author alalal47 if (studentName == null) { Ui.printStudentNamePrompt(); name = in.nextLine(); @@ -198,9 +197,9 @@ private static void viewStudent(ArrayList masterStudentList, Scanner in name = studentName; } - // @author blackmirag3 + //@@author blackmirag3 assert name != null : "Student name cannot be null"; - // @author tayponghee + //@@author tayponghee Student foundStudent = findStudentByName(masterStudentList, name); if (foundStudent != null) { @@ -314,6 +313,7 @@ private static String checkForEmptyName(ArrayList masterStudentList, Sc String name; while (true) { + //@@author alalal47 if (studentName == null) { Ui.printStudentNamePrompt(); name = in.nextLine().trim(); @@ -322,6 +322,7 @@ private static String checkForEmptyName(ArrayList masterStudentList, Sc studentName = NOTEMPTY; } + //@@author tayponghee assert studentName != null; if (name.isEmpty()) { diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index a54a3878c3..2d3a67dfda 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -27,7 +27,7 @@ public class Ui { private static final String STUDENT_PAYMENT_MESSAGE = "Last Payment Date: "; private static final String STUDENT_REMARKS_MESSAGE = "Remarks: "; - //@author alalal47 + //@@author alalal47 /** * Displays the help message to teach users how to use Classify. */ From b46caba349b9bae7c3959e78ba0dc39d17c6a70f Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 22 Mar 2024 13:39:36 +0800 Subject: [PATCH 076/503] Add sort_name command --- META-INF/MANIFEST.MF | 3 ++ src/main/java/classify/Classify.java | 2 +- src/main/java/classify/student/Student.java | 16 +++++++++ .../java/classify/student/StudentList.java | 3 ++ src/main/java/classify/user/InputParsing.java | 36 +++++++++++++++---- src/main/java/classify/user/Ui.java | 18 ++++++++++ src/main/java/classify/user/UserInput.java | 1 + 7 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 META-INF/MANIFEST.MF diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..aa8b655771 --- /dev/null +++ b/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: classify.Classify + diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index bbbdb7af6a..f367b47afb 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -11,7 +11,7 @@ public class Classify { public static Scanner in = new Scanner(System.in); /** - * Main entry-point for the the Classify application. + * Main entry-point for the Classify application. */ public static void main(String[] args) { diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 49a194c3ef..7b6997fb87 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -1,5 +1,7 @@ package classify.student; +import java.util.Comparator; + /** * Meant to represent a particular student of the tuition centre. * The student can first be declared with only a name, and the subsequent details @@ -20,6 +22,7 @@ public Student(String name) { this.attributes = new StudentAttributes(this); } + //@@author tayponghee public StudentAttributes getAttributes() { return attributes; } @@ -27,6 +30,19 @@ public StudentAttributes getAttributes() { public void setAttributes(StudentAttributes attributes) { this.attributes = attributes; } + public String getGender() { + return attributes.getGender(); + } + + public int getPhoneNumber() { + return attributes.getPhoneNumber(); + } + + public String getLastPaymentDate() { + return attributes.getLastPaymentDate(); + } + public static Comparator nameComparator = Comparator.comparing(Student::getName); + //@@ Cryolian public String getName() { diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index a1fb2b4ed0..a4d5d198f8 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -1,6 +1,8 @@ package classify.student; import java.util.ArrayList; +import java.util.Comparator; + /** * Class to represent a list of Students. @@ -91,4 +93,5 @@ public void removeStudent(String name) { } } } + } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 95808b9e3f..bd078d22de 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -6,8 +6,11 @@ import classify.student.SubjectGrade; import java.util.ArrayList; +import java.util.Collections; + import java.util.List; import java.util.Scanner; + import java.util.logging.Level; import java.util.logging.Logger; @@ -22,8 +25,12 @@ public class InputParsing { private static final String DELETE = "delete"; private static final String EDIT = "edit"; private static final String HELP = "help"; + private static final String SORT_NAME = "sort_name"; + public static final String NO_STUDENTS_IN_THE_LIST_CAN_T_SORT_BY_NAME = + "No students in the list, can't sort by name!"; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); + public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, Scanner in) { // @@author blackmirag3 if (masterStudentList == null) { @@ -55,12 +62,17 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas Ui.printEndConversation(); break; + case EDIT: + editStudent(masterStudentList, in, userCommand[1]); + break; + case LIST: listStudents(masterStudentList); break; - case EDIT: - editStudent(masterStudentList, in, userCommand[1]); + //@@ author tayponghee + case SORT_NAME: + listStudentsByName(masterStudentList); break; default: @@ -69,6 +81,22 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas } } + /** + * Lists students in the provided list by name in ascending order. + * If the list is empty, it prints a message indicating that there are no students in the list. + * + * @param students The list of students to be listed by name. + */ + public static void listStudentsByName(ArrayList students) { + if (students.isEmpty()) { + System.out.println(NO_STUDENTS_IN_THE_LIST_CAN_T_SORT_BY_NAME); + return; + } + Collections.sort(students, Student.nameComparator); + listStudents(students); + } + + // @@author blackmirag3 private static void listStudents(ArrayList list) { StudentList.printCurrentArrayList(list); @@ -137,10 +165,6 @@ private static void editStudentAttributes(Scanner in, Student student) { case DELETE: deleteAttribute(in, attributes); break; - - default: - Ui.printWrongInput(); - break; } } } diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index 2d3a67dfda..acfdeb0113 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -2,6 +2,8 @@ import classify.student.Student; +import java.util.ArrayList; + public class Ui { //@@author ParthGandhiNUS private static final String DIVIDER = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; @@ -38,9 +40,16 @@ public static void printHelp() { printDeleteHelpMessage(); printListHelpMessage(); printByeHelpMessage(); + printSortNameMessage(); System.out.println("help Prints this help message"); } + //@@ author tayponghee + private static void printSortNameMessage() { + System.out.println("sort_name sorts the students by name lexicographically"); + } + + //@@ author Cryolian private static void printByeHelpMessage() { System.out.println("bye Exits Classify"); } @@ -160,4 +169,13 @@ public static void printStudentGradesPrompt() { System.out.println(STUDENT_GRADES_PROMPT); } + //@@ author tayponghee + public static void printStudentList(ArrayList students) { + System.out.println("List of Students:"); + for (int i = 0; i < students.size(); i++) { + System.out.println((i + 1) + ". " + students.get(i).getName()); + } + System.out.println("Currently, there are " + students.size() + " students in the list."); + System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); + } } diff --git a/src/main/java/classify/user/UserInput.java b/src/main/java/classify/user/UserInput.java index b16c8b20fc..2b42a58c1a 100644 --- a/src/main/java/classify/user/UserInput.java +++ b/src/main/java/classify/user/UserInput.java @@ -20,4 +20,5 @@ public static String[] processInput(String userInput){ commandWithName[0] = commandWithName[0].toLowerCase(); return commandWithName; } + } From 28d9c15386f88b3e1f00b4c62c3b2e44361e46f4 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 22 Mar 2024 13:58:15 +0800 Subject: [PATCH 077/503] Fix gradle checks --- src/main/java/classify/student/Student.java | 4 ---- src/main/java/classify/student/StudentComparators.java | 7 +++++++ src/main/java/classify/student/StudentList.java | 2 -- src/main/java/classify/user/InputParsing.java | 10 ++++++++-- src/main/java/classify/user/Ui.java | 2 +- src/test/java/classify/user/InputParsingTest.java | 4 +++- 6 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 src/main/java/classify/student/StudentComparators.java diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 7b6997fb87..57befc51d4 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -1,7 +1,5 @@ package classify.student; -import java.util.Comparator; - /** * Meant to represent a particular student of the tuition centre. * The student can first be declared with only a name, and the subsequent details @@ -41,8 +39,6 @@ public int getPhoneNumber() { public String getLastPaymentDate() { return attributes.getLastPaymentDate(); } - public static Comparator nameComparator = Comparator.comparing(Student::getName); - //@@ Cryolian public String getName() { diff --git a/src/main/java/classify/student/StudentComparators.java b/src/main/java/classify/student/StudentComparators.java new file mode 100644 index 0000000000..479c7bae82 --- /dev/null +++ b/src/main/java/classify/student/StudentComparators.java @@ -0,0 +1,7 @@ +package classify.student; + +import java.util.Comparator; + +public class StudentComparators { + public static Comparator nameComparator = Comparator.comparing(Student::getName); +} diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index a4d5d198f8..65e2b6ec43 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -1,8 +1,6 @@ package classify.student; import java.util.ArrayList; -import java.util.Comparator; - /** * Class to represent a list of Students. diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index bd078d22de..eba5318a7e 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -2,6 +2,8 @@ import classify.student.Student; import classify.student.StudentAttributes; + +import classify.student.StudentComparators; import classify.student.StudentList; import classify.student.SubjectGrade; @@ -26,7 +28,7 @@ public class InputParsing { private static final String EDIT = "edit"; private static final String HELP = "help"; private static final String SORT_NAME = "sort_name"; - public static final String NO_STUDENTS_IN_THE_LIST_CAN_T_SORT_BY_NAME = + private static final String NO_STUDENTS_IN_THE_LIST_CAN_T_SORT_BY_NAME = "No students in the list, can't sort by name!"; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); @@ -92,7 +94,7 @@ public static void listStudentsByName(ArrayList students) { System.out.println(NO_STUDENTS_IN_THE_LIST_CAN_T_SORT_BY_NAME); return; } - Collections.sort(students, Student.nameComparator); + Collections.sort(students, StudentComparators.nameComparator); listStudents(students); } @@ -165,7 +167,11 @@ private static void editStudentAttributes(Scanner in, Student student) { case DELETE: deleteAttribute(in, attributes); break; + + default: + break; } + } } diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index acfdeb0113..e1c9bd5926 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -46,7 +46,7 @@ public static void printHelp() { //@@ author tayponghee private static void printSortNameMessage() { - System.out.println("sort_name sorts the students by name lexicographically"); + System.out.println("sort_name sorts the students by name lexicographically"); } //@@ author Cryolian diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index 451e6b5d51..f7fbef6d4c 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -80,8 +80,10 @@ public void testHelpCommand() { + System.lineSeparator() + "bye Exits Classify" + System.lineSeparator() + + "sort_name sorts the students by name lexicographically" + + System.lineSeparator() + "help Prints this help message" + - System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; assertEquals(expectedOutput.trim(), printedOutput); } From d6e943465d8665400d8205ce61afa99bd405dcdf Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 22 Mar 2024 14:14:39 +0800 Subject: [PATCH 078/503] Update UserGuide --- docs/UserGuide.md | 84 +++++++++++++++---- src/main/java/classify/user/InputParsing.java | 32 ++++--- 2 files changed, 91 insertions(+), 25 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index abd9fbe891..d2180386ce 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,39 +1,93 @@ -# User Guide +# User Guide for **Classify** ## Introduction -{Give a product intro} +Classify is a student management system meant to assist administrative staff of private tuition centres. + +The product is capable of storing students, and generating outputs based on provided parameters, such as grade improvements and payment statuses. + +Within our program, a student can be stored with their +- Subjects taken +- Grades in those subjects +- Phone Number +- Gender +- Last Payment Dates +- Remarks + +We have determined these to be the attributes important to running a working tuition centre. Based on these attributes, our program also has functions to sort students based on grades, subjects, improvements since joining the centre. ## Quick Start -{Give steps to get started quickly} +1. Ensure that you have Java __11 or above__ installed. +2. Download the provided jar file into an empty folder. +3. Run it from the terminal using the following command: +``` +java -jar ./Classify.jar +``` -1. Ensure that you have Java 11 or above installed. -1. Down the latest version of `Duke` from [here](http://link.to/duke). +4. Run the command ```help``` within the program to get a quick view of the available commands. ## Features -{Give detailed description of each feature} +### - Add a student `add` + +Initialises the process of adding in a student. + +### - View details of a student `view` + +Prints out the details of a given student in the interface. + +### - Edit details of a student `edit` + +Initialises the process of editing both academic and non-academic details of a student. + +### - Delete a student from the working list `delete` -### Adding a todo: `todo` -Adds a new item to the list of todo items. +Removes a student from the master list of students. -Format: `todo n/TODO_NAME d/DEADLINE` -* The `DEADLINE` can be in a natural language format. -* The `TODO_NAME` cannot contain punctuation. -Example of usage: +# Usage +//todo add usage guide for our different commands -`todo n/Write the rest of the User Guide d/next week` +### Adding a student: `add` +Initialises an interface for adding a student and their relevant details to the database. -`todo n/Refactor the User Guide to remove passive voice d/13/04/2020` +**to change** +Currently, no two students can have the same name within the system. + +Format: `add` or `add NAME` + +Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. + +Example: +``` +add wario + +Subject (enter nothing to skip): +SUBJECT + +Current marks out of 100 (blank to skip) : +GRADE + +Do you want to add another subject and grade? (yes/no) +no + +Please input a valid Phone number: +NUMBER +. +. +``` ## FAQ **Q**: How do I transfer my data to another computer? -**A**: {your answer here} +**A**: Plug out the corresponding drive from the computer you would like to transfer from, and connect it to either the SATA or m.2 port of the computer you would like to transfer to. Please make sure to reinstall any existing drivers to ensure maximum compatibility. + +**Q**: How do I transfer my data to another computer **without** removing any components? + +**A**: (parth this is for you to answer) ## Command Summary diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index eba5318a7e..c13627c9d2 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -17,7 +17,7 @@ import java.util.logging.Logger; public class InputParsing { - private static final int UPPER_LIMIT_PHONE_NUMBER = 10; + private static final int UPPER_LIMIT_PHONE_NUMBER = 99999999; private static final int LOWER_LIMIT_PHONE_NUMBER = 8; private static final String NOTEMPTY = "THIS STRING IS NOT EMPTY"; private static final String BYE = "bye"; @@ -156,7 +156,7 @@ private static void editStudentAttributes(Scanner in, Student student) { switch (command) { case ADD: - addAttribute(in, attributes); + addSubject(in, attributes); student.setAttributes(attributes); break; @@ -300,7 +300,7 @@ private static void addStudent(ArrayList masterStudentList, Scanner in, } Student student = new Student(name); - addAttribute(in, student.getAttributes()); + addSubject(in, student.getAttributes()); // @@author Cryolian int number = promptForPhoneNumber(in); @@ -308,7 +308,11 @@ private static void addStudent(ArrayList masterStudentList, Scanner in, while (number < 0) { number = promptForPhoneNumber(in); } + + //@@author ParthGandhiNUS + assert number > 0 && number <= UPPER_LIMIT_PHONE_NUMBER: "Number is outside the acceptable range."; + //@@author Cryolian student.getAttributes().setPhoneNumber(number); System.out.println("Please input the student's gender: "); @@ -443,7 +447,7 @@ private static void deleteAttribute(Scanner in, StudentAttributes attributes) { * @param attributes The StudentAttributes object to store the attributes of the * student. */ - private static void addAttribute(Scanner in, StudentAttributes attributes) { + private static void addSubject(Scanner in, StudentAttributes attributes) { while (true) { // @@author blackmirag3 System.out.print("Subject (enter nothing to skip): "); @@ -625,24 +629,32 @@ private static int promptForPhoneNumber(Scanner in) { try { - int number = Integer.parseInt(in.nextLine()); + int number = readInPhoneNumber(in); + while (!checkNumberValidity(number)) { System.out.println("Please input a valid number"); - number = Integer.parseInt(in.nextLine()); + number = readInPhoneNumber(in); } - + logger.log(Level.INFO, "Storing number: " + number); return number; } catch (NumberFormatException e) { - System.out.println("A valid number was not inputted. "); + System.out.println("A valid phone number was not inputted."); } return -1; } + private static int readInPhoneNumber(Scanner in) throws NumberFormatException{ + + String input = in.nextLine().trim(); + + return Integer.parseInt(input); + } + private static boolean checkNumberValidity(int number) { - return String.valueOf(number).length() == LOWER_LIMIT_PHONE_NUMBER - || String.valueOf(number).length() == UPPER_LIMIT_PHONE_NUMBER; + return number > 0 && + String.valueOf(number).length() == LOWER_LIMIT_PHONE_NUMBER; } /** From 1d6e6846f52bdc53db10d307ccee5a2e204f894a Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 22 Mar 2024 14:53:43 +0800 Subject: [PATCH 079/503] Add Assertion --- src/main/java/classify/user/InputParsing.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index eba5318a7e..3027d3c86e 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -308,7 +308,9 @@ private static void addStudent(ArrayList masterStudentList, Scanner in, while (number < 0) { number = promptForPhoneNumber(in); } - + //@@ author ParthGandhiNUS + assert number > 0 && number < 100000000: "Number is outside the acceptable range."; + //@@author Cryolian student.getAttributes().setPhoneNumber(number); System.out.println("Please input the student's gender: "); From 5ea6030f137756c2912f7777d4a29292416bc82c Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 22 Mar 2024 15:16:21 +0800 Subject: [PATCH 080/503] Fix CI errors --- src/main/java/classify/user/InputParsing.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index becdc4a2ad..b348825fb6 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -18,7 +18,6 @@ public class InputParsing { private static final String DEFAULT_STRING_VALUE = "Unknown"; - private static final int UPPER_LIMIT_PHONE_NUMBER = 99999999; private static final int LOWER_LIMIT_PHONE_NUMBER = 8; private static final String NOTEMPTY = "THIS STRING IS NOT EMPTY"; private static final String BYE = "bye"; From 3e992ac500393e00a2b33fdeaf09a4e0725b7480 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 22 Mar 2024 15:19:36 +0800 Subject: [PATCH 081/503] Fix CI error 2 --- src/main/java/classify/user/Ui.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index 3ccdd4015b..134fd7d703 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -17,7 +17,8 @@ public class Ui { private static final String STUDENT_GENDER_MESSAGE = "Gender: "; private static final String STUDENT_PAYMENT_MESSAGE = "Last Payment Date: "; private static final String STUDENT_REMARKS_MESSAGE = "Remarks: "; - private static final String SAME_NAME_ERROR = "Student with the same name already exists. Please enter a different name."; + private static final String SAME_NAME_ERROR = "Student with the same name already exists." + + "Please enter a different name."; private static final String EMPTY_NAME_ERROR = "Student name cannot be empty. Please enter a valid name."; private static final String GENDER_PROMPT = "Please input the student's gender: "; private static final String PAYMENT_PROMPT = "Please input their last payment date: "; From 31174beb4c136a9b1c6ffe9bff12a3026addff1c Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 22 Mar 2024 15:22:24 +0800 Subject: [PATCH 082/503] Update .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e80bf5aa50..b194f20b2d 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,5 @@ bin/ /text-ui-test/ACTUAL.TXT text-ui-test/EXPECTED-UNIX.TXT -/tp.jar +/*.jar +/.vscode From 40d8bcaca1fc180a063aab70503c71e86c84ed84 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 22 Mar 2024 17:24:06 +0800 Subject: [PATCH 083/503] Add search by subject --- src/main/java/classify/student/Student.java | 9 +++ src/main/java/classify/user/InputParsing.java | 59 ++++++++++++++++++- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 57befc51d4..2bc1d2310a 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -28,6 +28,7 @@ public StudentAttributes getAttributes() { public void setAttributes(StudentAttributes attributes) { this.attributes = attributes; } + public String getGender() { return attributes.getGender(); } @@ -39,6 +40,14 @@ public int getPhoneNumber() { public String getLastPaymentDate() { return attributes.getLastPaymentDate(); } + public boolean hasSubject(String subject) { + for (SubjectGrade subjectGrade : attributes.getSubjectGrades()) { + if (subjectGrade.getSubject().equalsIgnoreCase(subject)) { + return true; + } + } + return false; + } //@@ Cryolian public String getName() { diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index b348825fb6..385fc37802 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -28,11 +28,17 @@ public class InputParsing { private static final String EDIT = "edit"; private static final String HELP = "help"; private static final String SORT_NAME = "sort_name"; + private static final String VIEW_SUBJECT = "view_subject"; private static final String NO_STUDENTS_IN_THE_LIST_CAN_T_SORT_BY_NAME = "No students in the list, can't sort by name!"; + private static final String STUDENTS_WITH_THE_SUBJECT = "Students with the subject \""; + private static final String NO_STUDENTS_FOUND_WITH_THE_SUBJECT = "No students found with the subject: "; + private static final String ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK = + "Enter the subject name (type 'exit' to go back):"; + private static final String EXIT = "exit"; + private static final String EXITED_THE_COMMAND = "Exited the command."; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); - public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, Scanner in) { // @@author blackmirag3 if (masterStudentList == null) { @@ -77,12 +83,62 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas listStudentsByName(masterStudentList); break; + case VIEW_SUBJECT: + handleViewSubjectCommand(masterStudentList, in); + break; + default: Ui.printWrongInput(); break; } } + /** + * Lets the user check view a list of students with that corresponding subject. + * Will only exit from the command if the user types the command exit. + * + * @param masterStudentList The list of all students. + * @param in The user's input. + */ + private static void handleViewSubjectCommand(ArrayList masterStudentList, Scanner in) { + while (true) { + System.out.println(ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK); + String subject = in.nextLine().trim(); + + if (subject.equalsIgnoreCase(EXIT)) { + System.out.println(EXITED_THE_COMMAND); + Ui.printDivider(); + break; + } + + viewStudentsBySubject(masterStudentList, subject); + } + } + + /** + * Views all students who have the specified subject. + * + * @param masterStudentList The list of all students. + * @param subject The subject to search for among students. + */ + private static void viewStudentsBySubject(ArrayList masterStudentList, String subject) { + boolean found = false; + System.out.println(STUDENTS_WITH_THE_SUBJECT + subject + "\":"); + + for (Student student : masterStudentList) { + if (student.hasSubject(subject)) { + System.out.println("- " + student.getName()); + found = true; + } + } + + if (!found) { + System.out.println(NO_STUDENTS_FOUND_WITH_THE_SUBJECT + subject); + } + + Ui.printDivider(); + } + /** * Lists students in the provided list by name in ascending order. * If the list is empty, it prints a message indicating that there are no students in the list. @@ -98,7 +154,6 @@ public static void listStudentsByName(ArrayList students) { listStudents(students); } - // @@author blackmirag3 private static void listStudents(ArrayList list) { StudentList.printCurrentArrayList(list); From d543111b0f76023b29052491bf45d9ee089c6482 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 22 Mar 2024 17:53:29 +0800 Subject: [PATCH 084/503] Allow the user to specify if they want to view the subject directly --- src/main/java/classify/user/InputParsing.java | 41 +++++++++++++++---- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 385fc37802..a20cdf3eeb 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -84,7 +84,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas break; case VIEW_SUBJECT: - handleViewSubjectCommand(masterStudentList, in); + handleViewSubjectCommand(masterStudentList, in, userCommand[1]); break; default: @@ -95,23 +95,46 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas /** * Lets the user check view a list of students with that corresponding subject. - * Will only exit from the command if the user types the command exit. + * If the user types view_subject [subject], it will only generate the list of students with that subject, + * then exit. + * If the user types view_subject, the user can continuously view all students that + * have that subject, until they exit the command. * * @param masterStudentList The list of all students. * @param in The user's input. */ - private static void handleViewSubjectCommand(ArrayList masterStudentList, Scanner in) { + private static void handleViewSubjectCommand(ArrayList masterStudentList, Scanner in, String subject) { + if (subject != null && !subject.isEmpty()) { + viewStudentsBySubject(masterStudentList, subject); + } else { + findStudentsWithSubject(masterStudentList, in); + } + } + + /** + * Finds students with the specified subject and displays them to the user. + * Continuously prompts the user to enter a subject name until they choose to exit. + * + * @param masterStudentList The list of all students. + * @param in The scanner object to read user input. + */ + private static void findStudentsWithSubject(ArrayList masterStudentList, Scanner in) { while (true) { System.out.println(ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK); - String subject = in.nextLine().trim(); + String input = in.nextLine().trim(); - if (subject.equalsIgnoreCase(EXIT)) { + if (input.equalsIgnoreCase(EXIT)) { System.out.println(EXITED_THE_COMMAND); Ui.printDivider(); - break; + return; } - viewStudentsBySubject(masterStudentList, subject); + if (!input.isEmpty()) { + viewStudentsBySubject(masterStudentList, input); + return; + } else { + System.out.println("Please enter a valid subject name."); + } } } @@ -123,7 +146,7 @@ private static void handleViewSubjectCommand(ArrayList masterStudentLis */ private static void viewStudentsBySubject(ArrayList masterStudentList, String subject) { boolean found = false; - System.out.println(STUDENTS_WITH_THE_SUBJECT + subject + "\":"); + System.out.println("Students with the subject \"" + subject + "\":"); for (Student student : masterStudentList) { if (student.hasSubject(subject)) { @@ -133,7 +156,7 @@ private static void viewStudentsBySubject(ArrayList masterStudentList, } if (!found) { - System.out.println(NO_STUDENTS_FOUND_WITH_THE_SUBJECT + subject); + System.out.println("No students found with the subject: " + subject); } Ui.printDivider(); From 3d73afd9fe2f2c6a133535e1b8c96700da72ca81 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 22 Mar 2024 18:16:59 +0800 Subject: [PATCH 085/503] Implement recently deleted list, undo and restore functions from said list --- src/main/java/classify/Classify.java | 4 +- .../java/classify/student/StudentList.java | 4 +- src/main/java/classify/user/InputParsing.java | 87 ++++++++++++++++--- src/main/java/classify/user/Ui.java | 17 +++- .../java/classify/user/InputParsingTest.java | 9 +- 5 files changed, 104 insertions(+), 17 deletions(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index f367b47afb..693655ec78 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -26,9 +26,9 @@ public static void main(String[] args) { // Set up polling for the first word input by the user. // If user's first word is "bye", will exit the while loop. while (!(userCommand[0].equals("bye"))){ - InputParsing.parseUserCommand(userCommand, StudentList.masterStudentList, in); + InputParsing.parseUserCommand(userCommand, StudentList.masterStudentList, StudentList.recentlyDeletedList, + in); userCommand = UserInput.processInput(in.nextLine()); - } Ui.printEndConversation(); diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 65e2b6ec43..75d88fd738 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -13,13 +13,15 @@ public class StudentList { public static final String CURRENTLY_THERE_ARE = "Currently, there are "; public static final String STUDENTS_IN_THE_LIST = " students in the list."; public static ArrayList masterStudentList = new ArrayList<>(); + public static ArrayList recentlyDeletedList = new ArrayList<>(); //@@author Cryolian public ArrayList studentList; + //@@author Cryolian public StudentList() { - this.studentList = new ArrayList<>(); + this.studentList = new ArrayList<>();; } //@@author ParthGandhiNUS diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index b348825fb6..59f3245ea0 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -25,6 +25,8 @@ public class InputParsing { private static final String ADD = "add"; private static final String VIEW = "view"; private static final String DELETE = "delete"; + private static final String UNDO = "undo"; + private static final String RESTORE = "restore"; private static final String EDIT = "edit"; private static final String HELP = "help"; private static final String SORT_NAME = "sort_name"; @@ -33,7 +35,8 @@ public class InputParsing { private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); - public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, Scanner in) { + public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, + ArrayList recentlyDeletedList,Scanner in) { // @@author blackmirag3 if (masterStudentList == null) { System.out.println("Student list is null."); @@ -51,7 +54,15 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas //@@author alalal47 case DELETE: - deleteStudent(masterStudentList, in, userCommand[1]); + deleteStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); + break; + + case RESTORE: + restoreStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); + break; + + case UNDO: + undoDelete(masterStudentList, recentlyDeletedList); break; case HELP: @@ -182,13 +193,16 @@ private static void editStudentAttributes(Scanner in, Student student) { //@@author alalal47 /** * Removes a student from the list. + * Adds the removed student to a recently deleted list, where the student's information can be recovered * - * @param masterStudentList The list of all students. - * @param in The scanner object to read user input. - * @param studentName The name of the student if the user had entered it - * before being prompted + * @param masterStudentList The list of all students + * @param recentlyDeletedList The list of recently deleted students + * @param in The scanner object to read user input + * @param studentName The name of the student if the user had entered it + * before being prompted */ - private static void deleteStudent(ArrayList masterStudentList, Scanner in, String studentName) { + private static void deleteStudent(ArrayList masterStudentList, ArrayList recentlyDeletedList, + Scanner in, String studentName) { String name; if (studentName == null) { Ui.printStudentNamePrompt(); @@ -206,8 +220,61 @@ private static void deleteStudent(ArrayList masterStudentList, Scanner } Ui.printDivider(); + recentlyDeletedList.add(foundStudent); masterStudentList.remove(foundStudent); - assert foundStudent == null : "Student should be deleted"; + //assert foundStudent == null : "Student should be deleted"; + } + + /** + * Removes a student from the list. + * Adds the removed student to a recently deleted list, where the student's information can be recovered + * + * @param masterStudentList The list of all students. + * @param recentlyDeletedList The list of recently deleted students + * @param in The scanner object to read user input. + * @param studentName The name of the student if the user had entered it + * before being prompted + */ + private static void restoreStudent(ArrayList masterStudentList, ArrayList recentlyDeletedList, + Scanner in, String studentName) { + String name; + if (studentName == null) { + Ui.printStudentNamePrompt(); + name = in.nextLine().trim(); + } else { + name = studentName; + } + + Student foundStudent = findStudentByName(recentlyDeletedList, name); + + if (foundStudent != null) { + Ui.printRestoreMessage(); + } else { + Ui.printStudentNotFound(); + } + + Ui.printDivider(); + masterStudentList.add(foundStudent); + recentlyDeletedList.remove(foundStudent); + } + + /** + * Restores the latest deleted student that has not yet been restored + * + * @param masterStudentList The list of all students + * @param recentlyDeletedList The list of recently deleted students + */ + private static void undoDelete(ArrayList masterStudentList, ArrayList recentlyDeletedList) { + if (recentlyDeletedList.isEmpty()) { + Ui.printNoDeleteFound(); + Ui.printDivider(); + return; + } + Student student = recentlyDeletedList.get(recentlyDeletedList.size() - 1); + masterStudentList.add(student); + recentlyDeletedList.remove(student); + Ui.printDeleteUndone(); + Ui.printDivider(); } //@@author tayponghee @@ -274,7 +341,7 @@ private static void showAttributes(StudentAttributes attributes) { } } else { - Ui.printNullAttributeError();; + Ui.printNullAttributeError(); } } @@ -625,7 +692,7 @@ private static boolean isValidGrade(double grade) { * * @param in The scanner class to read inputs from. * @return -1 if an exception was thrown. An 8 - * or 10 digit number if not. + * or 10-digit number if not. */ private static int promptForPhoneNumber(Scanner in) { diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index 134fd7d703..79990a1180 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -42,6 +42,10 @@ public class Ui { private static final String SUBJECT_MESSAGE = "Subject: "; private static final String STUDENT_GRADES_PROMPT = "Current marks out of 100 (blank to skip) : "; private static final String STUDENT_GRADES_MESSAGE = "Current marks out of 100: "; + //@@author alalal47 + private static final String DELETE_UNDONE_MESSAGE = "Last delete undone!"; + private static final String STUDENT_RESTORED_MESSAGE = "Student has been restored!"; + private static final String NO_RECENT_DELETES = "No recent deletes found!"; //@@author alalal47 @@ -81,7 +85,6 @@ private static void printDeleteHelpMessage() { private static void printViewHelpMessage() { System.out.println("view Views a students details, expects a name" + ", can be used directly with a name e.g. add [name]"); - } private static void printEditHelpMessage() { @@ -239,4 +242,16 @@ public static void printNullAttributeError() { System.out.println(NULL_ATTRIBUTE_ERROR); } + //@@author alalal47 + public static void printDeleteUndone() { + System.out.println(DELETE_UNDONE_MESSAGE); + } + + public static void printRestoreMessage() { + System.out.println(STUDENT_RESTORED_MESSAGE); + } + + public static void printNoDeleteFound() { + System.out.println(NO_RECENT_DELETES); + } } diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index f7fbef6d4c..47381c768f 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -19,9 +19,10 @@ public void testByeCommand() { System.setOut(new PrintStream(outputStream)); ArrayList masterStudentList = new ArrayList<>(); + ArrayList recentlyDeletedList = new ArrayList<>(); String [] commands = new String[2]; commands[0] = "bye"; - InputParsing.parseUserCommand(commands, masterStudentList, new Scanner(System.in)); + InputParsing.parseUserCommand(commands, masterStudentList, recentlyDeletedList, new Scanner(System.in)); System.setOut(System.out); @@ -38,9 +39,10 @@ public void testUnknownCommand() { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); System.setOut(new PrintStream(outputStream)); ArrayList students = new ArrayList<>(); + ArrayList recentlyDeletedList = new ArrayList<>(); String [] commands = new String[2]; commands[0] = "yeet"; - InputParsing.parseUserCommand(commands, students, new Scanner(System.in)); + InputParsing.parseUserCommand(commands, students, recentlyDeletedList, new Scanner(System.in)); System.setOut(System.out); String printedOutput = outputStream.toString().trim(); String expectedOutput = "No such command, type \"help\" to view all commands" + @@ -55,9 +57,10 @@ public void testHelpCommand() { System.setOut(new PrintStream(outputStream)); ArrayList masterStudentList = new ArrayList<>(); + ArrayList recentlyDeletedList = new ArrayList<>(); String [] commands = new String[2]; commands[0] = "help"; - InputParsing.parseUserCommand(commands, masterStudentList, new Scanner(System.in)); + InputParsing.parseUserCommand(commands, masterStudentList, recentlyDeletedList, new Scanner(System.in)); System.setOut(System.out); From c5e4a5902e2c48f58350fd398c5991732a7bdf88 Mon Sep 17 00:00:00 2001 From: Tay Pong Hee <110646458+tayponghee@users.noreply.github.com> Date: Fri, 22 Mar 2024 21:07:44 +0800 Subject: [PATCH 086/503] Update UserGuide.md --- docs/UserGuide.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 9b47c24dab..7d9cbcb863 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -45,6 +45,14 @@ Initialises the process of editing both academic and non-academic details of a s Removes a student from the master list of students. +### - Produce a list of all the students who takes a subject `view_subject` + +Displays a list of all the students with that associated subject taken in the tuition centre. + +### - Sort the list lexicograpically, from A to Z `sort_name` + +Sorts the masterlist of students from A to Z. When the user types list, it will generate the updated sorted list. + # Usage //todo add usage guide for our different commands @@ -80,7 +88,6 @@ NUMBER ### - View details of a student `view` - ### - Edit details of a student `edit` @@ -100,4 +107,3 @@ NUMBER {Give a 'cheat sheet' of commands here} -* Add todo `todo n/TODO_NAME d/DEADLINE` From 1ebb6bab5b86058782f50ec2e4f6ca957fa91807 Mon Sep 17 00:00:00 2001 From: Tay Pong Hee <110646458+tayponghee@users.noreply.github.com> Date: Fri, 22 Mar 2024 21:24:55 +0800 Subject: [PATCH 087/503] Update UserGuide.md --- docs/UserGuide.md | 49 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 7d9cbcb863..c9618794e9 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -74,7 +74,10 @@ Subject (enter nothing to skip): SUBJECT Current marks out of 100 (blank to skip) : -GRADE +100 + +Enter Classes Attended (blank to skip): +1 Do you want to add another subject and grade? (yes/no) no @@ -86,12 +89,33 @@ NUMBER ``` ### - View details of a student `view` +Views a student details. Allows the user to do view or just view. + +Example: +view wario +Student details: +Name: wario +Phone Number: 12345678 +Gender: male +Last Payment Date: 12/12/2023 +Remarks: Unknown +Subject: subject +Current marks out of 100: 100.0 +Classes Attended: 1 ### - Edit details of a student `edit` ### - Delete a student from the working list `delete` +Deletes the student from the list. Allows the user to do delete or just delete. + +Example: +delete + +Enter student name: +wario +Student removed successfully! ## FAQ @@ -105,5 +129,26 @@ NUMBER ## Command Summary -{Give a 'cheat sheet' of commands here} +### `add ` +Adds a student into the list. If the name of the student is not specified in the initial command, the program will prompt the user for the name. + +### `list` +Displays the list of students. + +### `view ` +Views a students details. If the name of the student is not specified in the initial command, the program will prompt the user for the name. + +### `delete ` +Deletes the student from the list. If the name of the student is not specified in the initial command, the program will prompt the user for the name. + +### `edit ` +Allows the user to edit the details of the student. If the name of the student is not specified in the initial command, the program will prompt the user for the name. + +### `sort_name` +Sorts the list lexicographically. + +### `view_subject ` +Lists all the students associated with that subject. If the user specifies the subject in the initial command, the list will be generated and the command will be terminated. If the user does not specify the subject, the programme will continuously prompt the user for a subject, until they choose to terminate the command. +### `help` +Generates the list of commands. From 9ca7a80e14d19f5e2bdefd3131248caadb4c2986 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 23 Mar 2024 00:29:46 +0800 Subject: [PATCH 088/503] Add assertion enable to gradle build --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 9a1f9a7d66..4be295b23b 100644 --- a/build.gradle +++ b/build.gradle @@ -43,4 +43,5 @@ checkstyle { run{ standardInput = System.in + enableAssertions = true } From cbeffec8f83a7c60e4edface9afea5fdb1a1298c Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 23 Mar 2024 00:47:44 +0800 Subject: [PATCH 089/503] Add textFileInputString method to store student names --- src/main/java/classify/student/Student.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 2bc1d2310a..dd00eb8bbf 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -49,7 +49,12 @@ public boolean hasSubject(String subject) { return false; } - //@@ Cryolian + //@@author ParthGandhiNUS + public String textFileInputString() { + return String.format("%s",getName().trim()); + } + + //@@author Cryolian public String getName() { return name; } From 2baf9f24427c13d6ecbb10899c6b43f9942c6003 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 23 Mar 2024 00:49:42 +0800 Subject: [PATCH 090/503] Add new createParentFileFolder method --- .../java/classify/datacommands/DataStorage.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/classify/datacommands/DataStorage.java b/src/main/java/classify/datacommands/DataStorage.java index e0a23fb905..8e264724aa 100644 --- a/src/main/java/classify/datacommands/DataStorage.java +++ b/src/main/java/classify/datacommands/DataStorage.java @@ -2,4 +2,20 @@ public class DataStorage { + /** + * Used to create the parent folder for a certain file + * + * @param parentPath Path file containing the path of folder we wanna make the text file in + * @throws IOException Triggers whenever the input for the path or creation of the directory is improper + */ + public static void createParentFileFolder (Path parentPath) throws IOException { + try{ + Files.createDirectories(parentPath); + } catch (FileAlreadyExistsException ignored){ + //Ignore this error as this should not cause any issues, we dont want replicas of the same file + } catch (IOException e){ + System.out.println(FAILURE_TO_CREATE_PARENT_FOLDER_DIRECTORY); + throw e; + } + } } From c0d399f76cade45ed919cab7d5c9ced8a1f92be6 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 23 Mar 2024 00:51:06 +0800 Subject: [PATCH 091/503] Add writeStudentInfo method write info in the Student_Information.txt --- .../classify/datacommands/DataStorage.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/main/java/classify/datacommands/DataStorage.java b/src/main/java/classify/datacommands/DataStorage.java index 8e264724aa..4191ed7b56 100644 --- a/src/main/java/classify/datacommands/DataStorage.java +++ b/src/main/java/classify/datacommands/DataStorage.java @@ -1,6 +1,50 @@ package classify.datacommands; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import classify.user.Ui; + + +//@@author ParthGandhiNUS public class DataStorage { + private static final String NEWLINE = "\n"; + private static final String STUDENT_INFO_FILE_FOLDER = "data/studentInfo"; + private static final String STUDENT_INFO_TEXT_FILE = "data/studentInfo/Student_Information.txt"; + private static final String FAILURE_TO_CREATE_PARENT_FOLDER_DIRECTORY = "Failure to create the parent folder directory!"; + private static final String SUCCESSFULLY_UPDATE_STUDENT_RECORDS = "Updated Student Records successfully!"; + private static final String ISSUE_WITH_FOLDER_OR_TEXTFILE = "Issue with directory/text file. Please check!"; + + + //@@author ParthGandhiNUS + /** + * Accesses the parent directory to try to make the parent directory. + * Tries to write the lines which are made by the writeStudentInfo Method + * + * @param lines: Arraylist containing the processed current tasks in the CurrentTask + */ + public static void writeStudentInfoFile(List lines){ + try { + Path studentInfoFolder = Paths.get(STUDENT_INFO_FILE_FOLDER); + createParentFileFolder(studentInfoFolder); + + FileWriter studentInfoWriter = new FileWriter(STUDENT_INFO_TEXT_FILE); + for (String line : lines){ + studentInfoWriter.write(line + NEWLINE); + } + + System.out.println(SUCCESSFULLY_UPDATE_STUDENT_RECORDS); + Ui.printDivider(); + studentInfoWriter.close(); + } catch (IOException e){ + System.out.println(ISSUE_WITH_FOLDER_OR_TEXTFILE); + } + } /** * Used to create the parent folder for a certain file From eb2d35a3e74330ae89fd77147ab00eb3adeae854 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 23 Mar 2024 00:51:53 +0800 Subject: [PATCH 092/503] Update InputParsing for other methods to handle Student data --- src/main/java/classify/user/InputParsing.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 77d1014215..2196ffbc93 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -1,5 +1,6 @@ package classify.user; +import classify.datacommands.DataHandler; import classify.student.Student; import classify.student.StudentAttributes; @@ -33,8 +34,8 @@ public class InputParsing { private static final String VIEW_SUBJECT = "view_subject"; private static final String NO_STUDENTS_IN_THE_LIST_CAN_T_SORT_BY_NAME = "No students in the list, can't sort by name!"; - private static final String STUDENTS_WITH_THE_SUBJECT = "Students with the subject \""; - private static final String NO_STUDENTS_FOUND_WITH_THE_SUBJECT = "No students found with the subject: "; + //private static final String STUDENTS_WITH_THE_SUBJECT = "Students with the subject \""; + //private static final String NO_STUDENTS_FOUND_WITH_THE_SUBJECT = "No students found with the subject: "; private static final String ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK = "Enter the subject name (type 'exit' to go back):"; private static final String EXIT = "exit"; @@ -51,6 +52,9 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas switch (userCommand[0]) { case ADD: addStudent(masterStudentList, in, userCommand[1]); + // @@author ParthGandhiNUS + DataHandler.writeStudentInfo(masterStudentList); + // @@author tayponghee break; case VIEW: @@ -61,6 +65,9 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas //@@author alalal47 case DELETE: deleteStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); + // @@author ParthGandhiNUS + DataHandler.writeStudentInfo(masterStudentList); + //@@author alalal47 break; case RESTORE: @@ -79,6 +86,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas // @@author ParthGandhiNUS case BYE: Ui.printEndConversation(); + DataHandler.writeStudentInfo(masterStudentList); break; case EDIT: @@ -718,7 +726,7 @@ private static double promptForGrade(Scanner in) { * @param name The name of the student to search for. * @return The student object if found, null otherwise. */ - private static Student findStudentByName(ArrayList masterStudentList, String name) { + public static Student findStudentByName(ArrayList masterStudentList, String name) { for (Student student : masterStudentList) { if (student.getName().equalsIgnoreCase(name)) { return student; From e9cd5a69bb365f59659ae1e2407467c0b8ef7247 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 23 Mar 2024 00:53:41 +0800 Subject: [PATCH 093/503] Add data reading functionalities to Classify --- .../classify/datacommands/DataReader.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/main/java/classify/datacommands/DataReader.java b/src/main/java/classify/datacommands/DataReader.java index c8b7c1530f..fa206992ad 100644 --- a/src/main/java/classify/datacommands/DataReader.java +++ b/src/main/java/classify/datacommands/DataReader.java @@ -1,5 +1,49 @@ package classify.datacommands; +import java.util.ArrayList; +import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; + +import classify.student.Student; +import classify.user.InputParsing; +import classify.user.Ui; + +//@@author ParthGandhiNUS public class DataReader { + private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); + + public static Scanner in = new Scanner(System.in); + + //@@author ParthGandhiNUS + /** + * Method restores the previous student list by accessing the line-by-line information in the Student_Information.txt + * + * @param studentFileInput Line-by-line information of strings in the Student_Information.txt + * @param masterStudentList The list of all students + */ + public static void restoreStudentList(String studentFileInput, ArrayList masterStudentList ){ + + if (studentFileInput != null){ + if (InputParsing.findStudentByName(masterStudentList, studentFileInput) != null) { + assert InputParsing.findStudentByName(masterStudentList, studentFileInput) != null; + logger.log(Level.WARNING, "Student with the same name already exists."); + + Ui.printSameNameError(); + Ui.printDivider(); + return; + } + + Student student = new Student(studentFileInput); + + masterStudentList.add(student); + logger.log(Level.INFO, "Student added successfully."); + Ui.printStudentAdded(); + Ui.printDivider(); + } + } + } + + From 4ccd7f75c5cf9df64263a64356e6758a0151a1e2 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 23 Mar 2024 00:54:15 +0800 Subject: [PATCH 094/503] Add methods to read and write data from User --- .../classify/datacommands/DataHandler.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/main/java/classify/datacommands/DataHandler.java b/src/main/java/classify/datacommands/DataHandler.java index a06cc1ec1e..25592c0e6f 100644 --- a/src/main/java/classify/datacommands/DataHandler.java +++ b/src/main/java/classify/datacommands/DataHandler.java @@ -1,5 +1,73 @@ package classify.datacommands; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +import classify.student.Student; +import classify.student.StudentList; +import classify.user.Ui; + +//@@author ParthGandhiNUS public class DataHandler { + private static final String ANALYSING_INPUT_MESSAGE = "Analysing Inputs..."; + private static final String STUDENT_INFO_FILE_FOLDER = "data/studentInfo"; + private static final String STUDENT_INFO_TEXT_FILE = "data/studentInfo/Student_Information.txt"; + private static final String CREATE_NEW_STUDENT_INFO_FILE = "Creating a new Student Info File..."; + private static final String CREATE_NEW_STUDENT_INFO_FILE_SUCCESS = "Created a new student info file successfully!"; + private static final String CREATE_NEW_STUDENT_INFO_FILE_FAILURE = "Unable to create a new student info file!"; + private static final String RETRIEVING_PREVIOUS_STUDENT_DATA = "Now getting previous Student Info Records..."; + + //@@author ParthGandhiNUS + /** + * Function which is called to generate an arrayList "lines" which updates according to the users' inputs. + * Calls the writeStudentInfoFile function to update Student_Information.txt + * + * @param newList ArrayList containing the current students + */ + public static void writeStudentInfo(List newList){ + List lines = new ArrayList<>(); + for (Student student:newList){ + lines.add(student.textFileInputString()); + } + System.out.println(ANALYSING_INPUT_MESSAGE); + DataStorage.writeStudentInfoFile(lines); + } + + /** + * This accesses Student_Information.txt and calls the restoreStudentList function + * + * @param currentTask ArrayList containing the current students + * @throws IOException When unable to get the Student_Information.txt file or has any input errors + */ + public static void readStudentInfo(List newList) throws IOException{ + try{ + DataStorage.createParentFileFolder(Paths.get(STUDENT_INFO_FILE_FOLDER)); + Path studentInfoFilePath = Paths.get(STUDENT_INFO_TEXT_FILE); + if (!Files.exists(studentInfoFilePath)){ + System.out.println(CREATE_NEW_STUDENT_INFO_FILE); + Files.createFile(studentInfoFilePath); + } + + FileReader fileReader = new FileReader(STUDENT_INFO_TEXT_FILE); + BufferedReader line = new BufferedReader(fileReader); + System.out.println(RETRIEVING_PREVIOUS_STUDENT_DATA); + while (line.ready()){ + DataReader.restoreStudentList(line.readLine(), StudentList.masterStudentList); + } + + System.out.println(CREATE_NEW_STUDENT_INFO_FILE_SUCCESS); + Ui.printDivider(); + line.close(); + } catch (IOException e) { + System.out.println(CREATE_NEW_STUDENT_INFO_FILE_FAILURE); + throw e; + } + } } From 89b6ec4807c3d9580b07878b0477d00de7a322dd Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 23 Mar 2024 00:54:54 +0800 Subject: [PATCH 095/503] Update main for exception handling and to read Student_Information.txt before starting up --- src/main/java/classify/Classify.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 693655ec78..5c68717f9b 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -1,10 +1,12 @@ package classify; +import classify.datacommands.DataHandler; import classify.student.StudentList; import classify.user.InputParsing; import classify.user.Ui; import classify.user.UserInput; +import java.io.IOException; import java.util.Scanner; public class Classify { @@ -13,12 +15,12 @@ public class Classify { /** * Main entry-point for the Classify application. */ - public static void main(String[] args) { + public static void main(String[] args) throws IOException { - // @@author ParthGandhiNUS - // CAA: 9 March 2024 1pm + // @@author ParthGandhiNUS Ui.printWelcomeMessage(); Ui.printUserPrompt(); + DataHandler.readStudentInfo(StudentList.masterStudentList); // Takes in input from the user, and processes input to determine if it contains a command and a name String[] userCommand = UserInput.processInput(in.nextLine()); From c8b32c41bfc3829b09bb284bb14e705a51196a00 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 23 Mar 2024 01:21:58 +0800 Subject: [PATCH 096/503] Update text-ui-test --- text-ui-test/EXPECTED.TXT | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 6156a7ed33..064287f92c 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -2,5 +2,9 @@ Welcome to Classify! What can I do for you today? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Creating a new Student Info File... +Now getting previous Student Info Records... +Created a new student info file successfully! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Hope you've had a productive day. See you again! Goodbye! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From ae93f71317d117cb63ad099d4bc5e5263978c119 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 23 Mar 2024 01:22:15 +0800 Subject: [PATCH 097/503] Update text file --- data/studentInfo/Student_Information.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 data/studentInfo/Student_Information.txt diff --git a/data/studentInfo/Student_Information.txt b/data/studentInfo/Student_Information.txt new file mode 100644 index 0000000000..f874bc80c2 --- /dev/null +++ b/data/studentInfo/Student_Information.txt @@ -0,0 +1 @@ +James Bond From ec0881397b9a64ce49edab211d321769bebf282f Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 23 Mar 2024 01:22:41 +0800 Subject: [PATCH 098/503] Edit minor mistakes in code --- src/main/java/classify/Classify.java | 2 +- .../java/classify/datacommands/DataHandler.java | 13 ++++++------- src/main/java/classify/datacommands/DataReader.java | 11 ++++++----- .../java/classify/datacommands/DataStorage.java | 11 ++++++----- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 5c68717f9b..3bb2a04149 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -20,7 +20,7 @@ public static void main(String[] args) throws IOException { // @@author ParthGandhiNUS Ui.printWelcomeMessage(); Ui.printUserPrompt(); - DataHandler.readStudentInfo(StudentList.masterStudentList); + DataHandler.readStudentInfo(); // Takes in input from the user, and processes input to determine if it contains a command and a name String[] userCommand = UserInput.processInput(in.nextLine()); diff --git a/src/main/java/classify/datacommands/DataHandler.java b/src/main/java/classify/datacommands/DataHandler.java index 25592c0e6f..ef8c5fccab 100644 --- a/src/main/java/classify/datacommands/DataHandler.java +++ b/src/main/java/classify/datacommands/DataHandler.java @@ -1,5 +1,9 @@ package classify.datacommands; +import classify.student.Student; +import classify.student.StudentList; +import classify.user.Ui; + import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; @@ -9,10 +13,6 @@ import java.util.ArrayList; import java.util.List; -import classify.student.Student; -import classify.student.StudentList; -import classify.user.Ui; - //@@author ParthGandhiNUS public class DataHandler { private static final String ANALYSING_INPUT_MESSAGE = "Analysing Inputs..."; @@ -41,11 +41,10 @@ public static void writeStudentInfo(List newList){ /** * This accesses Student_Information.txt and calls the restoreStudentList function - * - * @param currentTask ArrayList containing the current students + * * @throws IOException When unable to get the Student_Information.txt file or has any input errors */ - public static void readStudentInfo(List newList) throws IOException{ + public static void readStudentInfo() throws IOException{ try{ DataStorage.createParentFileFolder(Paths.get(STUDENT_INFO_FILE_FOLDER)); Path studentInfoFilePath = Paths.get(STUDENT_INFO_TEXT_FILE); diff --git a/src/main/java/classify/datacommands/DataReader.java b/src/main/java/classify/datacommands/DataReader.java index fa206992ad..9ac81e7aa8 100644 --- a/src/main/java/classify/datacommands/DataReader.java +++ b/src/main/java/classify/datacommands/DataReader.java @@ -1,14 +1,14 @@ package classify.datacommands; +import classify.student.Student; +import classify.user.InputParsing; +import classify.user.Ui; + import java.util.ArrayList; import java.util.Scanner; import java.util.logging.Level; import java.util.logging.Logger; -import classify.student.Student; -import classify.user.InputParsing; -import classify.user.Ui; - //@@author ParthGandhiNUS public class DataReader { private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); @@ -18,7 +18,8 @@ public class DataReader { //@@author ParthGandhiNUS /** - * Method restores the previous student list by accessing the line-by-line information in the Student_Information.txt + * Method restores the previous student list by accessing the + * line-by-line information in the Student_Information.txt * * @param studentFileInput Line-by-line information of strings in the Student_Information.txt * @param masterStudentList The list of all students diff --git a/src/main/java/classify/datacommands/DataStorage.java b/src/main/java/classify/datacommands/DataStorage.java index 4191ed7b56..add00cfce5 100644 --- a/src/main/java/classify/datacommands/DataStorage.java +++ b/src/main/java/classify/datacommands/DataStorage.java @@ -1,5 +1,7 @@ package classify.datacommands; +import classify.user.Ui; + import java.io.FileWriter; import java.io.IOException; import java.nio.file.FileAlreadyExistsException; @@ -8,15 +10,14 @@ import java.nio.file.Paths; import java.util.List; -import classify.user.Ui; - //@@author ParthGandhiNUS public class DataStorage { private static final String NEWLINE = "\n"; private static final String STUDENT_INFO_FILE_FOLDER = "data/studentInfo"; private static final String STUDENT_INFO_TEXT_FILE = "data/studentInfo/Student_Information.txt"; - private static final String FAILURE_TO_CREATE_PARENT_FOLDER_DIRECTORY = "Failure to create the parent folder directory!"; + private static final String FAILURE_TO_CREATE_PARENT_FOLDER_DIRECTORY = + "Failure to create the parent folder directory!"; private static final String SUCCESSFULLY_UPDATE_STUDENT_RECORDS = "Updated Student Records successfully!"; private static final String ISSUE_WITH_FOLDER_OR_TEXTFILE = "Issue with directory/text file. Please check!"; @@ -26,7 +27,7 @@ public class DataStorage { * Accesses the parent directory to try to make the parent directory. * Tries to write the lines which are made by the writeStudentInfo Method * - * @param lines: Arraylist containing the processed current tasks in the CurrentTask + * @param lines Arraylist containing the processed current tasks in the masterStudentList */ public static void writeStudentInfoFile(List lines){ try { @@ -49,7 +50,7 @@ public static void writeStudentInfoFile(List lines){ /** * Used to create the parent folder for a certain file * - * @param parentPath Path file containing the path of folder we wanna make the text file in + * @param parentPath Path file containing the path of folder we want to make the text file in * @throws IOException Triggers whenever the input for the path or creation of the directory is improper */ public static void createParentFileFolder (Path parentPath) throws IOException { From 971612f1eebb0992db6168ca0d93d15710fe5400 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 23 Mar 2024 01:40:19 +0800 Subject: [PATCH 099/503] Edit test files --- src/test/java/classify/user/InputParsingTest.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index 47381c768f..ebb6325b16 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -28,7 +28,10 @@ public void testByeCommand() { String printedOutput = outputStream.toString().trim(); String expectedOutput = "Hope you've had a productive day. See you again! Goodbye!" + - System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + + System.lineSeparator() + "Analysing Inputs..." + System.lineSeparator() + + "Updated Student Records successfully!"+System.lineSeparator() + + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; assertEquals(expectedOutput.trim(), printedOutput); } From a9666ed1238a6d5c86abb3159553932eeb625548 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 23 Mar 2024 13:15:27 +0800 Subject: [PATCH 100/503] Add date parsing for payment dates --- .gitignore | 2 + src/main/java/classify/Classify.java | 3 ++ src/main/java/classify/student/Details.java | 10 ++-- src/main/java/classify/student/Student.java | 8 ++- .../classify/student/StudentAttributes.java | 1 + src/main/java/classify/user/InputParsing.java | 52 ++++++++++++++++++- src/main/java/classify/user/Ui.java | 11 +++- .../java/classify/user/InputParsingTest.java | 46 ++++++++++++++++ 8 files changed, 126 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index b194f20b2d..3d3f101804 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,5 @@ text-ui-test/EXPECTED-UNIX.TXT /*.jar /.vscode +/data/studentInfo/ +data/studentInfo diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 3bb2a04149..a7dd964174 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -14,6 +14,9 @@ public class Classify { /** * Main entry-point for the Classify application. + * + * @param args Input arguments when running the program. + * @throws IOException Thrown when error reading file. */ public static void main(String[] args) throws IOException { diff --git a/src/main/java/classify/student/Details.java b/src/main/java/classify/student/Details.java index bd650528a6..f2b8295581 100644 --- a/src/main/java/classify/student/Details.java +++ b/src/main/java/classify/student/Details.java @@ -1,5 +1,7 @@ package classify.student; +import java.time.LocalDate; + /** * Important details of a student the tuition centre * has to keep track of. @@ -9,11 +11,11 @@ public abstract class Details { //@@author Cryolian protected String gender; protected int phoneNumber = 0; - protected String lastPaymentDate = "unknown"; + protected LocalDate lastPaymentDate = LocalDate.now(); protected String remarks = "NA"; public Details() { - + } public String getGender() { @@ -24,7 +26,7 @@ public int getPhoneNumber() { return phoneNumber; } - public String getLastPaymentDate() { + public LocalDate getLastPaymentDate() { return lastPaymentDate; } @@ -40,7 +42,7 @@ public void setPhoneNumber(int phoneNumber) { this.phoneNumber = phoneNumber; } - public void setLastPaymentDate(String lastPaymentDate) { + public void setLastPaymentDate(LocalDate lastPaymentDate) { this.lastPaymentDate = lastPaymentDate; } diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index dd00eb8bbf..16728a7e39 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -1,5 +1,7 @@ package classify.student; +import java.time.LocalDate; + /** * Meant to represent a particular student of the tuition centre. * The student can first be declared with only a name, and the subsequent details @@ -20,6 +22,10 @@ public Student(String name) { this.attributes = new StudentAttributes(this); } + public void setLastPaymentDate(LocalDate lastPaymenDate) { + this.attributes.setLastPaymentDate(lastPaymenDate); + } + //@@author tayponghee public StudentAttributes getAttributes() { return attributes; @@ -37,7 +43,7 @@ public int getPhoneNumber() { return attributes.getPhoneNumber(); } - public String getLastPaymentDate() { + public LocalDate getLastPaymentDate() { return attributes.getLastPaymentDate(); } public boolean hasSubject(String subject) { diff --git a/src/main/java/classify/student/StudentAttributes.java b/src/main/java/classify/student/StudentAttributes.java index f2608f0f29..deaa09b36c 100644 --- a/src/main/java/classify/student/StudentAttributes.java +++ b/src/main/java/classify/student/StudentAttributes.java @@ -8,6 +8,7 @@ public class StudentAttributes extends Details { private List subjectGrades; public StudentAttributes(Student student) { + super(); this.student = student; this.subjectGrades = new ArrayList<>(); } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 2196ffbc93..25229eee32 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -8,6 +8,8 @@ import classify.student.StudentList; import classify.student.SubjectGrade; +import java.time.LocalDate; +import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.Collections; @@ -18,6 +20,7 @@ import java.util.logging.Logger; public class InputParsing { + private static final String EARLIER_POSSIBLE_DATE = "1970-01-01"; private static final String DEFAULT_STRING_VALUE = "Unknown"; private static final int LOWER_LIMIT_PHONE_NUMBER = 8; private static final String NOTEMPTY = "THIS STRING IS NOT EMPTY"; @@ -476,7 +479,7 @@ private static void addStudent(ArrayList masterStudentList, Scanner in, student.getAttributes().setGender(readInString(in)); Ui.promptForLastPaymentDate(); - student.getAttributes().setLastPaymentDate(readInString(in)); + student.getAttributes().setLastPaymentDate(readInDate(in)); Ui.promptForRemarks(); student.getAttributes().setRemarks(readInString(in)); @@ -830,4 +833,51 @@ private static String readInString(Scanner in) { } + protected static LocalDate readInDate(Scanner in) { + + String userInput; + LocalDate paymentDate; + + do { + + userInput = in.nextLine(); + paymentDate = parseDateFromString(userInput); + + } while(!isDateValid(paymentDate)); + + return paymentDate; + } + + protected static LocalDate parseDateFromString(String string) { + + if (string.isBlank()) { + logger.log(Level.INFO, "Storing today as the last payment date."); + return LocalDate.now(); + } + + LocalDate paymentDate; + + try { + + paymentDate = LocalDate.parse(string); + + } catch (DateTimeParseException e) { + return invalidDatePath(); + } + + return paymentDate; + } + + private static LocalDate invalidDatePath() { + logger.log(Level.WARNING, "Invalid date format entered."); + Ui.printInvalidDateError(); + return LocalDate.now().plusDays(2); + } + + private static boolean isDateValid(LocalDate paymentDate) { + + return paymentDate.isBefore(LocalDate.now().plusDays(1)) + && paymentDate.isAfter(LocalDate.parse(EARLIER_POSSIBLE_DATE)); + } + } diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index 79990a1180..90fa626d71 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -21,8 +21,11 @@ public class Ui { "Please enter a different name."; private static final String EMPTY_NAME_ERROR = "Student name cannot be empty. Please enter a valid name."; private static final String GENDER_PROMPT = "Please input the student's gender: "; - private static final String PAYMENT_PROMPT = "Please input their last payment date: "; + private static final String PAYMENT_PROMPT = "Please input their last payment date in the format of YYYY-MM-DD." + + "Enter blank to input today's date."; private static final String REMARKS_PROMPT = "Please input any remarks: "; + private static final String INVALID_DATE_ERROR = "Please input a valid date in the format YYYY-MM-DD" + + ", or blank for today."; //@@author ParthGandhiNUS private static final String DIVIDER = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; private static final String WELCOME_TO_CLASSIFY = "Welcome to Classify!"; @@ -48,6 +51,7 @@ public class Ui { private static final String NO_RECENT_DELETES = "No recent deletes found!"; + //@@author alalal47 /** * Displays the help message to teach users how to use Classify. @@ -197,6 +201,7 @@ public static void printStudentList(ArrayList students) { System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); } + //@@author Cryolian public static void printSameNameError() { System.out.println(SAME_NAME_ERROR); } @@ -242,6 +247,10 @@ public static void printNullAttributeError() { System.out.println(NULL_ATTRIBUTE_ERROR); } + public static void printInvalidDateError() { + System.out.println(INVALID_DATE_ERROR); + } + //@@author alalal47 public static void printDeleteUndone() { System.out.println(DELETE_UNDONE_MESSAGE); diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index ebb6325b16..78ed3df9b9 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -3,8 +3,12 @@ import classify.student.Student; import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.io.InputStream; import java.io.PrintStream; +import java.time.LocalDate; import java.util.ArrayList; import java.util.Scanner; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -93,4 +97,46 @@ public void testHelpCommand() { assertEquals(expectedOutput.trim(), printedOutput); } + + //@@author Cryolian + @Test + public void testReadInDateCommand() { + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outputStream)); + + String userInputDate = "2020-12-12"; + + InputStream stdin = System.in; + + try { + System.setIn(new ByteArrayInputStream(userInputDate.getBytes())); + Scanner scanner = new Scanner(System.in); + + LocalDate parsedDate = InputParsing.readInDate(scanner); + assertEquals(LocalDate.parse(userInputDate), parsedDate); + } finally { + System.setIn(stdin); + } + + userInputDate = " "; + + try { + System.setIn(new ByteArrayInputStream(userInputDate.getBytes())); + Scanner scanner = new Scanner(System.in); + + LocalDate parsedDate = InputParsing.readInDate(scanner); + assertEquals(LocalDate.now(), parsedDate); + } finally { + System.setIn(stdin); + } + } + + @Test + public void testParseDateFromString() { + LocalDate date = InputParsing.parseDateFromString("fiodjsfoi"); + + assertEquals(date, LocalDate.now().plusDays(2)); + + } } From 1818b09361800f234f237bc85d4376538fe62800 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 23 Mar 2024 13:15:45 +0800 Subject: [PATCH 101/503] Update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 3d3f101804..caad156da2 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ text-ui-test/EXPECTED-UNIX.TXT /.vscode /data/studentInfo/ data/studentInfo +data/studentInfo/Student_Information.txt From 255bf31a1112331681d13c0c203805b8a39813c8 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 23 Mar 2024 13:17:25 +0800 Subject: [PATCH 102/503] Remove dummy data file --- .gitignore | 4 ++-- data/studentInfo/Student_Information.txt | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) delete mode 100644 data/studentInfo/Student_Information.txt diff --git a/.gitignore b/.gitignore index caad156da2..6e708338e9 100644 --- a/.gitignore +++ b/.gitignore @@ -19,5 +19,5 @@ text-ui-test/EXPECTED-UNIX.TXT /*.jar /.vscode /data/studentInfo/ -data/studentInfo -data/studentInfo/Student_Information.txt + + diff --git a/data/studentInfo/Student_Information.txt b/data/studentInfo/Student_Information.txt deleted file mode 100644 index f874bc80c2..0000000000 --- a/data/studentInfo/Student_Information.txt +++ /dev/null @@ -1 +0,0 @@ -James Bond From e6b22d9376d20ff86a4c7f328ea7195a32b10e92 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 23 Mar 2024 13:29:59 +0800 Subject: [PATCH 103/503] Fix printing errors and line spacing --- src/main/java/classify/user/InputParsing.java | 5 +++-- src/main/java/classify/user/Ui.java | 20 ++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 25229eee32..4b66aa12ce 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -394,6 +394,7 @@ private static void viewStudent(ArrayList masterStudentList, Scanner in if (foundStudent != null) { logger.log(Level.INFO, "Viewing student details: " + name); + Ui.printDivider(); Ui.printStudentDetails(); Ui.printStudentName(name); Ui.printStudentDetails(foundStudent); @@ -851,7 +852,7 @@ protected static LocalDate readInDate(Scanner in) { protected static LocalDate parseDateFromString(String string) { if (string.isBlank()) { - logger.log(Level.INFO, "Storing today as the last payment date."); + logger.log(Level.INFO, "Storing today as the last payment date." + '\n'); return LocalDate.now(); } @@ -869,7 +870,7 @@ protected static LocalDate parseDateFromString(String string) { } private static LocalDate invalidDatePath() { - logger.log(Level.WARNING, "Invalid date format entered."); + logger.log(Level.WARNING, "Invalid date format entered." + '\n'); Ui.printInvalidDateError(); return LocalDate.now().plusDays(2); } diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index 90fa626d71..0647439a3f 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -17,11 +17,11 @@ public class Ui { private static final String STUDENT_GENDER_MESSAGE = "Gender: "; private static final String STUDENT_PAYMENT_MESSAGE = "Last Payment Date: "; private static final String STUDENT_REMARKS_MESSAGE = "Remarks: "; - private static final String SAME_NAME_ERROR = "Student with the same name already exists." + + private static final String SAME_NAME_ERROR = "Student with the same name already exists. " + "Please enter a different name."; private static final String EMPTY_NAME_ERROR = "Student name cannot be empty. Please enter a valid name."; private static final String GENDER_PROMPT = "Please input the student's gender: "; - private static final String PAYMENT_PROMPT = "Please input their last payment date in the format of YYYY-MM-DD." + + private static final String PAYMENT_PROMPT = "Please input their last payment date in the format of YYYY-MM-DD. " + "Enter blank to input today's date."; private static final String REMARKS_PROMPT = "Please input any remarks: "; private static final String INVALID_DATE_ERROR = "Please input a valid date in the format YYYY-MM-DD" @@ -149,16 +149,22 @@ public static void printStudentDetails() { } public static void printStudentDetails(Student student) { - System.out.println(STUDENT_PHONE_MESSAGE + student.getAttributes().getPhoneNumber()); - System.out.println(STUDENT_GENDER_MESSAGE + student.getAttributes().getGender()); - System.out.println(STUDENT_PAYMENT_MESSAGE + student.getAttributes().getLastPaymentDate()); - System.out.println(STUDENT_REMARKS_MESSAGE + student.getAttributes().getRemarks()); + System.out.println(STUDENT_PHONE_MESSAGE + student.getAttributes().getPhoneNumber() + "\n"); + System.out.println(STUDENT_GENDER_MESSAGE + student.getAttributes().getGender() + "\n"); + System.out.println(STUDENT_PAYMENT_MESSAGE + student.getAttributes().getLastPaymentDate() + "\n"); + System.out.println(STUDENT_REMARKS_MESSAGE + student.getAttributes().getRemarks() + "\n"); } public static void printStudentName(String name) { - System.out.println(STUDENT_NAME_MESSAGE + name); + System.out.println(STUDENT_NAME_MESSAGE + name + "\n"); } + //@@author Cryolian + public static void printStudentName(Student student) { + System.out.println(STUDENT_NAME_MESSAGE + student.getName() + "\n"); + } + + //@@author blackmirag3 public static void printClassesAttendedPrompt() { System.out.println(CLASSES_ATTENDED_PROMPT); } From d23face8cc2a863f88b23a5accd0e5c4f9286d79 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sat, 23 Mar 2024 19:51:55 +0800 Subject: [PATCH 104/503] Add sort by total classes attended --- src/main/java/classify/student/Student.java | 10 +++ src/main/java/classify/user/InputParsing.java | 90 ++++++++++++++++--- src/main/java/classify/user/Ui.java | 11 ++- 3 files changed, 100 insertions(+), 11 deletions(-) diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 16728a7e39..0f73c6ae97 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -15,6 +15,16 @@ public class Student { //@@author tayponghee private StudentAttributes attributes; + private int totalClassesAttended; + + public int getTotalClassesAttended() { + return totalClassesAttended; + } + + public void setTotalClassesAttended(int totalClassesAttended) { + this.totalClassesAttended = totalClassesAttended; + } + //@@author Cryolian public Student(String name) { diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 4b66aa12ce..752da15b08 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -10,11 +10,7 @@ import java.time.LocalDate; import java.time.format.DateTimeParseException; -import java.util.ArrayList; -import java.util.Collections; - -import java.util.List; -import java.util.Scanner; +import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; @@ -33,17 +29,20 @@ public class InputParsing { private static final String RESTORE = "restore"; private static final String EDIT = "edit"; private static final String HELP = "help"; - private static final String SORT_NAME = "sort_name"; + private static final String SORT = "sort"; private static final String VIEW_SUBJECT = "view_subject"; private static final String NO_STUDENTS_IN_THE_LIST_CAN_T_SORT_BY_NAME = "No students in the list, can't sort by name!"; - //private static final String STUDENTS_WITH_THE_SUBJECT = "Students with the subject \""; - //private static final String NO_STUDENTS_FOUND_WITH_THE_SUBJECT = "No students found with the subject: "; private static final String ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK = "Enter the subject name (type 'exit' to go back):"; private static final String EXIT = "exit"; private static final String EXITED_THE_COMMAND = "Exited the command."; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); + private static final String Sort_BY = "Sort by:\n1. Name " + + "\n2. Total Classes Attended\n(Type 'exit' to leave the command)"; + private static final String INVALID_CHOICE = "Invalid choice!"; + private static final String INVALID_INPUT = "Invalid input. " + + "Please enter a valid choice or type 'exit' to leave the command."; public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, ArrayList recentlyDeletedList, Scanner in) { @@ -101,8 +100,20 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas break; //@@ author tayponghee - case SORT_NAME: - listStudentsByName(masterStudentList); + case SORT: + boolean validChoice = false; + while (!validChoice) { + System.out.println(Sort_BY); + String input = in.nextLine().trim(); + + if (input.equalsIgnoreCase(EXIT)) { + System.out.println(EXITED_THE_COMMAND); + Ui.printDivider(); + return; + } + + validChoice = isValidChoice(masterStudentList, input, validChoice); + } break; case VIEW_SUBJECT: @@ -115,6 +126,47 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas } } + private static boolean isValidChoice(ArrayList masterStudentList, String input, boolean validChoice) { + try { + int choice = Integer.parseInt(input); + switch (choice) { + case 1: + listStudentsByName(masterStudentList); + validChoice = true; + break; + + case 2: + listStudentsByTotalClasses(masterStudentList); + validChoice = true; + break; + + default: + Ui.println(INVALID_CHOICE); + } + } catch (NumberFormatException e) { + Ui.println(INVALID_INPUT); + } + return validChoice; + } + + private static void listStudentsByTotalClasses(ArrayList masterStudentList) { + for (Student student : masterStudentList) { + int totalClassesAttended = 0; + StudentAttributes attributes = student.getAttributes(); + List subjectGrades = attributes.getSubjectGrades(); + for (SubjectGrade subjectGrade : subjectGrades) { + totalClassesAttended += subjectGrade.getClassesAttended(); + } + student.setTotalClassesAttended(totalClassesAttended); + } + + masterStudentList.sort(Comparator.comparingInt(Student::getTotalClassesAttended)); + + for (Student student : masterStudentList) { + System.out.println(student.getName() + " - Total Classes Attended: " + student.getTotalClassesAttended()); + } + } + /** * Lets the user check view a list of students with that corresponding subject. * If the user types view_subject [subject], it will only generate the list of students with that subject, @@ -400,12 +452,30 @@ private static void viewStudent(ArrayList masterStudentList, Scanner in Ui.printStudentDetails(foundStudent); StudentAttributes attributes = foundStudent.getAttributes(); showAttributes(attributes); + + int totalClassesAttended = getTotalClassesAttended(foundStudent); + Ui.printTotalClassesAttended(totalClassesAttended); + } else { logger.log(Level.WARNING, "Student not found: " + name); Ui.printStudentNotFound(); } } + /** + * Calculates the total number of classes attended by the student across all subjects. + * + * @param student The student whose total classes attended are to be calculated. + * @return The total number of classes attended by the student. + */ + private static int getTotalClassesAttended(Student student) { + int totalClassesAttended = 0; + for (SubjectGrade subjectGrade : student.getAttributes().getSubjectGrades()) { + totalClassesAttended += subjectGrade.getClassesAttended(); + } + return totalClassesAttended; + } + /** * Displays the attributes of a student. * diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index 0647439a3f..f4cb491429 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -49,7 +49,7 @@ public class Ui { private static final String DELETE_UNDONE_MESSAGE = "Last delete undone!"; private static final String STUDENT_RESTORED_MESSAGE = "Student has been restored!"; private static final String NO_RECENT_DELETES = "No recent deletes found!"; - + public static final String TOTAL_CLASSES_ATTENDED_ACROSS_ALL_SUBJECTS = "Total classes attended across all subjects: "; //@@author alalal47 @@ -269,4 +269,13 @@ public static void printRestoreMessage() { public static void printNoDeleteFound() { System.out.println(NO_RECENT_DELETES); } + + //@@ author tayponghee + public static void printTotalClassesAttended(int classes) { + System.out.println(TOTAL_CLASSES_ATTENDED_ACROSS_ALL_SUBJECTS + classes); + } + + public static void println (String text) { + System.out.println(text); + } } From f4fae38d7703b1d731258585e6195587d6d3b9dc Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sat, 23 Mar 2024 20:32:50 +0800 Subject: [PATCH 105/503] Shift sorting into another class --- .../java/classify/student/StudentSorter.java | 108 ++++++++++++++++++ src/main/java/classify/user/InputParsing.java | 102 +++++------------ 2 files changed, 137 insertions(+), 73 deletions(-) create mode 100644 src/main/java/classify/student/StudentSorter.java diff --git a/src/main/java/classify/student/StudentSorter.java b/src/main/java/classify/student/StudentSorter.java new file mode 100644 index 0000000000..7fd163986f --- /dev/null +++ b/src/main/java/classify/student/StudentSorter.java @@ -0,0 +1,108 @@ +package classify.student; + +import classify.user.Ui; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.Scanner; + +public class StudentSorter { + + public static final String ONE = "1"; + public static final String TWO = "2"; + public static final String INVALID_CHOICE = "Invalid choice! Type either 1 or 2 to sort the list by the selected attribute"; + + /** + * Sorts the list of students based on the specified choice. + * + * @param masterStudentList The list of students to be sorted. + * @param choice The sorting criterion ("1" for name, "2" for total classes). + * @param in The Scanner object for user input. + */ + public static void sortByChoice(ArrayList masterStudentList, String choice, Scanner in) { + while (!isValidChoice(choice)) { + Ui.println(INVALID_CHOICE); + choice = in.nextLine().trim(); + } + + switch (choice) { + case ONE: + listStudentsByName(masterStudentList); + break; + case TWO: + listStudentsByTotalClasses(masterStudentList); + break; + default: + Ui.println(INVALID_CHOICE); + break; + } + } + + /** + * Checks if the choice is valid (either "1" or "2"). + * + * @param choice The input choice. + * @return True if the choice is valid, false otherwise. + */ + public static boolean isValidChoice(String choice) { + return ONE.equals(choice) || TWO.equals(choice); + } + + /** + * Lists students in the provided list by name in ascending order. + * + * @param masterStudentList The list of students to be listed by name. + */ + private static void listStudentsByName(ArrayList masterStudentList) { + masterStudentList.sort(Comparator.comparing(Student::getName)); + listStudents(masterStudentList); + Ui.printDivider(); + } + + /** + * Lists students in the provided list by total classes attended in ascending order. + * + * @param masterStudentList The list of students to be listed by total classes attended. + */ + private static void listStudentsByTotalClasses(ArrayList masterStudentList) { + for (Student student : masterStudentList) { + int totalClassesAttended = 0; + + StudentAttributes attributes = student.getAttributes(); + List subjectGrades = attributes.getSubjectGrades(); + + for (SubjectGrade subjectGrade : subjectGrades) { + totalClassesAttended += subjectGrade.getClassesAttended(); + } + + student.setTotalClassesAttended(totalClassesAttended); + } + masterStudentList.sort(Comparator.comparingInt(Student::getTotalClassesAttended)); + listStudentsWithTotalClasses(masterStudentList); + + Ui.printDivider(); + } + + /** + * Lists students in the provided list. + * + * @param students The list of students to be listed. + */ + private static void listStudents(ArrayList students) { + for (Student student : students) { + System.out.println(student.getName()); + } + } + + /** + * Lists students in the provided list along with their total classes attended. + * + * @param students The list of students to be listed. + */ + private static void listStudentsWithTotalClasses(ArrayList students) { + for (Student student : students) { + System.out.println(student.getName() + " - Total Classes Attended: " + student.getTotalClassesAttended()); + } + } +} diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 752da15b08..5549a7f289 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -3,15 +3,16 @@ import classify.datacommands.DataHandler; import classify.student.Student; import classify.student.StudentAttributes; - -import classify.student.StudentComparators; import classify.student.StudentList; +import classify.student.StudentSorter; import classify.student.SubjectGrade; import java.time.LocalDate; import java.time.format.DateTimeParseException; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; import java.util.logging.Level; import java.util.logging.Logger; @@ -31,18 +32,11 @@ public class InputParsing { private static final String HELP = "help"; private static final String SORT = "sort"; private static final String VIEW_SUBJECT = "view_subject"; - private static final String NO_STUDENTS_IN_THE_LIST_CAN_T_SORT_BY_NAME = - "No students in the list, can't sort by name!"; private static final String ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK = "Enter the subject name (type 'exit' to go back):"; private static final String EXIT = "exit"; private static final String EXITED_THE_COMMAND = "Exited the command."; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); - private static final String Sort_BY = "Sort by:\n1. Name " + - "\n2. Total Classes Attended\n(Type 'exit' to leave the command)"; - private static final String INVALID_CHOICE = "Invalid choice!"; - private static final String INVALID_INPUT = "Invalid input. " + - "Please enter a valid choice or type 'exit' to leave the command."; public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, ArrayList recentlyDeletedList, Scanner in) { @@ -55,6 +49,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas case ADD: addStudent(masterStudentList, in, userCommand[1]); // @@author ParthGandhiNUS + assert masterStudentList != null; DataHandler.writeStudentInfo(masterStudentList); // @@author tayponghee break; @@ -101,19 +96,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas //@@ author tayponghee case SORT: - boolean validChoice = false; - while (!validChoice) { - System.out.println(Sort_BY); - String input = in.nextLine().trim(); - - if (input.equalsIgnoreCase(EXIT)) { - System.out.println(EXITED_THE_COMMAND); - Ui.printDivider(); - return; - } - - validChoice = isValidChoice(masterStudentList, input, validChoice); - } + sortStudents(masterStudentList, in); break; case VIEW_SUBJECT: @@ -126,44 +109,32 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas } } - private static boolean isValidChoice(ArrayList masterStudentList, String input, boolean validChoice) { - try { - int choice = Integer.parseInt(input); - switch (choice) { - case 1: - listStudentsByName(masterStudentList); - validChoice = true; - break; - - case 2: - listStudentsByTotalClasses(masterStudentList); - validChoice = true; - break; + /** + * Sorts the list of students based on user input. + * + * @param masterStudentList The list of students to be sorted. + * @param in The Scanner object to read user input. + */ + private static void sortStudents(ArrayList masterStudentList, Scanner in) { + while (true) { + System.out.println("Sort by: "); + Ui.println("1. Name (A to Z)"); + Ui.println("2. Total number of classes attended:"); + String input = in.nextLine().trim(); - default: - Ui.println(INVALID_CHOICE); + if (input.equalsIgnoreCase(EXIT)) { + System.out.println(EXITED_THE_COMMAND); + Ui.printDivider(); + return; } - } catch (NumberFormatException e) { - Ui.println(INVALID_INPUT); - } - return validChoice; - } - private static void listStudentsByTotalClasses(ArrayList masterStudentList) { - for (Student student : masterStudentList) { - int totalClassesAttended = 0; - StudentAttributes attributes = student.getAttributes(); - List subjectGrades = attributes.getSubjectGrades(); - for (SubjectGrade subjectGrade : subjectGrades) { - totalClassesAttended += subjectGrade.getClassesAttended(); + if (StudentSorter.isValidChoice(input)) { + StudentSorter.sortByChoice(masterStudentList, input, in); + Ui.println(EXITED_THE_COMMAND); + break; + } else { + Ui.println(StudentSorter.INVALID_CHOICE); } - student.setTotalClassesAttended(totalClassesAttended); - } - - masterStudentList.sort(Comparator.comparingInt(Student::getTotalClassesAttended)); - - for (Student student : masterStudentList) { - System.out.println(student.getName() + " - Total Classes Attended: " + student.getTotalClassesAttended()); } } @@ -236,21 +207,6 @@ private static void viewStudentsBySubject(ArrayList masterStudentList, Ui.printDivider(); } - /** - * Lists students in the provided list by name in ascending order. - * If the list is empty, it prints a message indicating that there are no students in the list. - * - * @param students The list of students to be listed by name. - */ - public static void listStudentsByName(ArrayList students) { - if (students.isEmpty()) { - System.out.println(NO_STUDENTS_IN_THE_LIST_CAN_T_SORT_BY_NAME); - return; - } - Collections.sort(students, StudentComparators.nameComparator); - listStudents(students); - } - // @@author blackmirag3 private static void listStudents(ArrayList list) { StudentList.printCurrentArrayList(list); @@ -470,7 +426,7 @@ private static void viewStudent(ArrayList masterStudentList, Scanner in */ private static int getTotalClassesAttended(Student student) { int totalClassesAttended = 0; - for (SubjectGrade subjectGrade : student.getAttributes().getSubjectGrades()) { + for (classify.student.SubjectGrade subjectGrade : student.getAttributes().getSubjectGrades()) { totalClassesAttended += subjectGrade.getClassesAttended(); } return totalClassesAttended; From ccfcbc44a2e0a77e8fc4b719b6809181e0489948 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sat, 23 Mar 2024 20:41:37 +0800 Subject: [PATCH 106/503] Fix gradle checks --- src/main/java/classify/student/Student.java | 15 +++++++-------- src/main/java/classify/student/StudentSorter.java | 3 ++- src/main/java/classify/user/InputParsing.java | 2 +- src/main/java/classify/user/Ui.java | 4 +++- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 0f73c6ae97..fd230ea697 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -14,9 +14,15 @@ public class Student { //@@author tayponghee private StudentAttributes attributes; - private int totalClassesAttended; + //@@author Cryolian + public Student(String name) { + this.name = name; + this.attributes = new StudentAttributes(this); + } + + //@@ author tayponghee public int getTotalClassesAttended() { return totalClassesAttended; } @@ -25,13 +31,6 @@ public void setTotalClassesAttended(int totalClassesAttended) { this.totalClassesAttended = totalClassesAttended; } - //@@author Cryolian - - public Student(String name) { - this.name = name; - this.attributes = new StudentAttributes(this); - } - public void setLastPaymentDate(LocalDate lastPaymenDate) { this.attributes.setLastPaymentDate(lastPaymenDate); } diff --git a/src/main/java/classify/student/StudentSorter.java b/src/main/java/classify/student/StudentSorter.java index 7fd163986f..16566331a5 100644 --- a/src/main/java/classify/student/StudentSorter.java +++ b/src/main/java/classify/student/StudentSorter.java @@ -11,7 +11,8 @@ public class StudentSorter { public static final String ONE = "1"; public static final String TWO = "2"; - public static final String INVALID_CHOICE = "Invalid choice! Type either 1 or 2 to sort the list by the selected attribute"; + public static final String INVALID_CHOICE = "Invalid choice! " + + "Type either 1 or 2 to sort the list by the selected attribute"; /** * Sorts the list of students based on the specified choice. diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 5549a7f289..893bca14d0 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -117,7 +117,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas */ private static void sortStudents(ArrayList masterStudentList, Scanner in) { while (true) { - System.out.println("Sort by: "); + System.out.println("Sort by: (Choose index)"); Ui.println("1. Name (A to Z)"); Ui.println("2. Total number of classes attended:"); String input = in.nextLine().trim(); diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index f4cb491429..11fe187895 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -6,6 +6,8 @@ //@@author Cryolian public class Ui { + public static final String TOTAL_CLASSES_ATTENDED_ACROSS_ALL_SUBJECTS = "Total classes " + + "attended across all subjects: "; private static final String EMPTY_SUBJECT_ERROR = "No subjects and grades found for this student."; private static final String NULL_ATTRIBUTE_ERROR = "No attributes found for this student."; private static final String EDIT_PROMPT = "How would you like to update a student's subject? (enter blank to exit)"; @@ -49,7 +51,7 @@ public class Ui { private static final String DELETE_UNDONE_MESSAGE = "Last delete undone!"; private static final String STUDENT_RESTORED_MESSAGE = "Student has been restored!"; private static final String NO_RECENT_DELETES = "No recent deletes found!"; - public static final String TOTAL_CLASSES_ATTENDED_ACROSS_ALL_SUBJECTS = "Total classes attended across all subjects: "; + //@@author alalal47 From bab84eb17e349e52608b8064c1820a1682b73181 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sat, 23 Mar 2024 20:43:55 +0800 Subject: [PATCH 107/503] Reduce magic literals --- src/main/java/classify/user/InputParsing.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 893bca14d0..d1b05779d9 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -37,6 +37,9 @@ public class InputParsing { private static final String EXIT = "exit"; private static final String EXITED_THE_COMMAND = "Exited the command."; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); + private static final String SORT_BY_CHOOSE_INDEX = "Sort by: (Choose index)"; + private static final String NAME_A_TO_Z = "1. Name (A to Z)"; + private static final String TOTAL_NUMBER_OF_CLASSES_ATTENDED = "2. Total number of classes attended:"; public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, ArrayList recentlyDeletedList, Scanner in) { @@ -117,9 +120,9 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas */ private static void sortStudents(ArrayList masterStudentList, Scanner in) { while (true) { - System.out.println("Sort by: (Choose index)"); - Ui.println("1. Name (A to Z)"); - Ui.println("2. Total number of classes attended:"); + Ui.println(SORT_BY_CHOOSE_INDEX); + Ui.println(NAME_A_TO_Z); + Ui.println(TOTAL_NUMBER_OF_CLASSES_ATTENDED); String input = in.nextLine().trim(); if (input.equalsIgnoreCase(EXIT)) { From e23ecfd591479315877bcc75ffda92185277bb85 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 23 Mar 2024 22:04:14 +0800 Subject: [PATCH 108/503] Fix date range error not printing --- src/main/java/classify/user/InputParsing.java | 13 ++++++++++--- src/main/java/classify/user/Ui.java | 11 ++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index d1b05779d9..da9f5c6a39 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -900,14 +900,21 @@ protected static LocalDate parseDateFromString(String string) { private static LocalDate invalidDatePath() { logger.log(Level.WARNING, "Invalid date format entered." + '\n'); - Ui.printInvalidDateError(); + Ui.printInvalidDateFormatError(); return LocalDate.now().plusDays(2); } private static boolean isDateValid(LocalDate paymentDate) { - return paymentDate.isBefore(LocalDate.now().plusDays(1)) - && paymentDate.isAfter(LocalDate.parse(EARLIER_POSSIBLE_DATE)); + if (paymentDate.isAfter(LocalDate.now().plusDays(1)) || + paymentDate.isBefore(LocalDate.parse(EARLIER_POSSIBLE_DATE))) { + + Ui.printInvalidDateRangeError(); + return false; + } + + return true; + } } diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index 11fe187895..944ac234b2 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -28,6 +28,8 @@ public class Ui { private static final String REMARKS_PROMPT = "Please input any remarks: "; private static final String INVALID_DATE_ERROR = "Please input a valid date in the format YYYY-MM-DD" + ", or blank for today."; + private static final String INVALID_DATE_RANGE = "Please input a date with a reasonable value. \n" + + "(eg. from 2010 until today.)"; //@@author ParthGandhiNUS private static final String DIVIDER = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; private static final String WELCOME_TO_CLASSIFY = "Welcome to Classify!"; @@ -52,8 +54,6 @@ public class Ui { private static final String STUDENT_RESTORED_MESSAGE = "Student has been restored!"; private static final String NO_RECENT_DELETES = "No recent deletes found!"; - - //@@author alalal47 /** * Displays the help message to teach users how to use Classify. @@ -255,10 +255,15 @@ public static void printNullAttributeError() { System.out.println(NULL_ATTRIBUTE_ERROR); } - public static void printInvalidDateError() { + public static void printInvalidDateFormatError() { System.out.println(INVALID_DATE_ERROR); } + public static void printInvalidDateRangeError() { + System.out.println(INVALID_DATE_RANGE); + printDivider(); + } + //@@author alalal47 public static void printDeleteUndone() { System.out.println(DELETE_UNDONE_MESSAGE); From 8d9edfd7bd162deeaf8288c65fdf19ec5a02c395 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sat, 23 Mar 2024 23:07:24 +0800 Subject: [PATCH 109/503] Implement student list sort by date of last payment as well as allow sort to be used directly with an additional parameter instead of having to go through the selection menu. Cleaned up some prints. Reinstated use of StudentComparators class to improve readability --- .../classify/student/StudentComparators.java | 6 ++ .../java/classify/student/StudentSorter.java | 61 ++++++++++++++++--- src/main/java/classify/user/InputParsing.java | 25 +++++--- src/main/java/classify/user/Ui.java | 6 ++ .../java/classify/user/InputParsingTest.java | 7 ++- 5 files changed, 90 insertions(+), 15 deletions(-) diff --git a/src/main/java/classify/student/StudentComparators.java b/src/main/java/classify/student/StudentComparators.java index 479c7bae82..b8664f12b9 100644 --- a/src/main/java/classify/student/StudentComparators.java +++ b/src/main/java/classify/student/StudentComparators.java @@ -3,5 +3,11 @@ import java.util.Comparator; public class StudentComparators { + //@@author tayponghee public static Comparator nameComparator = Comparator.comparing(Student::getName); + public static Comparator classesAttendedComparator = + Comparator.comparing(Student::getTotalClassesAttended); + + //@@author alalal47 + public static Comparator lastPaidDateComparator = Comparator.comparing(Student::getLastPaymentDate); } diff --git a/src/main/java/classify/student/StudentSorter.java b/src/main/java/classify/student/StudentSorter.java index 16566331a5..cde6358c11 100644 --- a/src/main/java/classify/student/StudentSorter.java +++ b/src/main/java/classify/student/StudentSorter.java @@ -9,11 +9,16 @@ public class StudentSorter { + public static final String NAME = "name"; + public static final String PAYMENT_DATE = "payment"; + public static final String TOTAL_CLASSES = "classes"; public static final String ONE = "1"; public static final String TWO = "2"; + public static final String THREE = "3"; public static final String INVALID_CHOICE = "Invalid choice! " + - "Type either 1 or 2 to sort the list by the selected attribute"; + "Type either 1, 2 or 3 to sort the list by the selected attribute"; + //@@author tayponghee /** * Sorts the list of students based on the specified choice. * @@ -31,9 +36,23 @@ public static void sortByChoice(ArrayList masterStudentList, String cho case ONE: listStudentsByName(masterStudentList); break; + case NAME: + listStudentsByName(masterStudentList); + break; case TWO: listStudentsByTotalClasses(masterStudentList); break; + case TOTAL_CLASSES: + listStudentsByTotalClasses(masterStudentList); + break; + //@@author alalal47 + case THREE: + listStudentsByLastPaidDate(masterStudentList); + break; + case PAYMENT_DATE: + listStudentsByLastPaidDate(masterStudentList); + break; + //@@author tayponghee default: Ui.println(INVALID_CHOICE); break; @@ -41,13 +60,14 @@ public static void sortByChoice(ArrayList masterStudentList, String cho } /** - * Checks if the choice is valid (either "1" or "2"). + * Checks if the choice is valid (either "1", "2" or "3"). * * @param choice The input choice. * @return True if the choice is valid, false otherwise. */ public static boolean isValidChoice(String choice) { - return ONE.equals(choice) || TWO.equals(choice); + return (ONE.equals(choice) || TWO.equals(choice) || THREE.equals(choice)) || + (NAME.equals(choice) || PAYMENT_DATE.equals(choice) || TOTAL_CLASSES.equals(choice)); } /** @@ -56,7 +76,7 @@ public static boolean isValidChoice(String choice) { * @param masterStudentList The list of students to be listed by name. */ private static void listStudentsByName(ArrayList masterStudentList) { - masterStudentList.sort(Comparator.comparing(Student::getName)); + masterStudentList.sort(StudentComparators.nameComparator); listStudents(masterStudentList); Ui.printDivider(); } @@ -79,20 +99,35 @@ private static void listStudentsByTotalClasses(ArrayList masterStudentL student.setTotalClassesAttended(totalClassesAttended); } - masterStudentList.sort(Comparator.comparingInt(Student::getTotalClassesAttended)); + masterStudentList.sort(StudentComparators.classesAttendedComparator); listStudentsWithTotalClasses(masterStudentList); Ui.printDivider(); } + //@@author alalal47 + /** + * Lists students in the provided list by last paid date attended in ascending order, with the most recent first. + * + * @param masterStudentList The list of students to be listed by total classes attended. + */ + private static void listStudentsByLastPaidDate(ArrayList masterStudentList) { + masterStudentList.sort(StudentComparators.lastPaidDateComparator); + listStudentsWithLastPaidDate(masterStudentList); + Ui.printDivider(); + } + + //@@author tayponghee /** * Lists students in the provided list. * * @param students The list of students to be listed. */ private static void listStudents(ArrayList students) { + int i = 1; for (Student student : students) { - System.out.println(student.getName()); + System.out.println(i + "." + student.getName()); + i ++; } } @@ -102,8 +137,20 @@ private static void listStudents(ArrayList students) { * @param students The list of students to be listed. */ private static void listStudentsWithTotalClasses(ArrayList students) { + int i = 1; + for (Student student : students) { + System.out.println(i + "." + student.getName() + " - Total Classes Attended: " + + student.getTotalClassesAttended()); + i ++; + } + } + + private static void listStudentsWithLastPaidDate(ArrayList students) { + int i = 1; for (Student student : students) { - System.out.println(student.getName() + " - Total Classes Attended: " + student.getTotalClassesAttended()); + System.out.println(i + "." + student.getName() + " - Date of last payment: " + + student.getLastPaymentDate()); + i ++; } } } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index d1b05779d9..70d85c1c9c 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -36,10 +36,12 @@ public class InputParsing { "Enter the subject name (type 'exit' to go back):"; private static final String EXIT = "exit"; private static final String EXITED_THE_COMMAND = "Exited the command."; + private static final String LIST_SORTED = "Sort complete!"; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); private static final String SORT_BY_CHOOSE_INDEX = "Sort by: (Choose index)"; private static final String NAME_A_TO_Z = "1. Name (A to Z)"; private static final String TOTAL_NUMBER_OF_CLASSES_ATTENDED = "2. Total number of classes attended:"; + private static final String LAST_PAID_DATE = "3. Date of last fee payment: "; public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, ArrayList recentlyDeletedList, Scanner in) { @@ -99,7 +101,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas //@@ author tayponghee case SORT: - sortStudents(masterStudentList, in); + sortStudents(masterStudentList, in, userCommand[1]); break; case VIEW_SUBJECT: @@ -118,12 +120,21 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas * @param masterStudentList The list of students to be sorted. * @param in The Scanner object to read user input. */ - private static void sortStudents(ArrayList masterStudentList, Scanner in) { + private static void sortStudents(ArrayList masterStudentList, Scanner in, String sortType) { + String input; while (true) { - Ui.println(SORT_BY_CHOOSE_INDEX); - Ui.println(NAME_A_TO_Z); - Ui.println(TOTAL_NUMBER_OF_CLASSES_ATTENDED); - String input = in.nextLine().trim(); + //@@author alalal47 + if (sortType == null) { + Ui.println(SORT_BY_CHOOSE_INDEX); + Ui.println(NAME_A_TO_Z); + Ui.println(TOTAL_NUMBER_OF_CLASSES_ATTENDED); + Ui.println(LAST_PAID_DATE); + input = in.nextLine().trim(); + } else { + input = sortType.trim().toLowerCase(); + } + //@@author tayponghee + //input = in.nextLine().trim(); if (input.equalsIgnoreCase(EXIT)) { System.out.println(EXITED_THE_COMMAND); @@ -133,7 +144,7 @@ private static void sortStudents(ArrayList masterStudentList, Scanner i if (StudentSorter.isValidChoice(input)) { StudentSorter.sortByChoice(masterStudentList, input, in); - Ui.println(EXITED_THE_COMMAND); + Ui.println(LIST_SORTED); break; } else { Ui.println(StudentSorter.INVALID_CHOICE); diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index 11fe187895..e203c073c8 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -66,9 +66,15 @@ public static void printHelp() { printListHelpMessage(); printByeHelpMessage(); printSortNameMessage(); + printSortHelpMessage(); System.out.println("help Prints this help message"); } + private static void printSortHelpMessage() { + System.out.println("sort Sorts the student list by the input parameter, expects an" + + " attribute to sort by, can be used directly by sort [type]."); + System.out.println(" Currently available types: name, classes, payment"); + } //@@ author tayponghee private static void printSortNameMessage() { System.out.println("sort_name sorts the students by name lexicographically"); diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index 78ed3df9b9..9d4c4eb3bc 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -90,7 +90,12 @@ public void testHelpCommand() { + System.lineSeparator() + "bye Exits Classify" + System.lineSeparator() + - "sort_name sorts the students by name lexicographically" + "sort_name sorts the students by name lexicographically" + + System.lineSeparator() + + "sort Sorts the student list by the input parameter, expects an" + + " attribute to sort by, can be used directly by sort [type]." + + System.lineSeparator() + + " Currently available types: name, classes, payment" + System.lineSeparator() + "help Prints this help message" + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; From 9cc73eea267ddcf6ab93e5f8e600e717427e660e Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sat, 23 Mar 2024 23:09:52 +0800 Subject: [PATCH 110/503] Fix checkstyle error caused by unused import --- src/main/java/classify/student/StudentSorter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/classify/student/StudentSorter.java b/src/main/java/classify/student/StudentSorter.java index cde6358c11..eefe347b38 100644 --- a/src/main/java/classify/student/StudentSorter.java +++ b/src/main/java/classify/student/StudentSorter.java @@ -3,7 +3,6 @@ import classify.user.Ui; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; import java.util.Scanner; From b01925c976cb3be3fa5e76886ac9aa34b00910c6 Mon Sep 17 00:00:00 2001 From: Tay Pong Hee <110646458+tayponghee@users.noreply.github.com> Date: Sun, 24 Mar 2024 15:05:19 +0800 Subject: [PATCH 111/503] Update UserGuide.md --- docs/UserGuide.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index c9618794e9..5c1e6d0e43 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -49,10 +49,14 @@ Removes a student from the master list of students. Displays a list of all the students with that associated subject taken in the tuition centre. -### - Sort the list lexicograpically, from A to Z `sort_name` +### - Sort the list lexicograpically, from A to Z `sort name` Sorts the masterlist of students from A to Z. When the user types list, it will generate the updated sorted list. +### - Sort the list by total classes attended, `sort payment_date` + +Sorts the masterlist of students from lowest number of classes attended to highest. When the user types list, it will generate the updated sorted list. + # Usage //todo add usage guide for our different commands @@ -90,7 +94,7 @@ NUMBER ### - View details of a student `view` Views a student details. Allows the user to do view or just view. - +``` Example: view wario @@ -103,19 +107,21 @@ Remarks: Unknown Subject: subject Current marks out of 100: 100.0 Classes Attended: 1 +``` ### - Edit details of a student `edit` ### - Delete a student from the working list `delete` Deletes the student from the list. Allows the user to do delete or just delete. - +``` Example: delete Enter student name: wario Student removed successfully! +``` ## FAQ @@ -144,11 +150,17 @@ Deletes the student from the list. If the name of the student is not specified i ### `edit ` Allows the user to edit the details of the student. If the name of the student is not specified in the initial command, the program will prompt the user for the name. -### `sort_name` -Sorts the list lexicographically. +### `sort ` +Sorts the list lexicographically. If the word `name` is not specified in the initial command, the program will prompt the user for an appropriate flag. + +### `sort ` +Sorts the list lexicographically. If the word `payment_date` is not specified in the initial command, the program will prompt the user for an appropriate flag. ### `view_subject ` Lists all the students associated with that subject. If the user specifies the subject in the initial command, the list will be generated and the command will be terminated. If the user does not specify the subject, the programme will continuously prompt the user for a subject, until they choose to terminate the command. ### `help` Generates the list of commands. + +### `bye` +Terminates the program. From e8527762f31374e25836bdccaec012730e1bd3f2 Mon Sep 17 00:00:00 2001 From: Tay Pong Hee <110646458+tayponghee@users.noreply.github.com> Date: Sun, 24 Mar 2024 15:06:51 +0800 Subject: [PATCH 112/503] Add acknowledgements to DeveloperGuide.md --- docs/DeveloperGuide.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 64e1f0ed2b..2335be8465 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -2,7 +2,10 @@ ## Acknowledgements -{list here sources of all reused/adapted ideas, code, documentation, and third-party libraries -- include links to the original source as well} +1. Reference to AB-3 Developer Guide + +- [Source](https://se-education.org/addressbook-level3/DeveloperGuide.html#proposed-undoredo-feature) +- Used as template to structure this Developer Guide ## Design & implementation From b40b83375aad56705992670e327b12c428abb6de Mon Sep 17 00:00:00 2001 From: Tay Pong Hee <110646458+tayponghee@users.noreply.github.com> Date: Sun, 24 Mar 2024 15:43:07 +0800 Subject: [PATCH 113/503] Add inputparsing as a component of the DeveloperGuide --- docs/DeveloperGuide.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 2335be8465..4d49e50933 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -11,6 +11,46 @@ {Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} +--- + +### InputParsing component + +--- + +The first and foremost component in the Student Tracking app is to ensure that the user parses in commands in a format that makes sense, which will modify the master list. + +#### Design considerations +- The parser must be effecive in breaking down the user's input into its constitutent commands, with further breakdown if an associated argument is added. +- There must be a way to prevent users from adding multiple instances of a student with the same name, to prevent confusion. +- The method of adding students to the master list must be straightforward and intuitive, allowing users to add a student without comprimising the integrity of the information. +- Allowing the user to input blank fields in certain information slots so as to simulate real life scenarios, where not all the information is present at the time of registration. For example, while a valid phone number must be present to register a student to the master list, the remarks tab can be left empty. +- Error handling must be intuitive for the user, so that appropriate error messages are produced if the user does not input a valid command. The error handling should also be robust, to account for the event a user is incapable in following instructions. + +#### Implementation and rationale + +The InputParsing class is designed to handle the considerations above by breaking down the input given by the user in a well structured process. Below is how the InputParsing class works: + +1. Splitting User Input: The Parser would take on the user's input and split it into 2 parts, which is the command and the argument, if any. + +2. Command recognition: Depending on the command and the argument given, if any, the parser would execute the command as per defined by the program. If the command and/or argument given is invalid/undefined, the input parser would generate a message to the user, informing them of the command's invalidity. + +3. Argument extraction: Depending on the specific command, if an argument can be parsed into that command, the parser would understand the argument and execute the sub-command specified by the user. Should the argument be invalid, the user would be informed of the argument's invalidity. + +Through structuring the InputParsing class in such a manner, the application ensures that the user input is correctly parsed into executable commands for the subsequent phases of the application. + +The InputParsing class uses the method below to achieve its functionality: + +- `public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, ArrayList recentlyDeletedList, Scanner in)` + +This method takes in the user's input as the userCommand, the master student list, a list of the recently deleted students and the next input as parameters, which then proceeds with executing the command as associated with the user's input. + +Given below is an example of how a user may add a student to the data base. + +- Suppose the user types in the command `add wario`. The parser first splits the input into two, checking for the command and the argument. +- It then recognises the `add` command, which then further checks if there is an argument given. +- Since the `add` command only allows the user to add a student to the list if there were no duplicate names present before, it will run the method "findStudentByName(ArrayList masterStudentList, String name)", to check if the name was already present in the masterlist. +- Assuming the name "wario" did not exist in the masterlist beforehand, the parser would grant the user's request to add the student to the masterlist. +- This `add wario` command is equivalent to having the user first type `add`, then after waiting fo the program to respond, type `wario`. In the latter scenario, the input parser deems that an argument was not present, and thus will ask the user to give the name of the student that they would like to add. ## Product scope ### Target user profile From d6a9a23d68e4b136c57fcf7839694a3146439f23 Mon Sep 17 00:00:00 2001 From: Tay Pong Hee <110646458+tayponghee@users.noreply.github.com> Date: Sun, 24 Mar 2024 15:52:01 +0800 Subject: [PATCH 114/503] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 4d49e50933..cc6306c90d 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -21,9 +21,8 @@ The first and foremost component in the Student Tracking app is to ensure that t #### Design considerations - The parser must be effecive in breaking down the user's input into its constitutent commands, with further breakdown if an associated argument is added. -- There must be a way to prevent users from adding multiple instances of a student with the same name, to prevent confusion. -- The method of adding students to the master list must be straightforward and intuitive, allowing users to add a student without comprimising the integrity of the information. -- Allowing the user to input blank fields in certain information slots so as to simulate real life scenarios, where not all the information is present at the time of registration. For example, while a valid phone number must be present to register a student to the master list, the remarks tab can be left empty. +- The parser should be quick and effective in understanding the user's input, with simple prompts given to help the user in correctly parsing the command through the input parser. +- Allowing the user to input optional arguments. For example, the user could type `view `, which takes in the "student name" as an optional argument. This is to increase the robustness of the program, which accounts for the two types of users, one who just types in `view`, and the other as formerly mentioned above. - Error handling must be intuitive for the user, so that appropriate error messages are produced if the user does not input a valid command. The error handling should also be robust, to account for the event a user is incapable in following instructions. #### Implementation and rationale From 38d7c9619cb05301f989851243432684c3bca066 Mon Sep 17 00:00:00 2001 From: Tay Pong Hee <110646458+tayponghee@users.noreply.github.com> Date: Sun, 24 Mar 2024 15:53:06 +0800 Subject: [PATCH 115/503] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index cc6306c90d..884224d5a2 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -47,7 +47,7 @@ Given below is an example of how a user may add a student to the data base. - Suppose the user types in the command `add wario`. The parser first splits the input into two, checking for the command and the argument. - It then recognises the `add` command, which then further checks if there is an argument given. -- Since the `add` command only allows the user to add a student to the list if there were no duplicate names present before, it will run the method "findStudentByName(ArrayList masterStudentList, String name)", to check if the name was already present in the masterlist. +- Since the `add` command only allows the user to add a student to the list if there were no duplicate names present before, it will run the method `findStudentByName(ArrayList masterStudentList, String name)`, to check if the name was already present in the masterlist. - Assuming the name "wario" did not exist in the masterlist beforehand, the parser would grant the user's request to add the student to the masterlist. - This `add wario` command is equivalent to having the user first type `add`, then after waiting fo the program to respond, type `wario`. In the latter scenario, the input parser deems that an argument was not present, and thus will ask the user to give the name of the student that they would like to add. From 3640642c2195269850455ae40527cee06076190c Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 24 Mar 2024 19:13:59 +0800 Subject: [PATCH 116/503] Update dev guide --- docs/DeveloperGuide.md | 32 ++++++++++- .../diagrams/src/DataStoring/DataStoring.puml | 52 ++++++++++++++++++ docs/diagrams/src/DataStoring/DateStoring.png | Bin 0 -> 33880 bytes 3 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 docs/diagrams/src/DataStoring/DataStoring.puml create mode 100644 docs/diagrams/src/DataStoring/DateStoring.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 884224d5a2..8460677605 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -15,8 +15,6 @@ ### InputParsing component ---- - The first and foremost component in the Student Tracking app is to ensure that the user parses in commands in a format that makes sense, which will modify the master list. #### Design considerations @@ -51,10 +49,38 @@ Given below is an example of how a user may add a student to the data base. - Assuming the name "wario" did not exist in the masterlist beforehand, the parser would grant the user's request to add the student to the masterlist. - This `add wario` command is equivalent to having the user first type `add`, then after waiting fo the program to respond, type `wario`. In the latter scenario, the input parser deems that an argument was not present, and thus will ask the user to give the name of the student that they would like to add. + +### Student Details + +To facilitate the management of students within a tuition centre, it is imperative to have easy access and storage of important information regarding said personnel. + +Seen below is an UML diagram of the relevant classes dealing with storage. + +![DataStoringUML](./diagrams/out/DataStoring.png) + +#### Design considerations + +When building our implementation, we wanted our program to be able to easily access a student's details from a student object, and vice versa. + +#### Implementation and rationale + +A `Student` is made up of a list of the subjects they are taking, along with relevant information one might need while managing their schedules and clienthood (maybe not gender, but who knows). Every `Student` object is stored in a public `static StudentList` that any class can call. + +Storage of these details are handled via the `StudentsAttributes` class when the user package calls upon its methods. To ensure easy access of information from either a `Student` object, and be able to retrieve the `Student` parent when having access to an `StudentAttributes` object, we linked both `Student` and `StudentAttribute`. + +Since both classes are referencing each other, it was easy for us to link it with the input parsing system, where we would just need a student's name (we have yet to account for repeat names; only showing a warning) to be able to edit their details. + +We created a parent `Details` class as those are information not specifically related to students. It can thus be repurposed in future updates should we wish to expand this application into a personnel management system, which would include employees of the tuition centre. + +However, our current implementation is not very secure as one can access every field of a `Student` object just by having access to it or the `StudentAttribute` object, which can be done via accessing the `static masterStudentList` variable.In future updates, we could possibly implement a Facade Pattern to better hide sensitive details. + +--- + ## Product scope + ### Target user profile -{Describe the target user profile} +We aim to target private tuition centres with our product, specifically smaller ones without a good system in place to track the progress of their students. ### Value proposition diff --git a/docs/diagrams/src/DataStoring/DataStoring.puml b/docs/diagrams/src/DataStoring/DataStoring.puml new file mode 100644 index 0000000000..b710c6966c --- /dev/null +++ b/docs/diagrams/src/DataStoring/DataStoring.puml @@ -0,0 +1,52 @@ +@startuml DateStoring + +package student { + + class StudentList { + {static} +masterStudentList:Student[] + {static} +recentlyDeletedList:Student[] + +studentList:Student[] + -- + Methods omitted + } + + class Student { + +name:String + -totalClassesAttended:int + -- + Methods omitted + } + + class SubjectGrade { + -subject:String + -grade:double + -classesAttended:int + -- + Methods omitted + } + + class Details { + #gender:String + #phoneNumber:int + #lastPaymentDate:LocalDate + #remarks:String + -- + Methods omitted + } + + class StudentAttributes { + -- + Methods omitted + } + + StudentList o-- Student + + Student "attributes"---> "1" StudentAttributes + + StudentAttributes --down|> Details + StudentAttributes -->"0..*" SubjectGrade + StudentAttributes "student" --> "1" Student + +} + +@enduml diff --git a/docs/diagrams/src/DataStoring/DateStoring.png b/docs/diagrams/src/DataStoring/DateStoring.png new file mode 100644 index 0000000000000000000000000000000000000000..088b8e1cc75bcd4a3b2f41fc5c242f2ad94c455c GIT binary patch literal 33880 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 literal 0 HcmV?d00001 From 0a4ff404886e35cf566263a323ab15556b641400 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 24 Mar 2024 19:15:19 +0800 Subject: [PATCH 117/503] Update UML --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 8460677605..9fc8e8bd91 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -56,7 +56,7 @@ To facilitate the management of students within a tuition centre, it is imperati Seen below is an UML diagram of the relevant classes dealing with storage. -![DataStoringUML](./diagrams/out/DataStoring.png) +![DataStoringUML](./diagrams/src/DataStoring/DateStoring.png) #### Design considerations From 9668ce4eeb4e0d824e89d63c998d48dbcd6d6b22 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Mon, 25 Mar 2024 10:37:37 +0800 Subject: [PATCH 118/503] Add AddStudent class --- .../java/classify/student/AddStudent.java | 216 ++++++++++++++++++ src/main/java/classify/user/InputParsing.java | 205 +---------------- 2 files changed, 226 insertions(+), 195 deletions(-) create mode 100644 src/main/java/classify/student/AddStudent.java diff --git a/src/main/java/classify/student/AddStudent.java b/src/main/java/classify/student/AddStudent.java new file mode 100644 index 0000000000..1ea54504f1 --- /dev/null +++ b/src/main/java/classify/student/AddStudent.java @@ -0,0 +1,216 @@ + +package classify.student; + +import classify.user.Ui; +import classify.user.InputParsing; +import java.util.ArrayList; +import java.util.Scanner; +import java.util.logging.Level; + +import static classify.user.InputParsing.logger; + +public class AddStudent { + private static final String NOTEMPTY = "THIS STRING IS NOT EMPTY"; + private static final String DO_YOU_WANT_TO_ADD_ANOTHER_SUBJECT_AND_GRADE_YES_NO = "Do you want to add another subject and grade? (yes/no)"; + private static final String YES = "yes"; + private static final String NO = "no"; + private static final String INVALID_RESPONSE_PLEASE_TYPE_YES_OR_NO = "Invalid response. Please type 'yes' or 'no'."; + private static final String SUBJECT_ENTER_NOTHING_TO_SKIP = "Subject (enter nothing to skip): "; + private static final String NO_SUBJECTS_ADDED = "No subjects added."; + private static final String SUBJECT_ALREADY_EXISTS = "Subject already exists."; + private static final String STUDENT_ADDED_SUCCESSFULLY = "Student added successfully."; + private static final String NUMBER_IS_OUTSIDE_THE_ACCEPTABLE_RANGE = "Number is outside the acceptable range."; + private static final String STUDENT_WITH_THE_SAME_NAME_ALREADY_EXISTS = "Student with the same name already exists."; + + /** + * Adds a new student to the list of students. + * Does not allow for students of the same name to be added. + * Checks if attributes added are in the correct format. + * Allows for multiple subjects to be added, along with their grades and classes + * attended. + * + * @param masterStudentList The list of all students. + * @param in The scanner object to read user input. + * @param studentName The name of the student if the user had entered it + * before being prompted + */ + public static void addStudent(ArrayList masterStudentList, Scanner in, String studentName) { + String name; + + name = checkForEmptyName(masterStudentList, in, studentName); + + if (InputParsing.findStudentByName(masterStudentList, name) != null) { + assert InputParsing.findStudentByName(masterStudentList, name) != null; + logger.log(Level.WARNING, STUDENT_WITH_THE_SAME_NAME_ALREADY_EXISTS); + + Ui.printSameNameError(); + Ui.printDivider(); + return; + } + + Student student = new Student(name); + addSubject(in, student.getAttributes()); + + // @@author Cryolian + int number = InputParsing.promptForPhoneNumber(in); + + while (number < 0) { + number = InputParsing.promptForPhoneNumber(in); + } + //@@ author ParthGandhiNUS + assert number > 0 && number < 100000000 : NUMBER_IS_OUTSIDE_THE_ACCEPTABLE_RANGE; + + //@@author Cryolian + student.getAttributes().setPhoneNumber(number); + + Ui.promptForGender(); + student.getAttributes().setGender(InputParsing.readInString(in)); + + Ui.promptForLastPaymentDate(); + student.getAttributes().setLastPaymentDate(InputParsing.readInDate(in)); + + Ui.promptForRemarks(); + student.getAttributes().setRemarks(InputParsing.readInString(in)); + + //@@author tayponghee + masterStudentList.add(student); + logger.log(Level.INFO, STUDENT_ADDED_SUCCESSFULLY); + Ui.printStudentAdded(); + Ui.printDivider(); + } + + /** + * Prompts the user to enter a non-empty name for a student and checks if it + * already exists in the list. + * If the name is empty or already exists, prompts the user again until valid + * input is provided. + * + * @param masterStudentList The list of all students. + * @param in The scanner object to read user input. + * @param studentName The name of the student if the user had entered it + * before being prompted + * @return The valid non-empty name entered by the user. + */ + private static String checkForEmptyName(ArrayList masterStudentList, Scanner in, String studentName) { + String name; + while (true) { + + //@@author alalal47 + if (studentName == null) { + Ui.printStudentNamePrompt(); + name = in.nextLine().trim(); + } else { + name = studentName.trim(); + studentName = NOTEMPTY; + } + + //@@author tayponghee + assert studentName != null; + + if (name.isEmpty()) { + Ui.printEmptyNameMessage(); + Ui.printDivider(); + } else { + break; + } + } + return name; + } + + /** + * Prompts the user to enter attributes for a student, including subject, grade, + * and classes attended. + * Continues to prompt the user until user enters blank to exit. + * + * @param in The scanner object to read user input. + * @param attributes The StudentAttributes object to store the attributes of the + * student. + */ + public static void addSubject(Scanner in, StudentAttributes attributes) { + while (true) { + //@@ author blackmirag3 + System.out.print(SUBJECT_ENTER_NOTHING_TO_SKIP); + String subject = in.nextLine().trim(); + + if (subject.isBlank()) { + System.out.println(NO_SUBJECTS_ADDED); + break; + + } else if (attributes.findSubject(subject) != null) { + // rejects subject if existing subject of same name exists in students' + // attributes + System.out.println(SUBJECT_ALREADY_EXISTS); + break; + + } else if (checkForValidSubjectResponse(in, attributes, subject)) { + //@@author tayponghee + return; + } + } + } + + /** + * Checks for a valid response from the user when prompted to add another subject and grade. + * + * @param in The scanner object to read user input. + * @param attributes The attributes of the student. + * @param subject The subject to be added. + * @return True if the user chooses not to add another subject and grade, false otherwise. + */ + private static boolean checkForValidSubjectResponse(Scanner in, StudentAttributes attributes, String subject) { + double grade = Math.max(InputParsing.promptForGrade(in), 0); + int classesAttended = promptForClassesAttended(in); + + SubjectGrade subjectGrade = new SubjectGrade(subject, grade, classesAttended); + attributes.addSubjectGrade(subjectGrade); + + while (true) { + System.out.println(DO_YOU_WANT_TO_ADD_ANOTHER_SUBJECT_AND_GRADE_YES_NO); + String response = in.nextLine().trim().toLowerCase(); + + if (response.equals(YES)) { + break; + + } else if (response.equals(NO)) { + return true; + + } else { + System.out.println(INVALID_RESPONSE_PLEASE_TYPE_YES_OR_NO); + } + + } + return false; + } + + /** + * Checks the format of the input for the number of classes attended. + * Prompts the user to enter a valid integer until one is provided. + * + * @param in The scanner object to read user input. + * @return The valid number of classes attended. + */ + public static int promptForClassesAttended(Scanner in) { + while (true) { + Ui.printClassesAttendedPrompt(); + String classesAttendedInput = in.nextLine(); + + if (classesAttendedInput.isBlank()) { + return -1; + } + + // @@author ParthGandhiNUS + int classesAttended; + try { + classesAttended = Integer.parseInt(classesAttendedInput); + } catch (NumberFormatException e) { + System.out.println("Wrong number format! Please try again! e.g. 12 "); + Ui.printDivider(); + classesAttended = promptForClassesAttended(in); + } + + if (InputParsing.isValidClassesAttended(classesAttended)) { + return classesAttended; + } + } + } +} diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 0270fe5e4d..78a0bec04e 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -1,6 +1,7 @@ package classify.user; import classify.datacommands.DataHandler; +import classify.student.AddStudent; import classify.student.Student; import classify.student.StudentAttributes; import classify.student.StudentList; @@ -37,7 +38,7 @@ public class InputParsing { private static final String EXIT = "exit"; private static final String EXITED_THE_COMMAND = "Exited the command."; private static final String LIST_SORTED = "Sort complete!"; - private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); + public static final Logger logger = Logger.getLogger(InputParsing.class.getName()); private static final String SORT_BY_CHOOSE_INDEX = "Sort by: (Choose index)"; private static final String NAME_A_TO_Z = "1. Name (A to Z)"; private static final String TOTAL_NUMBER_OF_CLASSES_ATTENDED = "2. Total number of classes attended:"; @@ -52,7 +53,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas // @@author tayponghee switch (userCommand[0]) { case ADD: - addStudent(masterStudentList, in, userCommand[1]); + AddStudent.addStudent(masterStudentList, in, userCommand[1]); // @@author ParthGandhiNUS assert masterStudentList != null; DataHandler.writeStudentInfo(masterStudentList); @@ -282,7 +283,7 @@ private static void editStudentAttributes(Scanner in, Student student) { switch (command) { case ADD: - addSubject(in, attributes); + AddStudent.addSubject(in, attributes); student.setAttributes(attributes); break; @@ -475,101 +476,6 @@ private static void showAttributes(StudentAttributes attributes) { } } - /** - * Adds a new student to the list of students. - * Does not allow for students of the same name to be added. - * Checks if attributes added are in the correct format. - * Allows for multiple subjects to be added, along with their grades and classes - * attended. - * - * @param masterStudentList The list of all students. - * @param in The scanner object to read user input. - * @param studentName The name of the student if the user had entered it - * before being prompted - */ - private static void addStudent(ArrayList masterStudentList, Scanner in, String studentName) { - String name; - - name = checkForEmptyName(masterStudentList, in, studentName); - - if (findStudentByName(masterStudentList, name) != null) { - assert findStudentByName(masterStudentList, name) != null; - logger.log(Level.WARNING, "Student with the same name already exists."); - - Ui.printSameNameError(); - Ui.printDivider(); - return; - } - - Student student = new Student(name); - addSubject(in, student.getAttributes()); - - // @@author Cryolian - int number = promptForPhoneNumber(in); - - while (number < 0) { - number = promptForPhoneNumber(in); - } - //@@ author ParthGandhiNUS - assert number > 0 && number < 100000000: "Number is outside the acceptable range."; - - //@@author Cryolian - student.getAttributes().setPhoneNumber(number); - - Ui.promptForGender(); - student.getAttributes().setGender(readInString(in)); - - Ui.promptForLastPaymentDate(); - student.getAttributes().setLastPaymentDate(readInDate(in)); - - Ui.promptForRemarks(); - student.getAttributes().setRemarks(readInString(in)); - - //@@author tayponghee - masterStudentList.add(student); - logger.log(Level.INFO, "Student added successfully."); - Ui.printStudentAdded(); - Ui.printDivider(); - } - - /** - * Prompts the user to enter a non-empty name for a student and checks if it - * already exists in the list. - * If the name is empty or already exists, prompts the user again until valid - * input is provided. - * - * @param masterStudentList The list of all students. - * @param in The scanner object to read user input. - * @param studentName The name of the student if the user had entered it - * before being prompted - * @return The valid non-empty name entered by the user. - */ - private static String checkForEmptyName(ArrayList masterStudentList, Scanner in, String studentName) { - String name; - while (true) { - - //@@author alalal47 - if (studentName == null) { - Ui.printStudentNamePrompt(); - name = in.nextLine().trim(); - } else { - name = studentName.trim(); - studentName = NOTEMPTY; - } - - //@@author tayponghee - assert studentName != null; - - if (name.isEmpty()) { - Ui.printEmptyNameMessage(); - Ui.printDivider(); - } else { - break; - } - } - return name; - } - // @@author blackmirag3 /** * Prompts the user to edit subject, grade, and classes attended for student. @@ -607,7 +513,7 @@ private static void editAttribute(Scanner in, StudentAttributes attributes) { currentSubject.setGrade(newGrade); } - int newClassesAttended = promptForClassesAttended(in); + int newClassesAttended = AddStudent.promptForClassesAttended(in); currentSubject.setClassesAttended(newClassesAttended); System.out.println("Subject updated."); @@ -638,97 +544,6 @@ private static void deleteAttribute(Scanner in, StudentAttributes attributes) { } } - // @@author tayponghee - /** - * Prompts the user to enter attributes for a student, including subject, grade, - * and classes attended. - * Continues to prompt the user until user enters blank to exit. - * - * @param in The scanner object to read user input. - * @param attributes The StudentAttributes object to store the attributes of the - * student. - */ - private static void addSubject(Scanner in, StudentAttributes attributes) { - while (true) { - // @@author blackmirag3 - System.out.print("Subject (enter nothing to skip): "); - String subject = in.nextLine().trim(); - - if (subject.isBlank()) { - System.out.println("No subjects added."); - break; - - } else if (attributes.findSubject(subject) != null) { - // rejects subject if existing subject of same name exists in students' - // attributes - System.out.println("Subject already exists."); - break; - - } else if (checkForValidSubjectResponse(in, attributes, subject)) { - //@@author tayponghee - return; - } - } - } - - /** - * Checks for a valid response from the user when prompted to add another subject and grade. - * - * @param in The scanner object to read user input. - * @param attributes The attributes of the student. - * @param subject The subject to be added. - * @return True if the user chooses not to add another subject and grade, false otherwise. - */ - private static boolean checkForValidSubjectResponse(Scanner in, StudentAttributes attributes, String subject) { - double grade = Math.max(promptForGrade(in), 0); - int classesAttended = promptForClassesAttended(in); - SubjectGrade subjectGrade = new SubjectGrade(subject, grade, classesAttended); - attributes.addSubjectGrade(subjectGrade); - while (true) { - System.out.println("Do you want to add another subject and grade? (yes/no)"); - String response = in.nextLine().trim().toLowerCase(); - if (response.equals("yes")) { - break; - } else if (response.equals("no")) { - return true; - } else { - System.out.println("Invalid response. Please type 'yes' or 'no'."); - } - } - return false; - } - - /** - * Checks the format of the input for the number of classes attended. - * Prompts the user to enter a valid integer until one is provided. - * - * @param in The scanner object to read user input. - * @return The valid number of classes attended. - */ - private static int promptForClassesAttended(Scanner in) { - while (true) { - Ui.printClassesAttendedPrompt(); - String classesAttendedInput = in.nextLine(); - - if (classesAttendedInput.isBlank()) { - return -1; - } - - // @@author ParthGandhiNUS - int classesAttended; - try { - classesAttended = Integer.parseInt(classesAttendedInput); - } catch (NumberFormatException e) { - System.out.println("Wrong number format! Please try again! e.g. 12 "); - Ui.printDivider(); - classesAttended = promptForClassesAttended(in); - } - - if (isValidClassesAttended(classesAttended)) { - return classesAttended; - } - } - } /** * Prompts for grade from user input and checks format @@ -738,7 +553,7 @@ private static int promptForClassesAttended(Scanner in) { * @param in The scanner object to read user input. * @return The valid grade. */ - private static double promptForGrade(Scanner in) { + public static double promptForGrade(Scanner in) { while (true) { Ui.printStudentGradesPrompt(); String gradeInput = in.nextLine(); @@ -780,7 +595,7 @@ public static Student findStudentByName(ArrayList masterStudentList, St } // @@author blackmirag3 - private static boolean isValidClassesAttended(int classesAttended) { + public static boolean isValidClassesAttended(int classesAttended) { try { if (classesAttended < 0) { System.out.println("Classes attended must be 0 or more."); @@ -824,7 +639,7 @@ private static boolean isValidGrade(double grade) { * @return -1 if an exception was thrown. An 8 * or 10-digit number if not. */ - private static int promptForPhoneNumber(Scanner in) { + public static int promptForPhoneNumber(Scanner in) { int number = 0; @@ -864,7 +679,7 @@ private static boolean checkNumberValidity(int number) { * @return "Unknown" if blank was inputted, or the * trimmed string inputted by the user. */ - private static String readInString(Scanner in) { + public static String readInString(Scanner in) { String string = in.nextLine(); if (string.isBlank()) { @@ -874,7 +689,7 @@ private static String readInString(Scanner in) { } - protected static LocalDate readInDate(Scanner in) { + public static LocalDate readInDate(Scanner in) { String userInput; LocalDate paymentDate; From 01c0ae6d6854ae332299ac74fe67a03ce59ebdbb Mon Sep 17 00:00:00 2001 From: tayponghee Date: Mon, 25 Mar 2024 10:49:41 +0800 Subject: [PATCH 119/503] Add ViewStudent class --- .../java/classify/student/ViewStudent.java | 99 +++++++++++++++++++ src/main/java/classify/user/InputParsing.java | 98 +----------------- 2 files changed, 104 insertions(+), 93 deletions(-) create mode 100644 src/main/java/classify/student/ViewStudent.java diff --git a/src/main/java/classify/student/ViewStudent.java b/src/main/java/classify/student/ViewStudent.java new file mode 100644 index 0000000000..f6c2943a9e --- /dev/null +++ b/src/main/java/classify/student/ViewStudent.java @@ -0,0 +1,99 @@ +package classify.student; + +import classify.user.Ui; +import classify.user.InputParsing; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ViewStudent { + + private static final Logger logger = Logger.getLogger(ViewStudent.class.getName()); + + //@@author tayponghee + /** + * Displays the details of a specific student. + * + * @param masterStudentList The list of all students. + * @param in The scanner object to read user input. + * @param studentName The name of the student if the user had entered it + * before being prompted + */ + public static void viewStudent(ArrayList masterStudentList, Scanner in, String studentName) { + + String name; + + //@@ author alalal47 + if (studentName == null) { + Ui.printStudentNamePrompt(); + name = in.nextLine(); + } else { + name = studentName; + } + + //@@author blackmirag3 + assert name != null : "Student name cannot be null"; + + //@@author tayponghee + Student foundStudent = InputParsing.findStudentByName(masterStudentList, name); + + if (foundStudent != null) { + logger.log(Level.INFO, "Viewing student details: " + name); + Ui.printDivider(); + Ui.printStudentDetails(); + Ui.printStudentName(name); + Ui.printStudentDetails(foundStudent); + StudentAttributes attributes = foundStudent.getAttributes(); + showAttributes(attributes); + + int totalClassesAttended = getTotalClassesAttended(foundStudent); + Ui.printTotalClassesAttended(totalClassesAttended); + + } else { + logger.log(Level.WARNING, "Student not found: " + name); + Ui.printStudentNotFound(); + } + } + + /** + * Calculates the total number of classes attended by the student across all subjects. + * + * @param student The student whose total classes attended are to be calculated. + * @return The total number of classes attended by the student. + */ + private static int getTotalClassesAttended(Student student) { + int totalClassesAttended = 0; + for (classify.student.SubjectGrade subjectGrade : student.getAttributes().getSubjectGrades()) { + totalClassesAttended += subjectGrade.getClassesAttended(); + } + return totalClassesAttended; + } + + /** + * Displays the attributes of a student. + * + * @param attributes The attributes of the student to display. + */ + public static void showAttributes(StudentAttributes attributes) { + if (attributes != null) { + List subjectGrades = attributes.getSubjectGrades(); + if (!subjectGrades.isEmpty()) { + for (SubjectGrade subjectGrade : subjectGrades) { + assert subjectGrade != null : "subjectGrade cannot be null"; + Ui.printSubjectName(subjectGrade.getSubject()); + Ui.printStudentGrades(subjectGrade.getGrade()); + Ui.printClassesAttended(subjectGrade.getClassesAttended()); + Ui.printDivider(); + } + } else { + Ui.printEmptySubjectError(); + } + } else { + Ui.printNullAttributeError(); + } + } + +} diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 78a0bec04e..0253407d93 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -1,18 +1,19 @@ package classify.user; import classify.datacommands.DataHandler; + import classify.student.AddStudent; import classify.student.Student; import classify.student.StudentAttributes; import classify.student.StudentList; import classify.student.StudentSorter; import classify.student.SubjectGrade; +import classify.student.ViewStudent; import java.time.LocalDate; import java.time.format.DateTimeParseException; -import java.util.ArrayList; -import java.util.List; +import java.util.ArrayList; import java.util.Scanner; import java.util.logging.Level; import java.util.logging.Logger; @@ -21,7 +22,6 @@ public class InputParsing { private static final String EARLIER_POSSIBLE_DATE = "1970-01-01"; private static final String DEFAULT_STRING_VALUE = "Unknown"; private static final int LOWER_LIMIT_PHONE_NUMBER = 8; - private static final String NOTEMPTY = "THIS STRING IS NOT EMPTY"; private static final String BYE = "bye"; private static final String LIST = "list"; private static final String ADD = "add"; @@ -61,7 +61,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas break; case VIEW: - viewStudent(masterStudentList, in, userCommand[1]); + ViewStudent.viewStudent(masterStudentList, in, userCommand[1]); Ui.printDivider(); break; @@ -269,7 +269,7 @@ private static void editStudent(ArrayList list, Scanner in, String name private static void editStudentAttributes(Scanner in, Student student) { StudentAttributes attributes = student.getAttributes(); - showAttributes(attributes); + ViewStudent.showAttributes(attributes); while (true) { Ui.printEditPrompt(); @@ -389,93 +389,6 @@ private static void undoDelete(ArrayList masterStudentList, ArrayList masterStudentList, Scanner in, String studentName) { - - String name; - - //@@author alalal47 - if (studentName == null) { - Ui.printStudentNamePrompt(); - name = in.nextLine(); - } else { - name = studentName; - } - - //@@author blackmirag3 - assert name != null : "Student name cannot be null"; - //@@author tayponghee - Student foundStudent = findStudentByName(masterStudentList, name); - - if (foundStudent != null) { - logger.log(Level.INFO, "Viewing student details: " + name); - Ui.printDivider(); - Ui.printStudentDetails(); - Ui.printStudentName(name); - Ui.printStudentDetails(foundStudent); - StudentAttributes attributes = foundStudent.getAttributes(); - showAttributes(attributes); - - int totalClassesAttended = getTotalClassesAttended(foundStudent); - Ui.printTotalClassesAttended(totalClassesAttended); - - } else { - logger.log(Level.WARNING, "Student not found: " + name); - Ui.printStudentNotFound(); - } - } - - /** - * Calculates the total number of classes attended by the student across all subjects. - * - * @param student The student whose total classes attended are to be calculated. - * @return The total number of classes attended by the student. - */ - private static int getTotalClassesAttended(Student student) { - int totalClassesAttended = 0; - for (classify.student.SubjectGrade subjectGrade : student.getAttributes().getSubjectGrades()) { - totalClassesAttended += subjectGrade.getClassesAttended(); - } - return totalClassesAttended; - } - - /** - * Displays the attributes of a student. - * - * @param attributes The attributes of the student to display. - */ - private static void showAttributes(StudentAttributes attributes) { - if (attributes != null) { - - List subjectGrades = attributes.getSubjectGrades(); - - if (!subjectGrades.isEmpty()) { - - for (SubjectGrade subjectGrade : subjectGrades) { - assert subjectGrade != null : "subjectGrade cannot be null"; - Ui.printSubjectName(subjectGrade.getSubject()); - Ui.printStudentGrades(subjectGrade.getGrade()); - Ui.printClassesAttended(subjectGrade.getClassesAttended()); - Ui.printDivider(); - } - - } else { - Ui.printEmptySubjectError(); - } - - } else { - Ui.printNullAttributeError(); - } - } - // @@author blackmirag3 /** * Prompts the user to edit subject, grade, and classes attended for student. @@ -544,7 +457,6 @@ private static void deleteAttribute(Scanner in, StudentAttributes attributes) { } } - /** * Prompts for grade from user input and checks format * Prompts the user to enter a valid double within the range [0, 100] until one From 7ffb2aad92f2eb45f17f8a1dab97032fac73ffeb Mon Sep 17 00:00:00 2001 From: tayponghee Date: Mon, 25 Mar 2024 10:53:15 +0800 Subject: [PATCH 120/503] Fix gradle checks --- src/main/java/classify/student/AddStudent.java | 15 +++++++++------ src/main/java/classify/user/InputParsing.java | 12 ++++++------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/main/java/classify/student/AddStudent.java b/src/main/java/classify/student/AddStudent.java index 1ea54504f1..f691ed3317 100644 --- a/src/main/java/classify/student/AddStudent.java +++ b/src/main/java/classify/student/AddStudent.java @@ -7,20 +7,23 @@ import java.util.Scanner; import java.util.logging.Level; -import static classify.user.InputParsing.logger; +import static classify.user.InputParsing.LOGGER; public class AddStudent { private static final String NOTEMPTY = "THIS STRING IS NOT EMPTY"; - private static final String DO_YOU_WANT_TO_ADD_ANOTHER_SUBJECT_AND_GRADE_YES_NO = "Do you want to add another subject and grade? (yes/no)"; + private static final String DO_YOU_WANT_TO_ADD_ANOTHER_SUBJECT_AND_GRADE_YES_NO = + "Do you want to add another subject and grade? (yes/no)"; private static final String YES = "yes"; private static final String NO = "no"; - private static final String INVALID_RESPONSE_PLEASE_TYPE_YES_OR_NO = "Invalid response. Please type 'yes' or 'no'."; + private static final String INVALID_RESPONSE_PLEASE_TYPE_YES_OR_NO = + "Invalid response. Please type 'yes' or 'no'."; private static final String SUBJECT_ENTER_NOTHING_TO_SKIP = "Subject (enter nothing to skip): "; private static final String NO_SUBJECTS_ADDED = "No subjects added."; private static final String SUBJECT_ALREADY_EXISTS = "Subject already exists."; private static final String STUDENT_ADDED_SUCCESSFULLY = "Student added successfully."; private static final String NUMBER_IS_OUTSIDE_THE_ACCEPTABLE_RANGE = "Number is outside the acceptable range."; - private static final String STUDENT_WITH_THE_SAME_NAME_ALREADY_EXISTS = "Student with the same name already exists."; + private static final String STUDENT_WITH_THE_SAME_NAME_ALREADY_EXISTS = + "Student with the same name already exists."; /** * Adds a new student to the list of students. @@ -41,7 +44,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, if (InputParsing.findStudentByName(masterStudentList, name) != null) { assert InputParsing.findStudentByName(masterStudentList, name) != null; - logger.log(Level.WARNING, STUDENT_WITH_THE_SAME_NAME_ALREADY_EXISTS); + LOGGER.log(Level.WARNING, STUDENT_WITH_THE_SAME_NAME_ALREADY_EXISTS); Ui.printSameNameError(); Ui.printDivider(); @@ -74,7 +77,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, //@@author tayponghee masterStudentList.add(student); - logger.log(Level.INFO, STUDENT_ADDED_SUCCESSFULLY); + LOGGER.log(Level.INFO, STUDENT_ADDED_SUCCESSFULLY); Ui.printStudentAdded(); Ui.printDivider(); } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 0253407d93..6fb086c688 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -19,6 +19,7 @@ import java.util.logging.Logger; public class InputParsing { + public static final Logger LOGGER = Logger.getLogger(InputParsing.class.getName()); private static final String EARLIER_POSSIBLE_DATE = "1970-01-01"; private static final String DEFAULT_STRING_VALUE = "Unknown"; private static final int LOWER_LIMIT_PHONE_NUMBER = 8; @@ -38,7 +39,6 @@ public class InputParsing { private static final String EXIT = "exit"; private static final String EXITED_THE_COMMAND = "Exited the command."; private static final String LIST_SORTED = "Sort complete!"; - public static final Logger logger = Logger.getLogger(InputParsing.class.getName()); private static final String SORT_BY_CHOOSE_INDEX = "Sort by: (Choose index)"; private static final String NAME_A_TO_Z = "1. Name (A to Z)"; private static final String TOTAL_NUMBER_OF_CLASSES_ATTENDED = "2. Total number of classes attended:"; @@ -516,7 +516,7 @@ public static boolean isValidClassesAttended(int classesAttended) { } return true; } catch (NumberFormatException e) { - logger.log(Level.WARNING, "Invalid input for classes attended: " + classesAttended, e); + LOGGER.log(Level.WARNING, "Invalid input for classes attended: " + classesAttended, e); System.out.println("Invalid input for classes attended. Please enter a valid whole number."); Ui.printDivider(); return false; @@ -532,7 +532,7 @@ private static boolean isValidGrade(double grade) { } return true; } catch (NumberFormatException e) { - logger.log(Level.WARNING, "Invalid input for grade: " + grade, e); + LOGGER.log(Level.WARNING, "Invalid input for grade: " + grade, e); Ui.printValidNumberError(); Ui.printDivider(); return false; @@ -562,7 +562,7 @@ public static int promptForPhoneNumber(Scanner in) { number = readInPhoneNumber(in); } while (!checkNumberValidity(number)); - logger.log(Level.INFO, "Storing number: " + number); + LOGGER.log(Level.INFO, "Storing number: " + number); return number; } catch (NumberFormatException e) { @@ -619,7 +619,7 @@ public static LocalDate readInDate(Scanner in) { protected static LocalDate parseDateFromString(String string) { if (string.isBlank()) { - logger.log(Level.INFO, "Storing today as the last payment date." + '\n'); + LOGGER.log(Level.INFO, "Storing today as the last payment date." + '\n'); return LocalDate.now(); } @@ -637,7 +637,7 @@ protected static LocalDate parseDateFromString(String string) { } private static LocalDate invalidDatePath() { - logger.log(Level.WARNING, "Invalid date format entered." + '\n'); + LOGGER.log(Level.WARNING, "Invalid date format entered." + '\n'); Ui.printInvalidDateFormatError(); return LocalDate.now().plusDays(2); } From a6497761283cb34fb4a73c4727625491b83d69a8 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Mon, 25 Mar 2024 23:40:39 +0800 Subject: [PATCH 121/503] Change UML visibility icons --- .../diagrams/src/DataStoring/DataStoring.puml | 4 +++- docs/diagrams/src/DataStoring/DateStoring.png | Bin 33880 -> 32245 bytes 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/diagrams/src/DataStoring/DataStoring.puml b/docs/diagrams/src/DataStoring/DataStoring.puml index b710c6966c..aa2d3c6548 100644 --- a/docs/diagrams/src/DataStoring/DataStoring.puml +++ b/docs/diagrams/src/DataStoring/DataStoring.puml @@ -1,7 +1,9 @@ @startuml DateStoring -package student { +skinparam classAttributeIconSize 0 +package student { + class StudentList { {static} +masterStudentList:Student[] {static} +recentlyDeletedList:Student[] diff --git a/docs/diagrams/src/DataStoring/DateStoring.png b/docs/diagrams/src/DataStoring/DateStoring.png index 088b8e1cc75bcd4a3b2f41fc5c242f2ad94c455c..433d8f879b8756acd8ab629814981d82907355b6 100644 GIT binary patch literal 32245 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 Xk<;jluP=oM*iWe_-??6{Xdd)m8oTgt literal 33880 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 From 77a5bd75593ccabcb4f2575b87a687d7e85e92bd Mon Sep 17 00:00:00 2001 From: tayponghee Date: Tue, 26 Mar 2024 14:54:22 +0800 Subject: [PATCH 122/503] Add InputParsing UML --- docs/DeveloperGuide.md | 2 + .../src/InputParsing/InputParsing.png | Bin 0 -> 21700 bytes .../src/InputParsing/InputParsing.puml | 38 ++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 docs/diagrams/src/InputParsing/InputParsing.png create mode 100644 docs/diagrams/src/InputParsing/InputParsing.puml diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 9fc8e8bd91..a35d5e3746 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -17,6 +17,8 @@ The first and foremost component in the Student Tracking app is to ensure that the user parses in commands in a format that makes sense, which will modify the master list. +![InputParsingUML](./diagrams/src/InputParsing/InputParsing.png) + #### Design considerations - The parser must be effecive in breaking down the user's input into its constitutent commands, with further breakdown if an associated argument is added. - The parser should be quick and effective in understanding the user's input, with simple prompts given to help the user in correctly parsing the command through the input parser. diff --git a/docs/diagrams/src/InputParsing/InputParsing.png b/docs/diagrams/src/InputParsing/InputParsing.png new file mode 100644 index 0000000000000000000000000000000000000000..4c0b341f87f2b43e05e31a8ef2d8a4731ffcc20d GIT binary patch literal 21700 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 PGnfpXu6{1-oD!M<%&Wmq literal 0 HcmV?d00001 diff --git a/docs/diagrams/src/InputParsing/InputParsing.puml b/docs/diagrams/src/InputParsing/InputParsing.puml new file mode 100644 index 0000000000..4143affa23 --- /dev/null +++ b/docs/diagrams/src/InputParsing/InputParsing.puml @@ -0,0 +1,38 @@ +@startuml InputParsing + +class Classify { + +} + +package user { + class InputParsing { + findStudentByName(masterStudentList:Student[], name:String) + } + + class Ui { + + } + + class UserInput { + + } +} + +package student { + class AddStudent { + addStudent(); + } + + class ViewStudent { + viewStudent(); + } +} + +Classify ..> InputParsing +Classify ..> UserInput +Classify ..> Ui +UserInput ...l> Ui +InputParsing ...r> Ui +InputParsing ..> student + +note "Inconsequential methods and attributes omitted" as N1 \ No newline at end of file From 536fe06c20124985cc14948fc04aa3a204d18037 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Thu, 28 Mar 2024 15:43:20 +0800 Subject: [PATCH 123/503] Add UI component to DG --- docs/DeveloperGuide.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 9fc8e8bd91..657e7cec88 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -13,9 +13,23 @@ --- +### Ui component + +The `Ui` class handles message output for the user within the terminal. + +The `UI`component, +- stores message output strings for user feedback +- holds methods for printing messages to be called by other classes, such as `InputParsing`. + +#### Design considerations + +Being a CLI application, UI/UX is minimal and user IO is confined within the terminal. + +Hence, public methods within the`Ui` class are static for easy access by other classes, without the need to instantiate an instance of the `Ui` class to call. + ### InputParsing component -The first and foremost component in the Student Tracking app is to ensure that the user parses in commands in a format that makes sense, which will modify the master list. +This component ensures that the user parses in commands in a format that makes sense, which will modify the master list. #### Design considerations - The parser must be effecive in breaking down the user's input into its constitutent commands, with further breakdown if an associated argument is added. @@ -84,7 +98,7 @@ We aim to target private tuition centres with our product, specifically smaller ### Value proposition -{Describe the value proposition: what problem does it solve?} +Classify serves as an attempt to modernise administrative tasks in education institutes, such as tuition centres or school environments. ## User Stories From 3f1ea8e4e4dc70cc6c25a94ce92fed048ede9168 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Thu, 28 Mar 2024 15:55:26 +0800 Subject: [PATCH 124/503] Refactor delete related commands to their own class Add a missing author tag Update assertion to match new code --- .../java/classify/student/StudentSorter.java | 1 + src/main/java/classify/user/InputParsing.java | 93 +----------------- .../java/classify/user/deleteCommands.java | 95 +++++++++++++++++++ 3 files changed, 99 insertions(+), 90 deletions(-) create mode 100644 src/main/java/classify/user/deleteCommands.java diff --git a/src/main/java/classify/student/StudentSorter.java b/src/main/java/classify/student/StudentSorter.java index eefe347b38..3f6b97cec0 100644 --- a/src/main/java/classify/student/StudentSorter.java +++ b/src/main/java/classify/student/StudentSorter.java @@ -144,6 +144,7 @@ private static void listStudentsWithTotalClasses(ArrayList students) { } } + //@@author alalal47 private static void listStudentsWithLastPaidDate(ArrayList students) { int i = 1; for (Student student : students) { diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 6fb086c688..a0c9b7aa52 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -67,18 +67,18 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas //@@author alalal47 case DELETE: - deleteStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); + deleteCommands.deleteStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); // @@author ParthGandhiNUS DataHandler.writeStudentInfo(masterStudentList); //@@author alalal47 break; case RESTORE: - restoreStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); + deleteCommands.restoreStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); break; case UNDO: - undoDelete(masterStudentList, recentlyDeletedList); + deleteCommands.undoDelete(masterStudentList, recentlyDeletedList); break; case HELP: @@ -302,93 +302,6 @@ private static void editStudentAttributes(Scanner in, Student student) { } } - //@@author alalal47 - /** - * Removes a student from the list. - * Adds the removed student to a recently deleted list, where the student's information can be recovered - * - * @param masterStudentList The list of all students - * @param recentlyDeletedList The list of recently deleted students - * @param in The scanner object to read user input - * @param studentName The name of the student if the user had entered it - * before being prompted - */ - private static void deleteStudent(ArrayList masterStudentList, ArrayList recentlyDeletedList, - Scanner in, String studentName) { - String name; - if (studentName == null) { - Ui.printStudentNamePrompt(); - name = in.nextLine().trim(); - } else { - name = studentName; - } - - Student foundStudent = findStudentByName(masterStudentList, name); - - if (foundStudent != null) { - Ui.printStudentDeleted(); - } else { - Ui.printStudentNotFound(); - } - - Ui.printDivider(); - recentlyDeletedList.add(foundStudent); - masterStudentList.remove(foundStudent); - //assert foundStudent == null : "Student should be deleted"; - } - - /** - * Removes a student from the list. - * Adds the removed student to a recently deleted list, where the student's information can be recovered - * - * @param masterStudentList The list of all students. - * @param recentlyDeletedList The list of recently deleted students - * @param in The scanner object to read user input. - * @param studentName The name of the student if the user had entered it - * before being prompted - */ - private static void restoreStudent(ArrayList masterStudentList, ArrayList recentlyDeletedList, - Scanner in, String studentName) { - String name; - if (studentName == null) { - Ui.printStudentNamePrompt(); - name = in.nextLine().trim(); - } else { - name = studentName; - } - - Student foundStudent = findStudentByName(recentlyDeletedList, name); - - if (foundStudent != null) { - Ui.printRestoreMessage(); - } else { - Ui.printStudentNotFound(); - } - - Ui.printDivider(); - masterStudentList.add(foundStudent); - recentlyDeletedList.remove(foundStudent); - } - - /** - * Restores the latest deleted student that has not yet been restored - * - * @param masterStudentList The list of all students - * @param recentlyDeletedList The list of recently deleted students - */ - private static void undoDelete(ArrayList masterStudentList, ArrayList recentlyDeletedList) { - if (recentlyDeletedList.isEmpty()) { - Ui.printNoDeleteFound(); - Ui.printDivider(); - return; - } - Student student = recentlyDeletedList.get(recentlyDeletedList.size() - 1); - masterStudentList.add(student); - recentlyDeletedList.remove(student); - Ui.printDeleteUndone(); - Ui.printDivider(); - } - // @@author blackmirag3 /** * Prompts the user to edit subject, grade, and classes attended for student. diff --git a/src/main/java/classify/user/deleteCommands.java b/src/main/java/classify/user/deleteCommands.java new file mode 100644 index 0000000000..589e5b8faa --- /dev/null +++ b/src/main/java/classify/user/deleteCommands.java @@ -0,0 +1,95 @@ +package classify.user; + +import classify.student.Student; + +import java.util.ArrayList; +import java.util.Scanner; + +public class deleteCommands { + //@@author alalal47 + /** + * Removes a student from the list. + * Adds the removed student to a recently deleted list, where the student's information can be recovered + * + * @param masterStudentList The list of all students + * @param recentlyDeletedList The list of recently deleted students + * @param in The scanner object to read user input + * @param studentName The name of the student if the user had entered it + * before being prompted + */ + static void deleteStudent(ArrayList masterStudentList, ArrayList recentlyDeletedList, + Scanner in, String studentName) { + String name; + if (studentName == null) { + Ui.printStudentNamePrompt(); + name = in.nextLine().trim(); + } else { + name = studentName; + } + + Student foundStudent = InputParsing.findStudentByName(masterStudentList, name); + + if (foundStudent != null) { + Ui.printStudentDeleted(); + } else { + Ui.printStudentNotFound(); + } + + Ui.printDivider(); + recentlyDeletedList.add(foundStudent); + masterStudentList.remove(foundStudent); + assert InputParsing.findStudentByName(masterStudentList, name) == null : "Student should be deleted"; + } + + /** + * Removes a student from the list. + * Adds the removed student to a recently deleted list, where the student's information can be recovered + * + * @param masterStudentList The list of all students. + * @param recentlyDeletedList The list of recently deleted students + * @param in The scanner object to read user input. + * @param studentName The name of the student if the user had entered it + * before being prompted + */ + static void restoreStudent(ArrayList masterStudentList, ArrayList recentlyDeletedList, + Scanner in, String studentName) { + String name; + if (studentName == null) { + Ui.printStudentNamePrompt(); + name = in.nextLine().trim(); + } else { + name = studentName; + } + + Student foundStudent = InputParsing.findStudentByName(recentlyDeletedList, name); + + if (foundStudent != null) { + Ui.printRestoreMessage(); + } else { + Ui.printStudentNotFound(); + } + + Ui.printDivider(); + masterStudentList.add(foundStudent); + recentlyDeletedList.remove(foundStudent); + } + + /** + * Restores the latest deleted student that has not yet been restored + * + * @param masterStudentList The list of all students + * @param recentlyDeletedList The list of recently deleted students + */ + static void undoDelete(ArrayList masterStudentList, ArrayList recentlyDeletedList) { + if (recentlyDeletedList.isEmpty()) { + Ui.printNoDeleteFound(); + Ui.printDivider(); + return; + } + Student student = recentlyDeletedList.get(recentlyDeletedList.size() - 1); + masterStudentList.add(student); + recentlyDeletedList.remove(student); + Ui.printDeleteUndone(); + Ui.printDivider(); + } +} From 83e17975182a51e32f2713f5e6933bd2d07513d7 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Thu, 28 Mar 2024 16:45:28 +0800 Subject: [PATCH 125/503] Add Instructions for manual testing for add and view functions to DG --- docs/DeveloperGuide.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 6bcbc51106..1fdc1589d7 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -119,4 +119,21 @@ Classify serves as an attempt to modernise administrative tasks in education ins ## Instructions for manual testing -{Give instructions on how to do a manual product testing e.g., how to load sample data to be used for testing} +### Adding a student to the student list +1. Adding a student with a name and phone number only + 1. Prerequisites: View if a student with the name 'joe' exists by using the `view joe` command. + 2. Test case: `add joe` and when prompted for phone number enter `11111111`, while pressing enter to skip other optional fields. +
+ Expected: `view joe` now shows the Student details of a student with Name: joe, Phone Number: 11111111. Other fields that were left blank will reflect 'Unknown' or for date fields, today's date. + 3. Test case: `add` and when prompted for Name, `joe`. `11111111` when prompted for phone number, press enter to skip other fields. +
+ Expected: `view joe` shows the same results as when a student was added via `add joe`. +### Viewing a student's details +1. View a student who has been added to the student list + 1. Prerequisites: Add one student named 'joe' to the list with the `add` command + 2. Test case: `view joe` +
+ Expected: Student's details shown correspond to the details input when `add` was used to add a student. + 3. Test case: `view dogman` +
+ Expected: No details are displayed, an error message stating 'Student not found!' is shown. \ No newline at end of file From 960a20fffaac2c8d99b95fce9b3c29f137464a74 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Thu, 28 Mar 2024 16:50:40 +0800 Subject: [PATCH 126/503] Fix class name to fit coding standards --- .../user/{deleteCommands.java => DeleteCommands.java} | 2 +- src/main/java/classify/user/InputParsing.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/main/java/classify/user/{deleteCommands.java => DeleteCommands.java} (99%) diff --git a/src/main/java/classify/user/deleteCommands.java b/src/main/java/classify/user/DeleteCommands.java similarity index 99% rename from src/main/java/classify/user/deleteCommands.java rename to src/main/java/classify/user/DeleteCommands.java index 589e5b8faa..3b59470999 100644 --- a/src/main/java/classify/user/deleteCommands.java +++ b/src/main/java/classify/user/DeleteCommands.java @@ -5,7 +5,7 @@ import java.util.ArrayList; import java.util.Scanner; -public class deleteCommands { +public class DeleteCommands { //@@author alalal47 /** * Removes a student from the list. diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index a0c9b7aa52..fcddd4d03a 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -67,18 +67,18 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas //@@author alalal47 case DELETE: - deleteCommands.deleteStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); + DeleteCommands.deleteStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); // @@author ParthGandhiNUS DataHandler.writeStudentInfo(masterStudentList); //@@author alalal47 break; case RESTORE: - deleteCommands.restoreStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); + DeleteCommands.restoreStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); break; case UNDO: - deleteCommands.undoDelete(masterStudentList, recentlyDeletedList); + DeleteCommands.undoDelete(masterStudentList, recentlyDeletedList); break; case HELP: From ea40c54e38cba0000f20ed63037ee822ceb7be98 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Thu, 28 Mar 2024 18:57:26 +0800 Subject: [PATCH 127/503] Shift strings from AddStudent to Ui class --- .../java/classify/student/AddStudent.java | 18 +++++------- src/main/java/classify/user/Ui.java | 28 +++++++++++++++++++ 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/main/java/classify/student/AddStudent.java b/src/main/java/classify/student/AddStudent.java index f691ed3317..c2de0cca8b 100644 --- a/src/main/java/classify/student/AddStudent.java +++ b/src/main/java/classify/student/AddStudent.java @@ -11,15 +11,9 @@ public class AddStudent { private static final String NOTEMPTY = "THIS STRING IS NOT EMPTY"; - private static final String DO_YOU_WANT_TO_ADD_ANOTHER_SUBJECT_AND_GRADE_YES_NO = - "Do you want to add another subject and grade? (yes/no)"; private static final String YES = "yes"; private static final String NO = "no"; - private static final String INVALID_RESPONSE_PLEASE_TYPE_YES_OR_NO = - "Invalid response. Please type 'yes' or 'no'."; private static final String SUBJECT_ENTER_NOTHING_TO_SKIP = "Subject (enter nothing to skip): "; - private static final String NO_SUBJECTS_ADDED = "No subjects added."; - private static final String SUBJECT_ALREADY_EXISTS = "Subject already exists."; private static final String STUDENT_ADDED_SUCCESSFULLY = "Student added successfully."; private static final String NUMBER_IS_OUTSIDE_THE_ACCEPTABLE_RANGE = "Number is outside the acceptable range."; private static final String STUDENT_WITH_THE_SAME_NAME_ALREADY_EXISTS = @@ -136,13 +130,13 @@ public static void addSubject(Scanner in, StudentAttributes attributes) { String subject = in.nextLine().trim(); if (subject.isBlank()) { - System.out.println(NO_SUBJECTS_ADDED); + Ui.printNoSubjectsAdded(); break; } else if (attributes.findSubject(subject) != null) { // rejects subject if existing subject of same name exists in students' // attributes - System.out.println(SUBJECT_ALREADY_EXISTS); + Ui.printSubjectAlreadyExists(); break; } else if (checkForValidSubjectResponse(in, attributes, subject)) { @@ -168,7 +162,7 @@ private static boolean checkForValidSubjectResponse(Scanner in, StudentAttribute attributes.addSubjectGrade(subjectGrade); while (true) { - System.out.println(DO_YOU_WANT_TO_ADD_ANOTHER_SUBJECT_AND_GRADE_YES_NO); + Ui.printAddSubject(); String response = in.nextLine().trim().toLowerCase(); if (response.equals(YES)) { @@ -178,7 +172,7 @@ private static boolean checkForValidSubjectResponse(Scanner in, StudentAttribute return true; } else { - System.out.println(INVALID_RESPONSE_PLEASE_TYPE_YES_OR_NO); + Ui.printInvalidResponse(); } } @@ -206,7 +200,9 @@ public static int promptForClassesAttended(Scanner in) { try { classesAttended = Integer.parseInt(classesAttendedInput); } catch (NumberFormatException e) { - System.out.println("Wrong number format! Please try again! e.g. 12 "); + //@@author tayponghee + Ui.printWrongNumberFormat(); + //@@author ParthGandhiNus Ui.printDivider(); classesAttended = promptForClassesAttended(in); } diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index 18a021f840..e9a821e6e0 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -53,6 +53,14 @@ public class Ui { private static final String DELETE_UNDONE_MESSAGE = "Last delete undone!"; private static final String STUDENT_RESTORED_MESSAGE = "Student has been restored!"; private static final String NO_RECENT_DELETES = "No recent deletes found!"; + //@@ author tayponghee + private static final String ADD_SUBJECT = + "Do you want to add another subject and grade? (yes/no)"; + private static final String INVALID_RESPONSE = + "Invalid response. Please type 'yes' or 'no'."; + private static final String NO_SUBJECTS_ADDED = "No subjects added."; + private static final String SUBJECT_ALREADY_EXISTS = "Subject already exists."; + private static final String WRONG_NUMBER_FORMAT = "Wrong number format! Please try again! e.g. 12 "; //@@author alalal47 /** @@ -291,4 +299,24 @@ public static void printTotalClassesAttended(int classes) { public static void println (String text) { System.out.println(text); } + + public static void printAddSubject() { + System.out.println(ADD_SUBJECT); + } + + public static void printInvalidResponse() { + System.out.println(INVALID_RESPONSE); + } + + public static void printNoSubjectsAdded() { + System.out.println(NO_SUBJECTS_ADDED); + } + + public static void printSubjectAlreadyExists() { + System.out.println(SUBJECT_ALREADY_EXISTS); + } + + public static void printWrongNumberFormat () { + System.out.println(WRONG_NUMBER_FORMAT); + } } From afde228306b02e5eb28cf4b1abee89f9808d3b52 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Thu, 28 Mar 2024 19:27:34 +0800 Subject: [PATCH 128/503] Refactor showAttributes --- .../java/classify/student/StudentSorter.java | 6 +--- .../java/classify/student/ViewStudent.java | 30 ++++++++++++------- src/main/java/classify/user/Ui.java | 1 + 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/main/java/classify/student/StudentSorter.java b/src/main/java/classify/student/StudentSorter.java index 3f6b97cec0..ed562bff23 100644 --- a/src/main/java/classify/student/StudentSorter.java +++ b/src/main/java/classify/student/StudentSorter.java @@ -123,11 +123,7 @@ private static void listStudentsByLastPaidDate(ArrayList masterStudentL * @param students The list of students to be listed. */ private static void listStudents(ArrayList students) { - int i = 1; - for (Student student : students) { - System.out.println(i + "." + student.getName()); - i ++; - } + Ui.printStudentList(students); } /** diff --git a/src/main/java/classify/student/ViewStudent.java b/src/main/java/classify/student/ViewStudent.java index f6c2943a9e..092b899ab7 100644 --- a/src/main/java/classify/student/ViewStudent.java +++ b/src/main/java/classify/student/ViewStudent.java @@ -80,20 +80,28 @@ private static int getTotalClassesAttended(Student student) { public static void showAttributes(StudentAttributes attributes) { if (attributes != null) { List subjectGrades = attributes.getSubjectGrades(); - if (!subjectGrades.isEmpty()) { - for (SubjectGrade subjectGrade : subjectGrades) { - assert subjectGrade != null : "subjectGrade cannot be null"; - Ui.printSubjectName(subjectGrade.getSubject()); - Ui.printStudentGrades(subjectGrade.getGrade()); - Ui.printClassesAttended(subjectGrade.getClassesAttended()); - Ui.printDivider(); - } - } else { - Ui.printEmptySubjectError(); - } + checkIfSubjectGradesIsEmpty(subjectGrades); } else { Ui.printNullAttributeError(); } } + private static void checkIfSubjectGradesIsEmpty(List subjectGrades) { + if (!subjectGrades.isEmpty()) { + printSubjectAttributes(subjectGrades); + } else { + Ui.printEmptySubjectError(); + } + } + + private static void printSubjectAttributes(List subjectGrades) { + for (SubjectGrade subjectGrade : subjectGrades) { + assert subjectGrade != null : "subjectGrade cannot be null"; + Ui.printSubjectName(subjectGrade.getSubject()); + Ui.printStudentGrades(subjectGrade.getGrade()); + Ui.printClassesAttended(subjectGrade.getClassesAttended()); + Ui.printDivider(); + } + } + } diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index e9a821e6e0..2e5a97ae5f 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -319,4 +319,5 @@ public static void printSubjectAlreadyExists() { public static void printWrongNumberFormat () { System.out.println(WRONG_NUMBER_FORMAT); } + } From 93a6ebfbb474deb33251ca04fcea836ab28cbd8a Mon Sep 17 00:00:00 2001 From: alalal47 Date: Thu, 28 Mar 2024 23:11:46 +0800 Subject: [PATCH 129/503] Fix infinite loop bug when invalid sort flag is entered --- src/main/java/classify/user/InputParsing.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index fcddd4d03a..11a34070da 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -148,6 +148,7 @@ private static void sortStudents(ArrayList masterStudentList, Scanner i Ui.println(LIST_SORTED); break; } else { + sortType = null; Ui.println(StudentSorter.INVALID_CHOICE); } } From f6a3d4706a2e7f047dd3501c843f250ec6643e2c Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 29 Mar 2024 13:06:21 +0800 Subject: [PATCH 130/503] Update Developer Guide to include Data Commands Component --- docs/DeveloperGuide.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 1fdc1589d7..4334f46540 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -90,6 +90,34 @@ We created a parent `Details` class as those are information not specifically re However, our current implementation is not very secure as one can access every field of a `Student` object just by having access to it or the `StudentAttribute` object, which can be done via accessing the `static masterStudentList` variable.In future updates, we could possibly implement a Facade Pattern to better hide sensitive details. +### Data Commands Component + +This section refers to `DataHandler.java`, `DataReader.java`, and `DataStorage.java` classes. + +We have currently implemented a basic data handler which has the abilities to store a student's name into a text file. + +This text file is created locally on the users' computer for easy access and retrieval. + +Currently there is a polling system set in place where every change in the list of students (eg, addition, deletion, modification) would override the current working text file on the users' computer. + +We intend to further the functionalities of this component by allowing us to add attributes (phone number, subjects, last fee payment date), + +#### Design Considerations + +In order to ensure the proper usage of OOP principles (such as encapsulation), we have segregated the 3 classes to read,store and handle the data. + +#### Implementation and Rationale + +##### DataHandler +Contains the methods to read and write student information which are used in other functions such as InputParser and Main. + +##### DataReader +Contains the restore student list method which is used to restore the previously saved information about the students which are part of the tuition centre. + +##### DataStorage +Contains the relevant methods to make the required file directories for storing the text file. +It checks for existing folders. If not found, it makes new folders to store text files properly. + --- ## Product scope From eb09f5fc5e9154c000cdbad41c25486d48bb489f Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 29 Mar 2024 15:56:50 +0800 Subject: [PATCH 131/503] Add tests for StudentSorter and StudentAttributes --- src/main/java/classify/student/Details.java | 4 + src/main/java/classify/user/InputParsing.java | 14 ++-- .../student/StudentAttributesTest.java | 78 +++++++++++++++++++ .../classify/student/StudentSorterTest.java | 74 ++++++++++++++++++ 4 files changed, 165 insertions(+), 5 deletions(-) create mode 100644 src/test/java/classify/student/StudentAttributesTest.java create mode 100644 src/test/java/classify/student/StudentSorterTest.java diff --git a/src/main/java/classify/student/Details.java b/src/main/java/classify/student/Details.java index f2b8295581..5215f792e8 100644 --- a/src/main/java/classify/student/Details.java +++ b/src/main/java/classify/student/Details.java @@ -50,4 +50,8 @@ public void setRemarks(String remarks) { this.remarks = remarks; } + public static Details getDetails() { + return StudentAttributes.getDetails(); + } + } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 11a34070da..83e2651b0e 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -53,11 +53,15 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas // @@author tayponghee switch (userCommand[0]) { case ADD: - AddStudent.addStudent(masterStudentList, in, userCommand[1]); - // @@author ParthGandhiNUS - assert masterStudentList != null; - DataHandler.writeStudentInfo(masterStudentList); - // @@author tayponghee + if (userCommand.length >= 2) { + AddStudent.addStudent(masterStudentList, in, userCommand[1]); + //@@author ParthGandhiNUS + assert masterStudentList != null; + DataHandler.writeStudentInfo(masterStudentList); + //@@ author tayponghee + } else { + System.out.println("Invalid command: Not enough arguments for 'add'."); + } break; case VIEW: diff --git a/src/test/java/classify/student/StudentAttributesTest.java b/src/test/java/classify/student/StudentAttributesTest.java new file mode 100644 index 0000000000..321ca9dd5a --- /dev/null +++ b/src/test/java/classify/student/StudentAttributesTest.java @@ -0,0 +1,78 @@ +package classify.student; + +import org.junit.jupiter.api.Test; +import java.util.List; +import static org.junit.jupiter.api.Assertions.*; + +public class StudentAttributesTest { + + @Test + public void testAddSubjectGrade() { + Student student = new Student("John Doe"); + StudentAttributes attributes = new StudentAttributes(student); + SubjectGrade subjectGrade = new SubjectGrade("Math", 90.5, 20); + + attributes.addSubjectGrade(subjectGrade); + + List subjectGrades = attributes.getSubjectGrades(); + assertTrue(subjectGrades.contains(subjectGrade)); + } + + @Test + public void testGetName() { + Student student = new Student("John Doe"); + StudentAttributes attributes = new StudentAttributes(student); + + assertEquals("John Doe", attributes.getName()); + } + + @Test + public void testSetName() { + Student student = new Student("John Doe"); + StudentAttributes attributes = new StudentAttributes(student); + + attributes.setName("Jane Smith"); + + assertEquals("Jane Smith", attributes.getName()); + } + + @Test + public void testGetSubject() { + SubjectGrade subjectGrade = new SubjectGrade("Math", 90.5, 20); + assertEquals("Math", subjectGrade.getSubject()); + } + + @Test + public void testGetGrade() { + SubjectGrade subjectGrade = new SubjectGrade("Math", 90.5, 20); + assertEquals(90.5, subjectGrade.getGrade()); + } + + @Test + public void testGetClassesAttended() { + SubjectGrade subjectGrade = new SubjectGrade("Math", 90.5, 20); + assertEquals(20, subjectGrade.getClassesAttended()); + } + + @Test + public void testSetSubject() { + SubjectGrade subjectGrade = new SubjectGrade("Math", 90.5, 20); + subjectGrade.setSubject("Science"); + assertEquals("Science", subjectGrade.getSubject()); + } + + @Test + public void testSetGrade() { + SubjectGrade subjectGrade = new SubjectGrade("Math", 90.5, 20); + subjectGrade.setGrade(85.0); + assertEquals(85.0, subjectGrade.getGrade()); + } + + @Test + public void testSetClassesAttended() { + SubjectGrade subjectGrade = new SubjectGrade("Math", 90.5, 20); + subjectGrade.setClassesAttended(25); + assertEquals(25, subjectGrade.getClassesAttended()); + } +} + diff --git a/src/test/java/classify/student/StudentSorterTest.java b/src/test/java/classify/student/StudentSorterTest.java new file mode 100644 index 0000000000..0b1955899c --- /dev/null +++ b/src/test/java/classify/student/StudentSorterTest.java @@ -0,0 +1,74 @@ +package classify.student; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class StudentSorterTest { + + public static final String PONG_HEE = "Pong Hee"; + public static final String PARTH = "Parth"; + public static final String YI_XIN = "Yi Xin"; + public static final String GERARD = "Gerard"; + public static final String SHUI_HON = "Shui Hon"; + public static final String SCIENCE = "Science"; + public static final String MATH = "Math"; + + @Test + public void testSortByChoice() { + ArrayList students = new ArrayList<>(); + Student student1 = new Student(PONG_HEE); + Student student2 = new Student(PARTH); + Student student3 = new Student(YI_XIN); + Student student4 = new Student(GERARD); + Student student5 = new Student(SHUI_HON); + + students.add(student1); + students.add(student2); + students.add(student3); + students.add(student4); + students.add(student5); + + StudentAttributes attributes1 = new StudentAttributes(student1); + attributes1.addSubjectGrade(new SubjectGrade(MATH, 90.0, 10)); + attributes1.addSubjectGrade(new SubjectGrade(SCIENCE, 85.0, 8)); + + StudentAttributes attributes2 = new StudentAttributes(student2); + attributes2.addSubjectGrade(new SubjectGrade(MATH, 88.0, 12)); + attributes2.addSubjectGrade(new SubjectGrade(SCIENCE, 80.0, 7)); + + StudentAttributes attributes3 = new StudentAttributes(student3); + attributes3.addSubjectGrade(new SubjectGrade(MATH, 85.0, 15)); + attributes3.addSubjectGrade(new SubjectGrade(SCIENCE, 82.0, 6)); + + StudentAttributes attributes4 = new StudentAttributes(student4); + attributes4.addSubjectGrade(new SubjectGrade(MATH, 92.0, 14)); + attributes4.addSubjectGrade(new SubjectGrade(SCIENCE, 88.0, 9)); + + StudentAttributes attributes5 = new StudentAttributes(student5); + attributes5.addSubjectGrade(new SubjectGrade(MATH, 85.0, 11)); + attributes5.addSubjectGrade(new SubjectGrade(SCIENCE, 90.0, 10)); + + student1.setAttributes(attributes1); + student2.setAttributes(attributes2); + student3.setAttributes(attributes3); + student4.setAttributes(attributes4); + student5.setAttributes(attributes5); + + StudentSorter.sortByChoice(students, "1", null); + assertEquals(GERARD, students.get(0).getName()); + assertEquals(PARTH, students.get(1).getName()); + assertEquals(PONG_HEE, students.get(2).getName()); + assertEquals(SHUI_HON, students.get(3).getName()); + assertEquals(YI_XIN, students.get(4).getName()); + + StudentSorter.sortByChoice(students, "2", null); + assertEquals(PONG_HEE, students.get(0).getName()); + assertEquals(PARTH, students.get(1).getName()); + assertEquals(SHUI_HON, students.get(2).getName()); + assertEquals(YI_XIN, students.get(3).getName()); + assertEquals(GERARD, students.get(4).getName()); + } +} From bbb529f962a317e0889abfc33f38fd2ed60ed85c Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 29 Mar 2024 16:04:35 +0800 Subject: [PATCH 132/503] Add SubjectGradeTest --- .../classify/student/SubjectGradeTest.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 src/test/java/classify/student/SubjectGradeTest.java diff --git a/src/test/java/classify/student/SubjectGradeTest.java b/src/test/java/classify/student/SubjectGradeTest.java new file mode 100644 index 0000000000..d9d98564c6 --- /dev/null +++ b/src/test/java/classify/student/SubjectGradeTest.java @@ -0,0 +1,55 @@ +package classify.student; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class SubjectGradeTest { + + public static final String MATH = "Math"; + public static final String SCIENCE = "Science"; + public static final String ENGLISH = "English"; + public static final String HISTORY = "History"; + public static final String PHYSICS = "Physics"; + public static final String CHEMISTRY = "Chemistry"; + public static final String BIOLOGY = "Biology"; + + @Test + public void testGetSubject() { + SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.0, 10); + assertEquals(MATH, subjectGrade.getSubject()); + } + + @Test + public void testGetGrade() { + SubjectGrade subjectGrade = new SubjectGrade(SCIENCE, 85.0, 8); + assertEquals(85.0, subjectGrade.getGrade()); + } + + @Test + public void testGetClassesAttended() { + SubjectGrade subjectGrade = new SubjectGrade(ENGLISH, 92.5, 12); + assertEquals(12, subjectGrade.getClassesAttended()); + } + + @Test + public void testSetSubject() { + SubjectGrade subjectGrade = new SubjectGrade(HISTORY, 88.0, 15); + subjectGrade.setSubject(PHYSICS); + assertEquals(PHYSICS, subjectGrade.getSubject()); + } + + @Test + public void testSetGrade() { + SubjectGrade subjectGrade = new SubjectGrade(CHEMISTRY, 78.0, 10); + subjectGrade.setGrade(80.5); + assertEquals(80.5, subjectGrade.getGrade()); + } + + @Test + public void testSetClassesAttended() { + SubjectGrade subjectGrade = new SubjectGrade(BIOLOGY, 95.0, 14); + subjectGrade.setClassesAttended(16); + assertEquals(16, subjectGrade.getClassesAttended()); + } +} From 2f314df53044e22f06911f7b2537d9d181d89acf Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 29 Mar 2024 16:20:08 +0800 Subject: [PATCH 133/503] Fix Gradle checks --- src/test/java/classify/student/StudentAttributesTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/classify/student/StudentAttributesTest.java b/src/test/java/classify/student/StudentAttributesTest.java index 321ca9dd5a..6fd7402552 100644 --- a/src/test/java/classify/student/StudentAttributesTest.java +++ b/src/test/java/classify/student/StudentAttributesTest.java @@ -2,7 +2,9 @@ import org.junit.jupiter.api.Test; import java.util.List; -import static org.junit.jupiter.api.Assertions.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; public class StudentAttributesTest { From abec2215a764cecd496f6f8ffab4db849ac5bde8 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 29 Mar 2024 16:28:15 +0800 Subject: [PATCH 134/503] Revert changes made to InputParsing --- src/main/java/classify/user/InputParsing.java | 14 +++---- .../student/StudentAttributesTest.java | 37 +++++++++++-------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 83e2651b0e..ea6450dd5d 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -53,15 +53,11 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas // @@author tayponghee switch (userCommand[0]) { case ADD: - if (userCommand.length >= 2) { - AddStudent.addStudent(masterStudentList, in, userCommand[1]); - //@@author ParthGandhiNUS - assert masterStudentList != null; - DataHandler.writeStudentInfo(masterStudentList); - //@@ author tayponghee - } else { - System.out.println("Invalid command: Not enough arguments for 'add'."); - } + AddStudent.addStudent(masterStudentList, in, userCommand[1]); + //@@author ParthGandhiNUS + assert masterStudentList != null; + DataHandler.writeStudentInfo(masterStudentList); + //@@ author tayponghee break; case VIEW: diff --git a/src/test/java/classify/student/StudentAttributesTest.java b/src/test/java/classify/student/StudentAttributesTest.java index 6fd7402552..65a297f7fb 100644 --- a/src/test/java/classify/student/StudentAttributesTest.java +++ b/src/test/java/classify/student/StudentAttributesTest.java @@ -8,11 +8,16 @@ public class StudentAttributesTest { + public static final String JOHN_DOE = "John Doe"; + public static final String MATH = "Math"; + public static final String JANE_SMITH = "Jane Smith"; + public static final String SCIENCE = "Science"; + @Test public void testAddSubjectGrade() { - Student student = new Student("John Doe"); + Student student = new Student(JOHN_DOE); StudentAttributes attributes = new StudentAttributes(student); - SubjectGrade subjectGrade = new SubjectGrade("Math", 90.5, 20); + SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); attributes.addSubjectGrade(subjectGrade); @@ -22,57 +27,57 @@ public void testAddSubjectGrade() { @Test public void testGetName() { - Student student = new Student("John Doe"); + Student student = new Student(JOHN_DOE); StudentAttributes attributes = new StudentAttributes(student); - assertEquals("John Doe", attributes.getName()); + assertEquals(JOHN_DOE, attributes.getName()); } @Test public void testSetName() { - Student student = new Student("John Doe"); + Student student = new Student(JOHN_DOE); StudentAttributes attributes = new StudentAttributes(student); - attributes.setName("Jane Smith"); + attributes.setName(JANE_SMITH); - assertEquals("Jane Smith", attributes.getName()); + assertEquals(JANE_SMITH, attributes.getName()); } @Test public void testGetSubject() { - SubjectGrade subjectGrade = new SubjectGrade("Math", 90.5, 20); - assertEquals("Math", subjectGrade.getSubject()); + SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); + assertEquals(MATH, subjectGrade.getSubject()); } @Test public void testGetGrade() { - SubjectGrade subjectGrade = new SubjectGrade("Math", 90.5, 20); + SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); assertEquals(90.5, subjectGrade.getGrade()); } @Test public void testGetClassesAttended() { - SubjectGrade subjectGrade = new SubjectGrade("Math", 90.5, 20); + SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); assertEquals(20, subjectGrade.getClassesAttended()); } @Test public void testSetSubject() { - SubjectGrade subjectGrade = new SubjectGrade("Math", 90.5, 20); - subjectGrade.setSubject("Science"); - assertEquals("Science", subjectGrade.getSubject()); + SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); + subjectGrade.setSubject(SCIENCE); + assertEquals(SCIENCE, subjectGrade.getSubject()); } @Test public void testSetGrade() { - SubjectGrade subjectGrade = new SubjectGrade("Math", 90.5, 20); + SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); subjectGrade.setGrade(85.0); assertEquals(85.0, subjectGrade.getGrade()); } @Test public void testSetClassesAttended() { - SubjectGrade subjectGrade = new SubjectGrade("Math", 90.5, 20); + SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); subjectGrade.setClassesAttended(25); assertEquals(25, subjectGrade.getClassesAttended()); } From 20e057ad8e1c5d08b8b1d96fa2cff53da3d8705d Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 29 Mar 2024 16:47:21 +0800 Subject: [PATCH 135/503] Update help command and related test --- src/main/java/classify/user/Ui.java | 14 ++++++++++---- src/test/java/classify/user/InputParsingTest.java | 7 +++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/user/Ui.java index 2e5a97ae5f..b1648a4a08 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/user/Ui.java @@ -71,9 +71,10 @@ public static void printHelp() { printEditHelpMessage(); printViewHelpMessage(); printDeleteHelpMessage(); + printRestoreHelpMessage(); + printUndoHelpMessage(); printListHelpMessage(); printByeHelpMessage(); - printSortNameMessage(); printSortHelpMessage(); System.out.println("help Prints this help message"); } @@ -83,9 +84,14 @@ private static void printSortHelpMessage() { " attribute to sort by, can be used directly by sort [type]."); System.out.println(" Currently available types: name, classes, payment"); } - //@@ author tayponghee - private static void printSortNameMessage() { - System.out.println("sort_name sorts the students by name lexicographically"); + + private static void printRestoreHelpMessage() { + System.out.println("restore Restore a student deleted within the current session, expects" + + " a name, can be used directly by restore [name]."); + } + + private static void printUndoHelpMessage() { + System.out.println("undo Restores the last student deleted in the current session."); } //@@ author Cryolian diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index 9d4c4eb3bc..971d882d72 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -86,12 +86,15 @@ public void testHelpCommand() { "delete Deletes a student from the student list, expects a name" + ", can be used directly with a name e.g. add [name]" + System.lineSeparator() + + "restore Restore a student deleted within the current session, expects a name, " + + "can be used directly by restore [name]." + + System.lineSeparator() + + "undo Restores the last student deleted in the current session." + + System.lineSeparator() + "list Displays the list of all students" + System.lineSeparator() + "bye Exits Classify" + System.lineSeparator() + - "sort_name sorts the students by name lexicographically" - + System.lineSeparator() + "sort Sorts the student list by the input parameter, expects an" + " attribute to sort by, can be used directly by sort [type]." + System.lineSeparator() + From 19369105b1106a59c4979f4913973691c044d7cc Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 29 Mar 2024 16:50:42 +0800 Subject: [PATCH 136/503] Add to DG --- docs/DeveloperGuide.md | 19 +++++++++++++++++++ .../src/InputParsing/InputParsing.puml | 4 +++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 4334f46540..c1bcb421c5 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -118,6 +118,25 @@ Contains the restore student list method which is used to restore the previously Contains the relevant methods to make the required file directories for storing the text file. It checks for existing folders. If not found, it makes new folders to store text files properly. +### AddStudent Component + +The `AddStudent` class is responsible for adding a new student to the list of students. It ensures that no two students with the same name are added and checks if the attributes added are in the correct format. + +#### Design Considerations + +- **Handling Duplicate Names**: The class checks if a student with the same name already exists in the master list before adding a new student. +- **Input Validation**: It validates the format of input attributes such as the name, phone number, gender, last payment date, and remarks. +- **Modular Approach**: The class is designed with modularity in mind, allowing easy addition of new attributes or modifications in the future. + +#### Implementation and Rationale + +- **Name Validation**: The `checkForEmptyName` method ensures that the name provided by the user is not empty and does not already exist in the master student list. +- **Attribute Validation**: Various methods such as `promptForPhoneNumber`, `promptForGender`, `promptForLastPaymentDate`, and `promptForRemarks` validate the format of different attributes. +- **Adding Subjects**: The `addSubject` method allows users to add multiple subjects along with their grades and classes attended for each student. +- **Error Handling**: The class provides appropriate error messages if invalid input or duplicate names are encountered. + +The `AddStudent` class contributes to the overall functionality of the application by providing a streamlined process for adding new students and ensuring data integrity within the student database. + --- ## Product scope diff --git a/docs/diagrams/src/InputParsing/InputParsing.puml b/docs/diagrams/src/InputParsing/InputParsing.puml index 4143affa23..10b0ae5f77 100644 --- a/docs/diagrams/src/InputParsing/InputParsing.puml +++ b/docs/diagrams/src/InputParsing/InputParsing.puml @@ -35,4 +35,6 @@ UserInput ...l> Ui InputParsing ...r> Ui InputParsing ..> student -note "Inconsequential methods and attributes omitted" as N1 \ No newline at end of file +note "Inconsequential methods and attributes omitted" as N1 + +@enduml From 932b51fbdb542b59f3ecdcaa1c04c65eda873ff1 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Fri, 29 Mar 2024 19:31:11 +0800 Subject: [PATCH 137/503] Refactor file IO class --- src/main/java/classify/Classify.java | 12 +-- .../datacommands/ArchiveCommands.java | 41 +++++++++ .../commands/datacommands/DataCommands.java | 40 +++++++++ .../deletecommands}/DeleteCommands.java | 38 ++++---- .../{datacommands => data}/DataReader.java | 52 ++++++++--- src/main/java/classify/data/DataWriter.java | 68 +++++++++++++++ .../classify/datacommands/DataHandler.java | 72 ---------------- .../classify/datacommands/DataStorage.java | 66 -------------- .../java/classify/student/AddStudent.java | 36 ++++---- .../java/classify/student/StudentSorter.java | 14 +-- .../java/classify/student/ViewStudent.java | 28 +++--- src/main/java/classify/ui/DataUI.java | 44 ++++++++++ .../classify/{user/Ui.java => ui/UI.java} | 5 +- src/main/java/classify/user/InputParsing.java | 86 ++++++++++--------- .../java/classify/user/InputParsingTest.java | 2 +- 15 files changed, 348 insertions(+), 256 deletions(-) create mode 100644 src/main/java/classify/commands/datacommands/ArchiveCommands.java create mode 100644 src/main/java/classify/commands/datacommands/DataCommands.java rename src/main/java/classify/{user => commands/deletecommands}/DeleteCommands.java (72%) rename src/main/java/classify/{datacommands => data}/DataReader.java (54%) create mode 100644 src/main/java/classify/data/DataWriter.java delete mode 100644 src/main/java/classify/datacommands/DataHandler.java delete mode 100644 src/main/java/classify/datacommands/DataStorage.java create mode 100644 src/main/java/classify/ui/DataUI.java rename src/main/java/classify/{user/Ui.java => ui/UI.java} (99%) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index a7dd964174..962244dc0c 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -1,9 +1,9 @@ package classify; -import classify.datacommands.DataHandler; +import classify.commands.datacommands.DataCommands; import classify.student.StudentList; import classify.user.InputParsing; -import classify.user.Ui; +import classify.ui.UI; import classify.user.UserInput; import java.io.IOException; @@ -21,9 +21,9 @@ public class Classify { public static void main(String[] args) throws IOException { // @@author ParthGandhiNUS - Ui.printWelcomeMessage(); - Ui.printUserPrompt(); - DataHandler.readStudentInfo(); + UI.printWelcomeMessage(); + UI.printUserPrompt(); + DataCommands.readStudentInfo(); // Takes in input from the user, and processes input to determine if it contains a command and a name String[] userCommand = UserInput.processInput(in.nextLine()); @@ -36,7 +36,7 @@ public static void main(String[] args) throws IOException { userCommand = UserInput.processInput(in.nextLine()); } - Ui.printEndConversation(); + UI.printEndConversation(); } } diff --git a/src/main/java/classify/commands/datacommands/ArchiveCommands.java b/src/main/java/classify/commands/datacommands/ArchiveCommands.java new file mode 100644 index 0000000000..14b5404461 --- /dev/null +++ b/src/main/java/classify/commands/datacommands/ArchiveCommands.java @@ -0,0 +1,41 @@ +package classify.commands.datacommands; + +import classify.data.DataReader; +import classify.data.DataWriter; +import classify.student.Student; +import classify.ui.DataUI; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +//@@author blackmirag3 +public class ArchiveCommands { + private static final String ARCHIVE_DIRECTORY_PATH = "data/archive"; + private static final String ARCHIVE_FILE_PATH = ARCHIVE_DIRECTORY_PATH + "/student_archive.txt"; + + /** + * This accesses Student_Information.txt and calls the restoreStudentList function + * + * @throws IOException When unable to get the Student_Information.txt file or has any input errors + */ + public void readArchive() throws IOException { + try{ + DataWriter.createParentFileFolder(ARCHIVE_DIRECTORY_PATH); + DataReader.initialiseData(ARCHIVE_DIRECTORY_PATH, ARCHIVE_FILE_PATH); + } catch (IOException e) { + DataUI.printCreateFailure(); + throw e; + } + } + + /** + * writes student info arraylist into archive file and creates new archive file if one is not found + * + * @param list ArrayList containing the current students to write + */ + public static void writeArchive(List list){ + DataWriter.writeStudentInfoFile(list, ARCHIVE_DIRECTORY_PATH, ARCHIVE_FILE_PATH); + } +} diff --git a/src/main/java/classify/commands/datacommands/DataCommands.java b/src/main/java/classify/commands/datacommands/DataCommands.java new file mode 100644 index 0000000000..38696cbb93 --- /dev/null +++ b/src/main/java/classify/commands/datacommands/DataCommands.java @@ -0,0 +1,40 @@ +package classify.commands.datacommands; + +import classify.data.DataReader; +import classify.data.DataWriter; +import classify.student.Student; +import classify.ui.DataUI; + +import java.io.IOException; +import java.util.List; + +//@@author ParthGandhiNUS +public class DataCommands { + private static final String DATA_DIRECTORY_PATH = "data/studentInfo"; + private static final String DATA_FILE_PATH = DATA_DIRECTORY_PATH + "/Student_Information.txt"; + + /** + * Function which is called to generate an arrayList "lines" which updates according to the users' inputs. + * Calls the writeStudentInfoFile function to update Student_Information.txt + * + * @param list ArrayList containing the current students + */ + public static void writeStudentInfo(List list){ + DataWriter.writeStudentInfoFile(list, DATA_DIRECTORY_PATH, DATA_FILE_PATH); + } + + /** + * This accesses Student_Information.txt and calls the restoreStudentList function + * + * @throws IOException When unable to get the Student_Information.txt file or has any input errors + */ + public static void readStudentInfo() throws IOException{ + try{ + DataWriter.createParentFileFolder(DATA_DIRECTORY_PATH); + DataReader.initialiseData(DATA_DIRECTORY_PATH, DATA_FILE_PATH); + } catch (IOException e) { + DataUI.printCreateFailure(); + throw e; + } + } +} diff --git a/src/main/java/classify/user/DeleteCommands.java b/src/main/java/classify/commands/deletecommands/DeleteCommands.java similarity index 72% rename from src/main/java/classify/user/DeleteCommands.java rename to src/main/java/classify/commands/deletecommands/DeleteCommands.java index 3b59470999..a5dda49d99 100644 --- a/src/main/java/classify/user/DeleteCommands.java +++ b/src/main/java/classify/commands/deletecommands/DeleteCommands.java @@ -1,6 +1,8 @@ -package classify.user; +package classify.commands.deletecommands; import classify.student.Student; +import classify.user.InputParsing; +import classify.ui.UI; import java.util.ArrayList; import java.util.Scanner; @@ -17,11 +19,11 @@ public class DeleteCommands { * @param studentName The name of the student if the user had entered it * before being prompted */ - static void deleteStudent(ArrayList masterStudentList, ArrayList recentlyDeletedList, - Scanner in, String studentName) { + public static void deleteStudent(ArrayList masterStudentList, ArrayList recentlyDeletedList, + Scanner in, String studentName) { String name; if (studentName == null) { - Ui.printStudentNamePrompt(); + UI.printStudentNamePrompt(); name = in.nextLine().trim(); } else { name = studentName; @@ -30,12 +32,12 @@ static void deleteStudent(ArrayList masterStudentList, ArrayList masterStudentList, ArrayList masterStudentList, ArrayList recentlyDeletedList, - Scanner in, String studentName) { + public static void restoreStudent(ArrayList masterStudentList, ArrayList recentlyDeletedList, + Scanner in, String studentName) { String name; if (studentName == null) { - Ui.printStudentNamePrompt(); + UI.printStudentNamePrompt(); name = in.nextLine().trim(); } else { name = studentName; @@ -64,12 +66,12 @@ static void restoreStudent(ArrayList masterStudentList, ArrayList masterStudentList, ArrayList masterStudentList, ArrayList recentlyDeletedList) { + public static void undoDelete(ArrayList masterStudentList, ArrayList recentlyDeletedList) { if (recentlyDeletedList.isEmpty()) { - Ui.printNoDeleteFound(); - Ui.printDivider(); + UI.printNoDeleteFound(); + UI.printDivider(); return; } Student student = recentlyDeletedList.get(recentlyDeletedList.size() - 1); masterStudentList.add(student); recentlyDeletedList.remove(student); - Ui.printDeleteUndone(); - Ui.printDivider(); + UI.printDeleteUndone(); + UI.printDivider(); } } diff --git a/src/main/java/classify/datacommands/DataReader.java b/src/main/java/classify/data/DataReader.java similarity index 54% rename from src/main/java/classify/datacommands/DataReader.java rename to src/main/java/classify/data/DataReader.java index 9ac81e7aa8..5b18f61206 100644 --- a/src/main/java/classify/datacommands/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -1,9 +1,17 @@ -package classify.datacommands; +package classify.data; import classify.student.Student; +import classify.student.StudentList; +import classify.ui.DataUI; import classify.user.InputParsing; -import classify.user.Ui; +import classify.ui.UI; +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Scanner; import java.util.logging.Level; @@ -14,37 +22,55 @@ public class DataReader { private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); public static Scanner in = new Scanner(System.in); - + //@@author ParthGandhiNUS /** * Method restores the previous student list by accessing the * line-by-line information in the Student_Information.txt - * + * * @param studentFileInput Line-by-line information of strings in the Student_Information.txt * @param masterStudentList The list of all students */ public static void restoreStudentList(String studentFileInput, ArrayList masterStudentList ){ - + if (studentFileInput != null){ if (InputParsing.findStudentByName(masterStudentList, studentFileInput) != null) { assert InputParsing.findStudentByName(masterStudentList, studentFileInput) != null; logger.log(Level.WARNING, "Student with the same name already exists."); - - Ui.printSameNameError(); - Ui.printDivider(); + + UI.printSameNameError(); + UI.printDivider(); return; } Student student = new Student(studentFileInput); - + masterStudentList.add(student); logger.log(Level.INFO, "Student added successfully."); - Ui.printStudentAdded(); - Ui.printDivider(); + UI.printStudentAdded(); + UI.printDivider(); } } - -} + public static void initialiseData(String directoryPath, String filePath) throws IOException { + Path directory = Paths.get(directoryPath); + if (!Files.exists(directory)) { + DataUI.printCreatingDirectory(); + Files.createFile(directory); + } else { + FileReader fileReader = new FileReader(filePath); + BufferedReader line = new BufferedReader(fileReader); + DataUI.printRetrieveData(); + + while (line.ready()) { + restoreStudentList(line.readLine(), StudentList.masterStudentList); + } + line.close(); + + DataUI.printLoadSuccess(); + UI.printDivider(); + } + } +} diff --git a/src/main/java/classify/data/DataWriter.java b/src/main/java/classify/data/DataWriter.java new file mode 100644 index 0000000000..09f525e21d --- /dev/null +++ b/src/main/java/classify/data/DataWriter.java @@ -0,0 +1,68 @@ +package classify.data; + +import classify.student.Student; +import classify.ui.DataUI; +import classify.ui.UI; + +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + + +//@@author ParthGandhiNUS +public class DataWriter { + private static final String NEWLINE = "\n"; + + //@@author ParthGandhiNUS + /** + * Accesses the parent directory to try to make the parent directory. + * Tries to write the lines which are made by the writeStudentInfo Method + * + * @param list list ArrayList containing the current students + */ + public static void writeStudentInfoFile(List list, String folderPath, String filePath){ + List lines = new ArrayList<>(); + + for (Student student:list){ + lines.add(student.textFileInputString()); + } + DataUI.printAnalysingInput(); + + try { + createParentFileFolder(folderPath); + FileWriter studentInfoWriter = new FileWriter(filePath); + for (String line : lines){ + studentInfoWriter.write(line + NEWLINE); + } + DataUI.printUpdateSuccess(); + UI.printDivider(); + studentInfoWriter.close(); + } catch (IOException e){ + DataUI.printFileIOError(); + } + } + + /** + * Used to create the parent folder for a certain file + * + * @param parentPath Path file containing the path of folder we want to make the text file in + * @throws IOException Triggers whenever the input for the path or creation of the directory is improper + */ + public static void createParentFileFolder (String parentPath) throws IOException { + try{ + Path path = Paths.get(parentPath); + Files.createDirectories(path); + DataUI.printDirectorySuccess(); + } catch (FileAlreadyExistsException ignored){ + //Ignore this error as this should not cause any issues, we dont want replicas of the same file + } catch (IOException e){ + DataUI.printCreateFailure(); + throw e; + } + } +} diff --git a/src/main/java/classify/datacommands/DataHandler.java b/src/main/java/classify/datacommands/DataHandler.java deleted file mode 100644 index ef8c5fccab..0000000000 --- a/src/main/java/classify/datacommands/DataHandler.java +++ /dev/null @@ -1,72 +0,0 @@ -package classify.datacommands; - -import classify.student.Student; -import classify.student.StudentList; -import classify.user.Ui; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.List; - -//@@author ParthGandhiNUS -public class DataHandler { - private static final String ANALYSING_INPUT_MESSAGE = "Analysing Inputs..."; - private static final String STUDENT_INFO_FILE_FOLDER = "data/studentInfo"; - private static final String STUDENT_INFO_TEXT_FILE = "data/studentInfo/Student_Information.txt"; - private static final String CREATE_NEW_STUDENT_INFO_FILE = "Creating a new Student Info File..."; - private static final String CREATE_NEW_STUDENT_INFO_FILE_SUCCESS = "Created a new student info file successfully!"; - private static final String CREATE_NEW_STUDENT_INFO_FILE_FAILURE = "Unable to create a new student info file!"; - private static final String RETRIEVING_PREVIOUS_STUDENT_DATA = "Now getting previous Student Info Records..."; - - //@@author ParthGandhiNUS - /** - * Function which is called to generate an arrayList "lines" which updates according to the users' inputs. - * Calls the writeStudentInfoFile function to update Student_Information.txt - * - * @param newList ArrayList containing the current students - */ - public static void writeStudentInfo(List newList){ - List lines = new ArrayList<>(); - for (Student student:newList){ - lines.add(student.textFileInputString()); - } - System.out.println(ANALYSING_INPUT_MESSAGE); - DataStorage.writeStudentInfoFile(lines); - } - - /** - * This accesses Student_Information.txt and calls the restoreStudentList function - * - * @throws IOException When unable to get the Student_Information.txt file or has any input errors - */ - public static void readStudentInfo() throws IOException{ - try{ - DataStorage.createParentFileFolder(Paths.get(STUDENT_INFO_FILE_FOLDER)); - Path studentInfoFilePath = Paths.get(STUDENT_INFO_TEXT_FILE); - if (!Files.exists(studentInfoFilePath)){ - System.out.println(CREATE_NEW_STUDENT_INFO_FILE); - Files.createFile(studentInfoFilePath); - } - - FileReader fileReader = new FileReader(STUDENT_INFO_TEXT_FILE); - BufferedReader line = new BufferedReader(fileReader); - System.out.println(RETRIEVING_PREVIOUS_STUDENT_DATA); - - while (line.ready()){ - DataReader.restoreStudentList(line.readLine(), StudentList.masterStudentList); - } - - System.out.println(CREATE_NEW_STUDENT_INFO_FILE_SUCCESS); - Ui.printDivider(); - line.close(); - } catch (IOException e) { - System.out.println(CREATE_NEW_STUDENT_INFO_FILE_FAILURE); - throw e; - } - } -} diff --git a/src/main/java/classify/datacommands/DataStorage.java b/src/main/java/classify/datacommands/DataStorage.java deleted file mode 100644 index add00cfce5..0000000000 --- a/src/main/java/classify/datacommands/DataStorage.java +++ /dev/null @@ -1,66 +0,0 @@ -package classify.datacommands; - -import classify.user.Ui; - -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.FileAlreadyExistsException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; - - -//@@author ParthGandhiNUS -public class DataStorage { - private static final String NEWLINE = "\n"; - private static final String STUDENT_INFO_FILE_FOLDER = "data/studentInfo"; - private static final String STUDENT_INFO_TEXT_FILE = "data/studentInfo/Student_Information.txt"; - private static final String FAILURE_TO_CREATE_PARENT_FOLDER_DIRECTORY = - "Failure to create the parent folder directory!"; - private static final String SUCCESSFULLY_UPDATE_STUDENT_RECORDS = "Updated Student Records successfully!"; - private static final String ISSUE_WITH_FOLDER_OR_TEXTFILE = "Issue with directory/text file. Please check!"; - - - //@@author ParthGandhiNUS - /** - * Accesses the parent directory to try to make the parent directory. - * Tries to write the lines which are made by the writeStudentInfo Method - * - * @param lines Arraylist containing the processed current tasks in the masterStudentList - */ - public static void writeStudentInfoFile(List lines){ - try { - Path studentInfoFolder = Paths.get(STUDENT_INFO_FILE_FOLDER); - createParentFileFolder(studentInfoFolder); - - FileWriter studentInfoWriter = new FileWriter(STUDENT_INFO_TEXT_FILE); - for (String line : lines){ - studentInfoWriter.write(line + NEWLINE); - } - - System.out.println(SUCCESSFULLY_UPDATE_STUDENT_RECORDS); - Ui.printDivider(); - studentInfoWriter.close(); - } catch (IOException e){ - System.out.println(ISSUE_WITH_FOLDER_OR_TEXTFILE); - } - } - - /** - * Used to create the parent folder for a certain file - * - * @param parentPath Path file containing the path of folder we want to make the text file in - * @throws IOException Triggers whenever the input for the path or creation of the directory is improper - */ - public static void createParentFileFolder (Path parentPath) throws IOException { - try{ - Files.createDirectories(parentPath); - } catch (FileAlreadyExistsException ignored){ - //Ignore this error as this should not cause any issues, we dont want replicas of the same file - } catch (IOException e){ - System.out.println(FAILURE_TO_CREATE_PARENT_FOLDER_DIRECTORY); - throw e; - } - } -} diff --git a/src/main/java/classify/student/AddStudent.java b/src/main/java/classify/student/AddStudent.java index c2de0cca8b..d8aea0a152 100644 --- a/src/main/java/classify/student/AddStudent.java +++ b/src/main/java/classify/student/AddStudent.java @@ -1,7 +1,7 @@ package classify.student; -import classify.user.Ui; +import classify.ui.UI; import classify.user.InputParsing; import java.util.ArrayList; import java.util.Scanner; @@ -40,8 +40,8 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, assert InputParsing.findStudentByName(masterStudentList, name) != null; LOGGER.log(Level.WARNING, STUDENT_WITH_THE_SAME_NAME_ALREADY_EXISTS); - Ui.printSameNameError(); - Ui.printDivider(); + UI.printSameNameError(); + UI.printDivider(); return; } @@ -60,20 +60,20 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, //@@author Cryolian student.getAttributes().setPhoneNumber(number); - Ui.promptForGender(); + UI.promptForGender(); student.getAttributes().setGender(InputParsing.readInString(in)); - Ui.promptForLastPaymentDate(); + UI.promptForLastPaymentDate(); student.getAttributes().setLastPaymentDate(InputParsing.readInDate(in)); - Ui.promptForRemarks(); + UI.promptForRemarks(); student.getAttributes().setRemarks(InputParsing.readInString(in)); //@@author tayponghee masterStudentList.add(student); LOGGER.log(Level.INFO, STUDENT_ADDED_SUCCESSFULLY); - Ui.printStudentAdded(); - Ui.printDivider(); + UI.printStudentAdded(); + UI.printDivider(); } /** @@ -94,7 +94,7 @@ private static String checkForEmptyName(ArrayList masterStudentList, Sc //@@author alalal47 if (studentName == null) { - Ui.printStudentNamePrompt(); + UI.printStudentNamePrompt(); name = in.nextLine().trim(); } else { name = studentName.trim(); @@ -105,8 +105,8 @@ private static String checkForEmptyName(ArrayList masterStudentList, Sc assert studentName != null; if (name.isEmpty()) { - Ui.printEmptyNameMessage(); - Ui.printDivider(); + UI.printEmptyNameMessage(); + UI.printDivider(); } else { break; } @@ -130,13 +130,13 @@ public static void addSubject(Scanner in, StudentAttributes attributes) { String subject = in.nextLine().trim(); if (subject.isBlank()) { - Ui.printNoSubjectsAdded(); + UI.printNoSubjectsAdded(); break; } else if (attributes.findSubject(subject) != null) { // rejects subject if existing subject of same name exists in students' // attributes - Ui.printSubjectAlreadyExists(); + UI.printSubjectAlreadyExists(); break; } else if (checkForValidSubjectResponse(in, attributes, subject)) { @@ -162,7 +162,7 @@ private static boolean checkForValidSubjectResponse(Scanner in, StudentAttribute attributes.addSubjectGrade(subjectGrade); while (true) { - Ui.printAddSubject(); + UI.printAddSubject(); String response = in.nextLine().trim().toLowerCase(); if (response.equals(YES)) { @@ -172,7 +172,7 @@ private static boolean checkForValidSubjectResponse(Scanner in, StudentAttribute return true; } else { - Ui.printInvalidResponse(); + UI.printInvalidResponse(); } } @@ -188,7 +188,7 @@ private static boolean checkForValidSubjectResponse(Scanner in, StudentAttribute */ public static int promptForClassesAttended(Scanner in) { while (true) { - Ui.printClassesAttendedPrompt(); + UI.printClassesAttendedPrompt(); String classesAttendedInput = in.nextLine(); if (classesAttendedInput.isBlank()) { @@ -201,9 +201,9 @@ public static int promptForClassesAttended(Scanner in) { classesAttended = Integer.parseInt(classesAttendedInput); } catch (NumberFormatException e) { //@@author tayponghee - Ui.printWrongNumberFormat(); + UI.printWrongNumberFormat(); //@@author ParthGandhiNus - Ui.printDivider(); + UI.printDivider(); classesAttended = promptForClassesAttended(in); } diff --git a/src/main/java/classify/student/StudentSorter.java b/src/main/java/classify/student/StudentSorter.java index ed562bff23..81644fa75e 100644 --- a/src/main/java/classify/student/StudentSorter.java +++ b/src/main/java/classify/student/StudentSorter.java @@ -1,6 +1,6 @@ package classify.student; -import classify.user.Ui; +import classify.ui.UI; import java.util.ArrayList; import java.util.List; @@ -27,7 +27,7 @@ public class StudentSorter { */ public static void sortByChoice(ArrayList masterStudentList, String choice, Scanner in) { while (!isValidChoice(choice)) { - Ui.println(INVALID_CHOICE); + UI.println(INVALID_CHOICE); choice = in.nextLine().trim(); } @@ -53,7 +53,7 @@ public static void sortByChoice(ArrayList masterStudentList, String cho break; //@@author tayponghee default: - Ui.println(INVALID_CHOICE); + UI.println(INVALID_CHOICE); break; } } @@ -77,7 +77,7 @@ public static boolean isValidChoice(String choice) { private static void listStudentsByName(ArrayList masterStudentList) { masterStudentList.sort(StudentComparators.nameComparator); listStudents(masterStudentList); - Ui.printDivider(); + UI.printDivider(); } /** @@ -101,7 +101,7 @@ private static void listStudentsByTotalClasses(ArrayList masterStudentL masterStudentList.sort(StudentComparators.classesAttendedComparator); listStudentsWithTotalClasses(masterStudentList); - Ui.printDivider(); + UI.printDivider(); } //@@author alalal47 @@ -113,7 +113,7 @@ private static void listStudentsByTotalClasses(ArrayList masterStudentL private static void listStudentsByLastPaidDate(ArrayList masterStudentList) { masterStudentList.sort(StudentComparators.lastPaidDateComparator); listStudentsWithLastPaidDate(masterStudentList); - Ui.printDivider(); + UI.printDivider(); } //@@author tayponghee @@ -123,7 +123,7 @@ private static void listStudentsByLastPaidDate(ArrayList masterStudentL * @param students The list of students to be listed. */ private static void listStudents(ArrayList students) { - Ui.printStudentList(students); + UI.printStudentList(students); } /** diff --git a/src/main/java/classify/student/ViewStudent.java b/src/main/java/classify/student/ViewStudent.java index 092b899ab7..e6e6ca69e9 100644 --- a/src/main/java/classify/student/ViewStudent.java +++ b/src/main/java/classify/student/ViewStudent.java @@ -1,6 +1,6 @@ package classify.student; -import classify.user.Ui; +import classify.ui.UI; import classify.user.InputParsing; import java.util.ArrayList; @@ -28,7 +28,7 @@ public static void viewStudent(ArrayList masterStudentList, Scanner in, //@@ author alalal47 if (studentName == null) { - Ui.printStudentNamePrompt(); + UI.printStudentNamePrompt(); name = in.nextLine(); } else { name = studentName; @@ -42,19 +42,19 @@ public static void viewStudent(ArrayList masterStudentList, Scanner in, if (foundStudent != null) { logger.log(Level.INFO, "Viewing student details: " + name); - Ui.printDivider(); - Ui.printStudentDetails(); - Ui.printStudentName(name); - Ui.printStudentDetails(foundStudent); + UI.printDivider(); + UI.printStudentDetails(); + UI.printStudentName(name); + UI.printStudentDetails(foundStudent); StudentAttributes attributes = foundStudent.getAttributes(); showAttributes(attributes); int totalClassesAttended = getTotalClassesAttended(foundStudent); - Ui.printTotalClassesAttended(totalClassesAttended); + UI.printTotalClassesAttended(totalClassesAttended); } else { logger.log(Level.WARNING, "Student not found: " + name); - Ui.printStudentNotFound(); + UI.printStudentNotFound(); } } @@ -82,7 +82,7 @@ public static void showAttributes(StudentAttributes attributes) { List subjectGrades = attributes.getSubjectGrades(); checkIfSubjectGradesIsEmpty(subjectGrades); } else { - Ui.printNullAttributeError(); + UI.printNullAttributeError(); } } @@ -90,17 +90,17 @@ private static void checkIfSubjectGradesIsEmpty(List subjectGrades if (!subjectGrades.isEmpty()) { printSubjectAttributes(subjectGrades); } else { - Ui.printEmptySubjectError(); + UI.printEmptySubjectError(); } } private static void printSubjectAttributes(List subjectGrades) { for (SubjectGrade subjectGrade : subjectGrades) { assert subjectGrade != null : "subjectGrade cannot be null"; - Ui.printSubjectName(subjectGrade.getSubject()); - Ui.printStudentGrades(subjectGrade.getGrade()); - Ui.printClassesAttended(subjectGrade.getClassesAttended()); - Ui.printDivider(); + UI.printSubjectName(subjectGrade.getSubject()); + UI.printStudentGrades(subjectGrade.getGrade()); + UI.printClassesAttended(subjectGrade.getClassesAttended()); + UI.printDivider(); } } diff --git a/src/main/java/classify/ui/DataUI.java b/src/main/java/classify/ui/DataUI.java new file mode 100644 index 0000000000..9a6b7203aa --- /dev/null +++ b/src/main/java/classify/ui/DataUI.java @@ -0,0 +1,44 @@ +package classify.ui; + +//@@author blackmirag3 +public class DataUI extends UI { + //@@author ParthGandhiNUS + private static final String ANALYSING_INPUT_MESSAGE = "Analysing Inputs..."; + private static final String CREATING_DIRECTORY_MESSAGE = "Creating a new directory..."; + private static final String DIRECTORY_SUCCESS_MESSAGE = "Directory loaded successfully!"; + private static final String CREATE_FAILURE_MESSAGE = "Unable to create a new file/directory!"; + private static final String RETRIEVING_DATA_MESSAGE = "Retrieving data..."; + private static final String LOAD_DATA_SUCCESS_MESSAGE = "Data loaded sucessfully!"; + private static final String UPDATE_SUCCESS_MESSAGE = "Data update success!"; + private static final String FILE_IO_ERROR_MESSAGE = "File IO Error."; + + //@@author blackmirag3 + public static void printLoadSuccess() { + System.out.println(LOAD_DATA_SUCCESS_MESSAGE); + } + public static void printFileIOError() { + System.out.println(FILE_IO_ERROR_MESSAGE); + } + public static void printUpdateSuccess() { + System.out.println(UPDATE_SUCCESS_MESSAGE); + } + public static void printAnalysingInput() { + System.out.println(ANALYSING_INPUT_MESSAGE); + } + + public static void printCreatingDirectory() { + System.out.println(CREATING_DIRECTORY_MESSAGE); + } + + public static void printDirectorySuccess() { + System.out.println(DIRECTORY_SUCCESS_MESSAGE); + } + + public static void printCreateFailure() { + System.out.println(CREATE_FAILURE_MESSAGE); + } + + public static void printRetrieveData() { + System.out.println(RETRIEVING_DATA_MESSAGE); + } +} diff --git a/src/main/java/classify/user/Ui.java b/src/main/java/classify/ui/UI.java similarity index 99% rename from src/main/java/classify/user/Ui.java rename to src/main/java/classify/ui/UI.java index 2e5a97ae5f..62cf764503 100644 --- a/src/main/java/classify/user/Ui.java +++ b/src/main/java/classify/ui/UI.java @@ -1,11 +1,11 @@ -package classify.user; +package classify.ui; import classify.student.Student; import java.util.ArrayList; //@@author Cryolian -public class Ui { +public class UI { public static final String TOTAL_CLASSES_ATTENDED_ACROSS_ALL_SUBJECTS = "Total classes " + "attended across all subjects: "; private static final String EMPTY_SUBJECT_ERROR = "No subjects and grades found for this student."; @@ -213,6 +213,7 @@ public static void printStudentGradesPrompt() { System.out.println(STUDENT_GRADES_PROMPT); } + //@@ author tayponghee public static void printStudentList(ArrayList students) { System.out.println("List of Students:"); diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 83e2651b0e..20a184c78a 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -1,7 +1,8 @@ package classify.user; -import classify.datacommands.DataHandler; +import classify.commands.datacommands.DataCommands; +import classify.commands.deletecommands.DeleteCommands; import classify.student.AddStudent; import classify.student.Student; import classify.student.StudentAttributes; @@ -9,6 +10,7 @@ import classify.student.StudentSorter; import classify.student.SubjectGrade; import classify.student.ViewStudent; +import classify.ui.UI; import java.time.LocalDate; import java.time.format.DateTimeParseException; @@ -33,6 +35,7 @@ public class InputParsing { private static final String EDIT = "edit"; private static final String HELP = "help"; private static final String SORT = "sort"; + private static final String ARCHIVE = "archive"; private static final String VIEW_SUBJECT = "view_subject"; private static final String ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK = "Enter the subject name (type 'exit' to go back):"; @@ -57,7 +60,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas AddStudent.addStudent(masterStudentList, in, userCommand[1]); //@@author ParthGandhiNUS assert masterStudentList != null; - DataHandler.writeStudentInfo(masterStudentList); + DataCommands.writeStudentInfo(masterStudentList); //@@ author tayponghee } else { System.out.println("Invalid command: Not enough arguments for 'add'."); @@ -66,14 +69,14 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas case VIEW: ViewStudent.viewStudent(masterStudentList, in, userCommand[1]); - Ui.printDivider(); + UI.printDivider(); break; //@@author alalal47 case DELETE: DeleteCommands.deleteStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); // @@author ParthGandhiNUS - DataHandler.writeStudentInfo(masterStudentList); + DataCommands.writeStudentInfo(masterStudentList); //@@author alalal47 break; @@ -86,18 +89,14 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas break; case HELP: - Ui.printHelp(); - Ui.printDivider(); + UI.printHelp(); + UI.printDivider(); break; // @@author ParthGandhiNUS case BYE: - Ui.printEndConversation(); - DataHandler.writeStudentInfo(masterStudentList); - break; - - case EDIT: - editStudent(masterStudentList, in, userCommand[1]); + UI.printEndConversation(); + DataCommands.writeStudentInfo(masterStudentList); break; case LIST: @@ -113,8 +112,17 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas handleViewSubjectCommand(masterStudentList, in, userCommand[1]); break; + //@@author blackmirag3 + case EDIT: + editStudent(masterStudentList, in, userCommand[1]); + break; + + case ARCHIVE: + //todo + break; + default: - Ui.printWrongInput(); + UI.printWrongInput(); break; } } @@ -130,10 +138,10 @@ private static void sortStudents(ArrayList masterStudentList, Scanner i while (true) { //@@author alalal47 if (sortType == null) { - Ui.println(SORT_BY_CHOOSE_INDEX); - Ui.println(NAME_A_TO_Z); - Ui.println(TOTAL_NUMBER_OF_CLASSES_ATTENDED); - Ui.println(LAST_PAID_DATE); + UI.println(SORT_BY_CHOOSE_INDEX); + UI.println(NAME_A_TO_Z); + UI.println(TOTAL_NUMBER_OF_CLASSES_ATTENDED); + UI.println(LAST_PAID_DATE); input = in.nextLine().trim(); } else { input = sortType.trim().toLowerCase(); @@ -143,17 +151,17 @@ private static void sortStudents(ArrayList masterStudentList, Scanner i if (input.equalsIgnoreCase(EXIT)) { System.out.println(EXITED_THE_COMMAND); - Ui.printDivider(); + UI.printDivider(); return; } if (StudentSorter.isValidChoice(input)) { StudentSorter.sortByChoice(masterStudentList, input, in); - Ui.println(LIST_SORTED); + UI.println(LIST_SORTED); break; } else { sortType = null; - Ui.println(StudentSorter.INVALID_CHOICE); + UI.println(StudentSorter.INVALID_CHOICE); } } } @@ -190,7 +198,7 @@ private static void findStudentsWithSubject(ArrayList masterStudentList if (input.equalsIgnoreCase(EXIT)) { System.out.println(EXITED_THE_COMMAND); - Ui.printDivider(); + UI.printDivider(); return; } @@ -224,7 +232,7 @@ private static void viewStudentsBySubject(ArrayList masterStudentList, System.out.println("No students found with the subject: " + subject); } - Ui.printDivider(); + UI.printDivider(); } // @@author blackmirag3 @@ -232,12 +240,12 @@ private static void listStudents(ArrayList list) { StudentList.printCurrentArrayList(list); // @@author ParthGandhiNUS StudentList.printCurrentArrayMessage(list); - Ui.printDivider(); + UI.printDivider(); } private static void editStudent(ArrayList list, Scanner in, String name) { if (list.isEmpty()) { - Ui.printEmptyListError(); + UI.printEmptyListError(); return; } @@ -246,7 +254,7 @@ private static void editStudent(ArrayList list, Scanner in, String name if (name != null) { student = findStudentByName(list, name); if (student == null) { - Ui.printStudentNotFound(); + UI.printStudentNotFound(); } } @@ -265,7 +273,7 @@ private static void editStudent(ArrayList list, Scanner in, String name if (student != null) { break; } else { - Ui.printStudentNotFound(); + UI.printStudentNotFound(); } } @@ -277,11 +285,11 @@ private static void editStudentAttributes(Scanner in, Student student) { ViewStudent.showAttributes(attributes); while (true) { - Ui.printEditPrompt(); + UI.printEditPrompt(); String command = in.nextLine().trim(); if (command.isBlank()) { System.out.println("Exiting edit"); - Ui.printDivider(); + UI.printDivider(); return; } @@ -385,7 +393,7 @@ private static void deleteAttribute(Scanner in, StudentAttributes attributes) { */ public static double promptForGrade(Scanner in) { while (true) { - Ui.printStudentGradesPrompt(); + UI.printStudentGradesPrompt(); String gradeInput = in.nextLine(); if (gradeInput.isBlank()) { @@ -398,7 +406,7 @@ public static double promptForGrade(Scanner in) { grade = Double.parseDouble(gradeInput); } catch (NumberFormatException e) { System.out.println("Wrong number format! Please try again! e.g. 75 "); - Ui.printDivider(); + UI.printDivider(); grade = promptForGrade(in); } @@ -429,14 +437,14 @@ public static boolean isValidClassesAttended(int classesAttended) { try { if (classesAttended < 0) { System.out.println("Classes attended must be 0 or more."); - Ui.printDivider(); + UI.printDivider(); return false; } return true; } catch (NumberFormatException e) { LOGGER.log(Level.WARNING, "Invalid input for classes attended: " + classesAttended, e); System.out.println("Invalid input for classes attended. Please enter a valid whole number."); - Ui.printDivider(); + UI.printDivider(); return false; } } @@ -445,14 +453,14 @@ private static boolean isValidGrade(double grade) { try { if (grade < 0 || grade > 100) { System.out.println("Grade must be between 0 and 100. Please enter a valid number."); - Ui.printDivider(); + UI.printDivider(); return false; } return true; } catch (NumberFormatException e) { LOGGER.log(Level.WARNING, "Invalid input for grade: " + grade, e); - Ui.printValidNumberError(); - Ui.printDivider(); + UI.printValidNumberError(); + UI.printDivider(); return false; } } @@ -476,7 +484,7 @@ public static int promptForPhoneNumber(Scanner in) { try { do { - Ui.printPhoneNumberPrompt(); + UI.printPhoneNumberPrompt(); number = readInPhoneNumber(in); } while (!checkNumberValidity(number)); @@ -484,7 +492,7 @@ public static int promptForPhoneNumber(Scanner in) { return number; } catch (NumberFormatException e) { - Ui.printValidNumberError(); + UI.printValidNumberError(); } return -1; @@ -556,7 +564,7 @@ protected static LocalDate parseDateFromString(String string) { private static LocalDate invalidDatePath() { LOGGER.log(Level.WARNING, "Invalid date format entered." + '\n'); - Ui.printInvalidDateFormatError(); + UI.printInvalidDateFormatError(); return LocalDate.now().plusDays(2); } @@ -565,7 +573,7 @@ private static boolean isDateValid(LocalDate paymentDate) { if (paymentDate.isAfter(LocalDate.now().plusDays(1)) || paymentDate.isBefore(LocalDate.parse(EARLIER_POSSIBLE_DATE))) { - Ui.printInvalidDateRangeError(); + UI.printInvalidDateRangeError(); return false; } diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index 9d4c4eb3bc..74fe5b96dd 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -33,7 +33,7 @@ public void testByeCommand() { String printedOutput = outputStream.toString().trim(); String expectedOutput = "Hope you've had a productive day. See you again! Goodbye!" + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - + System.lineSeparator() + "Analysing Inputs..." + System.lineSeparator() + + System.lineSeparator() + "Updated Student Records successfully!"+System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; From 7a7cc803f3d68eeb76c21f826a0caa13057c1339 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Fri, 29 Mar 2024 19:36:05 +0800 Subject: [PATCH 138/503] Fix test cases bug --- .../java/classify/commands/datacommands/ArchiveCommands.java | 2 -- src/test/java/classify/user/InputParsingTest.java | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/classify/commands/datacommands/ArchiveCommands.java b/src/main/java/classify/commands/datacommands/ArchiveCommands.java index 14b5404461..14f94c27cc 100644 --- a/src/main/java/classify/commands/datacommands/ArchiveCommands.java +++ b/src/main/java/classify/commands/datacommands/ArchiveCommands.java @@ -6,8 +6,6 @@ import classify.ui.DataUI; import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; import java.util.List; //@@author blackmirag3 diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index 74fe5b96dd..4009e48b91 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -33,8 +33,9 @@ public void testByeCommand() { String printedOutput = outputStream.toString().trim(); String expectedOutput = "Hope you've had a productive day. See you again! Goodbye!" + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - + System.lineSeparator() - + "Updated Student Records successfully!"+System.lineSeparator() + + System.lineSeparator() + "Analysing Inputs..." + + System.lineSeparator() + "Directory loaded successfully!" + System.lineSeparator() + + "Data update success!" + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; assertEquals(expectedOutput.trim(), printedOutput); From c66a3ddb4b91257f282b14e25f013b01309fda04 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 30 Mar 2024 00:50:26 +0800 Subject: [PATCH 139/503] Add preface for User Guide --- docs/UserGuide.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 5c1e6d0e43..172681facc 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,5 +1,16 @@ # User Guide for **Classify** +## Preface +With the increased competititiveness of cohorts in Singapore, tuition centres have become more prevalent than ever before. + +According to a **[newspaper article](https://www.straitstimes.com/singapore/education/families-spent-14b-on-private-tuition-for-kids-last-year-as-parents-fork-out)** in The Straits Times, billions of dollars are spent in the tuition industry in Singapore every single year. + +These are just the numbers in Singapore. If we go to other countries, the situation is much worse. In India, new tuition centres preparing students for competitive entrance exams like JEE and NEET spring up every single day. + +In such a fast-growing market, it is important that these tuition centres use better and more efficient student management systems to increase efficiency and automation of manual laborious tasks. + +These systems enable tutors and administrative staff to focus on more pressing issues and work on catering to every students' needs instead of being swamped with paperwork. + ## Introduction Classify is a student management system meant to assist administrative staff of private tuition centres. From a14d3ba93c061914db5e1a5cbaae0cef44fa8b3e Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Sat, 30 Mar 2024 11:43:56 +0800 Subject: [PATCH 140/503] Add archive student method --- src/main/java/classify/user/InputParsing.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 20a184c78a..1e31fb2ba8 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -118,7 +118,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas break; case ARCHIVE: - //todo + archiveStudent(userCommand[1]); break; default: @@ -127,6 +127,13 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas } } + private static void archiveStudent(String name) { + while (name == null) { + System.out.println("enter student name"); + String input = in.nextLine().trim(); + } + } + /** * Sorts the list of students based on user input. * From e8c4383a7e0e5e8c8fc6e71b06728a7588afc9e8 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sat, 30 Mar 2024 20:05:47 +0800 Subject: [PATCH 141/503] Add descriptions for edit and sort commands. Fix Command Summary for sort command. --- docs/UserGuide.md | 83 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 172681facc..30fac364bb 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -60,7 +60,7 @@ Removes a student from the master list of students. Displays a list of all the students with that associated subject taken in the tuition centre. -### - Sort the list lexicograpically, from A to Z `sort name` +### - Sort the list lexicographically, from A to Z `sort name` Sorts the masterlist of students from A to Z. When the user types list, it will generate the updated sorted list. @@ -72,7 +72,7 @@ Sorts the masterlist of students from lowest number of classes attended to highe //todo add usage guide for our different commands ### Adding a student: `add` -Initialises an interface for adding a student and their relevant details to the database. +Initialises an interface for adding a student and their relevant details to the database. Allows the user to do add or add [name] **to change** Currently, no two students can have the same name within the system. @@ -104,7 +104,12 @@ NUMBER ``` ### - View details of a student `view` -Views a student details. Allows the user to do view or just view. +Views a student's details. Allows the user to do view [name] or just view. + +Format: `view` or `view name` + +Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. + ``` Example: view wario @@ -121,10 +126,42 @@ Classes Attended: 1 ``` ### - Edit details of a student `edit` +Edit a student's details. Allows the user to do edit [student] or just edit. + +Format: `edit` or `edit NAME` + +Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. +``` +Example: +edit +Name of student to edit (enter blank to exit): +toad +No subjects and grades found for this student. +How would you like to update a student's subject? (enter blank to exit) +Add, Edit or Delete: +add +Subject (enter nothing to skip): Math +Current marks out of 100 (blank to skip) : +95 +Enter Classes Attended (blank to skip): +11 +Do you want to add another subject and grade? (yes/no) +no +How would you like to update a student's subject? (enter blank to exit) +Add, Edit or Delete: + +Exiting edit +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ### - Delete a student from the working list `delete` -Deletes the student from the list. Allows the user to do delete or just delete. +Deletes the student from the list. Allows the user to do delete [student] or just delete. + +Format: `delete` or `delete NAME` + +Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. + ``` Example: delete @@ -134,6 +171,37 @@ wario Student removed successfully! ``` +### - Sort the list of students `sort` +Sorts the list of students based on the following input. Allows the user to do sort [type] or just sort + +Format: `sort`, `sort name`, `sort classes` or `sort payment` + +Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. + +``` +Example: +sort +Sort by: (Choose index) +1. Name (A to Z) +2. Total number of classes attended: +3. Date of last fee payment: +1 +List of Students: +1. mario +2. toad +3. wario +Currently, there are 3 students in the list. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Sort complete! + +sort payment +1.toad - Date of last payment: 2015-10-21 +2.mario - Date of last payment: 2024-03-30 +3.wario - Date of last payment: 2024-03-30 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Sort complete! +``` ## FAQ **Q**: How do I transfer my data to another computer? @@ -164,8 +232,11 @@ Allows the user to edit the details of the student. If the name of the student i ### `sort ` Sorts the list lexicographically. If the word `name` is not specified in the initial command, the program will prompt the user for an appropriate flag. -### `sort ` -Sorts the list lexicographically. If the word `payment_date` is not specified in the initial command, the program will prompt the user for an appropriate flag. +### `sort ` +Sorts the list by the last fee payment date of a student. If the word `payment` is not specified in the initial command, the program will prompt the user for an appropriate flag. + +### `sort ` +Sorts the list by the number of classes a student has attended. If the word `classes` is not specified in the initial command, the program will prompt the user for an appropriate flag. ### `view_subject ` Lists all the students associated with that subject. If the user specifies the subject in the initial command, the list will be generated and the command will be terminated. If the user does not specify the subject, the programme will continuously prompt the user for a subject, until they choose to terminate the command. From 103e59355376c79da8c7c49ed09dd073e9749073 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Sun, 31 Mar 2024 00:14:46 +0800 Subject: [PATCH 142/503] Fix checkStyle violations --- src/main/java/classify/commands/FileIOCommands.java | 2 +- src/main/java/classify/data/DataReader.java | 4 ++-- src/main/java/classify/user/InputParsing.java | 1 - src/test/java/classify/user/InputParsingTest.java | 7 ++++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/classify/commands/FileIOCommands.java b/src/main/java/classify/commands/FileIOCommands.java index dbd0487767..e0eb68777f 100644 --- a/src/main/java/classify/commands/FileIOCommands.java +++ b/src/main/java/classify/commands/FileIOCommands.java @@ -13,7 +13,7 @@ public class FileIOCommands extends Commands { private static final String DATA_DIRECTORY_PATH = "data/studentInfo"; private static final String DATA_FILE_PATH = DATA_DIRECTORY_PATH + "/Student_Information.txt"; - static final String ARCHIVE_DIRECTORY_PATH = "data/archive"; + private static final String ARCHIVE_DIRECTORY_PATH = "data/archive"; private static final String ARCHIVE_FILE_PATH = ARCHIVE_DIRECTORY_PATH + "/student_archive.txt"; /** diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 148a548625..8678fe82d9 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -1,7 +1,6 @@ package classify.data; import classify.student.Student; -import classify.student.StudentList; import classify.ui.DataUI; import classify.user.InputParsing; import classify.ui.UI; @@ -53,7 +52,8 @@ public static void restoreStudentList(String studentFileInput, ArrayList list, String directoryPath, String filePath) throws IOException { + public static void initialiseData(ArrayList list, String directoryPath, + String filePath) throws IOException { Path directory = Paths.get(directoryPath); if (!Files.exists(directory)) { DataUI.printCreatingDirectory(); diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 5fd5a120f3..094b5f540a 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -12,7 +12,6 @@ import classify.student.ViewStudent; import classify.ui.UI; -import java.io.IOException; import java.time.LocalDate; import java.time.format.DateTimeParseException; diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index b1844008a2..75c16a72b7 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -13,7 +13,6 @@ import java.util.Scanner; import static org.junit.jupiter.api.Assertions.assertEquals; - public class InputParsingTest { //@@author tayponghee @@ -27,7 +26,8 @@ public void testByeCommand() { ArrayList archiveList = new ArrayList<>(); String [] commands = new String[2]; commands[0] = "bye"; - InputParsing.parseUserCommand(commands, masterStudentList, recentlyDeletedList, archiveList, new Scanner(System.in)); + InputParsing.parseUserCommand(commands, masterStudentList, recentlyDeletedList, + archiveList, new Scanner(System.in)); System.setOut(System.out); @@ -71,7 +71,8 @@ public void testHelpCommand() { ArrayList archiveList = new ArrayList<>(); String [] commands = new String[2]; commands[0] = "help"; - InputParsing.parseUserCommand(commands, masterStudentList, recentlyDeletedList, archiveList, new Scanner(System.in)); + InputParsing.parseUserCommand(commands, masterStudentList, recentlyDeletedList, + archiveList, new Scanner(System.in)); System.setOut(System.out); From 18956ae2f6b45c5a386d8bc9147a13439df3d357 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Sun, 31 Mar 2024 00:52:01 +0800 Subject: [PATCH 143/503] Update UG --- docs/UserGuide.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 30fac364bb..45cb1f8144 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -210,7 +210,7 @@ Sort complete! **Q**: How do I transfer my data to another computer **without** removing any components? -**A**: (parth this is for you to answer) +**A**: In the jar directory (folder containing jar file), data is stored in the "data" folder (./data). You can import the contents within this data directory to that of the jar directory on the new computer. ## Command Summary @@ -241,6 +241,12 @@ Sorts the list by the number of classes a student has attended. If the word `cla ### `view_subject ` Lists all the students associated with that subject. If the user specifies the subject in the initial command, the list will be generated and the command will be terminated. If the user does not specify the subject, the programme will continuously prompt the user for a subject, until they choose to terminate the command. +### `archive ` +Archives specified student. Removes student from current list and adds student to archive. + +### `unarchive ` +Unarchives specified student. Moves student from archive to current list. + ### `help` Generates the list of commands. From def487c035a3e38b9d6509acfa58331c1748ad75 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Sun, 31 Mar 2024 01:10:06 +0800 Subject: [PATCH 144/503] Fix IO exception bug --- src/main/java/classify/commands/FileIOCommands.java | 6 +++--- src/main/java/classify/data/DataReader.java | 8 +++++--- src/main/java/classify/ui/DataUI.java | 5 +++++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/java/classify/commands/FileIOCommands.java b/src/main/java/classify/commands/FileIOCommands.java index e0eb68777f..6fd8b0fa5c 100644 --- a/src/main/java/classify/commands/FileIOCommands.java +++ b/src/main/java/classify/commands/FileIOCommands.java @@ -35,7 +35,7 @@ public static void writeStudentInfo(List list){ public static void readStudentInfo(ArrayList list) throws IOException{ try{ DataWriter.createParentFileFolder(DATA_DIRECTORY_PATH); - DataReader.initialiseData(list, DATA_DIRECTORY_PATH, DATA_FILE_PATH); + DataReader.initialiseData(list, DATA_FILE_PATH); } catch (IOException e) { DataUI.printCreateFailure(); throw e; @@ -60,8 +60,8 @@ public static void writeArchive(List list){ */ public static void readArchive(ArrayList list) throws IOException { try{ - DataWriter.createParentFileFolder(FileIOCommands.ARCHIVE_DIRECTORY_PATH); - DataReader.initialiseData(list, ARCHIVE_DIRECTORY_PATH, ARCHIVE_FILE_PATH); + DataWriter.createParentFileFolder(ARCHIVE_DIRECTORY_PATH); + DataReader.initialiseData(list, ARCHIVE_FILE_PATH); } catch (IOException e) { DataUI.printCreateFailure(); throw e; diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 8678fe82d9..b992c0d88d 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -52,17 +52,19 @@ public static void restoreStudentList(String studentFileInput, ArrayList list, String directoryPath, + public static void initialiseData(ArrayList list, String filePath) throws IOException { - Path directory = Paths.get(directoryPath); + //@@author blackmirag3 + Path directory = Paths.get(filePath); if (!Files.exists(directory)) { - DataUI.printCreatingDirectory(); + DataUI.printCreatingFile(); Files.createFile(directory); } else { FileReader fileReader = new FileReader(filePath); BufferedReader line = new BufferedReader(fileReader); DataUI.printRetrieveData(); + //@@author ParthGandhiNUS while (line.ready()) { restoreStudentList(line.readLine(), list); } diff --git a/src/main/java/classify/ui/DataUI.java b/src/main/java/classify/ui/DataUI.java index 9a6b7203aa..e2ce08da0a 100644 --- a/src/main/java/classify/ui/DataUI.java +++ b/src/main/java/classify/ui/DataUI.java @@ -5,6 +5,7 @@ public class DataUI extends UI { //@@author ParthGandhiNUS private static final String ANALYSING_INPUT_MESSAGE = "Analysing Inputs..."; private static final String CREATING_DIRECTORY_MESSAGE = "Creating a new directory..."; + private static final String CREATING_FILE_MESSAGE = "Creating a new data file..."; private static final String DIRECTORY_SUCCESS_MESSAGE = "Directory loaded successfully!"; private static final String CREATE_FAILURE_MESSAGE = "Unable to create a new file/directory!"; private static final String RETRIEVING_DATA_MESSAGE = "Retrieving data..."; @@ -30,6 +31,10 @@ public static void printCreatingDirectory() { System.out.println(CREATING_DIRECTORY_MESSAGE); } + public static void printCreatingFile() { + System.out.println(CREATING_FILE_MESSAGE); + } + public static void printDirectorySuccess() { System.out.println(DIRECTORY_SUCCESS_MESSAGE); } From 46e935313506fdd0eff8f022076d1031c207a4e6 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 31 Mar 2024 09:05:19 +0800 Subject: [PATCH 145/503] Remove IO tests --- .github/workflows/gradle.yml | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index fd8c44d086..133b0e7f2b 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -31,20 +31,4 @@ jobs: java-package: jdk+fx - name: Build and check with Gradle - run: ./gradlew check - - - name: Perform IO redirection test (*NIX) - if: runner.os == 'Linux' - working-directory: ${{ github.workspace }}/text-ui-test - run: ./runtest.sh - - - name: Perform IO redirection test (MacOS) - if: always() && runner.os == 'macOS' - working-directory: ${{ github.workspace }}/text-ui-test - run: ./runtest.sh - - - name: Perform IO redirection test (Windows) - if: always() && runner.os == 'Windows' - working-directory: ${{ github.workspace }}/text-ui-test - shell: cmd - run: runtest.bat \ No newline at end of file + run: ./gradlew check \ No newline at end of file From ad0f886c7acfbf00609b63a5317866c9fc5b1910 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 31 Mar 2024 10:35:10 +0800 Subject: [PATCH 146/503] Change method name --- src/main/java/classify/user/InputParsing.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 094b5f540a..169b90c677 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -590,13 +590,13 @@ protected static LocalDate parseDateFromString(String string) { paymentDate = LocalDate.parse(string); } catch (DateTimeParseException e) { - return invalidDatePath(); + return printInvalidDateMessage(); } return paymentDate; } - private static LocalDate invalidDatePath() { + private static LocalDate printInvalidDateMessage() { LOGGER.log(Level.WARNING, "Invalid date format entered." + '\n'); UI.printInvalidDateFormatError(); return LocalDate.now().plusDays(2); From afdb1c634bf24a35050e33dca492392799322eca Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 31 Mar 2024 12:25:11 +0800 Subject: [PATCH 147/503] Add checks to ensure getTotalClasses accounts for empty cases --- .../java/classify/student/StudentSorter.java | 4 ++- .../java/classify/student/ViewStudent.java | 28 +++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/main/java/classify/student/StudentSorter.java b/src/main/java/classify/student/StudentSorter.java index 81644fa75e..9663beac05 100644 --- a/src/main/java/classify/student/StudentSorter.java +++ b/src/main/java/classify/student/StudentSorter.java @@ -93,7 +93,9 @@ private static void listStudentsByTotalClasses(ArrayList masterStudentL List subjectGrades = attributes.getSubjectGrades(); for (SubjectGrade subjectGrade : subjectGrades) { - totalClassesAttended += subjectGrade.getClassesAttended(); + if (subjectGrade.getClassesAttended() >= 0) { + totalClassesAttended += subjectGrade.getClassesAttended(); + } } student.setTotalClassesAttended(totalClassesAttended); diff --git a/src/main/java/classify/student/ViewStudent.java b/src/main/java/classify/student/ViewStudent.java index e6e6ca69e9..68ac6747e2 100644 --- a/src/main/java/classify/student/ViewStudent.java +++ b/src/main/java/classify/student/ViewStudent.java @@ -12,6 +12,7 @@ public class ViewStudent { private static final Logger logger = Logger.getLogger(ViewStudent.class.getName()); + private static final String NO_CLASSES_FOUND = "No classes was inputted for the corresponding subject."; //@@author tayponghee /** @@ -42,6 +43,7 @@ public static void viewStudent(ArrayList masterStudentList, Scanner in, if (foundStudent != null) { logger.log(Level.INFO, "Viewing student details: " + name); + UI.printDivider(); UI.printStudentDetails(); UI.printStudentName(name); @@ -60,6 +62,8 @@ public static void viewStudent(ArrayList masterStudentList, Scanner in, /** * Calculates the total number of classes attended by the student across all subjects. + * If the user does not specify the number of classes the student attended for that subject, i.e. + * the user left it blank, the total classes attended would not be affected. * * @param student The student whose total classes attended are to be calculated. * @return The total number of classes attended by the student. @@ -67,7 +71,9 @@ public static void viewStudent(ArrayList masterStudentList, Scanner in, private static int getTotalClassesAttended(Student student) { int totalClassesAttended = 0; for (classify.student.SubjectGrade subjectGrade : student.getAttributes().getSubjectGrades()) { - totalClassesAttended += subjectGrade.getClassesAttended(); + if (subjectGrade.getClassesAttended() >= 0) { + totalClassesAttended += subjectGrade.getClassesAttended(); + } } return totalClassesAttended; } @@ -86,6 +92,11 @@ public static void showAttributes(StudentAttributes attributes) { } } + /** + * Checks if the list of subject grades is empty and performs appropriate actions. + * + * @param subjectGrades The list of SubjectGrade objects to check. + */ private static void checkIfSubjectGradesIsEmpty(List subjectGrades) { if (!subjectGrades.isEmpty()) { printSubjectAttributes(subjectGrades); @@ -94,14 +105,25 @@ private static void checkIfSubjectGradesIsEmpty(List subjectGrades } } + /** + * Prints attributes of each SubjectGrade object in the provided list. + * + * @param subjectGrades The list of SubjectGrade objects to print attributes for. + */ private static void printSubjectAttributes(List subjectGrades) { for (SubjectGrade subjectGrade : subjectGrades) { assert subjectGrade != null : "subjectGrade cannot be null"; + UI.printSubjectName(subjectGrade.getSubject()); UI.printStudentGrades(subjectGrade.getGrade()); - UI.printClassesAttended(subjectGrade.getClassesAttended()); + + if (subjectGrade.getClassesAttended() >= 0) { + UI.printClassesAttended(subjectGrade.getClassesAttended()); + } else { + UI.println(NO_CLASSES_FOUND); + } + UI.printDivider(); } } - } From fff536dc3ff3a4db4522bb49cb5f8e1e7e5fd76e Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 31 Mar 2024 14:39:29 +0800 Subject: [PATCH 148/503] Add StudentSorter component to DG --- docs/diagrams/src/StudentSorter/StudentSorter.puml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 docs/diagrams/src/StudentSorter/StudentSorter.puml diff --git a/docs/diagrams/src/StudentSorter/StudentSorter.puml b/docs/diagrams/src/StudentSorter/StudentSorter.puml new file mode 100644 index 0000000000..ac2c2d3913 --- /dev/null +++ b/docs/diagrams/src/StudentSorter/StudentSorter.puml @@ -0,0 +1,11 @@ +@startuml +'https://plantuml.com/sequence-diagram + +autonumber + +Alice -> Bob: Authentication Request +Bob --> Alice: Authentication Response + +Alice -> Bob: Another authentication Request +Alice <-- Bob: another authentication Response +@enduml \ No newline at end of file From b12cd001af05866fef389825c1331518146014ec Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 31 Mar 2024 14:39:44 +0800 Subject: [PATCH 149/503] Add UML diagram --- docs/DeveloperGuide.md | 50 ++++++++++++++--- .../src/StudentSorter/StudentSorter.png | Bin 0 -> 47255 bytes .../src/StudentSorter/StudentSorter.puml | 51 +++++++++++++++--- 3 files changed, 86 insertions(+), 15 deletions(-) create mode 100644 docs/diagrams/src/StudentSorter/StudentSorter.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index c1bcb421c5..744e6a8d0d 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -90,6 +90,7 @@ We created a parent `Details` class as those are information not specifically re However, our current implementation is not very secure as one can access every field of a `Student` object just by having access to it or the `StudentAttribute` object, which can be done via accessing the `static masterStudentList` variable.In future updates, we could possibly implement a Facade Pattern to better hide sensitive details. + ### Data Commands Component This section refers to `DataHandler.java`, `DataReader.java`, and `DataStorage.java` classes. @@ -124,19 +125,54 @@ The `AddStudent` class is responsible for adding a new student to the list of st #### Design Considerations -- **Handling Duplicate Names**: The class checks if a student with the same name already exists in the master list before adding a new student. -- **Input Validation**: It validates the format of input attributes such as the name, phone number, gender, last payment date, and remarks. -- **Modular Approach**: The class is designed with modularity in mind, allowing easy addition of new attributes or modifications in the future. +- **Handling Duplicate Names**: The class checks if a student with the same name +already exists in the master list before adding a new student. +- **Input Validation**: It validates the format of input attributes such as +the name, phone number, gender, last payment date, and remarks. +- **Modular Approach**: The class is designed with modularity in mind, +allowing easy addition of new attributes or modifications in the future. #### Implementation and Rationale -- **Name Validation**: The `checkForEmptyName` method ensures that the name provided by the user is not empty and does not already exist in the master student list. -- **Attribute Validation**: Various methods such as `promptForPhoneNumber`, `promptForGender`, `promptForLastPaymentDate`, and `promptForRemarks` validate the format of different attributes. -- **Adding Subjects**: The `addSubject` method allows users to add multiple subjects along with their grades and classes attended for each student. -- **Error Handling**: The class provides appropriate error messages if invalid input or duplicate names are encountered. +- **Name Validation**: The `checkForEmptyName` method ensures that the name provided +by the user is not empty and does not already exist in the master student list. +- **Attribute Validation**: Various methods such as +`promptForPhoneNumber`, `promptForGender`, `promptForLastPaymentDate`, and `promptForRemarks` +validate the format of different attributes. +- **Adding Subjects**: The `addSubject` method allows users to add multiple subjects +along with their grades and classes attended for each student. +- **Error Handling**: The class provides appropriate error messages if invalid input +or duplicate names are encountered. The `AddStudent` class contributes to the overall functionality of the application by providing a streamlined process for adding new students and ensuring data integrity within the student database. + +### StudentSorter Component + +The `StudentSorter` class facilitates sorting of the list of students based on various criterion. +As of the latest iteration, it sorts the master list of students in the order specified by the user. + +![StudentSorterUML](./diagrams/src/StudentSorter/StudentSorter.png) + +#### Design Considerations + +- Support for sorting by name, total classes attended, and last payment date. +- Input validation to ensure only valid sorting choices are accepted. +- Clear user feedback on sorting choices and results. + +#### Implementation and Rationale + +- **Sorting Criteria**: Supports sorting by name, total classes attended, and last payment date. +- **Input Validation**: Validates user input to ensure only valid sorting choices are accepted. +- **Switch Case Structure**: Utilizes switch-case structure for efficient sorting based on user choice. +- **Reusable Comparators**: Utilizes reusable comparators for sorting students by name, +total classes attended, and last payment date. +- **Clear Output**: Provides clear output of sorted student lists with relevant information. +- **Error Handling**: Provides error message for invalid sorting choices. + +The `StudentSorter` class contributes to the overall functionality of the application by +providing a mechanism to organize and present student information based on user preferences. + --- ## Product scope diff --git a/docs/diagrams/src/StudentSorter/StudentSorter.png b/docs/diagrams/src/StudentSorter/StudentSorter.png new file mode 100644 index 0000000000000000000000000000000000000000..d366eca675acaab5603f39fd5f0aedaa436e939f GIT binary patch literal 47255 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 literal 0 HcmV?d00001 diff --git a/docs/diagrams/src/StudentSorter/StudentSorter.puml b/docs/diagrams/src/StudentSorter/StudentSorter.puml index ac2c2d3913..b27f38fd10 100644 --- a/docs/diagrams/src/StudentSorter/StudentSorter.puml +++ b/docs/diagrams/src/StudentSorter/StudentSorter.puml @@ -1,11 +1,46 @@ -@startuml -'https://plantuml.com/sequence-diagram +@startuml StudentSorter -autonumber +package student { + class StudentSorter { + +NAME:String + +PAYMENT_DATE:String + +TOTAL_CLASSES:String + +ONE:String + +TWO:String + +THREE:String + +INVALID_CHOICE:String + -- + +sortByChoice(ArrayList, String, Scanner) + +isValidChoice(String):boolean + } -Alice -> Bob: Authentication Request -Bob --> Alice: Authentication Response + class StudentList { + {static} +masterStudentList:ArrayList + {static} +recentlyDeletedList:ArrayList + +studentList:ArrayList + } -Alice -> Bob: Another authentication Request -Alice <-- Bob: another authentication Response -@enduml \ No newline at end of file + class Student { + +name:String + -totalClassesAttended:int + } + + class StudentAttributes { + +subjectGrades:List + } + + class SubjectGrade { + -subject:String + -grade:double + -classesAttended:int + } +} + +StudentSorter "1" --> "1..*" Student +StudentSorter "1" --> "1" StudentList +StudentSorter "1" --> "1" StudentAttributes +StudentAttributes "1" --> "0..*" SubjectGrade + +note "Inconsequential methods and attributes omitted" as N1 + +@enduml From 177ab64f23f3158d86fd00c4e3dfc201340643e0 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sun, 31 Mar 2024 15:15:08 +0800 Subject: [PATCH 150/503] Fix spelling and formatting of UG --- docs/UserGuide.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 45cb1f8144..43f9c624a1 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -29,14 +29,14 @@ We have determined these to be the attributes important to running a working tui ## Quick Start -1. Ensure that you have Java __11 or above__ installed. -2. Download the provided jar file into an empty folder. -3. Run it from the terminal using the following command: +1. Ensure that you have __Java 11 or above__ installed. +2. Download the provided jar file into an empty folder. +3. Open a terminal and change the working directory to the folder with the jar file. +4. Run it from the terminal using the following command: ``` java -jar ./Classify.jar ``` - -4. Run the command ```help``` within the program to get a quick view of the available commands. +5. Run the command ```help``` within the program to get a quick view of the available commands. ## Features @@ -64,9 +64,13 @@ Displays a list of all the students with that associated subject taken in the tu Sorts the masterlist of students from A to Z. When the user types list, it will generate the updated sorted list. -### - Sort the list by total classes attended, `sort payment_date` +### - Sort the list by total classes attended `sort classes` + +Sorts the masterlist of students from the lowest number of classes attended to highest. When the user types list, it will generate the updated sorted list. + +### - Sort the list by latest fee payment date `sort payment` -Sorts the masterlist of students from lowest number of classes attended to highest. When the user types list, it will generate the updated sorted list. +Sorts the masterlist of students from the oldest date to the most recent. When the user types list, it will generate the updated sorted list. # Usage //todo add usage guide for our different commands @@ -106,7 +110,7 @@ NUMBER ### - View details of a student `view` Views a student's details. Allows the user to do view [name] or just view. -Format: `view` or `view name` +Format: `view` or `view NAME` Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. From 604408aaff7dda545c9985b106455a7ea77211bd Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 31 Mar 2024 18:45:44 +0800 Subject: [PATCH 151/503] Add list comand into another class --- .../commands/ListStudentsCommand.java | 110 ++++++++++++++++++ src/main/java/classify/ui/UI.java | 32 +++++ src/main/java/classify/user/InputParsing.java | 50 +++----- 3 files changed, 157 insertions(+), 35 deletions(-) create mode 100644 src/main/java/classify/commands/ListStudentsCommand.java diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java new file mode 100644 index 0000000000..86934e0170 --- /dev/null +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -0,0 +1,110 @@ +package classify.commands; + +import classify.student.Student; +import classify.student.StudentList; +import classify.ui.UI; + +import java.util.ArrayList; +import java.util.Scanner; + +public class ListStudentsCommand { + + private static final String ONE = "1"; + private static final String TWO = "2"; + private static final String FULL_STUDENT_LIST = "Full Student list:"; + private static final String LIST_OF_STUDENTS_WITH_TOTAL_CLASSES_ATTENDED = "List of students with total classes attended:"; + private static final String INVALID_CHOICE = "Invalid choice!"; + private static final String TOTAL_CLASSES_ATTENDED = " - Total Classes Attended: "; + + /** + * Lets the user view a list of students, optionally filtered by subject. + * If a subject is provided, it will only list students with that subject. + * If no subject is provided, it will list all students. + * + * @param masterStudentList The list of all students. + * @param in The user's input. + * @param subject Optional subject to filter the list of students. + */ + public static void chooseListType(ArrayList masterStudentList, Scanner in, String subject) { + if (subject != null && !subject.isEmpty()) { + listStudentsBySubject(masterStudentList, subject); + } else { + listAllStudents(masterStudentList); + } + } + + /** + * Lists all students with the specified subject. + * + * @param masterStudentList The list of all students. + * @param subject The subject to filter the list of students. + */ + public static void listStudentsBySubject(ArrayList masterStudentList, String subject) { + boolean found = false; + UI.printStudentsWithSubject(subject); + + for (Student student : masterStudentList) { + if (student.hasSubject(subject)) { + System.out.println("- " + student.getName()); + found = true; + } + } + + if (!found) { + UI.printNoStudentsWithSubject(subject); + } + + UI.printDivider(); + } + + /** + * Lists all students in the provided list, giving the user the option to choose the type of list to display. + * + * @param masterStudentList The list of all students. + */ + private static void listAllStudents(ArrayList masterStudentList) { + UI.printListAllStudentsChoice(); + + Scanner scanner = new Scanner(System.in); + String choice = scanner.nextLine().trim(); + + //@@ author blackmirag3 + switch (choice) { + case ONE: + UI.println(FULL_STUDENT_LIST); + + StudentList.printCurrentArrayList(masterStudentList); + //@@ ParthGandhiNUS + StudentList.printCurrentArrayMessage(masterStudentList); + + UI.printDivider(); + break; + + case TWO: + UI.println(LIST_OF_STUDENTS_WITH_TOTAL_CLASSES_ATTENDED); + + listStudentsWithTotalClasses(masterStudentList); + UI.printDivider(); + break; + + default: + UI.println(INVALID_CHOICE); + } + + UI.printDivider(); + } + + /** + * Lists all students in the provided list along with their total classes attended. + * + * @param masterStudentList The list of all students. + */ + private static void listStudentsWithTotalClasses(ArrayList masterStudentList) { + int i = 1; + for (Student student : masterStudentList) { + System.out.println(i + "." + student.getName() + TOTAL_CLASSES_ATTENDED + + student.getTotalClassesAttended()); + i++; + } + } +} diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index a7f97ccaf2..aac591501f 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -61,6 +61,14 @@ public class UI { private static final String NO_SUBJECTS_ADDED = "No subjects added."; private static final String SUBJECT_ALREADY_EXISTS = "Subject already exists."; private static final String WRONG_NUMBER_FORMAT = "Wrong number format! Please try again! e.g. 12 "; + public static final String TYPE_LIST_ONLY = "Type 'list' only!"; + public static final String SUBJECT_NAME_LEAVE_BLANK = "Enter subject name (leave blank for all students):"; + private static final String STUDENTS_WITH_THE_SUBJECT = "Students with the subject"; + private static final String NO_STUDENTS_FOUND_WITH_THE_SUBJECT = "No students found with the subject: "; + private static final String CHOOSE_THE_TYPE_OF_LIST_TO_DISPLAY = "Choose the type of list to display: (index only)"; + private static final String FULL_STUDENT_LIST = "1. Full student list"; + private static final String STUDENTS_WITH_TOTAL_CLASSES = "2. List of students with total classes attended"; + private static final String ENTER_ONE_TWO = "Enter your choice (1 or 2):"; //@@author alalal47 /** @@ -101,6 +109,8 @@ private static void printByeHelpMessage() { private static void printListHelpMessage() { System.out.println("list Displays the list of all students"); + System.out.println(" Currently available types: Whole student list, with " + + "total classes attended or by certain subject only"); } private static void printDeleteHelpMessage() { @@ -327,4 +337,26 @@ public static void printWrongNumberFormat () { System.out.println(WRONG_NUMBER_FORMAT); } + public static void printInvalidListCommand() { + System.out.println(TYPE_LIST_ONLY); + } + + public static void printListCommandStart() { + System.out.println(SUBJECT_NAME_LEAVE_BLANK); + } + + public static void printStudentsWithSubject(String subject) { + System.out.println(STUDENTS_WITH_THE_SUBJECT + " \"" + subject + "\":"); + } + + public static void printNoStudentsWithSubject(String subject) { + System.out.println(NO_STUDENTS_FOUND_WITH_THE_SUBJECT + subject); + } + + public static void printListAllStudentsChoice () { + System.out.println(CHOOSE_THE_TYPE_OF_LIST_TO_DISPLAY); + System.out.println(FULL_STUDENT_LIST); + System.out.println(STUDENTS_WITH_TOTAL_CLASSES); + System.out.println(ENTER_ONE_TWO); + } } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 094b5f540a..61205626ba 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -3,10 +3,10 @@ import classify.commands.Commands; import classify.commands.FileIOCommands; import classify.commands.DeleteCommands; +import classify.commands.ListStudentsCommand; import classify.student.AddStudent; import classify.student.Student; import classify.student.StudentAttributes; -import classify.student.StudentList; import classify.student.StudentSorter; import classify.student.SubjectGrade; import classify.student.ViewStudent; @@ -97,7 +97,11 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas break; case LIST: - listStudents(masterStudentList); + if (userCommand[1] != null) { + UI.printInvalidListCommand(); + } else { + parseListCommand(masterStudentList, in); + } break; //@@ author tayponghee @@ -128,6 +132,13 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas } } + //@@ author tayponghee + public static void parseListCommand(ArrayList masterStudentList, Scanner scanner) { + UI.printListCommandStart(); + String subject = scanner.nextLine().trim(); + ListStudentsCommand.chooseListType(masterStudentList, scanner, subject); + } + //author blackmirag3 private static void unarchiveStudent(ArrayList masterList, ArrayList archiveList, String name, Scanner in) { @@ -212,7 +223,7 @@ private static void sortStudents(ArrayList masterStudentList, Scanner i */ private static void handleViewSubjectCommand(ArrayList masterStudentList, Scanner in, String subject) { if (subject != null && !subject.isEmpty()) { - viewStudentsBySubject(masterStudentList, subject); + ListStudentsCommand.listStudentsBySubject(masterStudentList, subject); } else { findStudentsWithSubject(masterStudentList, in); } @@ -237,7 +248,7 @@ private static void findStudentsWithSubject(ArrayList masterStudentList } if (!input.isEmpty()) { - viewStudentsBySubject(masterStudentList, input); + ListStudentsCommand.listStudentsBySubject(masterStudentList, input); return; } else { System.out.println("Please enter a valid subject name."); @@ -245,38 +256,7 @@ private static void findStudentsWithSubject(ArrayList masterStudentList } } - /** - * Views all students who have the specified subject. - * - * @param masterStudentList The list of all students. - * @param subject The subject to search for among students. - */ - private static void viewStudentsBySubject(ArrayList masterStudentList, String subject) { - boolean found = false; - System.out.println("Students with the subject \"" + subject + "\":"); - - for (Student student : masterStudentList) { - if (student.hasSubject(subject)) { - System.out.println("- " + student.getName()); - found = true; - } - } - - if (!found) { - System.out.println("No students found with the subject: " + subject); - } - - UI.printDivider(); - } - // @@author blackmirag3 - private static void listStudents(ArrayList list) { - StudentList.printCurrentArrayList(list); - // @@author ParthGandhiNUS - StudentList.printCurrentArrayMessage(list); - UI.printDivider(); - } - private static void editStudent(ArrayList list, Scanner in, String name) { if (list.isEmpty()) { UI.printEmptyListError(); From 61af7f13c3937b15e522446bf113283f0f2e6276 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 31 Mar 2024 18:54:58 +0800 Subject: [PATCH 152/503] Update DG --- docs/UserGuide.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 43f9c624a1..28c39f8830 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -56,10 +56,18 @@ Initialises the process of editing both academic and non-academic details of a s Removes a student from the master list of students. -### - Produce a list of all the students who takes a subject `view_subject` +### - Produce a list of all the students who takes a subject `list`, enter, then followed by `subject name` Displays a list of all the students with that associated subject taken in the tuition centre. +### Produce a list of all students with total classes attended `list`, enter, enter, `2` + +Displays a list of all the students with their total classes attended at the tuition centre. + +### Produce a list of all students `list`, enter, enter, `1` + +Displays a list of all the students at the tuition centre with no other parameters shown. + ### - Sort the list lexicographically, from A to Z `sort name` Sorts the masterlist of students from A to Z. When the user types list, it will generate the updated sorted list. From e661ecf4a993b5494fa0133b63c9e389871b526d Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 31 Mar 2024 18:55:14 +0800 Subject: [PATCH 153/503] Revert "Update DG" This reverts commit 61af7f13c3937b15e522446bf113283f0f2e6276. --- docs/UserGuide.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 28c39f8830..43f9c624a1 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -56,18 +56,10 @@ Initialises the process of editing both academic and non-academic details of a s Removes a student from the master list of students. -### - Produce a list of all the students who takes a subject `list`, enter, then followed by `subject name` +### - Produce a list of all the students who takes a subject `view_subject` Displays a list of all the students with that associated subject taken in the tuition centre. -### Produce a list of all students with total classes attended `list`, enter, enter, `2` - -Displays a list of all the students with their total classes attended at the tuition centre. - -### Produce a list of all students `list`, enter, enter, `1` - -Displays a list of all the students at the tuition centre with no other parameters shown. - ### - Sort the list lexicographically, from A to Z `sort name` Sorts the masterlist of students from A to Z. When the user types list, it will generate the updated sorted list. From 58b8b71092f469cb7a6b29850c75af33438aeb87 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 31 Mar 2024 18:55:30 +0800 Subject: [PATCH 154/503] Revert "Revert "Update DG"" This reverts commit e661ecf4a993b5494fa0133b63c9e389871b526d. --- docs/UserGuide.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 43f9c624a1..28c39f8830 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -56,10 +56,18 @@ Initialises the process of editing both academic and non-academic details of a s Removes a student from the master list of students. -### - Produce a list of all the students who takes a subject `view_subject` +### - Produce a list of all the students who takes a subject `list`, enter, then followed by `subject name` Displays a list of all the students with that associated subject taken in the tuition centre. +### Produce a list of all students with total classes attended `list`, enter, enter, `2` + +Displays a list of all the students with their total classes attended at the tuition centre. + +### Produce a list of all students `list`, enter, enter, `1` + +Displays a list of all the students at the tuition centre with no other parameters shown. + ### - Sort the list lexicographically, from A to Z `sort name` Sorts the masterlist of students from A to Z. When the user types list, it will generate the updated sorted list. From 1ee2b89e010057582bc7b7ce0e8d8e7cbb67af36 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 31 Mar 2024 19:03:17 +0800 Subject: [PATCH 155/503] Fix Gradle checks + update UG --- src/main/java/classify/commands/ListStudentsCommand.java | 3 ++- src/main/java/classify/ui/UI.java | 4 ++-- src/test/java/classify/user/InputParsingTest.java | 3 +++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 86934e0170..2960296ded 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -12,7 +12,8 @@ public class ListStudentsCommand { private static final String ONE = "1"; private static final String TWO = "2"; private static final String FULL_STUDENT_LIST = "Full Student list:"; - private static final String LIST_OF_STUDENTS_WITH_TOTAL_CLASSES_ATTENDED = "List of students with total classes attended:"; + private static final String LIST_OF_STUDENTS_WITH_TOTAL_CLASSES_ATTENDED = + "List of students with total classes attended:"; private static final String INVALID_CHOICE = "Invalid choice!"; private static final String TOTAL_CLASSES_ATTENDED = " - Total Classes Attended: "; diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index aac591501f..95aba26c35 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -61,8 +61,8 @@ public class UI { private static final String NO_SUBJECTS_ADDED = "No subjects added."; private static final String SUBJECT_ALREADY_EXISTS = "Subject already exists."; private static final String WRONG_NUMBER_FORMAT = "Wrong number format! Please try again! e.g. 12 "; - public static final String TYPE_LIST_ONLY = "Type 'list' only!"; - public static final String SUBJECT_NAME_LEAVE_BLANK = "Enter subject name (leave blank for all students):"; + private static final String TYPE_LIST_ONLY = "Type 'list' only!"; + private static final String SUBJECT_NAME_LEAVE_BLANK = "Enter subject name (leave blank for all students):"; private static final String STUDENTS_WITH_THE_SUBJECT = "Students with the subject"; private static final String NO_STUDENTS_FOUND_WITH_THE_SUBJECT = "No students found with the subject: "; private static final String CHOOSE_THE_TYPE_OF_LIST_TO_DISPLAY = "Choose the type of list to display: (index only)"; diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index 75c16a72b7..089506932c 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -98,6 +98,9 @@ public void testHelpCommand() { + System.lineSeparator() + "list Displays the list of all students" + System.lineSeparator() + + " Currently available types: Whole student list, with " + + "total classes attended or by certain subject only" + + System.lineSeparator() + "bye Exits Classify" + System.lineSeparator() + "sort Sorts the student list by the input parameter, expects an" + From 0633e412d4d5ab4fde6f94e73adf4c756659e559 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 31 Mar 2024 19:18:14 +0800 Subject: [PATCH 156/503] Add identification by Student Number --- .../classify/commands/DeleteCommands.java | 27 +- src/main/java/classify/data/DataReader.java | 16 +- .../java/classify/student/AddStudent.java | 35 +- src/main/java/classify/student/Student.java | 4 + .../java/classify/student/StudentList.java | 92 +++-- .../java/classify/student/ViewStudent.java | 2 +- src/main/java/classify/ui/UI.java | 4 +- .../classify/user/ClassifyExceptions.java | 4 +- src/main/java/classify/user/InputParsing.java | 319 ++++++++++-------- .../user/nameNumberMatchException.java | 8 + 10 files changed, 316 insertions(+), 195 deletions(-) create mode 100644 src/main/java/classify/user/nameNumberMatchException.java diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index 58048b5821..771de0eae7 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -1,7 +1,9 @@ package classify.commands; import classify.student.Student; +import classify.student.StudentList; import classify.user.InputParsing; +import classify.user.nameNumberMatchException; import classify.ui.UI; import java.util.ArrayList; @@ -27,7 +29,7 @@ public static void deleteStudent(ArrayList masterStudentList, ArrayList } //@@author alalal47 - Student foundStudent = InputParsing.findStudentByName(masterStudentList, studentName); + Student foundStudent = InputParsing.findStudentByName(masterStudentList, studentName, in); if (foundStudent != null) { UI.printStudentDeleted(); @@ -37,11 +39,13 @@ public static void deleteStudent(ArrayList masterStudentList, ArrayList UI.printDivider(); //@@author blackmirag3 + assert true : "Not false"; if (recentlyDeletedList != null) { recentlyDeletedList.add(foundStudent); } masterStudentList.remove(foundStudent); - assert InputParsing.findStudentByName(masterStudentList, studentName) == null : "Student should be deleted"; + //assert may be false after implementation of phone number indentification + // assert InputParsing.findStudentByName(masterStudentList, studentName) == null : "Student should be deleted"; } /** @@ -61,7 +65,7 @@ public static void restoreStudent(ArrayList masterStudentList, ArrayLis studentName = promptName(in); } - Student foundStudent = InputParsing.findStudentByName(recentlyDeletedList, studentName); + Student foundStudent = InputParsing.findStudentByName(recentlyDeletedList, studentName, in); if (foundStudent != null) { UI.printRestoreMessage(); @@ -69,9 +73,20 @@ public static void restoreStudent(ArrayList masterStudentList, ArrayLis UI.printStudentNotFound(); } - UI.printDivider(); - masterStudentList.add(foundStudent); - recentlyDeletedList.remove(foundStudent); + //@@author Cryolian + try { + StudentList.checkNameNumberPair(masterStudentList, studentName, foundStudent.getPhoneNumber()); + + //@@author blackmirag3 + UI.printDivider(); + masterStudentList.add(foundStudent); + recentlyDeletedList.remove(foundStudent); + + //@@author Cryolian + } catch (nameNumberMatchException e) { + return; + } + } /** diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index b992c0d88d..cc969294ad 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -34,14 +34,16 @@ public class DataReader { public static void restoreStudentList(String studentFileInput, ArrayList masterStudentList ){ if (studentFileInput != null){ - if (InputParsing.findStudentByName(masterStudentList, studentFileInput) != null) { - assert InputParsing.findStudentByName(masterStudentList, studentFileInput) != null; - logger.log(Level.WARNING, "Student with the same name already exists."); - UI.printSameNameError(); - UI.printDivider(); - return; - } + //removed below portion due to implementation of phone number identification. + // if (InputParsing.findStudentByName(masterStudentList, studentFileInput) != null) { + // assert InputParsing.findStudentByName(masterStudentList, studentFileInput) != null; + // logger.log(Level.WARNING, "Student with the same name already exists."); + + // UI.printSameNameError(); + // UI.printDivider(); + // return; + // } Student student = new Student(studentFileInput); diff --git a/src/main/java/classify/student/AddStudent.java b/src/main/java/classify/student/AddStudent.java index d8aea0a152..60b27157f6 100644 --- a/src/main/java/classify/student/AddStudent.java +++ b/src/main/java/classify/student/AddStudent.java @@ -3,6 +3,7 @@ import classify.ui.UI; import classify.user.InputParsing; +import classify.user.nameNumberMatchException; import java.util.ArrayList; import java.util.Scanner; import java.util.logging.Level; @@ -36,28 +37,40 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, name = checkForEmptyName(masterStudentList, in, studentName); - if (InputParsing.findStudentByName(masterStudentList, name) != null) { - assert InputParsing.findStudentByName(masterStudentList, name) != null; - LOGGER.log(Level.WARNING, STUDENT_WITH_THE_SAME_NAME_ALREADY_EXISTS); - - UI.printSameNameError(); - UI.printDivider(); - return; - } + //Check removed due to implementation of phone number identification. + // if (InputParsing.findStudentByName(masterStudentList, name) != null) { + // assert InputParsing.findStudentByName(masterStudentList, name) != null; + // LOGGER.log(Level.WARNING, STUDENT_WITH_THE_SAME_NAME_ALREADY_EXISTS); + // UI.printSameNameError(); + // UI.printDivider(); + // } + Student student = new Student(name); addSubject(in, student.getAttributes()); - // @@author Cryolian - int number = InputParsing.promptForPhoneNumber(in); + int number = 0; - while (number < 0) { + // @@author Cryolian + try { number = InputParsing.promptForPhoneNumber(in); + } catch (NumberFormatException e) { + UI.printValidNumberError(); + return; } + //@@ author ParthGandhiNUS assert number > 0 && number < 100000000 : NUMBER_IS_OUTSIDE_THE_ACCEPTABLE_RANGE; //@@author Cryolian + + try { + StudentList.checkNameNumberPair(StudentList.masterStudentList, name, number); + StudentList.checkNameNumberPair(StudentList.recentlyDeletedList, name, number); + } catch (nameNumberMatchException e) { + return; + } + student.getAttributes().setPhoneNumber(number); UI.promptForGender(); diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index fd230ea697..8484dc8333 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -82,4 +82,8 @@ public void setName(String name) { public String toString() { return this.name; } + + public void printStringNumber() { + System.out.println(this.name + ": " + String.valueOf(this.getPhoneNumber())); + } } diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index dd8e4c407a..ae87577055 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -2,11 +2,14 @@ import java.util.ArrayList; +import classify.user.ClassifyExceptions; +import classify.user.nameNumberMatchException; + /** * Class to represent a list of Students. */ public class StudentList { - //@@authorParthGandhiNUS + // @@authorParthGandhiNUS public static final String DOT = "."; public static final String ZERO_STUDENT_MESSAGE = "Currently, there are 0 students in the list."; public static final String ONE_STUDENT_MESSAGE = "Currently, there is 1 student in the list."; @@ -16,53 +19,58 @@ public class StudentList { public static ArrayList recentlyDeletedList = new ArrayList<>(); public static ArrayList archiveList = new ArrayList<>(); - //@@author Cryolian + // @@author Cryolian public ArrayList studentList; - - //@@author Cryolian + // @@author Cryolian public StudentList() { - this.studentList = new ArrayList<>();; + this.studentList = new ArrayList<>(); + ; } - //@@author ParthGandhiNUS + // @@author ParthGandhiNUS /** - * Used in the "list" command to print all the Current Tasks in the proper format - * @param currentList takes in an array to print out the name and other attributes of the Student + * Used in the "list" command to print all the Current Tasks in the proper + * format + * + * @param currentList takes in an array to print out the name and other + * attributes of the Student */ - public static void printCurrentArrayList(ArrayListcurrentList){ - for (int i = 1; i <= currentList.size(); i++){ - System.out.println(i + DOT + currentList.get(i-1)); + public static void printCurrentArrayList(ArrayList currentList) { + for (int i = 1; i <= currentList.size(); i++) { + System.out.println(i + DOT + currentList.get(i - 1)); } } - //@@author ParthGandhiNUS + // @@author ParthGandhiNUS /** - * Prints a statement displaying the number of students in the Student List + * Prints a statement displaying the number of students in the Student List + * * @param currentList takes in a Student list to get its size */ - public static void printCurrentArrayMessage(ArrayListcurrentList){ + public static void printCurrentArrayMessage(ArrayList currentList) { int numberOfStudents = currentList.size(); - switch (numberOfStudents){ - case 0: - System.out.println(ZERO_STUDENT_MESSAGE); - break; + switch (numberOfStudents) { + case 0: + System.out.println(ZERO_STUDENT_MESSAGE); + break; - case 1: - System.out.println(ONE_STUDENT_MESSAGE); - break; + case 1: + System.out.println(ONE_STUDENT_MESSAGE); + break; - default: - System.out.println(CURRENTLY_THERE_ARE + numberOfStudents + STUDENTS_IN_THE_LIST); - break; + default: + System.out.println(CURRENTLY_THERE_ARE + numberOfStudents + STUDENTS_IN_THE_LIST); + break; } } - //@@author Cryolian + // @@author Cryolian /** * Adds in an instance of a student to the student list. + * * @param s The student to add to the list. */ public void addStudent(Student s) { @@ -71,23 +79,24 @@ public void addStudent(Student s) { /** * Removes a student of a certain id from the student list. + * * @param id The id of the student to remove. */ public void removeStudent(int id) { this.studentList.remove(id); } - - //@@author Cryolian + // @@author Cryolian /** * Removes the first student in the list with a name matching * the given string. + * * @param name The string to search among the names of the student to remove. */ public void removeStudent(String name) { - for (Student s: studentList) { - + for (Student s : studentList) { + if (s.getName().equals(name)) { studentList.remove(s); return; @@ -95,4 +104,29 @@ public void removeStudent(String name) { } } + /** + * Function checks if a name and number pair already exists in a given list. + * Throws an exception if it does. + * @param studentList List to check through for the name and number. + * @param name Name of the student to find. + * @param number Phone number of the student to find. + * @throws nameNumberMatchException Thrown if a match is found. + */ + public static void checkNameNumberPair(ArrayList studentList, String name, int number) + throws nameNumberMatchException { + + for (Student s : studentList) { + if (s.getName().equalsIgnoreCase(name) && s.getPhoneNumber() == number) { + throw new nameNumberMatchException("Student with the same " + + "name and phone number."); + } + //@@author blackmirag3 + assert (s.getName().equalsIgnoreCase(name) && s.getPhoneNumber() == number) + == false: "something went wrong"; + + //@@author Cryolian + } + + } + } diff --git a/src/main/java/classify/student/ViewStudent.java b/src/main/java/classify/student/ViewStudent.java index 68ac6747e2..aafadd1713 100644 --- a/src/main/java/classify/student/ViewStudent.java +++ b/src/main/java/classify/student/ViewStudent.java @@ -39,7 +39,7 @@ public static void viewStudent(ArrayList masterStudentList, Scanner in, assert name != null : "Student name cannot be null"; //@@author tayponghee - Student foundStudent = InputParsing.findStudentByName(masterStudentList, name); + Student foundStudent = InputParsing.findStudentByName(masterStudentList, name, in); if (foundStudent != null) { logger.log(Level.INFO, "Viewing student details: " + name); diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index a7f97ccaf2..19be9478ef 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -19,8 +19,8 @@ public class UI { private static final String STUDENT_GENDER_MESSAGE = "Gender: "; private static final String STUDENT_PAYMENT_MESSAGE = "Last Payment Date: "; private static final String STUDENT_REMARKS_MESSAGE = "Remarks: "; - private static final String SAME_NAME_ERROR = "Student with the same name already exists. " + - "Please enter a different name."; + private static final String SAME_NAME_ERROR = "Name found in existing student. " + + "Please make sure the entered phone number will be unique."; private static final String EMPTY_NAME_ERROR = "Student name cannot be empty. Please enter a valid name."; private static final String GENDER_PROMPT = "Please input the student's gender: "; private static final String PAYMENT_PROMPT = "Please input their last payment date in the format of YYYY-MM-DD. " + diff --git a/src/main/java/classify/user/ClassifyExceptions.java b/src/main/java/classify/user/ClassifyExceptions.java index 7e6de811da..2f4a97947b 100644 --- a/src/main/java/classify/user/ClassifyExceptions.java +++ b/src/main/java/classify/user/ClassifyExceptions.java @@ -1,5 +1,5 @@ package classify.user; -public class ClassifyExceptions extends Exception{ - +public class ClassifyExceptions extends Exception { + } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 169b90c677..3280f1b663 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -38,8 +38,7 @@ public class InputParsing { private static final String ARCHIVE = "archive"; private static final String UNARCHIVE = "unarchive"; private static final String VIEW_SUBJECT = "view_subject"; - private static final String ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK = - "Enter the subject name (type 'exit' to go back):"; + private static final String ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK = "Enter the subject name (type 'exit' to go back):"; private static final String EXIT = "exit"; private static final String EXITED_THE_COMMAND = "Exited the command."; private static final String LIST_SORTED = "Sort complete!"; @@ -49,92 +48,92 @@ public class InputParsing { private static final String LAST_PAID_DATE = "3. Date of last fee payment: "; public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, - ArrayList recentlyDeletedList, - ArrayList archiveList, Scanner in) { + ArrayList recentlyDeletedList, + ArrayList archiveList, Scanner in) { // @@author blackmirag3 if (masterStudentList == null) { System.out.println("Student list is null."); } // @@author tayponghee switch (userCommand[0]) { - case ADD: - AddStudent.addStudent(masterStudentList, in, userCommand[1]); - //@@author ParthGandhiNUS - assert masterStudentList != null; - FileIOCommands.writeStudentInfo(masterStudentList); - break; - - case VIEW: - ViewStudent.viewStudent(masterStudentList, in, userCommand[1]); - UI.printDivider(); - break; + case ADD: + AddStudent.addStudent(masterStudentList, in, userCommand[1]); + // @@author ParthGandhiNUS + assert masterStudentList != null; + FileIOCommands.writeStudentInfo(masterStudentList); + break; + + case VIEW: + ViewStudent.viewStudent(masterStudentList, in, userCommand[1]); + UI.printDivider(); + break; + + // @@author alalal47 + case DELETE: + DeleteCommands.deleteStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); + // @@author ParthGandhiNUS + FileIOCommands.writeStudentInfo(masterStudentList); + // @@author alalal47 + break; + + case RESTORE: + DeleteCommands.restoreStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); + break; + + case UNDO: + DeleteCommands.undoDelete(masterStudentList, recentlyDeletedList); + break; + + case HELP: + UI.printHelp(); + UI.printDivider(); + break; - //@@author alalal47 - case DELETE: - DeleteCommands.deleteStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); // @@author ParthGandhiNUS - FileIOCommands.writeStudentInfo(masterStudentList); - //@@author alalal47 - break; + case BYE: + UI.printEndConversation(); + FileIOCommands.writeStudentInfo(masterStudentList); + break; - case RESTORE: - DeleteCommands.restoreStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); - break; + case LIST: + listStudents(masterStudentList); + break; - case UNDO: - DeleteCommands.undoDelete(masterStudentList, recentlyDeletedList); - break; + // @@ author tayponghee + case SORT: + sortStudents(masterStudentList, in, userCommand[1]); + break; - case HELP: - UI.printHelp(); - UI.printDivider(); - break; + case VIEW_SUBJECT: + handleViewSubjectCommand(masterStudentList, in, userCommand[1]); + break; - // @@author ParthGandhiNUS - case BYE: - UI.printEndConversation(); - FileIOCommands.writeStudentInfo(masterStudentList); - break; - - case LIST: - listStudents(masterStudentList); - break; - - //@@ author tayponghee - case SORT: - sortStudents(masterStudentList, in, userCommand[1]); - break; - - case VIEW_SUBJECT: - handleViewSubjectCommand(masterStudentList, in, userCommand[1]); - break; - - //@@author blackmirag3 - case EDIT: - editStudent(masterStudentList, in, userCommand[1]); - break; - - case ARCHIVE: - archiveStudent(masterStudentList, archiveList, userCommand[1], in); - break; - - case UNARCHIVE: - unarchiveStudent(masterStudentList, archiveList, userCommand[1], in); - break; - - default: - UI.printWrongInput(); - break; + // @@author blackmirag3 + case EDIT: + editStudent(masterStudentList, in, userCommand[1]); + break; + + case ARCHIVE: + archiveStudent(masterStudentList, archiveList, userCommand[1], in); + break; + + case UNARCHIVE: + unarchiveStudent(masterStudentList, archiveList, userCommand[1], in); + break; + + default: + UI.printWrongInput(); + break; } } - //author blackmirag3 + // author blackmirag3 private static void unarchiveStudent(ArrayList masterList, ArrayList archiveList, - String name, Scanner in) { + String name, Scanner in) { if (name == null) { name = Commands.promptName(in); } - Student student = findStudentByName(archiveList, name); + Student student = findStudentByName(archiveList, name, in); if (student == null) { UI.printStudentNotFound(); return; @@ -146,11 +145,11 @@ private static void unarchiveStudent(ArrayList masterList, ArrayList masterList, ArrayList archiveList, - String name, Scanner in) { + String name, Scanner in) { if (name == null) { name = Commands.promptName(in); } - Student student = findStudentByName(masterList, name); + Student student = findStudentByName(masterList, name, in); if (student == null) { UI.printStudentNotFound(); return; @@ -170,7 +169,7 @@ private static void archiveStudent(ArrayList masterList, ArrayList masterStudentList, Scanner in, String sortType) { String input; while (true) { - //@@author alalal47 + // @@author alalal47 if (sortType == null) { UI.println(SORT_BY_CHOOSE_INDEX); UI.println(NAME_A_TO_Z); @@ -180,8 +179,8 @@ private static void sortStudents(ArrayList masterStudentList, Scanner i } else { input = sortType.trim().toLowerCase(); } - //@@author tayponghee - //input = in.nextLine().trim(); + // @@author tayponghee + // input = in.nextLine().trim(); if (input.equalsIgnoreCase(EXIT)) { System.out.println(EXITED_THE_COMMAND); @@ -202,9 +201,11 @@ private static void sortStudents(ArrayList masterStudentList, Scanner i /** * Lets the user check view a list of students with that corresponding subject. - * If the user types view_subject [subject], it will only generate the list of students with that subject, + * If the user types view_subject [subject], it will only generate the list of + * students with that subject, * then exit. - * If the user types view_subject, the user can continuously view all students that + * If the user types view_subject, the user can continuously view all students + * that * have that subject, until they exit the command. * * @param masterStudentList The list of all students. @@ -220,7 +221,8 @@ private static void handleViewSubjectCommand(ArrayList masterStudentLis /** * Finds students with the specified subject and displays them to the user. - * Continuously prompts the user to enter a subject name until they choose to exit. + * Continuously prompts the user to enter a subject name until they choose to + * exit. * * @param masterStudentList The list of all students. * @param in The scanner object to read user input. @@ -282,16 +284,16 @@ private static void editStudent(ArrayList list, Scanner in, String name UI.printEmptyListError(); return; } - + Student student = null; - + if (name != null) { - student = findStudentByName(list, name); + student = findStudentByName(list, name, in); if (student == null) { UI.printStudentNotFound(); } } - + while (student == null) { System.out.println("Name of student to edit (enter blank to exit):"); @@ -302,7 +304,7 @@ private static void editStudent(ArrayList list, Scanner in, String name return; } - student = findStudentByName(list, name); + student = findStudentByName(list, name, in); if (student != null) { break; @@ -310,7 +312,7 @@ private static void editStudent(ArrayList list, Scanner in, String name UI.printStudentNotFound(); } } - + editStudentAttributes(in, student); } @@ -329,21 +331,21 @@ private static void editStudentAttributes(Scanner in, Student student) { switch (command) { - case ADD: - AddStudent.addSubject(in, attributes); - student.setAttributes(attributes); - break; + case ADD: + AddStudent.addSubject(in, attributes); + student.setAttributes(attributes); + break; - case EDIT: - editAttribute(in, attributes); - break; + case EDIT: + editAttribute(in, attributes); + break; - case DELETE: - deleteAttribute(in, attributes); - break; + case DELETE: + deleteAttribute(in, attributes); + break; - default: - break; + default: + break; } } @@ -381,11 +383,11 @@ private static void editAttribute(Scanner in, StudentAttributes attributes) { } double newGrade = promptForGrade(in); - + if (newGrade != -1) { currentSubject.setGrade(newGrade); } - + int newClassesAttended = AddStudent.promptForClassesAttended(in); currentSubject.setClassesAttended(newClassesAttended); System.out.println("Subject updated."); @@ -399,15 +401,15 @@ private static void editAttribute(Scanner in, StudentAttributes attributes) { private static void deleteAttribute(Scanner in, StudentAttributes attributes) { while (true) { - + System.out.println("Subject to delete (enter blank to exit)"); String subjectToDelete = in.nextLine().trim(); - + if (subjectToDelete.isBlank()) { System.out.println("no subject deleted"); return; } - + if (attributes.findSubject(subjectToDelete) != null) { attributes.deleteSubject(subjectToDelete); System.out.println("Subject deleted"); @@ -429,11 +431,11 @@ public static double promptForGrade(Scanner in) { while (true) { UI.printStudentGradesPrompt(); String gradeInput = in.nextLine(); - + if (gradeInput.isBlank()) { return -1; } - + // @@author ParthGandhiNUS double grade; try { @@ -443,7 +445,7 @@ public static double promptForGrade(Scanner in) { UI.printDivider(); grade = promptForGrade(in); } - + if (isValidGrade(grade)) { return grade; } @@ -455,14 +457,64 @@ public static double promptForGrade(Scanner in) { * * @param masterStudentList The list of all students. * @param name The name of the student to search for. - * @return The student object if found, null otherwise. + * @return A list of students with names matching the input. */ - public static Student findStudentByName(ArrayList masterStudentList, String name) { + public static Student findStudentByName(ArrayList masterStudentList, String name, Scanner in) { + + // @@author Cryolian + ArrayList studentsWithMatchingNames = new ArrayList(); for (Student student : masterStudentList) { if (student.getName().equalsIgnoreCase(name)) { - return student; + studentsWithMatchingNames.add(student); + } + } + + if (studentsWithMatchingNames.size() == 0) { + return null; + } + + if (studentsWithMatchingNames.size() == 1) { + return studentsWithMatchingNames.get(0); + } + + UI.printSameNameError(); + return findStudentByNumber(studentsWithMatchingNames, in); + + } + + /** + * Function looks through a list of students with the same name, + * prints them out, and expects an Integer input to specify a student. + * + * @param studentList List of students to look for. + * @param in Scanner to parse in the user input. + * @return Student with rigth name and number pair. + */ + private static Student findStudentByNumber(ArrayList studentList, Scanner in) { + assert studentList.size() > 1 : "List should contain more than one Student"; + + for (Student student : studentList) { + student.printStringNumber(); + } + int number; + + try { + + number = promptForPhoneNumber(in); + + for (Student student : studentList) { + + if (student.getPhoneNumber() == number) { + return student; + } + UI.println("No student found with a matching number. Please try again."); } + + } catch (NumberFormatException e) { + UI.printValidNumberError(); + return null; } + return null; } @@ -499,7 +551,7 @@ private static boolean isValidGrade(double grade) { } } - //@@author Cryolian + // @@author Cryolian /** * Creates a looping prompt asking for a phone number. * Only exits the loop when either an exception is thrown, @@ -507,35 +559,28 @@ private static boolean isValidGrade(double grade) { * the length of a Singaporean number, with or without * the country code. * - * @param in The scanner class to read inputs from. - * @return -1 if an exception was thrown. An 8 - * or 10-digit number if not. + * @param in The scanner class to read inputs from. + * @throws NumberFormatException thrown if invalid number is give + * @return -1 if an exception was thrown. An 8 + * or 10-digit number if not. */ - public static int promptForPhoneNumber(Scanner in) { + public static int promptForPhoneNumber(Scanner in) throws NumberFormatException { int number = 0; - - try { - - do { - UI.printPhoneNumberPrompt(); - number = readInPhoneNumber(in); - } while (!checkNumberValidity(number)); - - LOGGER.log(Level.INFO, "Storing number: " + number); - return number; - } catch (NumberFormatException e) { - UI.printValidNumberError(); - } + do { + UI.printPhoneNumberPrompt(); + number = readInPhoneNumber(in); + } while (!checkNumberValidity(number)); - return -1; + LOGGER.log(Level.INFO, "Storing number: " + number); + return number; } - private static int readInPhoneNumber(Scanner in) throws NumberFormatException{ + private static int readInPhoneNumber(Scanner in) throws NumberFormatException { String input = in.nextLine().trim(); - + return Integer.parseInt(input); } @@ -547,18 +592,18 @@ private static boolean checkNumberValidity(int number) { /** * A prompting input to scan in a string from the user input. * - * @param in The scanner class to scan inputs from. - * @return "Unknown" if blank was inputted, or the - * trimmed string inputted by the user. + * @param in The scanner class to scan inputs from. + * @return "Unknown" if blank was inputted, or the + * trimmed string inputted by the user. */ public static String readInString(Scanner in) { - + String string = in.nextLine(); if (string.isBlank()) { return DEFAULT_STRING_VALUE; - } + } return string.trim(); - + } public static LocalDate readInDate(Scanner in) { @@ -571,7 +616,7 @@ public static LocalDate readInDate(Scanner in) { userInput = in.nextLine(); paymentDate = parseDateFromString(userInput); - } while(!isDateValid(paymentDate)); + } while (!isDateValid(paymentDate)); return paymentDate; } @@ -604,15 +649,15 @@ private static LocalDate printInvalidDateMessage() { private static boolean isDateValid(LocalDate paymentDate) { - if (paymentDate.isAfter(LocalDate.now().plusDays(1)) || + if (paymentDate.isAfter(LocalDate.now().plusDays(1)) || paymentDate.isBefore(LocalDate.parse(EARLIER_POSSIBLE_DATE))) { - + UI.printInvalidDateRangeError(); return false; } return true; - + } } diff --git a/src/main/java/classify/user/nameNumberMatchException.java b/src/main/java/classify/user/nameNumberMatchException.java new file mode 100644 index 0000000000..82f872ce96 --- /dev/null +++ b/src/main/java/classify/user/nameNumberMatchException.java @@ -0,0 +1,8 @@ +package classify.user; + +public class nameNumberMatchException extends Exception{ + + public nameNumberMatchException(String errorMessage) { + super(errorMessage); + } +} From 3b67e533f0dd8cccb9e9e2ae0224f1b69bc7b479 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 31 Mar 2024 19:23:32 +0800 Subject: [PATCH 157/503] Fix checkstyle errors --- .../classify/commands/DeleteCommands.java | 4 +- .../java/classify/student/AddStudent.java | 4 +- .../java/classify/student/StudentList.java | 24 ++-- src/main/java/classify/user/InputParsing.java | 113 +++++++++--------- .../user/nameNumberMatchException.java | 4 +- 5 files changed, 75 insertions(+), 74 deletions(-) diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index 771de0eae7..7c6f60eb3e 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -3,7 +3,7 @@ import classify.student.Student; import classify.student.StudentList; import classify.user.InputParsing; -import classify.user.nameNumberMatchException; +import classify.user.NameNumberMatchException; import classify.ui.UI; import java.util.ArrayList; @@ -83,7 +83,7 @@ public static void restoreStudent(ArrayList masterStudentList, ArrayLis recentlyDeletedList.remove(foundStudent); //@@author Cryolian - } catch (nameNumberMatchException e) { + } catch (NameNumberMatchException e) { return; } diff --git a/src/main/java/classify/student/AddStudent.java b/src/main/java/classify/student/AddStudent.java index 60b27157f6..e91c2742d1 100644 --- a/src/main/java/classify/student/AddStudent.java +++ b/src/main/java/classify/student/AddStudent.java @@ -3,7 +3,7 @@ import classify.ui.UI; import classify.user.InputParsing; -import classify.user.nameNumberMatchException; +import classify.user.NameNumberMatchException; import java.util.ArrayList; import java.util.Scanner; import java.util.logging.Level; @@ -67,7 +67,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, try { StudentList.checkNameNumberPair(StudentList.masterStudentList, name, number); StudentList.checkNameNumberPair(StudentList.recentlyDeletedList, name, number); - } catch (nameNumberMatchException e) { + } catch (NameNumberMatchException e) { return; } diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index ae87577055..1b3fc35d35 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -3,7 +3,7 @@ import java.util.ArrayList; import classify.user.ClassifyExceptions; -import classify.user.nameNumberMatchException; +import classify.user.NameNumberMatchException; /** * Class to represent a list of Students. @@ -52,17 +52,17 @@ public static void printCurrentArrayMessage(ArrayList currentList) { int numberOfStudents = currentList.size(); switch (numberOfStudents) { - case 0: - System.out.println(ZERO_STUDENT_MESSAGE); - break; + case 0: + System.out.println(ZERO_STUDENT_MESSAGE); + break; - case 1: - System.out.println(ONE_STUDENT_MESSAGE); - break; + case 1: + System.out.println(ONE_STUDENT_MESSAGE); + break; - default: - System.out.println(CURRENTLY_THERE_ARE + numberOfStudents + STUDENTS_IN_THE_LIST); - break; + default: + System.out.println(CURRENTLY_THERE_ARE + numberOfStudents + STUDENTS_IN_THE_LIST); + break; } } @@ -113,11 +113,11 @@ public void removeStudent(String name) { * @throws nameNumberMatchException Thrown if a match is found. */ public static void checkNameNumberPair(ArrayList studentList, String name, int number) - throws nameNumberMatchException { + throws NameNumberMatchException { for (Student s : studentList) { if (s.getName().equalsIgnoreCase(name) && s.getPhoneNumber() == number) { - throw new nameNumberMatchException("Student with the same " + + throw new NameNumberMatchException("Student with the same " + "name and phone number."); } //@@author blackmirag3 diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 3280f1b663..3119f93351 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -38,7 +38,8 @@ public class InputParsing { private static final String ARCHIVE = "archive"; private static final String UNARCHIVE = "unarchive"; private static final String VIEW_SUBJECT = "view_subject"; - private static final String ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK = "Enter the subject name (type 'exit' to go back):"; + private static final String ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK = + "Enter the subject name (type 'exit' to go back):"; private static final String EXIT = "exit"; private static final String EXITED_THE_COMMAND = "Exited the command."; private static final String LIST_SORTED = "Sort complete!"; @@ -56,74 +57,74 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas } // @@author tayponghee switch (userCommand[0]) { - case ADD: - AddStudent.addStudent(masterStudentList, in, userCommand[1]); - // @@author ParthGandhiNUS - assert masterStudentList != null; - FileIOCommands.writeStudentInfo(masterStudentList); - break; + case ADD: + AddStudent.addStudent(masterStudentList, in, userCommand[1]); + // @@author ParthGandhiNUS + assert masterStudentList != null; + FileIOCommands.writeStudentInfo(masterStudentList); + break; - case VIEW: - ViewStudent.viewStudent(masterStudentList, in, userCommand[1]); - UI.printDivider(); - break; + case VIEW: + ViewStudent.viewStudent(masterStudentList, in, userCommand[1]); + UI.printDivider(); + break; + // @@author alalal47 + case DELETE: + DeleteCommands.deleteStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); + // @@author ParthGandhiNUS + FileIOCommands.writeStudentInfo(masterStudentList); // @@author alalal47 - case DELETE: - DeleteCommands.deleteStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); - // @@author ParthGandhiNUS - FileIOCommands.writeStudentInfo(masterStudentList); - // @@author alalal47 - break; + break; - case RESTORE: - DeleteCommands.restoreStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); - break; + case RESTORE: + DeleteCommands.restoreStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); + break; - case UNDO: - DeleteCommands.undoDelete(masterStudentList, recentlyDeletedList); - break; + case UNDO: + DeleteCommands.undoDelete(masterStudentList, recentlyDeletedList); + break; - case HELP: - UI.printHelp(); - UI.printDivider(); - break; + case HELP: + UI.printHelp(); + UI.printDivider(); + break; - // @@author ParthGandhiNUS - case BYE: - UI.printEndConversation(); - FileIOCommands.writeStudentInfo(masterStudentList); - break; + // @@author ParthGandhiNUS + case BYE: + UI.printEndConversation(); + FileIOCommands.writeStudentInfo(masterStudentList); + break; - case LIST: - listStudents(masterStudentList); - break; + case LIST: + listStudents(masterStudentList); + break; - // @@ author tayponghee - case SORT: - sortStudents(masterStudentList, in, userCommand[1]); - break; + // @@ author tayponghee + case SORT: + sortStudents(masterStudentList, in, userCommand[1]); + break; - case VIEW_SUBJECT: - handleViewSubjectCommand(masterStudentList, in, userCommand[1]); - break; + case VIEW_SUBJECT: + handleViewSubjectCommand(masterStudentList, in, userCommand[1]); + break; - // @@author blackmirag3 - case EDIT: - editStudent(masterStudentList, in, userCommand[1]); - break; + // @@author blackmirag3 + case EDIT: + editStudent(masterStudentList, in, userCommand[1]); + break; - case ARCHIVE: - archiveStudent(masterStudentList, archiveList, userCommand[1], in); - break; + case ARCHIVE: + archiveStudent(masterStudentList, archiveList, userCommand[1], in); + break; - case UNARCHIVE: - unarchiveStudent(masterStudentList, archiveList, userCommand[1], in); - break; + case UNARCHIVE: + unarchiveStudent(masterStudentList, archiveList, userCommand[1], in); + break; - default: - UI.printWrongInput(); - break; + default: + UI.printWrongInput(); + break; } } @@ -560,9 +561,9 @@ private static boolean isValidGrade(double grade) { * the country code. * * @param in The scanner class to read inputs from. - * @throws NumberFormatException thrown if invalid number is give * @return -1 if an exception was thrown. An 8 * or 10-digit number if not. + * @throws NumberFormatException thrown if invalid number is give */ public static int promptForPhoneNumber(Scanner in) throws NumberFormatException { diff --git a/src/main/java/classify/user/nameNumberMatchException.java b/src/main/java/classify/user/nameNumberMatchException.java index 82f872ce96..5b83b0d175 100644 --- a/src/main/java/classify/user/nameNumberMatchException.java +++ b/src/main/java/classify/user/nameNumberMatchException.java @@ -1,8 +1,8 @@ package classify.user; -public class nameNumberMatchException extends Exception{ +public class NameNumberMatchException extends Exception{ - public nameNumberMatchException(String errorMessage) { + public NameNumberMatchException(String errorMessage) { super(errorMessage); } } From 87b40e959c4808ba4ff4c79a2f0badbd6fb86148 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 31 Mar 2024 19:24:22 +0800 Subject: [PATCH 158/503] Fix checkstyle errors --- src/main/java/classify/student/StudentList.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 1b3fc35d35..2b446671dd 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -2,7 +2,6 @@ import java.util.ArrayList; -import classify.user.ClassifyExceptions; import classify.user.NameNumberMatchException; /** From ec24e6b11ef302b1fac206557e4f9d53b9cbb929 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 31 Mar 2024 19:25:09 +0800 Subject: [PATCH 159/503] Fix indentation --- src/main/java/classify/user/InputParsing.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 3119f93351..50807724e3 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -332,21 +332,21 @@ private static void editStudentAttributes(Scanner in, Student student) { switch (command) { - case ADD: - AddStudent.addSubject(in, attributes); - student.setAttributes(attributes); - break; + case ADD: + AddStudent.addSubject(in, attributes); + student.setAttributes(attributes); + break; - case EDIT: - editAttribute(in, attributes); - break; + case EDIT: + editAttribute(in, attributes); + break; - case DELETE: - deleteAttribute(in, attributes); - break; + case DELETE: + deleteAttribute(in, attributes); + break; - default: - break; + default: + break; } } From e5a9f300daa57a56d9eed3737adf6b0b7466ab3e Mon Sep 17 00:00:00 2001 From: Cryolian <102575848+Cryolian@users.noreply.github.com> Date: Sun, 31 Mar 2024 19:28:03 +0800 Subject: [PATCH 160/503] Change file name --- ...ameNumberMatchException.java => NameNumberMatchException.java} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/main/java/classify/user/{nameNumberMatchException.java => NameNumberMatchException.java} (100%) diff --git a/src/main/java/classify/user/nameNumberMatchException.java b/src/main/java/classify/user/NameNumberMatchException.java similarity index 100% rename from src/main/java/classify/user/nameNumberMatchException.java rename to src/main/java/classify/user/NameNumberMatchException.java From 6502d6ec43d4ec0361a9df4530ca706697b8b9df Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 31 Mar 2024 19:29:12 +0800 Subject: [PATCH 161/503] Fix author tag --- src/main/java/classify/commands/DeleteCommands.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index 7c6f60eb3e..a17bc9ef43 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -88,7 +88,8 @@ public static void restoreStudent(ArrayList masterStudentList, ArrayLis } } - + + //@@author blackmirag3 /** * Restores the latest deleted student that has not yet been restored * From 16c860506ac7250e4217ab1f26a9b398743e8e3b Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 31 Mar 2024 19:45:07 +0800 Subject: [PATCH 162/503] Add author tags --- src/main/java/classify/commands/ListStudentsCommand.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 2960296ded..6d2c28a0b7 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.Scanner; +//@@ author tayponghee public class ListStudentsCommand { private static final String ONE = "1"; @@ -75,12 +76,13 @@ private static void listAllStudents(ArrayList masterStudentList) { UI.println(FULL_STUDENT_LIST); StudentList.printCurrentArrayList(masterStudentList); - //@@ ParthGandhiNUS + //@@ author ParthGandhiNUS StudentList.printCurrentArrayMessage(masterStudentList); UI.printDivider(); break; + //@@author tayponghee case TWO: UI.println(LIST_OF_STUDENTS_WITH_TOTAL_CLASSES_ATTENDED); From d3aa4a732bfd4d75a52b83a4634a9403d61fb702 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 31 Mar 2024 22:36:50 +0800 Subject: [PATCH 163/503] Fix minor bugs --- docs/UserGuide.md | 8 +- src/main/java/classify/FallenCode.java | 54 - .../{student => commands}/AddStudent.java | 22 +- .../classify/commands/DeleteCommands.java | 4 +- .../classify/commands/FileIOCommands.java | 2 + .../StudentComparators.java | 4 +- .../{student => commands}/StudentSorter.java | 5 +- .../{student => commands}/ViewStudent.java | 5 +- src/main/java/classify/data/DataReader.java | 10 - .../classify/user/ClassifyExceptions.java | 1168 +++++++++++++++++ src/main/java/classify/user/InputParsing.java | 12 +- .../classify/student/StudentSorterTest.java | 2 + 12 files changed, 1209 insertions(+), 87 deletions(-) delete mode 100644 src/main/java/classify/FallenCode.java rename src/main/java/classify/{student => commands}/AddStudent.java (93%) rename src/main/java/classify/{student => commands}/StudentComparators.java (88%) rename src/main/java/classify/{student => commands}/StudentSorter.java (97%) rename src/main/java/classify/{student => commands}/ViewStudent.java (96%) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 28c39f8830..3e6dbadad1 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -86,13 +86,17 @@ Sorts the masterlist of students from the oldest date to the most recent. When t ### Adding a student: `add` Initialises an interface for adding a student and their relevant details to the database. Allows the user to do add or add [name] -**to change** -Currently, no two students can have the same name within the system. +Students of the same name can be added so long as they possess a different phone number. Students with the same phone number can be added so long as they have different names. Format: `add` or `add NAME` Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. +Please note that the user input NUMBER (shown below) must be an *8 digit number starting with 8 or 9*. +Thus, please be informed and educated that our software only works in countries that have phone numbers that are 8 digits long and start with 8 or 9. +To be specific, this is referring to a city-state republic in South East Asia, that lies in the timezone GMT +8 in the Straits of Johor. +Some may debate that our time zone is actually GMT+7.5 or GMT+7, but it was changed to facilitate business deals and decisions with other financial hubs in the region thanks to our capitalistic overlords. + Example: ``` add wario diff --git a/src/main/java/classify/FallenCode.java b/src/main/java/classify/FallenCode.java deleted file mode 100644 index e4eeedbd1b..0000000000 --- a/src/main/java/classify/FallenCode.java +++ /dev/null @@ -1,54 +0,0 @@ -package classify; -//import classify.student.StudentList; - -//import classify.Commands.Ui; -//import classify.student.Master; - -//import java.util.Scanner; - -//@@author ParthGandhiNUS -public class FallenCode { -// while (!(userCommand.equals("bye"))){ -// InputParsing.parseUserCommand(UserInput.processInput(userCommand), StudentList.masterStudentList, in); -// } -// -// //for master class -// while (!(userCommand.equals("bye"))){ -// InputParsing.parseUserCommand(UserInput.processInput(userCommand), masterStudentList, in); -// } - -// public static void parseUserCommand(String UserCommand, Master studentList, Scanner in){ -// switch (UserCommand) { -// case BYE: -// break; -// -// case LIST: -// Ui.printDivider(); -// break; -// } -// } - - //@@author Cryolian - // public Class getCurrentClass() { - // return currentClass; - // } - // public void setCurrentClass(Class currentClass) { - // this.currentClass = currentClass; - // } - - // /** - // * Add a student as attending this class. - // * @param s Student to add to the class. - // */ - // public void addStudent(Student s) { - // this.studentList.addStudent(s); - // } - - /* - //@@author tayponghee - if (attributes.getSubjectGrades().isEmpty()) { - System.out.println("At least one subject must be provided. Please add subjects and grades."); - Ui.printDivider(); - attributeInput(in, attributes); - }*/ -} diff --git a/src/main/java/classify/student/AddStudent.java b/src/main/java/classify/commands/AddStudent.java similarity index 93% rename from src/main/java/classify/student/AddStudent.java rename to src/main/java/classify/commands/AddStudent.java index e91c2742d1..7ce092aaa7 100644 --- a/src/main/java/classify/student/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -1,6 +1,10 @@ -package classify.student; +package classify.commands; +import classify.student.Student; +import classify.student.StudentAttributes; +import classify.student.StudentList; +import classify.student.SubjectGrade; import classify.ui.UI; import classify.user.InputParsing; import classify.user.NameNumberMatchException; @@ -10,6 +14,7 @@ import static classify.user.InputParsing.LOGGER; +//@@author tayponghee public class AddStudent { private static final String NOTEMPTY = "THIS STRING IS NOT EMPTY"; private static final String YES = "yes"; @@ -36,15 +41,6 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, String name; name = checkForEmptyName(masterStudentList, in, studentName); - - //Check removed due to implementation of phone number identification. - // if (InputParsing.findStudentByName(masterStudentList, name) != null) { - // assert InputParsing.findStudentByName(masterStudentList, name) != null; - // LOGGER.log(Level.WARNING, STUDENT_WITH_THE_SAME_NAME_ALREADY_EXISTS); - - // UI.printSameNameError(); - // UI.printDivider(); - // } Student student = new Student(name); addSubject(in, student.getAttributes()); @@ -56,6 +52,8 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, number = InputParsing.promptForPhoneNumber(in); } catch (NumberFormatException e) { UI.printValidNumberError(); + UI.println("Exiting the adding interface."); + UI.printDivider(); return; } @@ -68,6 +66,9 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, StudentList.checkNameNumberPair(StudentList.masterStudentList, name, number); StudentList.checkNameNumberPair(StudentList.recentlyDeletedList, name, number); } catch (NameNumberMatchException e) { + UI.println("Student and Phone number pair found. Please input a new name" + + " or a new phone number"); + UI.printDivider(); return; } @@ -87,6 +88,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, LOGGER.log(Level.INFO, STUDENT_ADDED_SUCCESSFULLY); UI.printStudentAdded(); UI.printDivider(); + FileIOCommands.writeStudentInfo(masterStudentList); } /** diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index a17bc9ef43..250e76ee42 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -44,8 +44,8 @@ public static void deleteStudent(ArrayList masterStudentList, ArrayList recentlyDeletedList.add(foundStudent); } masterStudentList.remove(foundStudent); - //assert may be false after implementation of phone number indentification - // assert InputParsing.findStudentByName(masterStudentList, studentName) == null : "Student should be deleted"; + FileIOCommands.writeStudentInfo(masterStudentList); + } /** diff --git a/src/main/java/classify/commands/FileIOCommands.java b/src/main/java/classify/commands/FileIOCommands.java index 6fd8b0fa5c..b0f65357bc 100644 --- a/src/main/java/classify/commands/FileIOCommands.java +++ b/src/main/java/classify/commands/FileIOCommands.java @@ -34,6 +34,7 @@ public static void writeStudentInfo(List list){ */ public static void readStudentInfo(ArrayList list) throws IOException{ try{ + System.out.println("Trying to load Student info"); DataWriter.createParentFileFolder(DATA_DIRECTORY_PATH); DataReader.initialiseData(list, DATA_FILE_PATH); } catch (IOException e) { @@ -60,6 +61,7 @@ public static void writeArchive(List list){ */ public static void readArchive(ArrayList list) throws IOException { try{ + System.out.println("Trying to load Student Archive."); DataWriter.createParentFileFolder(ARCHIVE_DIRECTORY_PATH); DataReader.initialiseData(list, ARCHIVE_FILE_PATH); } catch (IOException e) { diff --git a/src/main/java/classify/student/StudentComparators.java b/src/main/java/classify/commands/StudentComparators.java similarity index 88% rename from src/main/java/classify/student/StudentComparators.java rename to src/main/java/classify/commands/StudentComparators.java index b8664f12b9..57da0900b2 100644 --- a/src/main/java/classify/student/StudentComparators.java +++ b/src/main/java/classify/commands/StudentComparators.java @@ -1,7 +1,9 @@ -package classify.student; +package classify.commands; import java.util.Comparator; +import classify.student.Student; + public class StudentComparators { //@@author tayponghee public static Comparator nameComparator = Comparator.comparing(Student::getName); diff --git a/src/main/java/classify/student/StudentSorter.java b/src/main/java/classify/commands/StudentSorter.java similarity index 97% rename from src/main/java/classify/student/StudentSorter.java rename to src/main/java/classify/commands/StudentSorter.java index 9663beac05..8932c1f61c 100644 --- a/src/main/java/classify/student/StudentSorter.java +++ b/src/main/java/classify/commands/StudentSorter.java @@ -1,5 +1,8 @@ -package classify.student; +package classify.commands; +import classify.student.Student; +import classify.student.StudentAttributes; +import classify.student.SubjectGrade; import classify.ui.UI; import java.util.ArrayList; diff --git a/src/main/java/classify/student/ViewStudent.java b/src/main/java/classify/commands/ViewStudent.java similarity index 96% rename from src/main/java/classify/student/ViewStudent.java rename to src/main/java/classify/commands/ViewStudent.java index aafadd1713..c69cef1228 100644 --- a/src/main/java/classify/student/ViewStudent.java +++ b/src/main/java/classify/commands/ViewStudent.java @@ -1,5 +1,8 @@ -package classify.student; +package classify.commands; +import classify.student.Student; +import classify.student.StudentAttributes; +import classify.student.SubjectGrade; import classify.ui.UI; import classify.user.InputParsing; diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index cc969294ad..2903158049 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -35,16 +35,6 @@ public static void restoreStudentList(String studentFileInput, ArrayList mas AddStudent.addStudent(masterStudentList, in, userCommand[1]); // @@author ParthGandhiNUS assert masterStudentList != null; - FileIOCommands.writeStudentInfo(masterStudentList); + break; case VIEW: @@ -73,7 +73,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas case DELETE: DeleteCommands.deleteStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); // @@author ParthGandhiNUS - FileIOCommands.writeStudentInfo(masterStudentList); + // @@author alalal47 break; @@ -566,7 +566,7 @@ private static int readInPhoneNumber(Scanner in) throws NumberFormatException { } private static boolean checkNumberValidity(int number) { - return number > 0 && + return number > 0 && number > 80000000 && String.valueOf(number).length() == LOWER_LIMIT_PHONE_NUMBER; } diff --git a/src/test/java/classify/student/StudentSorterTest.java b/src/test/java/classify/student/StudentSorterTest.java index 0b1955899c..7c89fb8c6a 100644 --- a/src/test/java/classify/student/StudentSorterTest.java +++ b/src/test/java/classify/student/StudentSorterTest.java @@ -2,6 +2,8 @@ import org.junit.jupiter.api.Test; +import classify.commands.StudentSorter; + import java.util.ArrayList; import static org.junit.jupiter.api.Assertions.assertEquals; From 385d14572980e8c7b6e2f04619629100cc2489f6 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 31 Mar 2024 22:41:54 +0800 Subject: [PATCH 164/503] Fix checkstyle errors --- .../classify/user/ClassifyExceptions.java | 177 +----------------- 1 file changed, 1 insertion(+), 176 deletions(-) diff --git a/src/main/java/classify/user/ClassifyExceptions.java b/src/main/java/classify/user/ClassifyExceptions.java index e83054ec68..16cb41a65b 100644 --- a/src/main/java/classify/user/ClassifyExceptions.java +++ b/src/main/java/classify/user/ClassifyExceptions.java @@ -1,6 +1,6 @@ //@@author blackmirag3 /** - * + * sdsdsds * * * @@ -115,67 +115,6 @@ * * * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣤⣤⣤⣤⣤⣤⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⡿⠛⠉⠙⠛⠛⠛⠛⠻⢿⣿⣷⣤⡀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⠋⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⠈⢻⣿⣿⡄⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣸⣿⡏⠀⠀⠀⣠⣶⣾⣿⣿⣿⠿⠿⠿⢿⣿⣿⣿⣄⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠁⠀⠀⢰⣿⣿⣯⠁⠀⠀⠀⠀⠀⠀⠀⠈⠙⢿⣷⡄⠀ -⠀⠀⣀⣤⣴⣶⣶⣿⡟⠀⠀⠀⢸⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣷⠀ -⠀⢰⣿⡟⠋⠉⣹⣿⡇⠀⠀⠀⠘⣿⣿⣿⣿⣷⣦⣤⣤⣤⣶⣶⣶⣶⣿⣿⣿⠀ -⠀⢸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀ -⠀⣸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠉⠻⠿⣿⣿⣿⣿⡿⠿⠿⠛⢻⣿⡇⠀⠀ -⠀⣿⣿⠁⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣧⠀⠀ -⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ -⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ -⠀⢿⣿⡆⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡇⠀⠀ -⠀⠸⣿⣧⡀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠃⠀⠀ -⠀⠀⠛⢿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⣰⣿⣿⣷⣶⣶⣶⣶⠶⠀⢠⣿⣿⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⣽⣿⡏⠁⠀⠀⢸⣿⡇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⢹⣿⡆⠀⠀⠀⣸⣿⠇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⢿⣿⣦⣄⣀⣠⣴⣿⣿⠁⠀⠈⠻⣿⣿⣿⣿⡿⠏⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠈⠛⠻⠿⠿⠿⠿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ * * * @@ -302,25 +241,6 @@ * * * - * ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣤⣤⣤⣤⣤⣤⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⡿⠛⠉⠙⠛⠛⠛⠛⠻⢿⣿⣷⣤⡀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⠋⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⠈⢻⣿⣿⡄⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣸⣿⡏⠀⠀⠀⣠⣶⣾⣿⣿⣿⠿⠿⠿⢿⣿⣿⣿⣄⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠁⠀⠀⢰⣿⣿⣯⠁⠀⠀⠀⠀⠀⠀⠀⠈⠙⢿⣷⡄⠀ -⠀⠀⣀⣤⣴⣶⣶⣿⡟⠀⠀⠀⢸⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣷⠀ -⠀⢰⣿⡟⠋⠉⣹⣿⡇⠀⠀⠀⠘⣿⣿⣿⣿⣷⣦⣤⣤⣤⣶⣶⣶⣶⣿⣿⣿⠀ -⠀⢸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀ -⠀⣸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠉⠻⠿⣿⣿⣿⣿⡿⠿⠿⠛⢻⣿⡇⠀⠀ -⠀⣿⣿⠁⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣧⠀⠀ -⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ -⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ -⠀⢿⣿⡆⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡇⠀⠀ -⠀⠸⣿⣧⡀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠃⠀⠀ -⠀⠀⠛⢿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⣰⣿⣿⣷⣶⣶⣶⣶⠶⠀⢠⣿⣿⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⣽⣿⡏⠁⠀⠀⢸⣿⡇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⢹⣿⡆⠀⠀⠀⣸⣿⠇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⢿⣿⣦⣄⣀⣠⣴⣿⣿⠁⠀⠈⠻⣿⣿⣿⣿⡿⠏⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠈⠛⠻⠿⠿⠿⠿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ * * * @@ -470,25 +390,6 @@ * * * - * ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣤⣤⣤⣤⣤⣤⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⡿⠛⠉⠙⠛⠛⠛⠛⠻⢿⣿⣷⣤⡀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⠋⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⠈⢻⣿⣿⡄⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣸⣿⡏⠀⠀⠀⣠⣶⣾⣿⣿⣿⠿⠿⠿⢿⣿⣿⣿⣄⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠁⠀⠀⢰⣿⣿⣯⠁⠀⠀⠀⠀⠀⠀⠀⠈⠙⢿⣷⡄⠀ -⠀⠀⣀⣤⣴⣶⣶⣿⡟⠀⠀⠀⢸⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣷⠀ -⠀⢰⣿⡟⠋⠉⣹⣿⡇⠀⠀⠀⠘⣿⣿⣿⣿⣷⣦⣤⣤⣤⣶⣶⣶⣶⣿⣿⣿⠀ -⠀⢸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀ -⠀⣸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠉⠻⠿⣿⣿⣿⣿⡿⠿⠿⠛⢻⣿⡇⠀⠀ -⠀⣿⣿⠁⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣧⠀⠀ -⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ -⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ -⠀⢿⣿⡆⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡇⠀⠀ -⠀⠸⣿⣧⡀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠃⠀⠀ -⠀⠀⠛⢿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⣰⣿⣿⣷⣶⣶⣶⣶⠶⠀⢠⣿⣿⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⣽⣿⡏⠁⠀⠀⢸⣿⡇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⢹⣿⡆⠀⠀⠀⣸⣿⠇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⢿⣿⣦⣄⣀⣠⣴⣿⣿⠁⠀⠈⠻⣿⣿⣿⣿⡿⠏⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠈⠛⠻⠿⠿⠿⠿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ * * * @@ -601,25 +502,6 @@ * * * - * ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣤⣤⣤⣤⣤⣤⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⡿⠛⠉⠙⠛⠛⠛⠛⠻⢿⣿⣷⣤⡀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⠋⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⠈⢻⣿⣿⡄⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣸⣿⡏⠀⠀⠀⣠⣶⣾⣿⣿⣿⠿⠿⠿⢿⣿⣿⣿⣄⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠁⠀⠀⢰⣿⣿⣯⠁⠀⠀⠀⠀⠀⠀⠀⠈⠙⢿⣷⡄⠀ -⠀⠀⣀⣤⣴⣶⣶⣿⡟⠀⠀⠀⢸⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣷⠀ -⠀⢰⣿⡟⠋⠉⣹⣿⡇⠀⠀⠀⠘⣿⣿⣿⣿⣷⣦⣤⣤⣤⣶⣶⣶⣶⣿⣿⣿⠀ -⠀⢸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀ -⠀⣸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠉⠻⠿⣿⣿⣿⣿⡿⠿⠿⠛⢻⣿⡇⠀⠀ -⠀⣿⣿⠁⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣧⠀⠀ -⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ -⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ -⠀⢿⣿⡆⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡇⠀⠀ -⠀⠸⣿⣧⡀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠃⠀⠀ -⠀⠀⠛⢿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⣰⣿⣿⣷⣶⣶⣶⣶⠶⠀⢠⣿⣿⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⣽⣿⡏⠁⠀⠀⢸⣿⡇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⢹⣿⡆⠀⠀⠀⣸⣿⠇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⢿⣿⣦⣄⣀⣠⣴⣿⣿⠁⠀⠈⠻⣿⣿⣿⣿⡿⠏⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠈⠛⠻⠿⠿⠿⠿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ * * * @@ -902,25 +784,6 @@ * * * - * ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣤⣤⣤⣤⣤⣤⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⡿⠛⠉⠙⠛⠛⠛⠛⠻⢿⣿⣷⣤⡀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⠋⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⠈⢻⣿⣿⡄⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣸⣿⡏⠀⠀⠀⣠⣶⣾⣿⣿⣿⠿⠿⠿⢿⣿⣿⣿⣄⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠁⠀⠀⢰⣿⣿⣯⠁⠀⠀⠀⠀⠀⠀⠀⠈⠙⢿⣷⡄⠀ -⠀⠀⣀⣤⣴⣶⣶⣿⡟⠀⠀⠀⢸⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣷⠀ -⠀⢰⣿⡟⠋⠉⣹⣿⡇⠀⠀⠀⠘⣿⣿⣿⣿⣷⣦⣤⣤⣤⣶⣶⣶⣶⣿⣿⣿⠀ -⠀⢸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀ -⠀⣸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠉⠻⠿⣿⣿⣿⣿⡿⠿⠿⠛⢻⣿⡇⠀⠀ -⠀⣿⣿⠁⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣧⠀⠀ -⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ -⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ -⠀⢿⣿⡆⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡇⠀⠀ -⠀⠸⣿⣧⡀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠃⠀⠀ -⠀⠀⠛⢿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⣰⣿⣿⣷⣶⣶⣶⣶⠶⠀⢠⣿⣿⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⣽⣿⡏⠁⠀⠀⢸⣿⡇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⢹⣿⡆⠀⠀⠀⣸⣿⠇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⢿⣿⣦⣄⣀⣠⣴⣿⣿⠁⠀⠈⠻⣿⣿⣿⣿⡿⠏⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠈⠛⠻⠿⠿⠿⠿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ * * * @@ -930,25 +793,6 @@ * * * - * ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣤⣤⣤⣤⣤⣤⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⡿⠛⠉⠙⠛⠛⠛⠛⠻⢿⣿⣷⣤⡀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⠋⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⠈⢻⣿⣿⡄⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣸⣿⡏⠀⠀⠀⣠⣶⣾⣿⣿⣿⠿⠿⠿⢿⣿⣿⣿⣄⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠁⠀⠀⢰⣿⣿⣯⠁⠀⠀⠀⠀⠀⠀⠀⠈⠙⢿⣷⡄⠀ -⠀⠀⣀⣤⣴⣶⣶⣿⡟⠀⠀⠀⢸⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣷⠀ -⠀⢰⣿⡟⠋⠉⣹⣿⡇⠀⠀⠀⠘⣿⣿⣿⣿⣷⣦⣤⣤⣤⣶⣶⣶⣶⣿⣿⣿⠀ -⠀⢸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀ -⠀⣸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠉⠻⠿⣿⣿⣿⣿⡿⠿⠿⠛⢻⣿⡇⠀⠀ -⠀⣿⣿⠁⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣧⠀⠀ -⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ -⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ -⠀⢿⣿⡆⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡇⠀⠀ -⠀⠸⣿⣧⡀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠃⠀⠀ -⠀⠀⠛⢿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⣰⣿⣿⣷⣶⣶⣶⣶⠶⠀⢠⣿⣿⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⣽⣿⡏⠁⠀⠀⢸⣿⡇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⢹⣿⡆⠀⠀⠀⣸⣿⠇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⢿⣿⣦⣄⣀⣠⣴⣿⣿⠁⠀⠈⠻⣿⣿⣿⣿⡿⠏⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠈⠛⠻⠿⠿⠿⠿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ * * * @@ -1129,25 +973,6 @@ * * * - * ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣤⣤⣤⣤⣤⣤⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⣿⡿⠛⠉⠙⠛⠛⠛⠛⠻⢿⣿⣷⣤⡀⠀⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⠋⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⠈⢻⣿⣿⡄⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣸⣿⡏⠀⠀⠀⣠⣶⣾⣿⣿⣿⠿⠿⠿⢿⣿⣿⣿⣄⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠁⠀⠀⢰⣿⣿⣯⠁⠀⠀⠀⠀⠀⠀⠀⠈⠙⢿⣷⡄⠀ -⠀⠀⣀⣤⣴⣶⣶⣿⡟⠀⠀⠀⢸⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣷⠀ -⠀⢰⣿⡟⠋⠉⣹⣿⡇⠀⠀⠀⠘⣿⣿⣿⣿⣷⣦⣤⣤⣤⣶⣶⣶⣶⣿⣿⣿⠀ -⠀⢸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠃⠀ -⠀⣸⣿⡇⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠉⠻⠿⣿⣿⣿⣿⡿⠿⠿⠛⢻⣿⡇⠀⠀ -⠀⣿⣿⠁⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣧⠀⠀ -⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ -⠀⣿⣿⠀⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⠀⠀ -⠀⢿⣿⡆⠀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⡇⠀⠀ -⠀⠸⣿⣧⡀⠀⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⠃⠀⠀ -⠀⠀⠛⢿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⣰⣿⣿⣷⣶⣶⣶⣶⠶⠀⢠⣿⣿⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⣽⣿⡏⠁⠀⠀⢸⣿⡇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⠀⠀⠀⣿⣿⡇⠀⢹⣿⡆⠀⠀⠀⣸⣿⠇⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⢿⣿⣦⣄⣀⣠⣴⣿⣿⠁⠀⠈⠻⣿⣿⣿⣿⡿⠏⠀⠀⠀⠀ -⠀⠀⠀⠀⠀⠀⠀⠈⠛⠻⠿⠿⠿⠿⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ * * * From e52e10e2792036209a81899a7e46303e0621d0fa Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 31 Mar 2024 22:49:21 +0800 Subject: [PATCH 165/503] Fix author tags --- src/main/java/classify/user/InputParsing.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 42f7daa8f3..55d3feb7f6 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -132,14 +132,14 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas } } - //@@ author tayponghee + //@@author tayponghee public static void parseListCommand(ArrayList masterStudentList, Scanner scanner) { UI.printListCommandStart(); String subject = scanner.nextLine().trim(); ListStudentsCommand.chooseListType(masterStudentList, scanner, subject); } - //author blackmirag3 + //@@author blackmirag3 private static void unarchiveStudent(ArrayList masterList, ArrayList archiveList, String name, Scanner in) { if (name == null) { @@ -259,7 +259,7 @@ private static void findStudentsWithSubject(ArrayList masterStudentList } } - // @@author blackmirag3 + //@@author blackmirag3 private static void editStudent(ArrayList list, Scanner in, String name) { if (list.isEmpty()) { UI.printEmptyListError(); @@ -332,7 +332,7 @@ private static void editStudentAttributes(Scanner in, Student student) { } } - // @@author blackmirag3 + //@@author blackmirag3 /** * Prompts the user to edit subject, grade, and classes attended for student. * Continues to prompt the user until user enters blank to exit. @@ -442,7 +442,7 @@ public static double promptForGrade(Scanner in) { */ public static Student findStudentByName(ArrayList masterStudentList, String name, Scanner in) { - // @@author Cryolian + //@@author Cryolian ArrayList studentsWithMatchingNames = new ArrayList(); for (Student student : masterStudentList) { if (student.getName().equalsIgnoreCase(name)) { @@ -499,7 +499,7 @@ private static Student findStudentByNumber(ArrayList studentList, Scann return null; } - // @@author blackmirag3 + //@@author blackmirag3 public static boolean isValidClassesAttended(int classesAttended) { try { if (classesAttended < 0) { From f06ff4b6feb84cca199886c4ee436ab14907c633 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Mon, 1 Apr 2024 13:49:34 +0800 Subject: [PATCH 166/503] Remove unnecessary code --- src/main/java/classify/Classify.java | 9 +- .../classify/user/ClassifyExceptions.java | 992 ------------------ 2 files changed, 5 insertions(+), 996 deletions(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index ae422b2dcf..0483626ded 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -19,12 +19,13 @@ public class Classify { * @throws IOException Thrown when error reading file. */ public static void main(String[] args) throws IOException { - - // @@author ParthGandhiNUS - UI.printWelcomeMessage(); - UI.printUserPrompt(); + //@@author blackmirag3 FileIOCommands.readStudentInfo(StudentList.masterStudentList); FileIOCommands.readArchive(StudentList.archiveList); + // @@author ParthGandhiNUS + UI.printWelcomeMessage(); + UI.printUserPrompt(); + // Takes in input from the user, and processes input to determine if it contains a command and a name String[] userCommand = UserInput.processInput(in.nextLine()); diff --git a/src/main/java/classify/user/ClassifyExceptions.java b/src/main/java/classify/user/ClassifyExceptions.java index 16cb41a65b..0892de4e64 100644 --- a/src/main/java/classify/user/ClassifyExceptions.java +++ b/src/main/java/classify/user/ClassifyExceptions.java @@ -1,996 +1,4 @@ //@@author blackmirag3 -/** - * sdsdsds - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * d - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * this is an experiment to see how line contributions work, and if it adds to your reposense. - */ package classify.user; public class ClassifyExceptions extends Exception { From 42f137c443714e2d3ca867da72410888a306f020 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Tue, 2 Apr 2024 13:41:34 +0800 Subject: [PATCH 167/503] Add all list commands to UG --- docs/UserGuide.md | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 3e6dbadad1..46e9bde12a 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -60,14 +60,14 @@ Removes a student from the master list of students. Displays a list of all the students with that associated subject taken in the tuition centre. -### Produce a list of all students with total classes attended `list`, enter, enter, `2` - -Displays a list of all the students with their total classes attended at the tuition centre. - ### Produce a list of all students `list`, enter, enter, `1` Displays a list of all the students at the tuition centre with no other parameters shown. +### Produce a list of all students with total classes attended `list`, enter, enter, `2` + +Displays a list of all the students with their total classes attended at the tuition centre. + ### - Sort the list lexicographically, from A to Z `sort name` Sorts the masterlist of students from A to Z. When the user types list, it will generate the updated sorted list. @@ -233,8 +233,14 @@ Sort complete! ### `add ` Adds a student into the list. If the name of the student is not specified in the initial command, the program will prompt the user for the name. -### `list` -Displays the list of students. +### `list`, press enter, [subject] +Displays the list of students that has taken that subject. + +### `list`, press enter, press enter, [1] +Displays the list of students that is registered in the tuition centre. + +### `list`, press enter, press enter, [2] +Displays the list of students that is registered in the tuition centre with the total number of classes taken. ### `view ` Views a students details. If the name of the student is not specified in the initial command, the program will prompt the user for the name. From a9a33fc09cc71f241c44db697571f2fd532f15c1 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Tue, 2 Apr 2024 15:01:32 +0800 Subject: [PATCH 168/503] Add sequence diagrams and update DG --- docs/DeveloperGuide.md | 18 +++-- .../diagrams/src/DataStoring/DataStoring.puml | 4 +- .../DataStoring/Student Identification.png | Bin 0 -> 36585 bytes .../DataStoring/studentIdentification.puml | 62 ++++++++++++++++++ .../InputParsingSequenceDiagram.png | Bin 0 -> 25816 bytes .../src/InputParsing/SequenceDiagram.puml | 42 ++++++++++++ 6 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 docs/diagrams/src/DataStoring/Student Identification.png create mode 100644 docs/diagrams/src/DataStoring/studentIdentification.puml create mode 100644 docs/diagrams/src/InputParsing/InputParsingSequenceDiagram.png create mode 100644 docs/diagrams/src/InputParsing/SequenceDiagram.puml diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 744e6a8d0d..ea49230304 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -41,13 +41,15 @@ This component ensures that the user parses in commands in a format that makes s #### Implementation and rationale +![InputParsingSequenceDigram](./diagrams/src/InputParsing/InputParsingSequenceDiagram.png) + The InputParsing class is designed to handle the considerations above by breaking down the input given by the user in a well structured process. Below is how the InputParsing class works: -1. Splitting User Input: The Parser would take on the user's input and split it into 2 parts, which is the command and the argument, if any. +1. Splitting User Input: The Parser would take on the user's input and split it into 2 parts, which is the command and the argument, if any. this is done by the `UserInput` Class -2. Command recognition: Depending on the command and the argument given, if any, the parser would execute the command as per defined by the program. If the command and/or argument given is invalid/undefined, the input parser would generate a message to the user, informing them of the command's invalidity. +2. Command recognition: Depending on the command and the argument given, if any, the parser would execute the command as per defined by the program. If the command and/or argument given is invalid/undefined, the input parser would generate a message to the user, informing them of the command's invalidity. This is done by the `InputParsing` Class. -3. Argument extraction: Depending on the specific command, if an argument can be parsed into that command, the parser would understand the argument and execute the sub-command specified by the user. Should the argument be invalid, the user would be informed of the argument's invalidity. +3. Argument extraction: Depending on the specific command, if an argument can be parsed into that command, the parser would understand the argument and execute the sub-command specified by the user. Should the argument be invalid, the user would be informed of the argument's invalidity. This is also done by the `InputParsing` Class. Through structuring the InputParsing class in such a manner, the application ensures that the user input is correctly parsed into executable commands for the subsequent phases of the application. @@ -65,6 +67,8 @@ Given below is an example of how a user may add a student to the data base. - Assuming the name "wario" did not exist in the masterlist beforehand, the parser would grant the user's request to add the student to the masterlist. - This `add wario` command is equivalent to having the user first type `add`, then after waiting fo the program to respond, type `wario`. In the latter scenario, the input parser deems that an argument was not present, and thus will ask the user to give the name of the student that they would like to add. +All the while these commands are being processed, the runtime database `masterStudentList` is being updated, and subsequently being written to the stored database under the `data/studentInfo/Student_information.txt` file. + ### Student Details @@ -84,13 +88,19 @@ A `Student` is made up of a list of the subjects they are taking, along with rel Storage of these details are handled via the `StudentsAttributes` class when the user package calls upon its methods. To ensure easy access of information from either a `Student` object, and be able to retrieve the `Student` parent when having access to an `StudentAttributes` object, we linked both `Student` and `StudentAttribute`. -Since both classes are referencing each other, it was easy for us to link it with the input parsing system, where we would just need a student's name (we have yet to account for repeat names; only showing a warning) to be able to edit their details. +Since both classes are referencing each other, it was easy for us to link it with the input parsing system, where we would just need a student's name, and maybe their number if there are multiple students with the same name, to be able to edit their details. + +Please see the diagram below to see how identifying a student works. + +![studentIdentification](./diagrams/src/DataStoring/Student%20Identification.png) We created a parent `Details` class as those are information not specifically related to students. It can thus be repurposed in future updates should we wish to expand this application into a personnel management system, which would include employees of the tuition centre. However, our current implementation is not very secure as one can access every field of a `Student` object just by having access to it or the `StudentAttribute` object, which can be done via accessing the `static masterStudentList` variable.In future updates, we could possibly implement a Facade Pattern to better hide sensitive details. + + ### Data Commands Component This section refers to `DataHandler.java`, `DataReader.java`, and `DataStorage.java` classes. diff --git a/docs/diagrams/src/DataStoring/DataStoring.puml b/docs/diagrams/src/DataStoring/DataStoring.puml index aa2d3c6548..98fca6c10a 100644 --- a/docs/diagrams/src/DataStoring/DataStoring.puml +++ b/docs/diagrams/src/DataStoring/DataStoring.puml @@ -1,9 +1,7 @@ @startuml DateStoring - skinparam classAttributeIconSize 0 - package student { - + class StudentList { {static} +masterStudentList:Student[] {static} +recentlyDeletedList:Student[] diff --git a/docs/diagrams/src/DataStoring/Student Identification.png b/docs/diagrams/src/DataStoring/Student Identification.png new file mode 100644 index 0000000000000000000000000000000000000000..40f804e1eee5b7a939cc0233e4e0bfbf8df9214c GIT binary patch literal 36585 zcmc$`cRbba{|9_%P!bX<KYyk z(|1)lKCb%XEOb_yJgpl;i#-z9GdPVeAI)(ZM-SPU>9BO?Gnw`DF$w98xbKpMJt!m* z&3VK~o{EUg@yQOzq9LMV=x3R#fpGd4#ufyh3gfWYT+~;Mb=9H|IiC}xL}l)3B4?uU zgtI*1I)~mUY{_a;>U3btaJtt8%f>l1yJ0e7D`vZ!H6@~42t!MO;|q7`^89&fh?(__ zvbpgCy+$e68=aj-((F5MFR^!=Ov65_NJp%5&c?ru`r=%)(gT}la)i<5)+<^=)_Y+t zsWoRWJxz76OAU<=ghDlW1VSh0%<#^3@g$uJ7N1(&X+9=BH*qssN#RQ~z7K!!S%$b# zSqXurWH=Q!inNz>_FI9Pb8%PHW3e*8AFN8^0cY@##0T? z$y7_vES$BYyg7e)p{$LIk~+e(C=P$e_j-Q4?w+cgSd#AJehVKq`ndYFQM2pa*pnB& zY+Vu#ZM8W6Cga)e8hQVQKYlbvqaC)e?47$0X6$2yl#4E2%sG+C%`3n5{6jGTLNv(R zJ!T%8x8dmvIy{~JQAPv2kjS8yHLX9wUpG1i+9!v;9Fll z>BKmij#PH%n_uh$PLxJO1ggf}HCcA#j8A$m%le~o#V zg~w{{MMqL=iLLi~Sle1n^eevZ43*+f3|J6Cz5M}l40>;pQs^|>sm3sh8_y~Bn3rz! z>GuUfAh@^PWFQb7#R4NrJYPTFm3REo;e$Q7SySpQNqnau&X4asH~}#Uk>uZYJ5fu0 zZ=qF3w4L0ZbVGUWV&0$eS9*0~vWI&<2zlYhEMS)A%@??DyC zR(Uq&KqH0DCa2B!<{Gbz&sBTwxcA21@c8&g>mkQQFB1LLRlITCLsPjZCA2%@{$;VOSa)O2cC+6coe3ZC zPLQO!ce{rxHAkc8?VQcVRiq3!!C}q)V-$3kar|Dyj?Qhd@`{Pi;U{l}el);*t+4;~ zxfc)8MKR}fFlBJE&ZjZQn|K#|m?VH%$EE+vhvt+#a%&yZ=2UQp$+a2DSNVJ!J<{yj zO?%^kl6i^Kjob`A^x-j?QQp+?eW%D?E*Tce9cPj$=9`v3O-<5t%Y2gEeq*kE2=`v6 zD%^4YM`voD4x?$`sW?x$8T~1B++?dtq09Xdp_wEvPtO|>j0S_9XU|3}wJkOh<|B9g zV92%hzT6l1YTJc;4F($$Ge1mlq8rS7wC<)U*Mis z6s54KeDR_6*PO7(ZndZ~W0R~5P)#$x@;|M8dYfEeXu81dnB)cVTRXqT9Cn%P)fb8t zEc<@UF@aF3;t@6c*fcpZ#AFyuRv2N$ns4}>gOs8>eK*xf{L#KbW$ScAyXg$m{MSb} z+9hGx!-X$e&5+^m{-|0@xls9u=3LB5913uD_E#c^I{A%r=h{d)u`ux)r+MYHv@{kv zIyzd75C7A*E^t`Q^~j|^ogXZfN3hUyaKJD++?Tj{PWiaTBWc$g)zvjtbAbU$aI|Bqz|0uzy|dfD&e(Xc#P-dl z+YNQ^w%R2{*1e^xF%~v=yEpemOpk^Mk;&cFt-MM&_0aswGAZ2TXCM6$SZi;b#N2+k zp?A6^*Ih|(^TagvgDqEG>X4SqrszeW%O&~iJ2NG}z1g?cx!ZY?Gkk@(g|Q<~M-m^; zTeV{UJhCeCXPXP9w8Fd{g{D%?;kS7#rdi--+%zQH zB_%1)>)pFhn`bg#UcaHCjSJ_L47;TpzV%i?Mg|{wY=(4N*MlA=?{wk4wA0s9A7(+4m|s^yLE#sxq$fH@kkYdtVWPVe^&=CXTxp;@*)7}t=yQO|pd z3~QGSTQ=ryyGi;|V5?C#f@X(E`svRDsGr7PYUV^6b!U7Dl;mHnCL3}@Bj0ll+A!b9 zUKV33txP2?y=VhYNSL9?NJ1>M47J))yOtmtv1Mgcq_yO8G1q#2Cu|_ZYM}{wn@MA? zXGqs~8F6BnaBv*Qi+{IkWyR?dySCu&2IV@zTR$DP{(>RYhnR}jUaQ>%WTe zu_{K9wEDekJ2(PiV`ood==K*VN}ftFPwxwfymIyKXmdHry-W@9^35eWVPWBfkNJxE z1|-laSX`3#lap&^qDiVh(9?|DaXPobrJTB7+f9|nHxOpzVqyv`pTqh_;M zN_*+ngJ(MY#)Imn4&Zzzn0fG~*Jo>qSG{%KCu+@GBO=VUC)O2po8EcOU0)VJ&a}2v zquk$H&EJ9Ve(&Ni?9;934b0(T=0PPVMw4?cY<{?+ecdj*2g`hlRWq@+tT$9mmBaFf zPhsKb6|;GEF1TZy8c!y-2KrX7$0CR-p9Au&!gKGG!+B4T^^kPC%pok zfM!F`3<5dtICsIxr2V6~I{~!JbWE5HozF<8eB7lB_r=G6+8J*M&$HFZ%#-+{es9tT z5?k=04ohM0s-}0<$+ow)UUw_EOFId-Vr0auV3ma9(v8oZeXIMn!DkSXu2cX71Fmp$ge<48P~2cZUklOJArr?$69vubPhT zib_Hox}MK=@vX3XVT5w8cRrkGBE2hr-wA21olKHV?dn#8e)C)X2)EDL81r*yE1tVK zsDm!9VYLcB7Ua4kjG*(8P_Px(i9#R^Q=Ll8r;NTAz#Df{gAi8htJq7uM)(yxATVjq+dsW*Ty3&vzpKA_Wq&(ahy%} ztI`;9Se=hBE)$1EyjbzBK0D0G&QZ7XJ>N0iHnw$pmK@pl^09)#yO1jA}*25{1b9=smb(EO?QQ3MIPfxIl4`Sy>1Q8j!#eTF(q^kDp?^W~DZC5hE$h`&6oR?pUaTWA& zoB}}P^9||)Mas4(hgPT1o}1MXBVjtKdV{=L8*^kF23txJUs<;ezpzF%hGrJ6H0TTa zQrsiZyMzq6e&_jivXB~85F*I<%8=8p_vH1~9!rGfEV}>9c&*;fT!ZS&r|j(PhE(U) znTvegW!~+;SS_O#ojA4X{OuK{^1m-caP{O;4Ri}M@cbQTe4M6gb#ug#NmA3wV z<6g_D7lpTW0}9$=azn#%l;~xC-sH4ZuZSn-m!36EQNcp4LNQu zM%}UOq@W!-B%=exn;+xj`B7W#b1romj%+1a@v5bb)oLy0zJIn|4FXmt8x7MiKDjN8 z4dhBCYgl#z{sVYDR@9GDv&Wd=?O+qK%%ksEo-9Th^aga7+7sOP$~w&w1z&q|me~=t z%_*J8Z;D2u{X*3>^ug|QQSzYj7TeUshKdV3R3<>`n$f1K(;U8AN9*Uf+KlM^!XO!) z(XtcHHZc|8_ndaD2C0goUP~_+tdJOvwx{|gnX}loNR+x(EyWtue;~*0ok>sb@yLXY zj*j~H_*7L@B_$Hje3C!7XQ^I8KN@H+Qj7@%&dH3vqFAnI$XXovA}4blK_M8A$!v zE<^p!lxjf&yd3qt^a6f$+D`Nstoy$DpY43(8^&>snZJx$Y!D=WJ{Qn4iE$v$j$>&O z5*E(>k@V!^Xp2bC8wMcK*G|l?5|qk;h+$$&Uez|PO&5;Z?&--!Xt)}@CO4)iXI!+zUc_ zcq6*JqF}|&%J%c?qk*zcPHH>at9djIK<6CE;K9egCp~#``{}0_-1ZxI>dLmMdGo=i zC$Hf@bF(?-meOi`3MbkG_j|}STk!~vZa?>w)=ZV^>c=a6`kB?WwVW@$Jp*w_u1-sa ze5R_Vrlyq@2W)tE5rLS`{~iz!@ZrOUzC8Vc=U-0pmpLKrtQ3IH%q-jaAqhhUNzyH8 zP{H?1In3jP-%#0(zcruwx_nnotCr!)6##L#JJuUzg8;vzih|e1Kk5|hQM7ndy(e4m zCj!1TLi^KJuYqfgnfT%p?YKNz-5kNGlP%y7v1Wcsy`*hXC7Rl&tm1Ue{c<4zBZ*?% ztzM>5ISAQ)rbE)CbgBG7-4F!h+CWD1UQZ3~IE+RjvJtxj=N%bkKz6~z`Z{0;wNW4> zB*c=E)3IKDjNm*OS*B8f?*zG%K!MS~WJ^qoIw^S!x4E{uIt^3@Co4@(RkcjJIlQAo z<_7uVb!NFVg+h~&nf64y)2BnODb?(ZzO!E}4HYjm9^&87az9Hs*%bDLo{Zr9c<-%| zhYs77cx=4ORm27yq#uhdW@u_Wbr1`mXUldMit)%;>xSr;m0d1muGxpaYUNb88-iPi z>oHmG?HrTdrhmfZXUb4fl7Qvowuc{Uyrxw7l7S+Hl$ba$q)QCttWyX4sI2lCy6x@l zH1o-(i(NwqIO4)4_X3SolUAro&F=E@GE4VPmm`(sdZ&CN+T;b0GFx}bz|c^J8gp}V zX(=gilt#d{0K>YS+rm#wM?nB&CX1{54gVmQIT8wZk*l986 z`p!w_x^q}$SgjN`L`%7{cIgn-@nXJj^82d!_8`IGS^`OIoLaG$_xt;(z)`SXk20>; z6DeTxhAg{PSPVRutp{!0*Lf^|to3O4c}il}`=uxq7`erR{T{v03>&aO?QKU!MuxHL zY|M6N+O7WpvP2@{r7>Q%r)6RBX-h=ZkCKNT>?zECgJp4*?KY*j8hs5ja`1NL1bNzJ zvE!J`@83lPlQgTmGPNQ?0+pt_ecQ4=fDXJLxjhv#p|P^E!eP|k19ZTXm_d)Kx+6nH zX?xM5?Z%7M$!1{ghaD%jWt8{y!$-xqzXS&bd6>dt_+rmYp*JN=Ru0axF!sM}&FQf@ znw?XpPL29SST7Ey6Wma9SblZ$l;wP%<>FxJsMuZhd#)$(zeaM?mhoEtkWp5qSY&Q- z-(DzQtO}I}(9HXL?l$nokZbDwEjseiMJW66wK3tLVwPW8Qhws!1<8m05|Ew?I%KVq z;^HdV>O#7@jCh(WIM#gy#)zMLt)-*mEjiVZEUg2QlM^RSq#;a3Diw3Jqj+rt9JztS zksB4hgvNQ^l}?n1;&g8rGpvOga^v%XS>_RZ z_8j(ez))B;-|oijnTi7=EcD6aRrDbp`1`)qQbi;W1yLK|oIT%ed@3>OdiaarGAojk z6*3F(otZ>%9v;5F+NUfh8iLh%85rE(>`iT=R36DY_*W$BZD zv|v+rCPLM=ZiHWuQB_3&Y$xX`1qn&8zrTN27$fSuQuG`6k)9@GQrZx|z3=(+DG=MTeJbYjIM5;BUUi~v7m^dT zb+q^>S2)Zk=YTQPmuwA?U=zDuA&Va?r*)#ee%41GLv-z`1|<`(GXdA8#uE<4dB3&;IXc|A~6NXiEFT`>@WF z1ZDH(FOP-uO%m*)t@8h}cEbmb8%4TgOsH3{wMBP_W(bCCG=_%FFl7Uqi-Jtyuih9Y z#?_VyN`Q4a3sA>@Q0&>VI{d$?ga0{S#(XzEfBvyV-aqY+P;QoPeju8=6E$Q$^0$RG zSAHClaGI3)r(v{UMw~PnJC$=R$mOVUhkrlEA za!oUmK&qe1$c!61u|HNj{fUzIlQ`^x1^aB(cy5l)+c){r31B{dlLv(04>p_v4&AmF z+g?)=k^Oo0EjUp;1uBKpjH)>_vkEs7Vb^Zv?Ci`5>3nrcWjoO~IyO6l<7%WG^{z-~ zLQ>;&W-F5{l=Iv*V!&MAD=YUT$58{ zmscvrs(ISmcWbLVsdx+3mOXh*$5+i0ff*j0hBSYwsvruzni}rjKIFnnqW?++QMle! zX8EJ)>?MmYtr}{2XUm>tSv2%kMViG}l3t7M&C!y!E%GICw5+A%6cXwF(UZMC^?j(V zi58}8YuCUnZj6DlAd=D$gp6lNf3;7y;OE-usK-_Yx&MNNM zt@bt?@5SmQCaQ&&g3CJ>FK#y5k7NhZ756mwP}*mro=vnd>I5bRj%j9N>z;14 z&O|keCFqnrAHr@-uKE(3m>AijDeHej|r#R)3c)H4e{F4M~A|dwIK8GK};zFQtqKfo#(jQ!KVhl zT&DTbvNM8hrR>4=6R*^G!-B)22N6Qvnm6hMRTl^4K}c6qb>FyUK;TS+cvym7hlf|8 z8=ss^wHohZs@Sj)ey+;JsngR+&vK)f(URj@XjznuR1r9}aVEaH=m(MMWlWo3)x2$M z!frDEU=V=tS9yM!Ado<6H8=9vt5)pNRIL55oQQuIH|V4@^R?tnxPm!2JvuQRfEC2H z-EEFEgE2CW81!0Ky=^##eWwRKHQL-_{QhB}@SaF;t+zG(m8w|+`Va~Bh-nJOx=w-y z(6_M!#F7MAX4ov9M+*O?x1*?kZT?*>JXP5~)@APW;XM~jNheuPQcI=6mma7Ds1L=h)Awi+waOJH_u1EXw?{7V9#F|txGekMn^ zmpvr1uleiaGfbh(v}0wP94JpmywpL5Z0SUf(UH+Ku*i1luex@$`8-dsv5)wM73TPy znw**2-4@=y8NuOwbCQ|-v^7F5in&%!5gd#UAD(JyiK0JQFrGHwmY}l!12H<|bs;F? zCN&8aaulG=K5yPE43>Ub;6o#eaaO=)`h1k7nnRn*?p!-VX@{r8JP4EWw_k1UuCBVj zxi}QDzK+8jDq*DV5BEt{EiF8Ompkp>Kx1rY2j946G24Y|%p4qXT~YL;{VCr zA5V*@eSXZD%Id_sYEf7L5BB@pb z%oFY)9RwAm4H`_7LvaYG z48Fx;EsimK1Y=FM4Juwcoh-L^DbCeB-?I$8+UR#WgAu+-{FD&P4h2l^1`~^FNugF_ z$lJGXdwY8wOlG^%b#--b+_>TC>Dd^{MkWGMxzuGc!=9`Wgt)98B;;cc=W4Ruew#NRRjeq_qJCj z7*2ot|n7H#nl9Ug~7L_`Dxv=y3;Esxda#uk}RNjwRlrJrR}$QrJDOS@9I!Ykqj zWXzk53g#3U^^TFc6K#1+zVdfq^w3`IOq@Sc%M5xC1=Z~!lxo(ivSJXuG$+gDu$48v zOUm5P&@le4&QJ43(7GQLA5)EOA_$Mus_w9;#Tx&1W;784lA4kBeI4kzOYg zKPxP6B`C=C;lqc(W~Bwj#AL#@FK;1?hDHDAx$dHOga1>THE$*3d8I^&Ibdm*;8V!T zYLAV*eqEK~{B8<|wCPlyg+j(VpXF+O(_urX5UzLDX89RnVzVGYjC$9zlsD0`d>7^C z-Ib;|_9L~}X=Ns&D)t3Ys0W)GTtgMPW7&JJONZ^I9cy#k_(xtt@-=-boUv4S(qqJv(YHoIH<3;m2XckWn zx5h21B11z(TO4vVXIMzLswzs_GgN+r=dDVHIyHYh2VePmjw<4Z^7bZNan(#uk6rz- zk-EenU`b$H;x>#zls9zmY7wJkMD$$?CO+9)S{O^z_V_hIwbV{L{MJmA^(wm68fd9;>VipI@|o`1I+Psq=M*ttF5@FZShmSGR*mstM%Ab3NH5=PzEgT^hbS zC@+yg;jlI0uJbigQCXSSZtcakbL{p%30ItON72fnqB~N4FEU_2xbgOX{diFm@>M2GT8jmdTCg6cr8UvCi0E0?-P(-T8vrni{LcK}V2A?$83{wtY97iegYg?2p`EB+rk!y-~0JG&}@L9ddTR)g%m}A>N>MTv| zwR&iaKCr|gg;!@Prx$K5%BL$A1;9UoP^UZsggS8|L)TCeKaLT^uilOO6#CY5$etW6 z101HTaam8YGtca`J(6rCm0Jorw7oP>%1P9)jJraay=_qmWL= zFqCyZMIKEeX2UWC96tG-wUFuQr{UWZWh+JFBK6|7eGM1aqC_Q0#Cr*)x-->c0s^FR zwVTTvcNc~bYSIIrbO9nHrLH~-s+id}%j$d2NFWg2>P&yH*V;m~f+MyolTo@=;v!Bls3t<_7Jxq{)o#C?E1INRf`kkt_3U(1nG3U*x3mSH&bOO*RG(0@~ z?c4X;JjrVf-(*doyT;VR4nMup&v^?n%}c^}FxxOz^JW4XrT2~bo_vMl99rQR7xZUz z;O6f|n)BLUv?oVP44m0I>`rGacsKCQTw!X|>%;F2KNzpgKAFikLRKav)eY@w$D#?y zM5x#X!`_;zsjJ`PxTmL=%aD6>8_{Z4v024rh=S$42sc(vl4jVLjL6(w*!9Cyt<}m# zxtl#u*NGz(G#wdZ<<>*Lx4ib(t3m@hk?O_IKwyV8LB6!LW%mK9tmo;IR>p7N8kRfs zLrhqlx7DAT6UJx1lKml5f#cfMJsNiN@gPQmj+Fs&d!yjiY8?R^?@o1k z!G;zy_ls}%B7Tk!n`Yqm9;Dx~)0$=~^g}}RA-{x?i6EKG;=Rt^)~=YuylSx#mN&hF zNu}F!o>h*Js9mS}HpM{tH#FM*JYzKj@Epxh-j=$z)_h^Xwm;UWx`;%KS_b?B0{RP0 zvF%ku+^pstBw^`K)VSZT7z9tng-KiWYK3|t%yz!r+br2?8%tZQ^!C%y_6>sW7Wl~z z+D<{54Or?j6nW4VGu@di5!X-#QL^s%#eoSeh&0<3y&+C(xeJ4sMj&nsW4bnb)3P zX>6$;%|sR5SF`Oii<4C1t~-aYk#dw>$kmyGkGUYbrx}{V52?v!HkuUs>p}JxMl2N= zaL$JGmflX1=B<_%d(PaigO2F)t{{*hsrSnRflxI=NKhb1CleTCqSMWoCN3M}5EzO* zGPqhc2mGTavHOtK_csk=i4v6T@QOfnH%eaJwxog~#n0@<8VM~zG5P&#()D8RBLl0E z?Fnk+&9s{lw{)xE0S)JD1qFFc+0=`3;d$SEril3KvV?z}3w&>{hEKqWV1CXA!eNs!8Dt z>o0NIJh_noiuq}ez(#A}|8fNZYSfm~-;_SY=`WYv3_bssG!#0m^G$?qf>)^4`pkuI zJRr$$?qu@<#T%TnbJ7JyQTtI%70|x(u)RP@AGlSbYAIL9`5BCX;)OPIepLb5ihoJ@ z>$#M@0`3AMr4~^baxdBG+@PuwD)PcXT0EB)9m6AjhDlOjff?xJ=z|HcAkDkne5J66 zT%fROPU~l(GG+a9vW44|v+C*}b~hKBcd8;$oNgT{aew>~NqXDHqMBJ%;#lh*AX5Ie zzBk=ui2LdTRHPGq-@=Vy;jmvPi!t@U%?Nsfw7Y%k2SCQw>27`ar7s{#swb4%_p84( zzxL8^L2#4#Bxg@znqAtH1l{-{W079(e#Ox4CyPeET-1`)l4u)Is+ilfZ*- zrd}C#7Y{Vq@3!;m0g#BBJdA4*`5{$R_`utM^_m>NBhf0$_G@zhj?0BjnK+#i+6sI; zh%h71P?J!+^p&>gZ2aZ(00ibMP|NuFht@&70PBMMQb$06`rRKR1DL@_ zhddI39GVe`IuNh^WkE;86+|wF9{c-3HmF9a$6 zr%#_ibq4SVCK^M%Y1JIpJGZ8L0w zu1c8hAMcHn90L$U{{Mk9To6oojYM2N`LFY`-dcLzx_M15C^)$O##?B;`qfz|pPh`) zsssqu6+A5!$~2z`5$Hw2;QR~>I-uZ;+*#L9GzS%X2W4WZ^~89JMmCT@9RNLQp!X35@~R}!NI}N(Ssj^@VMz!3r+5t$MDcVH11vPHchMdjK_s8O96y9f(DYBdZQ_X|a@|XsLS_A?ot95Z!%{b> zcRdWGFJ1l0V{2<`@hE5)pdMOUTI$M~01p8^yER=Lt%sAlxt*L7i8tu2k-8=Ra4Nl7oNJcuv@6Yy^h`%>~KoKgAo;>pve z;amb2_#L(Y;lO&nuX=O_(6Ycjv0Ke4sCxPM@Y*b0USwvFKg++j^o3pLD+?HLhUD$=<-gU~^$$bFMcImJ=KMY`FX-5bSi2 z)(Hv7~{$U`1uw*h-RVaYTWpxE+;o12_uAio+ z)1-DZb1OKN)qMKf`(S4Il@@m_hz;oxMgIa=y!b$dZFbgX01}v(n5f@qlnwGpz}z0R z8GB<~w*4{xBxD%>h%LmI2Bmb#hYyoMYCTj2*h)j0*NSl)ldnDf1Pp}1V9EA90zSa} zq@E{&Kr;Sf|M)|s0UX!;*>YBxY#p?Fpej-h?--~J5>0an$(Qh{k2VTS79*x`#3=AaaG-5$d z%eWql4z6a?%2;>QC=j^*j+ z*M0UP9!=nhTWEjkd)h70Dl#%vIl9lEKiAft3}TeFVT`p+v58*!qKE(hGN303%eHco zA77#tPn$FCw@}LQ>Mt+nXHNFF;DEx<|V2O~p1?Ffji8Xf-(Y-i5*E zcPyr_8}{8=7TI&rrrM_dU_5H8H>oq#9w*`l{DGG2TC)(M%7TQq5~W6d+(-+pnsao4 zdTv@dC-6wK>hgZ_o&fk%bRRxm_f}C+F;Ox`oAL(NU$OR4YJiq7Gcsa&tn68vc}Y$( zTyAV`7Jv9qx4&?CYk5r30n`T)uQIlXFGScx@1Sa-aM1T=eMvT5;9xG#u>NT(@oESs z3|V73&JSz@-N`pJq0@kmN5y60Y`L;5mz*#XhnRp6d0+@FrKs9g6WKez!)e! zaC375>#m8Ddwd^x&*0@O0-M3K3u+kv<-M5_?t8>wXm%zLU%vcXGdpqd^h)hFeZ9QA zJU#21nKwS91qYVn|#;sn4U(O+3lgqdycUm_eZD01Rhl2;HTRPRwb^ zF$MrAsQCoTwjYSWfn7`cY=M2;tt_JLXFS>lh~c5EDoomsg)>}Suv-B}-B)bQHaqvd zK$2?Q^YO<>QRvt$hRdmH2o!*Pt3m?A#%yD9zG%E24{6|MJ9x2Q9lyI>ker%N! z|1NER$UVyh*O%{haoa4#PUoKUehnOGtOscB@{PKwb-K|PH0u$$&N*Yy=L&%RCnO{+ z-_^1UoRW`rHrQGkX-||K%F`#~asP=yyYum|_1Z=^9D5hYAZfMG-2&kyU>5!hs8S4X=+*#_s#1^=L+ zs+EKb0L-4AFBqaCC;tvkh0lIt>DPqzl3ZL|fQRn_Y#m_R0iP-?EDX%JM03iPiC{Q{ zO-({Z{60p`Amt-RH$KUz@6!yRQ-Ma50YK;bbbHAU-P(?(JtkCAMG`Cv8X&)>h%pEV z{Bl8Soq#ZhMh>A32R>V>tE&SH)cf}HX-w$pPpv{=vG)Zn z--vQLTj7?}{!&}Oxei6aP8jaC`_-p!aQA36w70)4^|3!7qvz%XY&-p)WGBA4vDOjC{@^NCM-t zwxIa}!kIp0Oio$h@7~pYU@}W->_KOrJcQv=+=V7;?ptH(6fh+D4fW$rl7LLZwI9(C zB{DIk?k911mBVV007x~#{vT&+0FXEo>+kQ)*!hF70U&XQ;_bhEcLZ)elmH&ZIF8Kd zuR!zRxCdZiM>682x1ph-M5jUAgo?W%*U2xS1uAlVBA*8U0}W-Zk(S~J;y-6;VCf~l zUICudRj3pfd;Sj0Mi01CP~P}KyV>;I$_CIs)T8SMI(bg`745AwqM!T7<`ID3 znnZ*Ah&Eo3&gOwu_M(DY|a0@NOrVkqA0ndLJ()gzt?(iKO12!%ZG}<@Q4| zdZr2deB0m0YH(yeP9`;h!nnkX1lVZ0V}O183{43lb!ggX+uW=u`^5d%Yo zEC9w@k}@InI^gk_pmt_KUw{hWAcGJzLk$t_w`xLvXH<-N$)eD9ReOF@!#T#Mf3Y() zRGSwU(3dp`*jQLJ(OQoD3f0`Y7H1MthxtRC(y$J%5055Z)pjBn5Lx%Y(Sb~$it2m( zLt_4~U&6|aKi|-($*O0Nh)hCi`_xyw-GtgrzXxa9IA$jM*cTUsFb44@C6UO`^@)q) zUmo4ZtQzFegkaB$E(*7zE4KtZ!#QfuMK^{6btpe}5z6@^;%cGW)Ay&7 z(*i?6==~aH?{d>zVPFtZ-XTA`HRc2)2Syz)IN^eu49fp=)b?znFMa&T*PG8-2&P}h zP4mC6QsH@(RZBoc8z-t z;L8I^V)J-;{S}5VV*!Hn{l#&l+6kunqg0dgpK+wdc>I+7HYMD{FPmEO*Ao@AB>qRS zq98~HqGb2ocFTB9L@>DZMi8hqDcIp1d6CTnOO`7#_y+?3r0Dr+3_EfLup?hJ02%Y1 z4=@Ei76Yn)ZCzybpfVMOPE8!Vdq@(vCs?zweuFRol%Wv32m@J_yIE+D^I>4>?0X+5 zFctTT#0>txQ<&p;Ttna{v-G~7jwAMv`AdN6JOA1e#xWd0rme>d=g1F(S8V{i`ZZmt ze;%WN5LX&gDihlbxakDoAA(<#Wu#$6HYR)^CdHs;Ky3yEFF(S-aKNH8Y!OLpYGl3q zHUINq(%Ap~2Zt0d-Um8j0Xs>4)!GvulUtsevsVNH0K6A1EiDka>R1QoCk!l@GTp&` zRn9n_;rO+_b2O|d;!F_HgM?gzTlP!?&IQX#Yz$rqkWA{JW!lJv+GocOR>JhskqtC4 zk~)fuaC>0LZ_n7Z_HYw-Z}bQpY_w?XYLXct==g_}YyV|!!2(mQAap|lWp-l|J9PR| zHGU?ap|1Er#Z@OUkmPZ#2XB0Qlo3wIWa&gIho!rY96}FXEosdhl3T_x5v~Ehijxg0 z>c=pkrOVCu6@n+7sq)4nm9KUTy!=m(G#--QhZkW-R(%stOPJ*|crB*=^M|c|LYIdP zrPdzkl!yKtoTw9@oMR2xW6)`+lyA`5#p|pP=GBn$*MofNf13a2658bbD7bHe93Tip zW>r-n@~~%rFP9`IEc_Q82GjZ@yk?dFt^l2-&wGRL^9_1)Kp+$?o<#C8jU0GCjU!Si zTkR)7uF{rosN~1caT?Yo&T|}?O5TR8KXXv;1j*O(GbTYMlfLSJZy-^AcM|gUl!#Kl@qUgF3FYiVU4VVjVkqA6zsdzKyua5euIbIe>fq zJpN12e`D{sKNr8Fa?bSBqC99ZMWc}F$`qt-;JTFAOhmL~Si& zNpO>6-w)B5nT#V7W1OC{Q@Qo`_v>et$~~$a3u=x0^BBtI!fzAB?<50k)N7~EI^c`# z*MB5{5W;>=R$he;L{#`^e^v|*s}K~%L@0Il9ztw4M0Ae-hl1(ffq}W^n%MF`EDWrmH)EdAB1_FLHdsBK-2^W%YAz9mBuv;_v18 zxWpCxoK>90!5e-kAT8Xhrb|LAf4xZfjo z;sCVyck}bBsI!^9MvDDkeAa*Qdp~`^e^P~iljUEA8Ad`zrlYBOg`OV7WPs_St)&$l z8oJsB(pd+;g!@S-ah9h7t2k~4gbkozL`(Ce{o=nIcOvz@*GC!IsuuI_y`E4g>OD(3K3})xyAGU@6e}TwH%rjW7dN= z9SIZ^%*Nc75`M)a(ndx`qN1VzEvof{wv3K_jp7k{c=6E$3h*%jJ60lwzxj?jphcVl z^@6FdQA(dJW&loJbr0mu@={VcMgw<3q;IdjJK!7~${GH;B&7A>-Z4MAI$+S3O|`BE z?*al5&RL3QnA*sVo-{@FkjIKs;O#6ZFLw%l2ZgoUlGY2;HzT)a&X97|CtZi3g9z7p2-Rv==qTVN=yYW#I)Au zBJIguEO4RHGgkm#0N`oNwE>V^e;yxr$-To4(JSNJc%8!I$Jaqu7l8di2kbR!YHD`& z+)tl^LSLVyyhKUayt{Wy5|H$i3QgYI0Icr-v-xDVu6M&`ZMqfQCB(a z|M6W1am%L#sFfKDMw9dD04! z$N_-8fN%wXnzo0-m4ETk^`HgYtYE-ONlNM*xdGr4g8-5*;xRL}A|@6%lyn|;?Aa+> zt&Dz&kIc++YKiq;L1#ZwV$0|Lo0&?@*X#5`%3qNo{Nzpd_sIEAu%lND#^I6xuyz_AObYug}EWu`7ym*n3kr9MKT2fL0wdN^+ zk_|kz!r_>zO}?5y4ir23K~mc?DT8dN`=?KwthPz>!P-8Q`e$-jB}z zkn_7Th6$B+ww{2YF72q$h&&v`^f2BYQwA4L3_5PA*xs*eZpPeRcAMZWBK~(8htY-U zF_9C3OfRObJt^pHV_rRJ<|+UwC8$eU{^-yJ&5yul28zwqrDl8v_Geq{2;af&Pe}A6 z;14{3-T09Wv1bNq$e_&2>NjLsO9@!a_LTR{1J3 zvj%%dx)LWHose|OH{_D+(E$!0?4g-Rt+ltcjhh+)mjDtFOoa|yJ@Z6Wl{J*B`QA9& z%7L=)`>^A0f*D4q#jx79WU_5hZ`-IT@fCMt$)?<(Ecg}s(?EenE zu6SJk!SI{cqOg;F^6!D>(p6nMiOxr2zv&|X8bJNu!;XCt3s~FXiTty+Apga_{ZA5y z{|_RyBTn#7@_8@|J&HRP4|p_LXqMnFSz@>UxozfWjgE-S6Xiw1eBaa0LxNBeRMXl<%BR7wN3$t7>P|eFHk)!)uCk+{` zFoO!06D(%win;XQ`bdIHLaeP&ZZl0exh~LLpeS-i;@x#>Hnv4jvjbJBs9U-LHgzDu z1%VqVvD8M3u}i+HI8|r1e}Mp?V)Huf*^ol57y21R8_WYSg|9O7axHYob}CA^(?9oU z0Ay12iX;+)Tm2?GT#(&ep9NP=#QO2?OoLVo^>0_rJe>dw9l(SN3^17584mp}A39hU zx7j$Zckn3nPlzV5a`^bI-wig8tgegsr^=;|jvY)PCnh?&Ot+mrPVa@{4xaj<$a%yA zkC_XDsFfcg1I2a$J~_C`1aOi1`<3@go|q=g^e0_kG#Wm7};`}P%|K5Y=Q zicVaC7;Udi+`lce9}sncOiV6ASy4tN{+i6mpLi?)I7O5dD!4Jpov^7_+)uv8E75Hz z9};%%@(Tci=>lH_n%@8@#$kwmx#^$GLQ>FvsSqp0WugNRSLo^KF@6}}b9X`CM0ps1 zSjgo5g2c)&jnd2~`Np_oy#o({f@6-gb-VYHtE>r*)?WFmzacWuMaN|_K>2m6g2|2N zaG<$wH--DZK+5qzUm++k##45-sxm_MTnQxZdhF+Qv-H2KUzpr4QUgGyfHX7g2`=`e z2e%CUXpO54pcC7Yl$zn>S2=N6!S29sl@=#z3 zx;6PEvL-PVa$GF)`k&Zz%`)&$zy_d^7u#qyiPrx#CRTayG-g@2B!9MT=kvo~SXIV- z#PST2K+>U9r(67h$^$W>+h3lb&>#4+%;=y{kL}F7|6W3-f1h1p?9i44iSx4=65)Rs z0pqoSJyQPmpQisa4Ee7EfdYidUCc@#6>ZEue*yr_Qt;^H(0s4OlC@)!PT zH-3h=|9L_O`=71$dcK*Caz+yK2GxH3EY(aJ!_{F4H zC~CwVy0JKf{up7TPH8w#W2bGq9Chy^EXnv7?*mK<{96KkjV=ygkLh+#ugkEk!a^J1 z^}yA$p=Fw+96G?nh>41h6D3n+#X_CH?NAPuM6)mSo&3p$xB-e^cLKXW3RBYf>nR%2 zPUXhthEKi(d;rW{X90{ok*iZJZ~$daUfWttKM$&!)x!tvuR9=gE?w_Z0=}Fbcr-w#@ce&@`|_}u z`>+3S$8AlUh>UHblF+I&LyNR)T2%_st{QD<8FbSo-AbiJX>XDiNlFXaEG=54U7I#i zwAakOEK24p}|QgYuuD*$&O!?<29FeqrO zr*bFQ##^T1AukoQyMa3dM^Vk6*|ej)q=#7K2tDPPDndnlebeNVG;fmQ$L5HH$KGU@v1Z5ValFG$s7(83qkih?mv?r` z>0o#6bZh1UM*wse^jp=zzeqh(pcAGGWqMH0hk(Yf+5sle;f;##;%W)<#7D=oe%^^H zRcV9v$y}mVVPcj@_f3`iey~8P(LEx2P=|gY6CEFIg~a1{xy0aIxz5|hsZ{}4WYW|} zb?c^QYGJ;W>fVDPXJ51Iq0}|y}EmsO<7n{(gl36VUOWPWU0AU}bi8p2L{_sA=B?*nytDe(BWSNub2~j-8*heZOW{<-y+ES9?0-{@uOG3IWKr zC5Hl#K_)mkZr*v`esoEguA`dFhV_Nb=g*u`JIP+D$@xLYC_|%=(|}XjJR~tq;dCT# z1Dlbhkc=B@a#%>UQ(3REYNG|iqm0-pbK-{PI*r0_#FbhxIsA5A=kI8LKJ;nb=d23J z57QRHeMo^TD=(XJl;CUg()#F3y*&(<9dyB>ufrFnXVe<3)usR5V_{Qq))=P{!V! zxzQJsr#2j*gJx$KEz?gE`ejbmjZe$gK%UzOTkkC@1iY_X7|*6m>sAluox`YYx4rW$ zBg2U?sGx0_q%i?#{j)K{7e6G28GgO9;_!E+>DB|BcJ}sNhI@rXpg}@r=uuVGihBo) zqP%4ZKR}dAm5v#G?*MF_wgdXgs=P0PF0qOD&(;|j9L03FPJaz=9-E%DsQlf za(|y^%o{ptE<(P2`!v-3_%Xj4++W9T?2#?r0(wyT52~PWC#%9F zer0>X74mh^H7(#$gYE!_sG+4LoctQ7RQj$HU87zTA5P|8$>W9=Zfj}Eohujwwo zZ_!c#yoTxb(oC`(-lQJ5@7d|;f}Ei*0UxzI_i1c>#58rXYBtw+l+FfdFw~3M7FGTG zDflJNgxrY5+Pm!I#Vd#(LHr9)>$Zs5G(0gIwU#V?9+sS(4DMyPZTTV5R_F9_i|<8g z1R4*9#XeI67wfT#=`o z`SsOGXMWya&)14DU9+f_d>pYsYwG|*oQV~1;o($;QtoEQR{QS;A5+grTUc1g$+^#* z7=6Op$P~ElP$4goA=SFuD|UNc zX=?fmny~>tti_#4>z$${R!6*Z{ZGeCodyvnO8oJ7`xJEf{Z{K=mwYO;RN>5IOmP*GV~nOgP7_wP@W#tT_hWg=qQ&0m@k3rF3Qc`3W2-!Hay zQ~0JZKSF&BF1g;vSACU2P2@4MW4@UxsO4$n)&tDyFJHO}+PicpP<9-6o%&+71; z2M-I1p?3&;f_;<0Khw3*gt-Cn*&YGNT3*XdIc7^NACB3063Bay)W|eFhfaW ztpoz3i86r~hqNl}X@??qV`zGytt|?XDrnuTo>56-io?vx zgZ7;TvOV3-Mma3T(#ri%E(&3CvTnv(yMIQ{PA_q=fqo{z$G*n~8DtN?^JN0 zM3GkUQlx*?z34MQU2_QAxNF}rUm>peO@qzPMafGbDm~x^n2)fquq+4onHRQNFONgR zSV=B1Gm-cSEFb;==LrRxK(|RPP!{gWywvrr8i{T%g7y|$7TD!_;HbLB*VNTD$Tb9c z@l7rtkX2Yl6My~VKi{4?xn;0g@jN?wSYQKKB1o8*J&2Dt0WiL@2nb#Ywmy6{R_zg* zJtsAIX>w$L zcNe%b37pD)lA9|zboa06^wQ@IX-4k3DlRu^0(g0XN9Sj~HFvg!4*MswtDpuTaPP_M zn@h&)*C5_`cX#(DLF0OXVc2L#u#0fEmKGL`;2E~_+$e4@0&@P^jr(61#Lr33;@aex zqvIH8tqIhHDE+j>Zz9W`An>iKpgyP>7@eRLTfvMSjNW$5{0+O}Vu}VaAk))No65+^li!6W&rs_R6# z;=K_4;a`ju&uxnd4BX(5a5u%2A1x5OZ86PfcvLp)tZ1IRvXeOp-h{cAAdT)zKX-ZY zA5)HZdbNtHU$*naumEA=9g>4`a&oG9g_?TEddj=u5_ViK{~3{;Yc zkdTnDaGGkYl!oKRxrJ{dwB9QCS&K7O^|;m6)oHo9dCAa!md*#Isz=*tz#YtX%=QNiRSvdot8= z9hF~i&h$O&7wBd%cy5A%cUf<HGb;BaRq2wOw1` z7qsVa(}rQ-%L`u)SL+26FJ4y2o2K;egRh6j9`#jR<{FZ-?nzn{_eej);_AT{2Xn_l zG9^I|lZVQoF$@`ZPu^d3+m2Seo<}IgMO>^V;mYh>&&nz%noW^HdEhAm>#|1I?`5L? zWXwl*@|8_0R4;)@_!fDrR$8Bj;&T5iY;G)Njce&XK8L&o(a?iXoBwZ|6E4s@~9hZlW^^C%(BXO6P z)#^8j1_kb%0Z1^U?G?WoytcHvAvNPV(ybviowYSW1{>hdi?D3*xpzqH3AZ$S*T40O zYLpuG`v8lij^ExZ1-3N_BSa)mf5zqy2c(2Kea!-+h#)pvDF$4pd_y)%q!Mb7NF|tq z03A;K$QVW$Yi^9|Kw3#@dCU9vsTaExhL$+IZ-J_GJ&UbbfW|<(DI-82jHls@8Zf7! z?$+Mk9zj3=3@9yv&$mJ=+wTuufMQWg>g(c^mJBg=b*DBEVU*-M?=ChemT1tQE>RDA<%yN-(~4rxk_Rt&Uk z&71KNZP{NTT&8X(X>K)Ka$eM=e9QNCro-Qk3>(I!_RJKPRA8nCK=!l+p>XusID^Fa z#|qa`s6v+OfXZZm9xB%;WtyNs0Snwy`LHHV<-Yko*Uu8I2aLYA59WNoy{R!>DX(upo*vQOr(lgZ&q#r4SnTM@!GDF69)#g0g1SaiWH`3YshRaKM zRf7aR#Pdz}j77EE_=B|tJKz;Dq??kl4YbKEY{d!1RjW{9xMypN=mc&4po>A6O{$j~59XZu^qjE8F7ZV>o5lO{e_)*pU%`^z#|bb5IB zR>6da58vH4CnW(Lsa_81+4fH|YuQPXb{@O6k(taK;XM3i3|gbFWaXC8W>HSOj2FZJ z`a@bBE{1=#Chyw~fzDMqu_-QJER6Nl)otMhh6cJo2jd~_RDt6%@myBY^Vf_j(v$CF z_8H{VAMSc+IMauSL_(xzG6!dnTB~@C{rgFlS$o@((aqEE*$ag2UzG1SsU>@B>P%k=2-|x}}X3dpNH`^)qx^H_jn<@u5H)ls8Ap2!Lv2FIxv}$U$tZV1lv`S4?b5GjJPn6z2T4BT^)9Sf z(vN53Bc@@dxcF>uClkuX}e0{)h16adLCSCHxToDQIG3JpH_N zX5VBZBOvSwhrK-#|5|j@M1+NdJVqdYQ0nG#Y&ug7iK^Qh4@AYqbpr@QhF-~5P{RQvP^B=j1EeBip|`j7 zo5P6PgdEMO6f+(8Xmeq@M}k6|2wObqr8}o46F&A*_P^3eEDxEK`w$-ha1W6AiMT`F zoFP3|oO9suw(3K{q+W7Fpw!!S!a>C1)e)j%{N8KIH2>DfuRB7qag!@h<{B(u3H5ox z_d)Pn*eC6;d!|>Sriob0$C}H5v9<{@xXI1CJ~4mW&Bse2{2O7y)FkWz%lHg;_|)s| zTArF+%H}7Qj6-ZN%?S`tITTxKRlI1H4 zx+n0*BpVIrr0(Pr9Adb6Cpx#~dur0}MZ;!zyKxj!(E}*Qf%*f$w=>npwVteU+v##? z6_MsU5eajv8``)HPyqVX-6(us08d&$#sLLY@cFfaY*Qtd*w$ueXIteA6+_*yBfcM7a+Pmx<-|3I6U@k)Vr_*xeKq%IASE#QTM*85&;%JeRaVDy8@PKYTnF!R z5)L_Pm_^&GgaPqKY(kdL`j1~?S$C`CK-Cw#pwZd+#$R~_^5lWchawm(IVGj_>4nfu zK=v;(*dlr5N$&}Y0*srfzQ zsy?RJFye|l4WuohlP0ReNiR*b7?U+$1lw}Z!QLLaeDj0i#dO>f1Y4bU`sH@0yk}I!xH{gfjT-VSt12%q2hii`)2CMTsoR6qj479)t+;|+5jg|K;}i#$>Qv7Q z%!C=l$irRlQnI>3Zr;3E87-GCJ#q_)^6n5iN zs+4$|kTVyn(am}`X8duRpI2bkBbXQb`MB{nNA+{;_*;3V*n0twKQ6pM5g0-JJv|92 zDJhR0LH@KUO4b{m2Hq-*o^d={wq}=aE?*h^jAXw`qk zE}~!30WVb5PZa}=HzoWN%1JD=t;n?lCN@gU<^>54ugU->=Ua>(xsR3AJZO4Q zS6izbfpGz)Kgt7K77H^oA`$6gqilyJO?KS?&>rxR6k%#Y1UcTNF-SBRd(j5xFlW=B z1pSZM#`uBx1kbFvDfAD-++vxt#)J38@a@of`10_Z-H_n76o1WOaA|w?K9RT~yo<{W zH0mim4NDnq2cxF!ZoV8iXd+)yT;2jxeL(EM9*Oxx#jLniiA(TA&zax`QS00hEp>Hu zp$(g>$Hz;-K0=w&CcxDS4F-_MfYi+`ELc@NeLFbbtp*`kAlg44#%R@l&pv7#0MrOk zDU@rn@LQ0in}Jt-;N?E|ILT&MDKPLQfg`vlkx2Xqcr6!@of{4tLnilWmXNPL)DHCG zLAx6XgsiZHU|U~5+s+J7LOV4}Tt|wb0W~!}qq_{rxzdX`y*g3f_P=BjgE*-2OgOsc zkK;!_f9?b<>?`Cm@rg8n1mi@BMCSc9I+gWTFBE`SKmYO+swS)vE6T`Fs+6oVmxTX~ zdM%^i!JfOrpMfE#;=u(2Cv2-q3qQ>Pps4uyD?snS4x4geUsg2Ov7;5qqRk2?y#?^Uy;-z;+7?(7 zYVHbJ7ayOsQJ_Moa}FAvCFKa4-enJ@J;<^&12zQiNE9iFNbCjB<~T-tm+WW$%bp(2 z?)3f`onG%SGchrdlao_aRCIEhf))u&2i2Xh)-r5=)BBcmf)X6j0EG^mobXiQCd-Hr ztRVhBTbI9pTMn1W;$G{6rGox^fe-@y2WhC@LiSc?oQI@;cOtV1*+sPFLLX=z5vNzo ziv(~Gc>V6Gu*Vj6_+qU{rlga>X&*I<`nPl(`0QhJd)XGIEn+8fw)!aZ8jRT=KL7Tv z>kTI1#H~Po5FoACLDkvh5=r{}=>J!Yd8d@2j)7s#Zh4ub8vi%(CfJETUP~HoKaYGb zewF?^2Uq<=>AqzNnHBY29G2wMVLbp_P_XN z@C3x;j>023uemc67IW7Y8LP?Hi{oRA*2={k&tF!p`}bElO1|;2{38|`1Bc!k9M)YJ zKyC-LpORPXgP;$ffX`!bmbi!iQ1ePZ-J)LxGq-beOwrG}2;9RV@3a1#E}rJpQ0mQ~ zGG)fU3em##U44?C4#DxD<%J8)ltf=Cj&d=d4cQjq5Cn&cJJ2gmB>AJ{+R)rQ;~z17 z4szVUvH-5dzzNT3|Je{}QC!C}{{H>@z}tb$xw)z7Mp3IRSZVaI=3wTH^}m6NC~*-` zSWemC`sHB&XU*A|Xi;29siCQ9%SfDz%$-h^Pr|?Pe)VmJ{cDitwSfwjmUciq0uY^j zS)DAdetl@fJ3Gc`z)tarE#&E<9NExEooMlu6-tL)pmPmk5fe0XJ9mu|sR)wVHSHUe zKus4gh*`~lY%rAHt3c2nQRZL-p{}t2Q!9uFg+`lZBocvU1k(BUcUo17J|Xbdkx6(| z1}Srbmq|?!rJL~Lp%fD9nDf(PT~E|$93CO`X+?Znt0r_ju z9h@JSoPdP)^bQV_=jxQ&(2h_IY83v5 zb+f&gG1b=ACdmRf=+r`qe_M4~iG3RdMgt*GKVpfqFgJ&+UvqV}AXMN^x7=0cJs$)L z@DBsj^nCqlkae*O>a$rt6mbhrveZ&Z6Mn6skL6CCe%MN?8sc6c$rDsK_2Q znb|;`Ok>z%xR@?ddm^9Ffn-kk3?~#^TynF-Ae%Ny#3$yX{z*iwzB;_9lFYTn?HqN} ztbQaSDw?k9lkjz$#*7ZbT>(0InnS)`TT6EwnS|$jm4gr7h=@O?;kZ80buYtP4!XNE z=UrYE5z^jU#!eDYxpB;XMPy&e(g)6qY24+Il2QolYc-Gm%}=82fc1>shvYW$PEs@W zJ9vw?=(L@P?i(^9(pYv$d(b;}y!}@SNes=hGLoQoAIbMN{2?ipLLQKjsgdaZrVwtT zaekH_KxCNCRKY9A$jAh9&oeL}$8?TJdgMS^UP#LUcG+53V!V12IP!5c%`CjyGxm@xNpWVWB7j;6?H z&NKAx6>u#zUl97);$iLxp-+Py$yo2$v16DiR3mW}G7b3B1W>dz86h)y*TchOx_~<% zaVd4f3G1j*k;a>#&uge?i6iprpHLcJxl3(E`5i?DkeT5obit3PO&E5(juNxJMq969 zmxU*MHu`PrO4qg=#@mcXCUn>}_64M%VH!TXgx%xUzHbntEng!q5T+`eINe%4y6iK* z4G0XfqeN$Z5Gr{lzavrH66Xp3Pv`?8qq)WeJd3uXT(6C`SAUuj zte07n3;bO8r(ut%ab{+<+B5#h@yckzPEdYupS-M)NvLLnU^oe?X&K~YRb-N-PGA3j DP^L$i literal 0 HcmV?d00001 diff --git a/docs/diagrams/src/DataStoring/studentIdentification.puml b/docs/diagrams/src/DataStoring/studentIdentification.puml new file mode 100644 index 0000000000..01e09f22e0 --- /dev/null +++ b/docs/diagrams/src/DataStoring/studentIdentification.puml @@ -0,0 +1,62 @@ +@startuml Student Identification +footbox off + +participant Class as class +participant findStudentByName as fsbname +database "masterStudentList:Student[ ]" as msl +participant findStudentByNumber as fsbnumber +participant User as user + + +class -> fsbname : name:String +activate class + +note left + Class here refers to a function + or class that calls + the findStudentByName function +end note + +activate fsbname + + fsbname -> msl : name:String + activate msl + msl -> fsbname : students:Student[N] + deactivate msl + +alt N == 0 + + fsbname -> class : null + +else N == 1 + + fsbname -> class : :Student + +else N > 1 + + fsbname -> fsbnumber : students:Student[N] + activate fsbnumber + + fsbnumber -> user : promptForPhoneNumber():int + activate user + user -> fsbnumber : number:int + deactivate user + + alt number matches + fsbnumber -> fsbname : :Student + fsbname -> class : :Student + + else + fsbnumber -> fsbname : null + deactivate fsbnumber + + fsbname -> class : null + deactivate fsbname + end + +end + + +deactivate class + +@enduml \ No newline at end of file diff --git a/docs/diagrams/src/InputParsing/InputParsingSequenceDiagram.png b/docs/diagrams/src/InputParsing/InputParsingSequenceDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..552c36974bf4d5e48b71c094d66d17c2eef4cce7 GIT binary patch literal 25816 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 literal 0 HcmV?d00001 diff --git a/docs/diagrams/src/InputParsing/SequenceDiagram.puml b/docs/diagrams/src/InputParsing/SequenceDiagram.puml new file mode 100644 index 0000000000..990cf94359 --- /dev/null +++ b/docs/diagrams/src/InputParsing/SequenceDiagram.puml @@ -0,0 +1,42 @@ +@startuml InputParsingSequenceDiagram + +hide footbox + +actor ":User" as u +participant ":UserInput" as UI +participant ":InputParsing" as IP +collections ":Commands" as commands +database "masterStudentList:Student[ ]" as msl +participant ":FileIOCommands" as fioc +database "studentInfo.txt" as studentInfo + + +u -> UI : processInput(String) +activate u +activate UI +UI -> u : userCommand:String[ ] +deactivate UI + +u -> IP : parseUserCommand(userCommand:String[ ]) +activate IP +IP -> commands : command to execute +activate commands +commands -> msl : update runtime database +activate msl +commands -> fioc : update stored database +activate fioc +fioc -> studentInfo : write in msl +activate studentInfo +studentInfo --> fioc +deactivate studentInfo +fioc --> commands +deactivate fioc +msl --> commands +deactivate msl +commands --> IP +deactivate commands +IP --> u +deactivate IP + +@enduml + From 077047dfeb3d3e2df6b3350910270ce181ecef7d Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Tue, 2 Apr 2024 20:49:34 +0800 Subject: [PATCH 169/503] Remove redundant assertion --- src/main/java/classify/commands/DeleteCommands.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index 250e76ee42..3219659795 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -38,8 +38,6 @@ public static void deleteStudent(ArrayList masterStudentList, ArrayList } UI.printDivider(); - //@@author blackmirag3 - assert true : "Not false"; if (recentlyDeletedList != null) { recentlyDeletedList.add(foundStudent); } From db4d4c06dcb6ab983560c425f2b3aed1507fe1ef Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Tue, 2 Apr 2024 20:50:22 +0800 Subject: [PATCH 170/503] Clean code --- src/main/java/classify/commands/AddStudent.java | 2 +- src/main/java/classify/user/InputParsing.java | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 7ce092aaa7..228220e45f 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -57,7 +57,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, return; } - //@@ author ParthGandhiNUS + //@@author ParthGandhiNUS assert number > 0 && number < 100000000 : NUMBER_IS_OUTSIDE_THE_ACCEPTABLE_RANGE; //@@author Cryolian diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 55d3feb7f6..0b61c22146 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -61,7 +61,6 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas AddStudent.addStudent(masterStudentList, in, userCommand[1]); // @@author ParthGandhiNUS assert masterStudentList != null; - break; case VIEW: @@ -72,9 +71,6 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas // @@author alalal47 case DELETE: DeleteCommands.deleteStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); - // @@author ParthGandhiNUS - - // @@author alalal47 break; case RESTORE: From e4ce9bdcedfd78a3692bc89f084c71f675ca0918 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Tue, 2 Apr 2024 20:50:48 +0800 Subject: [PATCH 171/503] Close scanner --- src/main/java/classify/commands/ListStudentsCommand.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 6d2c28a0b7..ef57051739 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -69,6 +69,7 @@ private static void listAllStudents(ArrayList masterStudentList) { Scanner scanner = new Scanner(System.in); String choice = scanner.nextLine().trim(); + scanner.close(); //@@ author blackmirag3 switch (choice) { From 771b0b6d29521b52ecf84a8daea260be729d6971 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Tue, 2 Apr 2024 23:58:23 +0800 Subject: [PATCH 172/503] Add editing of attributes --- .../classify/commands/DeleteCommands.java | 1 - .../java/classify/commands/EditStudent.java | 222 ++++++++++++++++++ .../commands/ListStudentsCommand.java | 2 +- .../java/classify/student/StudentList.java | 2 +- src/main/java/classify/ui/UI.java | 2 +- src/main/java/classify/user/InputParsing.java | 158 +------------ 6 files changed, 234 insertions(+), 153 deletions(-) create mode 100644 src/main/java/classify/commands/EditStudent.java diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index 250e76ee42..56642f752e 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -39,7 +39,6 @@ public static void deleteStudent(ArrayList masterStudentList, ArrayList UI.printDivider(); //@@author blackmirag3 - assert true : "Not false"; if (recentlyDeletedList != null) { recentlyDeletedList.add(foundStudent); } diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java new file mode 100644 index 0000000000..9d0f0827f6 --- /dev/null +++ b/src/main/java/classify/commands/EditStudent.java @@ -0,0 +1,222 @@ +package classify.commands; + +import java.util.ArrayList; +import java.util.Scanner; + +import classify.student.Student; +import classify.student.StudentAttributes; +import classify.student.StudentList; +import classify.student.SubjectGrade; +import classify.user.InputParsing; +import classify.user.NameNumberMatchException; +import classify.ui.UI; + +public class EditStudent { + private static final String NUMBER = "number"; + private static final String PAYMENT = "payment"; + private static final String REMARKS = "remarks"; + private static final String ADD = "add"; + private static final String EDIT = "edit"; + private static final String DELETE = "delete"; + private static final String DEFAULT_STRING_VALUE = "Unknown"; + + // @@author blackmirag3 + public static void editStudent(ArrayList list, Scanner in, String name) { + if (list.isEmpty()) { + UI.printEmptyListError(); + return; + } + + Student student = null; + + if (name != null) { + student = InputParsing.findStudentByName(list, name, in); + if (student == null) { + UI.printStudentNotFound(); + } + } + + while (student == null) { + + System.out.println("Name of student to edit (enter blank to exit):"); + name = in.nextLine().trim(); + + if (name.isBlank()) { + System.out.println("Exiting edit."); + return; + } + + student = InputParsing.findStudentByName(list, name, in); + + if (student != null) { + break; + } else { + UI.printStudentNotFound(); + } + } + + editStudentAttributes(in, student); + } + + private static void editStudentAttributes(Scanner in, Student student) { + StudentAttributes attributes = student.getAttributes(); + ViewStudent.showAttributes(attributes); + + while (true) { + UI.printEditPrompt(); + String command = in.nextLine().trim(); + if (command.isBlank()) { + System.out.println("Exiting edit"); + UI.printDivider(); + return; + } + + switch (command) { + + case ADD: + AddStudent.addSubject(in, attributes); + student.setAttributes(attributes); + break; + + case EDIT: + editAttribute(in, attributes); + break; + + case DELETE: + deleteAttribute(in, attributes); + break; + + // @@author Cryolian + case NUMBER: + editNumber(in, attributes); + break; + + case PAYMENT: + editPaymentDate(in, attributes); + break; + + case REMARKS: + editRemarks(in, attributes); + break; + + default: + break; + } + + } + } + + // @@author Cryolian + private static void editPaymentDate(Scanner in, StudentAttributes attributes) { + UI.println("Current stored date: " + attributes.getLastPaymentDate()); + attributes.setLastPaymentDate(InputParsing.readInDate(in)); + } + + private static void editRemarks(Scanner in, StudentAttributes attributes) { + UI.println(attributes.getRemarks()); + UI.printDivider(); + UI.println("Enter blank to stop editing."); + + String newRemarks = InputParsing.readInString(in); + + if (newRemarks.equals(DEFAULT_STRING_VALUE)) { + return; + } + + attributes.setRemarks(newRemarks); + UI.printDivider(); + } + + private static void editNumber(Scanner in, StudentAttributes attributes) { + try { + openNumberEditInterface(in, attributes); + UI.println("Number updated successfully: " + String.valueOf(attributes.getPhoneNumber())); + } catch (NameNumberMatchException e) { + UI.println("Please try again with a different number."); + UI.println("Another student of the same name was found with the same number."); + } catch (NumberFormatException e) { + UI.println("Exiting number edit."); + } + UI.printDivider(); + } + + private static void openNumberEditInterface(Scanner in, StudentAttributes attributes) + throws NameNumberMatchException, NumberFormatException { + + UI.printDivider(); + UI.println("Current Number: " + String.valueOf(attributes.getPhoneNumber())); + UI.println("Type in and enter the letter a if you wish to stop editing."); + int number = InputParsing.promptForPhoneNumber(in); + StudentList.checkNameNumberPair(StudentList.masterStudentList, attributes.getName(), number); + attributes.setPhoneNumber(number); + } + + // @@author blackmirag3 + /** + * Prompts the user to edit subject, grade, and classes attended for student. + * Continues to prompt the user until user enters blank to exit. + * + * @param in The scanner object to read user input. + * @param attributes The StudentAttributes object to store the attributes of the + * student. + */ + private static void editAttribute(Scanner in, StudentAttributes attributes) { + + while (true) { + + System.out.print("Subject to edit (enter nothing to exit): "); + String subjectToFind = in.nextLine().trim(); + + if (subjectToFind.isBlank()) { + System.out.println("No subject edited."); + return; + } + + SubjectGrade currentSubject = attributes.findSubject(subjectToFind); + + if (currentSubject != null) { + System.out.print("New subject name (enter nothing to skip): "); + String newName = in.nextLine().trim(); + + if (!newName.isBlank()) { + currentSubject.setSubject(newName); + } + + double newGrade = InputParsing.promptForGrade(in); + + if (newGrade != -1) { + currentSubject.setGrade(newGrade); + } + + int newClassesAttended = AddStudent.promptForClassesAttended(in); + currentSubject.setClassesAttended(newClassesAttended); + System.out.println("Subject updated."); + + } else { + System.out.println("Subject not found."); + } + + } + } + + private static void deleteAttribute(Scanner in, StudentAttributes attributes) { + while (true) { + + System.out.println("Subject to delete (enter blank to exit)"); + String subjectToDelete = in.nextLine().trim(); + + if (subjectToDelete.isBlank()) { + System.out.println("no subject deleted"); + return; + } + + if (attributes.findSubject(subjectToDelete) != null) { + attributes.deleteSubject(subjectToDelete); + System.out.println("Subject deleted"); + } else { + System.out.println("subject not found"); + } + } + } + +} diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 6d2c28a0b7..8ad59391fa 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -93,7 +93,7 @@ private static void listAllStudents(ArrayList masterStudentList) { default: UI.println(INVALID_CHOICE); } - + scanner.close(); UI.printDivider(); } diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 2b446671dd..41fd93b6af 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -117,7 +117,7 @@ public static void checkNameNumberPair(ArrayList studentList, String na for (Student s : studentList) { if (s.getName().equalsIgnoreCase(name) && s.getPhoneNumber() == number) { throw new NameNumberMatchException("Student with the same " + - "name and phone number."); + "name and phone number found."); } //@@author blackmirag3 assert (s.getName().equalsIgnoreCase(name) && s.getPhoneNumber() == number) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 4469f5aafe..fd15feee6f 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -11,7 +11,7 @@ public class UI { private static final String EMPTY_SUBJECT_ERROR = "No subjects and grades found for this student."; private static final String NULL_ATTRIBUTE_ERROR = "No attributes found for this student."; private static final String EDIT_PROMPT = "How would you like to update a student's subject? (enter blank to exit)"; - private static final String EDIT_TYPES_PROMPT = "Add, Edit or Delete: "; + private static final String EDIT_TYPES_PROMPT = "Add, Edit (subjects), Number, Remarks, Payment or Delete: "; private static final String EMPTY_LIST_ERROR = "Currently no students in list."; private static final String VALID_NUMBER_ERROR = "A valid number was not entered. Please input a valid number. "; private static final String PHONE_NUMBER_PROMPT = "Please input a valid phone number: "; diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 55d3feb7f6..ec724cd583 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -7,9 +7,8 @@ import classify.commands.ListStudentsCommand; import classify.commands.StudentSorter; import classify.commands.ViewStudent; +import classify.commands.EditStudent; import classify.student.Student; -import classify.student.StudentAttributes; -import classify.student.SubjectGrade; import classify.ui.UI; import java.time.LocalDate; @@ -24,7 +23,6 @@ public class InputParsing { public static final Logger LOGGER = Logger.getLogger(InputParsing.class.getName()); private static final String EARLIER_POSSIBLE_DATE = "1970-01-01"; private static final String DEFAULT_STRING_VALUE = "Unknown"; - private static final int LOWER_LIMIT_PHONE_NUMBER = 8; private static final String BYE = "bye"; private static final String LIST = "list"; private static final String ADD = "add"; @@ -47,6 +45,8 @@ public class InputParsing { private static final String NAME_A_TO_Z = "1. Name (A to Z)"; private static final String TOTAL_NUMBER_OF_CLASSES_ATTENDED = "2. Total number of classes attended:"; private static final String LAST_PAID_DATE = "3. Date of last fee payment: "; + private static final int NUMBER_TOO_SMALL = 80000000; + private static final int NUMBER_TOO_BIG = 1000_000_000; public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, ArrayList recentlyDeletedList, @@ -115,7 +115,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas // @@author blackmirag3 case EDIT: - editStudent(masterStudentList, in, userCommand[1]); + EditStudent.editStudent(masterStudentList, in, userCommand[1]); break; case ARCHIVE: @@ -181,7 +181,7 @@ private static void archiveStudent(ArrayList masterList, ArrayList masterStudentList, Scanner in, String sortType) { String input; while (true) { - // @@author alalal47 + //@@author alalal47 if (sortType == null) { UI.println(SORT_BY_CHOOSE_INDEX); UI.println(NAME_A_TO_Z); @@ -191,7 +191,7 @@ private static void sortStudents(ArrayList masterStudentList, Scanner i } else { input = sortType.trim().toLowerCase(); } - // @@author tayponghee + //@@author tayponghee // input = in.nextLine().trim(); if (input.equalsIgnoreCase(EXIT)) { @@ -259,147 +259,8 @@ private static void findStudentsWithSubject(ArrayList masterStudentList } } - //@@author blackmirag3 - private static void editStudent(ArrayList list, Scanner in, String name) { - if (list.isEmpty()) { - UI.printEmptyListError(); - return; - } - - Student student = null; - - if (name != null) { - student = findStudentByName(list, name, in); - if (student == null) { - UI.printStudentNotFound(); - } - } - - while (student == null) { - - System.out.println("Name of student to edit (enter blank to exit):"); - name = in.nextLine().trim(); - - if (name.isBlank()) { - System.out.println("Exiting edit."); - return; - } - - student = findStudentByName(list, name, in); - - if (student != null) { - break; - } else { - UI.printStudentNotFound(); - } - } - - editStudentAttributes(in, student); - } - - private static void editStudentAttributes(Scanner in, Student student) { - StudentAttributes attributes = student.getAttributes(); - ViewStudent.showAttributes(attributes); - - while (true) { - UI.printEditPrompt(); - String command = in.nextLine().trim(); - if (command.isBlank()) { - System.out.println("Exiting edit"); - UI.printDivider(); - return; - } - - switch (command) { - - case ADD: - AddStudent.addSubject(in, attributes); - student.setAttributes(attributes); - break; - - case EDIT: - editAttribute(in, attributes); - break; - - case DELETE: - deleteAttribute(in, attributes); - break; - - default: - break; - } - - } - } //@@author blackmirag3 - /** - * Prompts the user to edit subject, grade, and classes attended for student. - * Continues to prompt the user until user enters blank to exit. - * - * @param in The scanner object to read user input. - * @param attributes The StudentAttributes object to store the attributes of the - * student. - */ - private static void editAttribute(Scanner in, StudentAttributes attributes) { - - while (true) { - - System.out.print("Subject to edit (enter nothing to exit): "); - String subjectToFind = in.nextLine().trim(); - - if (subjectToFind.isBlank()) { - System.out.println("No subject edited."); - return; - } - - SubjectGrade currentSubject = attributes.findSubject(subjectToFind); - - if (currentSubject != null) { - System.out.print("New subject name (enter nothing to skip): "); - String newName = in.nextLine().trim(); - - if (!newName.isBlank()) { - currentSubject.setSubject(newName); - } - - double newGrade = promptForGrade(in); - - if (newGrade != -1) { - currentSubject.setGrade(newGrade); - } - - int newClassesAttended = AddStudent.promptForClassesAttended(in); - currentSubject.setClassesAttended(newClassesAttended); - System.out.println("Subject updated."); - - } else { - System.out.println("Subject not found."); - } - - } - } - - private static void deleteAttribute(Scanner in, StudentAttributes attributes) { - while (true) { - - System.out.println("Subject to delete (enter blank to exit)"); - String subjectToDelete = in.nextLine().trim(); - - if (subjectToDelete.isBlank()) { - System.out.println("no subject deleted"); - return; - } - - if (attributes.findSubject(subjectToDelete) != null) { - attributes.deleteSubject(subjectToDelete); - System.out.println("Subject deleted"); - } else { - System.out.println("subject not found"); - } - } - } - /** * Prompts for grade from user input and checks format * Prompts the user to enter a valid double within the range [0, 100] until one @@ -417,7 +278,7 @@ public static double promptForGrade(Scanner in) { return -1; } - // @@author ParthGandhiNUS + //@@author ParthGandhiNUS double grade; try { grade = Double.parseDouble(gradeInput); @@ -488,8 +349,8 @@ private static Student findStudentByNumber(ArrayList studentList, Scann if (student.getPhoneNumber() == number) { return student; } - UI.println("No student found with a matching number. Please try again."); } + UI.println("No student found with a matching number. Please try again."); } catch (NumberFormatException e) { UI.printValidNumberError(); @@ -566,8 +427,7 @@ private static int readInPhoneNumber(Scanner in) throws NumberFormatException { } private static boolean checkNumberValidity(int number) { - return number > 0 && number > 80000000 && - String.valueOf(number).length() == LOWER_LIMIT_PHONE_NUMBER; + return number > NUMBER_TOO_SMALL && number < NUMBER_TOO_BIG; } /** From 82706b8fcf2b4a7b9b80b71596b9e7f54821b5a7 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Wed, 3 Apr 2024 00:11:30 +0800 Subject: [PATCH 173/503] Refactor archive commands to new class --- src/main/java/classify/Classify.java | 6 +-- .../java/classify/commands/AddStudent.java | 3 +- .../classify/commands/ArchiveCommands.java | 44 +++++++++++++++++ .../classify/commands/DeleteCommands.java | 3 +- .../DataHandler.java} | 7 ++- src/main/java/classify/user/InputParsing.java | 49 ++----------------- 6 files changed, 59 insertions(+), 53 deletions(-) create mode 100644 src/main/java/classify/commands/ArchiveCommands.java rename src/main/java/classify/{commands/FileIOCommands.java => data/DataHandler.java} (95%) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 0483626ded..c50acc4445 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -1,6 +1,6 @@ package classify; -import classify.commands.FileIOCommands; +import classify.data.DataHandler; import classify.student.StudentList; import classify.user.InputParsing; import classify.ui.UI; @@ -20,8 +20,8 @@ public class Classify { */ public static void main(String[] args) throws IOException { //@@author blackmirag3 - FileIOCommands.readStudentInfo(StudentList.masterStudentList); - FileIOCommands.readArchive(StudentList.archiveList); + DataHandler.readStudentInfo(StudentList.masterStudentList); + DataHandler.readArchive(StudentList.archiveList); // @@author ParthGandhiNUS UI.printWelcomeMessage(); UI.printUserPrompt(); diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 7ce092aaa7..1decece58f 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -1,6 +1,7 @@ package classify.commands; +import classify.data.DataHandler; import classify.student.Student; import classify.student.StudentAttributes; import classify.student.StudentList; @@ -88,7 +89,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, LOGGER.log(Level.INFO, STUDENT_ADDED_SUCCESSFULLY); UI.printStudentAdded(); UI.printDivider(); - FileIOCommands.writeStudentInfo(masterStudentList); + DataHandler.writeStudentInfo(masterStudentList); } /** diff --git a/src/main/java/classify/commands/ArchiveCommands.java b/src/main/java/classify/commands/ArchiveCommands.java new file mode 100644 index 0000000000..6a82c1dcdb --- /dev/null +++ b/src/main/java/classify/commands/ArchiveCommands.java @@ -0,0 +1,44 @@ +package classify.commands; + +import classify.data.DataHandler; +import classify.student.Student; +import classify.ui.UI; +import classify.user.InputParsing; + +import java.util.ArrayList; +import java.util.Scanner; + +public class ArchiveCommands { + //@@author blackmirag3 + public static void unarchiveStudent(ArrayList masterList, ArrayList archiveList, + String name, Scanner in) { + if (name == null) { + name = Commands.promptName(in); + } + Student student = InputParsing.findStudentByName(archiveList, name, in); + if (student == null) { + UI.printStudentNotFound(); + return; + } + archiveList.remove(student); + masterList.add(student); + DataHandler.writeArchive(archiveList); + DataHandler.writeStudentInfo(masterList); + } + + public static void archiveStudent(ArrayList masterList, ArrayList archiveList, + String name, Scanner in) { + if (name == null) { + name = Commands.promptName(in); + } + Student student = InputParsing.findStudentByName(masterList, name, in); + if (student == null) { + UI.printStudentNotFound(); + return; + } + masterList.remove(student); + archiveList.add(student); + DataHandler.writeArchive(archiveList); + DataHandler.writeStudentInfo(masterList); + } +} diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index 56642f752e..25d5c6d2c6 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -1,5 +1,6 @@ package classify.commands; +import classify.data.DataHandler; import classify.student.Student; import classify.student.StudentList; import classify.user.InputParsing; @@ -43,7 +44,7 @@ public static void deleteStudent(ArrayList masterStudentList, ArrayList recentlyDeletedList.add(foundStudent); } masterStudentList.remove(foundStudent); - FileIOCommands.writeStudentInfo(masterStudentList); + DataHandler.writeStudentInfo(masterStudentList); } diff --git a/src/main/java/classify/commands/FileIOCommands.java b/src/main/java/classify/data/DataHandler.java similarity index 95% rename from src/main/java/classify/commands/FileIOCommands.java rename to src/main/java/classify/data/DataHandler.java index b0f65357bc..628c5acd79 100644 --- a/src/main/java/classify/commands/FileIOCommands.java +++ b/src/main/java/classify/data/DataHandler.java @@ -1,7 +1,6 @@ -package classify.commands; +package classify.data; -import classify.data.DataReader; -import classify.data.DataWriter; +import classify.commands.Commands; import classify.student.Student; import classify.ui.DataUI; @@ -10,7 +9,7 @@ import java.util.List; //@@author blackmirag3 -public class FileIOCommands extends Commands { +public class DataHandler extends Commands { private static final String DATA_DIRECTORY_PATH = "data/studentInfo"; private static final String DATA_FILE_PATH = DATA_DIRECTORY_PATH + "/Student_Information.txt"; private static final String ARCHIVE_DIRECTORY_PATH = "data/archive"; diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index ec724cd583..ef0742b4cc 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -1,13 +1,7 @@ package classify.user; -import classify.commands.AddStudent; -import classify.commands.Commands; -import classify.commands.FileIOCommands; -import classify.commands.DeleteCommands; -import classify.commands.ListStudentsCommand; -import classify.commands.StudentSorter; -import classify.commands.ViewStudent; -import classify.commands.EditStudent; +import classify.commands.*; +import classify.data.DataHandler; import classify.student.Student; import classify.ui.UI; @@ -93,7 +87,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas // @@author ParthGandhiNUS case BYE: UI.printEndConversation(); - FileIOCommands.writeStudentInfo(masterStudentList); + DataHandler.writeStudentInfo(masterStudentList); break; case LIST: @@ -119,11 +113,11 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas break; case ARCHIVE: - archiveStudent(masterStudentList, archiveList, userCommand[1], in); + ArchiveCommands.archiveStudent(masterStudentList, archiveList, userCommand[1], in); break; case UNARCHIVE: - unarchiveStudent(masterStudentList, archiveList, userCommand[1], in); + ArchiveCommands.unarchiveStudent(masterStudentList, archiveList, userCommand[1], in); break; default: @@ -139,39 +133,6 @@ public static void parseListCommand(ArrayList masterStudentList, Scanne ListStudentsCommand.chooseListType(masterStudentList, scanner, subject); } - //@@author blackmirag3 - private static void unarchiveStudent(ArrayList masterList, ArrayList archiveList, - String name, Scanner in) { - if (name == null) { - name = Commands.promptName(in); - } - Student student = findStudentByName(archiveList, name, in); - if (student == null) { - UI.printStudentNotFound(); - return; - } - archiveList.remove(student); - masterList.add(student); - FileIOCommands.writeArchive(archiveList); - FileIOCommands.writeStudentInfo(masterList); - } - - private static void archiveStudent(ArrayList masterList, ArrayList archiveList, - String name, Scanner in) { - if (name == null) { - name = Commands.promptName(in); - } - Student student = findStudentByName(masterList, name, in); - if (student == null) { - UI.printStudentNotFound(); - return; - } - masterList.remove(student); - archiveList.add(student); - FileIOCommands.writeArchive(archiveList); - FileIOCommands.writeStudentInfo(masterList); - } - /** * Sorts the list of students based on user input. * From 20676e56c1278868db5e8a2364aa3d0a4dfcd639 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Wed, 3 Apr 2024 00:21:50 +0800 Subject: [PATCH 174/503] Add javadoc for archive commands --- .../classify/commands/ArchiveCommands.java | 51 +++++++++++++++---- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/src/main/java/classify/commands/ArchiveCommands.java b/src/main/java/classify/commands/ArchiveCommands.java index 6a82c1dcdb..b2c599a42c 100644 --- a/src/main/java/classify/commands/ArchiveCommands.java +++ b/src/main/java/classify/commands/ArchiveCommands.java @@ -9,36 +9,67 @@ import java.util.Scanner; public class ArchiveCommands { + //@@author blackmirag3 + /*** + * Prompts for student name to search in archive list + * If student exists, this method removes student from archive list to add to master list + * Writes archive and student information file in data directory + * + * @param masterList ArrayList of Students who are in master list + * @param archiveList ArrayList of Students who are archived + * @param name String for student's name + * @param in Scanner to read user input + */ public static void unarchiveStudent(ArrayList masterList, ArrayList archiveList, String name, Scanner in) { - if (name == null) { - name = Commands.promptName(in); - } - Student student = InputParsing.findStudentByName(archiveList, name, in); + + Student student = getStudent(archiveList, name, in); + if (student == null) { - UI.printStudentNotFound(); return; } + archiveList.remove(student); masterList.add(student); DataHandler.writeArchive(archiveList); DataHandler.writeStudentInfo(masterList); } + /*** + * Prompts for student name to search in master student list + * If student exists, this method removes student from master list to add to archive list + * Writes archive and student information file in data directory + * + * @param masterList ArrayList of Students who are in master list + * @param archiveList ArrayList of Students who are archived + * @param name String for student's name + * @param in Scanner to read user input + */ public static void archiveStudent(ArrayList masterList, ArrayList archiveList, String name, Scanner in) { - if (name == null) { - name = Commands.promptName(in); - } - Student student = InputParsing.findStudentByName(masterList, name, in); + + Student student = getStudent(masterList, name, in); + if (student == null) { - UI.printStudentNotFound(); return; } + masterList.remove(student); archiveList.add(student); DataHandler.writeArchive(archiveList); DataHandler.writeStudentInfo(masterList); } + + private static Student getStudent(ArrayList archiveList, String name, Scanner in) { + if (name == null) { + name = Commands.promptName(in); + } + Student student = InputParsing.findStudentByName(archiveList, name, in); + if (student == null) { + UI.printStudentNotFound(); + return null; + } + return student; + } } From ca1984824e870dbf6bde762e1159d7ca7455c6ca Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 00:35:04 +0800 Subject: [PATCH 175/503] Make private class public --- src/main/java/classify/commands/AddStudent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 228220e45f..73fceb3776 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -103,7 +103,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, * before being prompted * @return The valid non-empty name entered by the user. */ - private static String checkForEmptyName(ArrayList masterStudentList, Scanner in, String studentName) { + public static String checkForEmptyName(ArrayList masterStudentList, Scanner in, String studentName) { String name; while (true) { From 04f2c9cfab298d846f581ec6d012a4eaaec370d9 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 00:35:43 +0800 Subject: [PATCH 176/503] Remove scanner.close(); --- src/main/java/classify/commands/ListStudentsCommand.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index ef57051739..6d2c28a0b7 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -69,7 +69,6 @@ private static void listAllStudents(ArrayList masterStudentList) { Scanner scanner = new Scanner(System.in); String choice = scanner.nextLine().trim(); - scanner.close(); //@@ author blackmirag3 switch (choice) { From 327ca7135ac26610864cff7b2b493e628e369658 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 00:36:10 +0800 Subject: [PATCH 177/503] Edit author tag --- src/main/java/classify/user/ClassifyExceptions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/user/ClassifyExceptions.java b/src/main/java/classify/user/ClassifyExceptions.java index 0892de4e64..34ab05e2dd 100644 --- a/src/main/java/classify/user/ClassifyExceptions.java +++ b/src/main/java/classify/user/ClassifyExceptions.java @@ -1,4 +1,4 @@ -//@@author blackmirag3 +//@@author ParthGandhiNUS package classify.user; public class ClassifyExceptions extends Exception { From bdda25f115a1f7e654eeccdfbd5733d2129ff878 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 00:37:06 +0800 Subject: [PATCH 178/503] Edit Data Management to support basic attributes --- src/main/java/classify/data/DataReader.java | 38 +++++++++++++++++++-- src/main/java/classify/student/Student.java | 3 +- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 2903158049..be16372d6d 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -11,6 +11,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.Scanner; import java.util.logging.Level; @@ -35,15 +38,46 @@ public static void restoreStudentList(String studentFileInput, ArrayList list, String filePath) throws IOException { //@@author blackmirag3 diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 8484dc8333..a362756837 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -66,7 +66,8 @@ public boolean hasSubject(String subject) { //@@author ParthGandhiNUS public String textFileInputString() { - return String.format("%s",getName().trim()); + return String.format("%s ~~ %s ~~ %s ~~ %s ~~ %s",getName().trim(), getAttributes().getGender(), + getAttributes().getPhoneNumber(),getAttributes().getLastPaymentDate(), getAttributes().getRemarks()); } //@@author Cryolian From a3beaa1c4fd4d52a0a1ef61de7ca155037d97894 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Wed, 3 Apr 2024 01:06:13 +0800 Subject: [PATCH 179/503] Add javadocs to methods in edit class --- .../java/classify/commands/EditStudent.java | 64 ++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index 9d0f0827f6..32d3008ea1 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -20,6 +20,16 @@ public class EditStudent { private static final String DELETE = "delete"; private static final String DEFAULT_STRING_VALUE = "Unknown"; + // @@author alalal47 + /** + * Prompts the user to input a name for the student whose details are to be edited, if the user has not used the + * command with a name flag. + * + * + * @param list The list of all students. + * @param in The scanner object to read user input. + * @param name The name of the student if the user has entered it when invoking the function. + */ // @@author blackmirag3 public static void editStudent(ArrayList list, Scanner in, String name) { if (list.isEmpty()) { @@ -58,6 +68,17 @@ public static void editStudent(ArrayList list, Scanner in, String name) editStudentAttributes(in, student); } + // @@author alalal47 + /** + * Displays the attributes of the student that the user has chosen to edit, and prints the options available for + * editing. + * Allows user to select options for editing, for example, editing the saved phone number. + * The user can exit the edit state by pressing enter. + * + * @param in The scanner object to read user input. + * @param student The student that the user has chosen to edit. + */ + // @@author blackmirag3 private static void editStudentAttributes(Scanner in, Student student) { StudentAttributes attributes = student.getAttributes(); ViewStudent.showAttributes(attributes); @@ -105,13 +126,27 @@ private static void editStudentAttributes(Scanner in, Student student) { } } - + // @@author alalal47 + /** + * Edits the last payment date for a particular student + * + * @param in The scanner object to read user input. + * @param attributes The attributes object of the student that the user has chosen to edit. + */ // @@author Cryolian private static void editPaymentDate(Scanner in, StudentAttributes attributes) { UI.println("Current stored date: " + attributes.getLastPaymentDate()); attributes.setLastPaymentDate(InputParsing.readInDate(in)); } + // @@author alalal47 + /** + * Edits the last payment date for a particular student + * + * @param in The scanner object to read user input. + * @param attributes The attributes object of the student that the user has chosen to edit. + */ + // @@author Cryolian private static void editRemarks(Scanner in, StudentAttributes attributes) { UI.println(attributes.getRemarks()); UI.printDivider(); @@ -127,6 +162,14 @@ private static void editRemarks(Scanner in, StudentAttributes attributes) { UI.printDivider(); } + // @@author alalal47 + /** + * Edits the phone number for a particular student + * + * @param in The scanner object to read user input. + * @param attributes The attributes object of the student that the user has chosen to edit. + */ + // @@author Cryolian private static void editNumber(Scanner in, StudentAttributes attributes) { try { openNumberEditInterface(in, attributes); @@ -140,6 +183,15 @@ private static void editNumber(Scanner in, StudentAttributes attributes) { UI.printDivider(); } + // @@author alalal47 + /** + * Displays the interface to guide the user on how to edit the phone number for a particular student. + * Displays the current number and instructions to stop editing + * + * @param in The scanner object to read user input. + * @param attributes The attributes object of the student that the user has chosen to edit. + */ + // @@author Cryolian private static void openNumberEditInterface(Scanner in, StudentAttributes attributes) throws NameNumberMatchException, NumberFormatException { @@ -198,7 +250,15 @@ private static void editAttribute(Scanner in, StudentAttributes attributes) { } } - + // @@author alalal47 + /** + * Removes the subject that the user inputs from a particular student + * Continues to prompt the user until user enters blank to exit. + * + * @param in The scanner object to read user input. + * @param attributes The attributes object of the student that the user has chosen to edit. + */ + // @@author blackmirag3 private static void deleteAttribute(Scanner in, StudentAttributes attributes) { while (true) { From b25424e4fc68cdca359f9ac12d741f547b54247c Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Wed, 3 Apr 2024 01:16:06 +0800 Subject: [PATCH 180/503] Remove unnecessary try catch blocks from grade and class value check --- src/main/java/classify/user/InputParsing.java | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index ef0742b4cc..1f04e58ddb 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -323,35 +323,25 @@ private static Student findStudentByNumber(ArrayList studentList, Scann //@@author blackmirag3 public static boolean isValidClassesAttended(int classesAttended) { - try { - if (classesAttended < 0) { - System.out.println("Classes attended must be 0 or more."); - UI.printDivider(); - return false; - } - return true; - } catch (NumberFormatException e) { - LOGGER.log(Level.WARNING, "Invalid input for classes attended: " + classesAttended, e); - System.out.println("Invalid input for classes attended. Please enter a valid whole number."); + + if (classesAttended < 0) { + System.out.println("Classes attended must be 0 or more."); UI.printDivider(); return false; } + + return true; } private static boolean isValidGrade(double grade) { - try { - if (grade < 0 || grade > 100) { - System.out.println("Grade must be between 0 and 100. Please enter a valid number."); - UI.printDivider(); - return false; - } - return true; - } catch (NumberFormatException e) { - LOGGER.log(Level.WARNING, "Invalid input for grade: " + grade, e); - UI.printValidNumberError(); + + if (grade < 0 || grade > 100) { + System.out.println("Grade must be between 0 and 100. Please enter a valid number."); UI.printDivider(); return false; } + + return true; } // @@author Cryolian From f5422bcaa7ceb00070ac818d4ae5f9df10e1ea2d Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Wed, 3 Apr 2024 01:21:08 +0800 Subject: [PATCH 181/503] Remove wildcard import for checkstyle violation --- src/main/java/classify/user/InputParsing.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 1f04e58ddb..9da70c03db 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -1,6 +1,12 @@ package classify.user; -import classify.commands.*; +import classify.commands.AddStudent; +import classify.commands.ArchiveCommands; +import classify.commands.DeleteCommands; +import classify.commands.EditStudent; +import classify.commands.ListStudentsCommand; +import classify.commands.StudentSorter; +import classify.commands.ViewStudent; import classify.data.DataHandler; import classify.student.Student; import classify.ui.UI; From a29ce80ccd3959f10b9722a7320c9d8b06e6a7d0 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 01:22:39 +0800 Subject: [PATCH 182/503] Remove Scanner.close() --- src/main/java/classify/commands/ListStudentsCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 8ad59391fa..291727f5f0 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -93,7 +93,7 @@ private static void listAllStudents(ArrayList masterStudentList) { default: UI.println(INVALID_CHOICE); } - scanner.close(); + //scanner.close(); UI.printDivider(); } From 6de2f328d31b2dc341efd4f6400b4645d93d4aec Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 01:24:03 +0800 Subject: [PATCH 183/503] Add promptForLastPaymentDate --- src/main/java/classify/user/InputParsing.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 9f9e1017f5..b64f9524a3 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -447,7 +447,7 @@ public static LocalDate readInDate(Scanner in) { String userInput; LocalDate paymentDate; - + UI.promptForLastPaymentDate(); do { userInput = in.nextLine(); From 42e8be414395c98509b605fb8ec1316143c133a0 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 01:25:20 +0800 Subject: [PATCH 184/503] Edit UI prompt when making edits --- src/main/java/classify/ui/UI.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index fd15feee6f..c64977b419 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -11,7 +11,8 @@ public class UI { private static final String EMPTY_SUBJECT_ERROR = "No subjects and grades found for this student."; private static final String NULL_ATTRIBUTE_ERROR = "No attributes found for this student."; private static final String EDIT_PROMPT = "How would you like to update a student's subject? (enter blank to exit)"; - private static final String EDIT_TYPES_PROMPT = "Add, Edit (subjects), Number, Remarks, Payment or Delete: "; + private static final String EDIT_TYPES_PROMPT = "Add(subject), Edit(subject), Number, Remarks, Payment " + + "or Delete(subject): "; private static final String EMPTY_LIST_ERROR = "Currently no students in list."; private static final String VALID_NUMBER_ERROR = "A valid number was not entered. Please input a valid number. "; private static final String PHONE_NUMBER_PROMPT = "Please input a valid phone number: "; From 83ac113499d289297bf52077ed7d3cb8dac004e9 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 01:26:10 +0800 Subject: [PATCH 185/503] Remove redundant exception catches --- .../classify/commands/FileIOCommands.java | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/src/main/java/classify/commands/FileIOCommands.java b/src/main/java/classify/commands/FileIOCommands.java index b0f65357bc..898e702279 100644 --- a/src/main/java/classify/commands/FileIOCommands.java +++ b/src/main/java/classify/commands/FileIOCommands.java @@ -3,7 +3,6 @@ import classify.data.DataReader; import classify.data.DataWriter; import classify.student.Student; -import classify.ui.DataUI; import java.io.IOException; import java.util.ArrayList; @@ -33,14 +32,10 @@ public static void writeStudentInfo(List list){ * @throws IOException When unable to get the Student_Information.txt file or has any input errors */ public static void readStudentInfo(ArrayList list) throws IOException{ - try{ - System.out.println("Trying to load Student info"); - DataWriter.createParentFileFolder(DATA_DIRECTORY_PATH); - DataReader.initialiseData(list, DATA_FILE_PATH); - } catch (IOException e) { - DataUI.printCreateFailure(); - throw e; - } + + System.out.println("Trying to load Student info"); + DataWriter.createParentFileFolder(DATA_DIRECTORY_PATH); + DataReader.initialiseData(list, DATA_FILE_PATH); } /** @@ -60,13 +55,8 @@ public static void writeArchive(List list){ * @throws IOException When unable to get the Student_Information.txt file or has any input errors */ public static void readArchive(ArrayList list) throws IOException { - try{ - System.out.println("Trying to load Student Archive."); - DataWriter.createParentFileFolder(ARCHIVE_DIRECTORY_PATH); - DataReader.initialiseData(list, ARCHIVE_FILE_PATH); - } catch (IOException e) { - DataUI.printCreateFailure(); - throw e; - } + System.out.println("Trying to load Student Archive."); + DataWriter.createParentFileFolder(ARCHIVE_DIRECTORY_PATH); + DataReader.initialiseData(list, ARCHIVE_FILE_PATH); } } From 17312adc1693366ab145300f5713a18c7189c651 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 01:31:26 +0800 Subject: [PATCH 186/503] Edit Expected.txt to match new changes --- text-ui-test/EXPECTED.TXT | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index 064287f92c..f402f407a2 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -1,10 +1,12 @@ +Trying to load Student info +Directory loaded successfully! +Creating a new data file... +Trying to load Student Archive. +Directory loaded successfully! +Creating a new data file... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Welcome to Classify! What can I do for you today? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Creating a new Student Info File... -Now getting previous Student Info Records... -Created a new student info file successfully! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Hope you've had a productive day. See you again! Goodbye! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From bf79c41ffb0431dfe3ba6fdf96eb2fa019c2512e Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 01:34:19 +0800 Subject: [PATCH 187/503] Use proper indentation --- src/main/java/classify/data/DataReader.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index be16372d6d..5808fa27f7 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -49,15 +49,15 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Wed, 3 Apr 2024 01:51:26 +0800 Subject: [PATCH 188/503] Fix author tags and add collision checking for data reading --- .../classify/commands/DeleteCommands.java | 3 + .../java/classify/commands/EditStudent.java | 64 ++++++++++++++++++- src/main/java/classify/data/DataReader.java | 14 +++- 3 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index 25d5c6d2c6..98f0458da0 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -44,6 +44,8 @@ public static void deleteStudent(ArrayList masterStudentList, ArrayList recentlyDeletedList.add(foundStudent); } masterStudentList.remove(foundStudent); + //@@author alalal47 + assert masterStudentList.contains(foundStudent) == false : "student should be removed"; DataHandler.writeStudentInfo(masterStudentList); } @@ -96,6 +98,7 @@ public static void restoreStudent(ArrayList masterStudentList, ArrayLis * @param masterStudentList The list of all students * @param recentlyDeletedList The list of recently deleted students */ + //@@author alalal47 public static void undoDelete(ArrayList masterStudentList, ArrayList recentlyDeletedList) { if (recentlyDeletedList.isEmpty()) { UI.printNoDeleteFound(); diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index 9d0f0827f6..32d3008ea1 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -20,6 +20,16 @@ public class EditStudent { private static final String DELETE = "delete"; private static final String DEFAULT_STRING_VALUE = "Unknown"; + // @@author alalal47 + /** + * Prompts the user to input a name for the student whose details are to be edited, if the user has not used the + * command with a name flag. + * + * + * @param list The list of all students. + * @param in The scanner object to read user input. + * @param name The name of the student if the user has entered it when invoking the function. + */ // @@author blackmirag3 public static void editStudent(ArrayList list, Scanner in, String name) { if (list.isEmpty()) { @@ -58,6 +68,17 @@ public static void editStudent(ArrayList list, Scanner in, String name) editStudentAttributes(in, student); } + // @@author alalal47 + /** + * Displays the attributes of the student that the user has chosen to edit, and prints the options available for + * editing. + * Allows user to select options for editing, for example, editing the saved phone number. + * The user can exit the edit state by pressing enter. + * + * @param in The scanner object to read user input. + * @param student The student that the user has chosen to edit. + */ + // @@author blackmirag3 private static void editStudentAttributes(Scanner in, Student student) { StudentAttributes attributes = student.getAttributes(); ViewStudent.showAttributes(attributes); @@ -105,13 +126,27 @@ private static void editStudentAttributes(Scanner in, Student student) { } } - + // @@author alalal47 + /** + * Edits the last payment date for a particular student + * + * @param in The scanner object to read user input. + * @param attributes The attributes object of the student that the user has chosen to edit. + */ // @@author Cryolian private static void editPaymentDate(Scanner in, StudentAttributes attributes) { UI.println("Current stored date: " + attributes.getLastPaymentDate()); attributes.setLastPaymentDate(InputParsing.readInDate(in)); } + // @@author alalal47 + /** + * Edits the last payment date for a particular student + * + * @param in The scanner object to read user input. + * @param attributes The attributes object of the student that the user has chosen to edit. + */ + // @@author Cryolian private static void editRemarks(Scanner in, StudentAttributes attributes) { UI.println(attributes.getRemarks()); UI.printDivider(); @@ -127,6 +162,14 @@ private static void editRemarks(Scanner in, StudentAttributes attributes) { UI.printDivider(); } + // @@author alalal47 + /** + * Edits the phone number for a particular student + * + * @param in The scanner object to read user input. + * @param attributes The attributes object of the student that the user has chosen to edit. + */ + // @@author Cryolian private static void editNumber(Scanner in, StudentAttributes attributes) { try { openNumberEditInterface(in, attributes); @@ -140,6 +183,15 @@ private static void editNumber(Scanner in, StudentAttributes attributes) { UI.printDivider(); } + // @@author alalal47 + /** + * Displays the interface to guide the user on how to edit the phone number for a particular student. + * Displays the current number and instructions to stop editing + * + * @param in The scanner object to read user input. + * @param attributes The attributes object of the student that the user has chosen to edit. + */ + // @@author Cryolian private static void openNumberEditInterface(Scanner in, StudentAttributes attributes) throws NameNumberMatchException, NumberFormatException { @@ -198,7 +250,15 @@ private static void editAttribute(Scanner in, StudentAttributes attributes) { } } - + // @@author alalal47 + /** + * Removes the subject that the user inputs from a particular student + * Continues to prompt the user until user enters blank to exit. + * + * @param in The scanner object to read user input. + * @param attributes The attributes object of the student that the user has chosen to edit. + */ + // @@author blackmirag3 private static void deleteAttribute(Scanner in, StudentAttributes attributes) { while (true) { diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 5808fa27f7..420b79a45a 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -1,8 +1,10 @@ package classify.data; import classify.student.Student; +import classify.student.StudentList; import classify.ui.DataUI; import classify.user.InputParsing; +import classify.user.NameNumberMatchException; import classify.ui.UI; import java.io.BufferedReader; @@ -49,9 +51,19 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Wed, 3 Apr 2024 02:40:13 +0800 Subject: [PATCH 189/503] Add javadocs --- src/main/java/classify/commands/Commands.java | 6 ++++ .../classify/commands/DeleteCommands.java | 2 +- .../java/classify/commands/EditStudent.java | 28 +++++++++++++++++++ src/main/java/classify/data/DataReader.java | 13 ++++++++- 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/commands/Commands.java b/src/main/java/classify/commands/Commands.java index 18ec7c4a92..8dfbe72f21 100644 --- a/src/main/java/classify/commands/Commands.java +++ b/src/main/java/classify/commands/Commands.java @@ -6,6 +6,12 @@ //@@author blackmirag3 public class Commands { + /*** + * prompts for student name from user input and trims string + * + * @param in String containing student's name + * @return + */ public static String promptName(Scanner in) { UI.printStudentNamePrompt(); return in.nextLine().trim(); diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index 25d5c6d2c6..4595f6b632 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -89,7 +89,7 @@ public static void restoreStudent(ArrayList masterStudentList, ArrayLis } - //@@author blackmirag3 + //@@author alalal47 /** * Restores the latest deleted student that has not yet been restored * diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index 9d0f0827f6..2a41c2c68e 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -21,6 +21,16 @@ public class EditStudent { private static final String DEFAULT_STRING_VALUE = "Unknown"; // @@author blackmirag3 + + /*** + * Searches for specified student in a list and edit attributes of found student + * Prompts for input from user for name if student is not found in list + * Prompts for input from user for name if there is no valid string input for name + * + * @param list ArrayList containing students + * @param in Scanner instance + * @param name String containing student's name + */ public static void editStudent(ArrayList list, Scanner in, String name) { if (list.isEmpty()) { UI.printEmptyListError(); @@ -58,6 +68,13 @@ public static void editStudent(ArrayList list, Scanner in, String name) editStudentAttributes(in, student); } + /*** + * Edit StudentAttributes within specified instance of student + * Prompts for user input to either add, edit or delete attributes + * + * @param in Scanner instance + * @param student instance of student to edit + */ private static void editStudentAttributes(Scanner in, Student student) { StudentAttributes attributes = student.getAttributes(); ViewStudent.showAttributes(attributes); @@ -199,6 +216,17 @@ private static void editAttribute(Scanner in, StudentAttributes attributes) { } } + /** + * Prompts the user to delete subject for student. + * Prompts user for input for subject name + * Method searches student attributes for specified subject + * If subject is found, subject is deleted + * If subject is not found or user enters blank to indicate exit, method returns. + * + * @param in The scanner object to read user input. + * @param attributes The StudentAttributes object to store the attributes of the + * student. + */ private static void deleteAttribute(Scanner in, StudentAttributes attributes) { while (true) { diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 2903158049..42fca59e8d 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -44,9 +44,20 @@ public static void restoreStudentList(String studentFileInput, ArrayList list, String filePath) throws IOException { - //@@author blackmirag3 + Path directory = Paths.get(filePath); if (!Files.exists(directory)) { DataUI.printCreatingFile(); From 1a37def06ca6892f7c89e9ff12d3767326430c88 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 12:54:09 +0800 Subject: [PATCH 190/503] Add new constants --- src/main/java/classify/student/Student.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index a362756837..f0ae337869 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -8,6 +8,8 @@ * added later. */ public class Student { + private static final String SUBJECTINFOSEPARATOR = " ## "; + private static final String SUBJECTSEPARATIOR = " #--# "; //@@author Cryolian public String name; From 075e049c7b5e2846580d854c8eec9ffe74610f16 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 12:55:03 +0800 Subject: [PATCH 191/503] Mae method more readable and clearer --- src/main/java/classify/student/Student.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index f0ae337869..44fa514e47 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -68,8 +68,13 @@ public boolean hasSubject(String subject) { //@@author ParthGandhiNUS public String textFileInputString() { - return String.format("%s ~~ %s ~~ %s ~~ %s ~~ %s",getName().trim(), getAttributes().getGender(), - getAttributes().getPhoneNumber(),getAttributes().getLastPaymentDate(), getAttributes().getRemarks()); + return String.format("%s ~~ %s ~~ %s ~~ %s ~~ %s ~~ %s", + getName().trim(), + getAttributes().getGender(), + getAttributes().getPhoneNumber(), + getAttributes().getLastPaymentDate(), + getAttributes().getRemarks(), + listOfSubjectAttributes()); } //@@author Cryolian From b377e1d05e7adc3e58e3c495dd9c421a0af6b625 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 12:57:00 +0800 Subject: [PATCH 192/503] Create listOfSubjectAttributes method to include different subject attributes --- src/main/java/classify/student/Student.java | 37 +++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 44fa514e47..90e2ce848d 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -1,6 +1,7 @@ package classify.student; import java.time.LocalDate; +import java.util.List; /** * Meant to represent a particular student of the tuition centre. @@ -67,6 +68,42 @@ public boolean hasSubject(String subject) { } //@@author ParthGandhiNUS + public String listOfSubjectAttributes(){ + List currentStudent = this.getAttributes().getSubjectGrades(); + + StringBuilder subjectInfo = new StringBuilder(""); + StringBuilder separateSubjectInfo = new StringBuilder(SUBJECTINFOSEPARATOR); + StringBuilder separateSubject = new StringBuilder(SUBJECTSEPARATIOR); + //Checks for an empty list + if (currentStudent.isEmpty()){ + return subjectInfo.toString(); + } + + int numberOfSubjects = currentStudent.size(); + + for (int i = 0; i < numberOfSubjects ; i++){ + //Subject Name + StringBuilder subject = new StringBuilder(currentStudent.get(i).getSubject()); + + //Grade information + String gradeInfo = Double.toString(currentStudent.get(i).getGrade()); + StringBuilder gradeInformation = new StringBuilder(gradeInfo); + + //Class Attended Information + String classInfo = Integer.toString(currentStudent.get(i).getClassesAttended()); + StringBuilder classInformation = new StringBuilder(classInfo); + + subjectInfo.append(subject); + subjectInfo.append(separateSubjectInfo); + subjectInfo.append(gradeInformation); + subjectInfo.append(separateSubjectInfo); + subjectInfo.append(classInformation); + subjectInfo.append(separateSubject); + } + + return subjectInfo.toString(); + } + public String textFileInputString() { return String.format("%s ~~ %s ~~ %s ~~ %s ~~ %s ~~ %s", getName().trim(), From f2df118322298122ed4bab7db80e5d3ffa956b7e Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 12:57:43 +0800 Subject: [PATCH 193/503] Update the parsing capabilities of DataReader for subject Attributes --- src/main/java/classify/data/DataReader.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 420b79a45a..7cb166eba5 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -2,6 +2,7 @@ import classify.student.Student; import classify.student.StudentList; +import classify.student.SubjectGrade; import classify.ui.DataUI; import classify.user.InputParsing; import classify.user.NameNumberMatchException; @@ -76,6 +77,23 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Wed, 3 Apr 2024 13:16:56 +0800 Subject: [PATCH 194/503] Fix checkstyle violation --- src/main/java/classify/commands/EditStudent.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index cbf3ad333f..d845ea23d3 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -30,17 +30,6 @@ public class EditStudent { * @param in The scanner object to read user input. * @param name The name of the student if the user has entered it when invoking the function. */ - // @@author blackmirag3 - - /*** - * Searches for specified student in a list and edit attributes of found student - * Prompts for input from user for name if student is not found in list - * Prompts for input from user for name if there is no valid string input for name - * - * @param list ArrayList containing students - * @param in Scanner instance - * @param name String containing student's name - */ public static void editStudent(ArrayList list, Scanner in, String name) { if (list.isEmpty()) { UI.printEmptyListError(); From 9555fdad798d1a048d08d956f43cd0c2f5201d96 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 16:37:19 +0800 Subject: [PATCH 195/503] Fix minor number editing bug --- src/main/java/classify/commands/EditStudent.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index 32d3008ea1..724b355f2c 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -199,7 +199,11 @@ private static void openNumberEditInterface(Scanner in, StudentAttributes attrib UI.println("Current Number: " + String.valueOf(attributes.getPhoneNumber())); UI.println("Type in and enter the letter a if you wish to stop editing."); int number = InputParsing.promptForPhoneNumber(in); - StudentList.checkNameNumberPair(StudentList.masterStudentList, attributes.getName(), number); + //@@author ParthGandhiNUS + if (number != attributes.getPhoneNumber()){ + StudentList.checkNameNumberPair(StudentList.masterStudentList, attributes.getName(), number); + } + // @@author Cryolian attributes.setPhoneNumber(number); } From dd77de21f25f6d9b3381c5c83bb0b417a5639987 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 3 Apr 2024 17:32:48 +0800 Subject: [PATCH 196/503] Fix listStudentsWithTotalClassesAttended() method --- src/main/java/classify/commands/AddStudent.java | 2 -- .../classify/commands/ListStudentsCommand.java | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 836548d04e..1c3cef0bc3 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -23,8 +23,6 @@ public class AddStudent { private static final String SUBJECT_ENTER_NOTHING_TO_SKIP = "Subject (enter nothing to skip): "; private static final String STUDENT_ADDED_SUCCESSFULLY = "Student added successfully."; private static final String NUMBER_IS_OUTSIDE_THE_ACCEPTABLE_RANGE = "Number is outside the acceptable range."; - private static final String STUDENT_WITH_THE_SAME_NAME_ALREADY_EXISTS = - "Student with the same name already exists."; /** * Adds a new student to the list of students. diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 291727f5f0..979f423f94 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -2,6 +2,7 @@ import classify.student.Student; import classify.student.StudentList; +import classify.student.SubjectGrade; import classify.ui.UI; import java.util.ArrayList; @@ -99,14 +100,26 @@ private static void listAllStudents(ArrayList masterStudentList) { /** * Lists all students in the provided list along with their total classes attended. + * If the user had left the classes attended blank for that subject, + * it would not be counted into the total classes attended. * * @param masterStudentList The list of all students. */ private static void listStudentsWithTotalClasses(ArrayList masterStudentList) { int i = 1; for (Student student : masterStudentList) { + int totalClassesAttended = 0; + + for (SubjectGrade subjectGrade : student.getAttributes().getSubjectGrades()) { + if (subjectGrade.getClassesAttended() >= 0) { + totalClassesAttended += subjectGrade.getClassesAttended(); + } else { + totalClassesAttended += 0; + } + } + System.out.println(i + "." + student.getName() + TOTAL_CLASSES_ATTENDED + - student.getTotalClassesAttended()); + totalClassesAttended); i++; } } From 41118ada0e8484d1e22c8ea16950e1c6e1e65c29 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 3 Apr 2024 19:13:50 +0800 Subject: [PATCH 197/503] Fix printing of date request --- src/main/java/classify/student/SubjectGrade.java | 11 ++++++----- src/main/java/classify/user/InputParsing.java | 1 - 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/classify/student/SubjectGrade.java b/src/main/java/classify/student/SubjectGrade.java index cebbcff584..8412e9a36a 100644 --- a/src/main/java/classify/student/SubjectGrade.java +++ b/src/main/java/classify/student/SubjectGrade.java @@ -1,14 +1,14 @@ package classify.student; - +//@@author tayponghee public class SubjectGrade { private String subject; private double grade; - private int classesAttended; + private static int classesAttended; public SubjectGrade(String subject, double grade, int classesAttended) { this.subject = subject; this.grade = grade; - this.classesAttended = classesAttended; + SubjectGrade.classesAttended = classesAttended; } public String getSubject() { @@ -19,10 +19,11 @@ public double getGrade() { return grade; } - public int getClassesAttended() { + public static int getClassesAttended() { return classesAttended; } + //@@author blackmirag3 public void setSubject(String subject) { this.subject = subject; } @@ -32,6 +33,6 @@ public void setGrade(double grade) { } public void setClassesAttended(int classesAttended) { - this.classesAttended = classesAttended; + SubjectGrade.classesAttended = classesAttended; } } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index b051ae6236..383fa209e1 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -404,7 +404,6 @@ public static LocalDate readInDate(Scanner in) { String userInput; LocalDate paymentDate; - UI.promptForLastPaymentDate(); do { userInput = in.nextLine(); From bc63d4c9fd4296163ee16bc2cf5e8117fbb580e6 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 3 Apr 2024 19:35:50 +0800 Subject: [PATCH 198/503] Fix number bug and printing date bug --- src/main/java/classify/commands/AddStudent.java | 1 - src/main/java/classify/user/InputParsing.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 836548d04e..fffbf2f3de 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -78,7 +78,6 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, UI.promptForGender(); student.getAttributes().setGender(InputParsing.readInString(in)); - UI.promptForLastPaymentDate(); student.getAttributes().setLastPaymentDate(InputParsing.readInDate(in)); UI.promptForRemarks(); diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index b051ae6236..daf95e156c 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -46,7 +46,7 @@ public class InputParsing { private static final String TOTAL_NUMBER_OF_CLASSES_ATTENDED = "2. Total number of classes attended:"; private static final String LAST_PAID_DATE = "3. Date of last fee payment: "; private static final int NUMBER_TOO_SMALL = 80000000; - private static final int NUMBER_TOO_BIG = 1000_000_000; + private static final int NUMBER_TOO_BIG = 1000_000_00; public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, ArrayList recentlyDeletedList, From 3b920a40308c165c84fff972c55838c16317d065 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 3 Apr 2024 19:52:24 +0800 Subject: [PATCH 199/503] Revert "Fix printing of date request" This reverts commit 41118ada0e8484d1e22c8ea16950e1c6e1e65c29. --- src/main/java/classify/student/SubjectGrade.java | 11 +++++------ src/main/java/classify/user/InputParsing.java | 1 + 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/classify/student/SubjectGrade.java b/src/main/java/classify/student/SubjectGrade.java index 8412e9a36a..cebbcff584 100644 --- a/src/main/java/classify/student/SubjectGrade.java +++ b/src/main/java/classify/student/SubjectGrade.java @@ -1,14 +1,14 @@ package classify.student; -//@@author tayponghee + public class SubjectGrade { private String subject; private double grade; - private static int classesAttended; + private int classesAttended; public SubjectGrade(String subject, double grade, int classesAttended) { this.subject = subject; this.grade = grade; - SubjectGrade.classesAttended = classesAttended; + this.classesAttended = classesAttended; } public String getSubject() { @@ -19,11 +19,10 @@ public double getGrade() { return grade; } - public static int getClassesAttended() { + public int getClassesAttended() { return classesAttended; } - //@@author blackmirag3 public void setSubject(String subject) { this.subject = subject; } @@ -33,6 +32,6 @@ public void setGrade(double grade) { } public void setClassesAttended(int classesAttended) { - SubjectGrade.classesAttended = classesAttended; + this.classesAttended = classesAttended; } } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 383fa209e1..b051ae6236 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -404,6 +404,7 @@ public static LocalDate readInDate(Scanner in) { String userInput; LocalDate paymentDate; + UI.promptForLastPaymentDate(); do { userInput = in.nextLine(); From 814fd881f872387c3fa55cc73b93f90168735584 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 3 Apr 2024 20:08:48 +0800 Subject: [PATCH 200/503] Update UG --- docs/UserGuide.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 46e9bde12a..93824d12fa 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,7 +1,7 @@ # User Guide for **Classify** ## Preface -With the increased competititiveness of cohorts in Singapore, tuition centres have become more prevalent than ever before. +With the increased competitiveness of cohorts in Singapore, tuition centres have become more prevalent than ever before. According to a **[newspaper article](https://www.straitstimes.com/singapore/education/families-spent-14b-on-private-tuition-for-kids-last-year-as-parents-fork-out)** in The Straits Times, billions of dollars are spent in the tuition industry in Singapore every single year. @@ -228,6 +228,10 @@ Sort complete! **A**: In the jar directory (folder containing jar file), data is stored in the "data" folder (./data). You can import the contents within this data directory to that of the jar directory on the new computer. +**Q**: What inputs are not allowed? + +**A** The inputs that are banned (which are used for file saving) are `#` and `~`. In the event the program does not understand the saved file due to irresponsible behaviour, it is to be expected and hence the user has been warned. + ## Command Summary ### `add ` From 8aabe4a76b897ff80472c68693bbf160f8c7ae14 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 3 Apr 2024 20:16:24 +0800 Subject: [PATCH 201/503] Update UG --- docs/UserGuide.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 93824d12fa..f47e607e81 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -230,7 +230,7 @@ Sort complete! **Q**: What inputs are not allowed? -**A** The inputs that are banned (which are used for file saving) are `#` and `~`. In the event the program does not understand the saved file due to irresponsible behaviour, it is to be expected and hence the user has been warned. +**A**: The inputs that are banned (which are used for file saving) are `#` and `~`. In the event the program does not understand the saved file due to irresponsible behaviour, it is to be expected and hence the user has been warned. ## Command Summary @@ -273,6 +273,12 @@ Archives specified student. Removes student from current list and adds student t ### `unarchive ` Unarchives specified student. Moves student from archive to current list. +### `undo` +Undoes the last deleted entry. + +### `restore` +Restores the student from the current session. + ### `help` Generates the list of commands. From d1a5759987e3e1e0b63beac68a641eed109bead4 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 3 Apr 2024 20:18:44 +0800 Subject: [PATCH 202/503] Update UG --- docs/UserGuide.md | 26 ++++++++++++++++--- .../classify/commands/DeleteCommands.java | 2 +- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 46e9bde12a..d70403a266 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -19,10 +19,10 @@ The product is capable of storing students, and generating outputs based on prov Within our program, a student can be stored with their - Subjects taken -- Grades in those subjects +- Number grades of those subjects - Phone Number - Gender -- Last Payment Dates +- Last Payment Date - Remarks We have determined these to be the attributes important to running a working tuition centre. Based on these attributes, our program also has functions to sort students based on grades, subjects, improvements since joining the centre. @@ -80,6 +80,14 @@ Sorts the masterlist of students from the lowest number of classes attended to h Sorts the masterlist of students from the oldest date to the most recent. When the user types list, it will generate the updated sorted list. +### - Undo the most recent delete action `undo` + +Adds in the most recently deleted student back into the runtime database. + +### - Restore a specific deleted student `restore` + +Finds a specific deleted student and adds it back into the runtime database. + # Usage //todo add usage guide for our different commands @@ -155,7 +163,7 @@ Name of student to edit (enter blank to exit): toad No subjects and grades found for this student. How would you like to update a student's subject? (enter blank to exit) -Add, Edit or Delete: +Add(subject), Edit(subject), Number, Remarks, Payment or Delete(subject): add Subject (enter nothing to skip): Math Current marks out of 100 (blank to skip) : @@ -165,7 +173,16 @@ Enter Classes Attended (blank to skip): Do you want to add another subject and grade? (yes/no) no How would you like to update a student's subject? (enter blank to exit) -Add, Edit or Delete: +Add(subject), Edit(subject), Number, Remarks, Payment or Delete(subject): +payment +Current stored date: 12/12/2023 +Please input their last payment date in the format of YYYY-MM-DD. Enter blank to input today's date. + +Apr 03, 2024 8:09:34 PM classify.user.InputParsing parseDateFromString +INFO: Storing today as the last payment date. + +How would you like to update a student's subject? (enter blank to exit) +Add(subject), Edit(subject), Number, Remarks, Payment or Delete(subject): Exiting edit ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -218,6 +235,7 @@ sort payment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sort complete! ``` + ## FAQ **Q**: How do I transfer my data to another computer? diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index 42084a3f0a..77ee37014c 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -63,7 +63,7 @@ public static void deleteStudent(ArrayList masterStudentList, ArrayList public static void restoreStudent(ArrayList masterStudentList, ArrayList recentlyDeletedList, Scanner in, String studentName) { //@@author blackmirag3 - if (studentName == null) { + if (studentName == null || studentName.isBlank()) { studentName = promptName(in); } From e3d96622d48bb46d672462f070612b3c7786c96e Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 3 Apr 2024 20:28:38 +0800 Subject: [PATCH 203/503] Fix crashing bugs --- src/main/java/classify/Classify.java | 1 - src/main/java/classify/commands/DeleteCommands.java | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index c50acc4445..f4625ae0ad 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -41,4 +41,3 @@ public static void main(String[] args) throws IOException { UI.printEndConversation(); } } - diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index 77ee37014c..b64a59768f 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -86,6 +86,10 @@ public static void restoreStudent(ArrayList masterStudentList, ArrayLis //@@author Cryolian } catch (NameNumberMatchException e) { + UI.printDivider(); + return; + } catch (NullPointerException e) { + UI.printDivider(); return; } From 224e77af4faa7811c96e74e5d7e0a09b3273fc39 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 3 Apr 2024 20:51:56 +0800 Subject: [PATCH 204/503] Fix Crashing Bugs --- data/archive/student_archive.txt | 1 + src/main/java/classify/commands/AddStudent.java | 10 ++++++---- src/main/java/classify/user/InputParsing.java | 10 +++++----- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/data/archive/student_archive.txt b/data/archive/student_archive.txt index e69de29bb2..b6aa3949d7 100644 --- a/data/archive/student_archive.txt +++ b/data/archive/student_archive.txt @@ -0,0 +1 @@ +parth ~~ Unknown ~~ 99999999 ~~ 2024-04-03 ~~ Unknown ~~ diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 56c5e0ce71..a5e583fa16 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -112,19 +112,21 @@ public static String checkForEmptyName(ArrayList masterStudentList, Sca } else { name = studentName.trim(); studentName = NOTEMPTY; + + //@@author tayponghee + assert studentName != null; } - //@@author tayponghee - assert studentName != null; - - if (name.isEmpty()) { + if (name == null || name.isEmpty()) { UI.printEmptyNameMessage(); UI.printDivider(); } else { break; } + } return name; + } /** diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index daf95e156c..31c5f6d6f7 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -68,7 +68,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas UI.printDivider(); break; - // @@author alalal47 + //@@author alalal47 case DELETE: DeleteCommands.deleteStudent(masterStudentList, recentlyDeletedList, in, userCommand[1]); break; @@ -86,7 +86,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas UI.printDivider(); break; - // @@author ParthGandhiNUS + //@@author ParthGandhiNUS case BYE: UI.printEndConversation(); DataHandler.writeStudentInfo(masterStudentList); @@ -100,7 +100,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas } break; - // @@ author tayponghee + //@@ author tayponghee case SORT: sortStudents(masterStudentList, in, userCommand[1]); break; @@ -109,7 +109,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas handleViewSubjectCommand(masterStudentList, in, userCommand[1]); break; - // @@author blackmirag3 + //@@author blackmirag3 case EDIT: EditStudent.editStudent(masterStudentList, in, userCommand[1]); break; @@ -346,7 +346,7 @@ private static boolean isValidGrade(double grade) { return true; } - // @@author Cryolian + //@@author Cryolian /** * Creates a looping prompt asking for a phone number. * Only exits the loop when either an exception is thrown, From 77d2befbc106f01585fe01506c51522029f96d07 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Wed, 3 Apr 2024 21:21:43 +0800 Subject: [PATCH 205/503] Update UG with description of undo and restore features --- docs/UserGuide.md | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index e93a790cb1..be55109397 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -193,7 +193,7 @@ Deletes the student from the list. Allows the user to do delete [student] or jus Format: `delete` or `delete NAME` -Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. +Depending on whether the user entered the student's name or not during the command, a field will be printed out in the terminal, awaiting a user input. ``` Example: @@ -203,7 +203,33 @@ Enter student name: wario Student removed successfully! ``` +### - Restore a student to the working list `restore` +Restores a student deleted in the current session. Allows the user to do restore [student] or just restore. + +Format: `restore` or `restore NAME` +Depending on whether the user entered the student's name or not during the command, a field will be printed out in the terminal, awaiting a user input. + +``` +Example: +restore +Enter student name: +mario +Student has been restored! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` + +### - Undo a delete and restore the deleted student to the working list +Undoes the latest delete. Used by typing `undo` + +Format: `undo` + +``` +Example: +undo +Last delete undone! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ### - Sort the list of students `sort` Sorts the list of students based on the following input. Allows the user to do sort [type] or just sort @@ -294,7 +320,7 @@ Unarchives specified student. Moves student from archive to current list. ### `undo` Undoes the last deleted entry. -### `restore` +### `restore ` Restores the student from the current session. ### `help` From 53929c6331750fe85d7c5936d04f04c5e6d8f307 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 3 Apr 2024 21:51:03 +0800 Subject: [PATCH 206/503] Fix some bugs, update UG and DG --- docs/DeveloperGuide.md | 9 ++--- docs/UserGuide.md | 8 +++-- src/main/java/classify/Classify.java | 2 +- .../java/classify/commands/AddStudent.java | 3 +- .../classify/commands/ArchiveCommands.java | 26 ++++++++++++++ .../java/classify/commands/EditStudent.java | 31 +++++++++-------- .../java/classify/commands/ViewStudent.java | 2 +- src/main/java/classify/data/DataReader.java | 34 ++++++++++--------- src/main/java/classify/data/DataWriter.java | 1 - src/main/java/classify/ui/UI.java | 2 +- src/main/java/classify/user/InputParsing.java | 17 +++++++++- src/main/java/classify/user/UserInput.java | 3 ++ 12 files changed, 94 insertions(+), 44 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index ea49230304..8b1e2ad4c0 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -98,9 +98,6 @@ We created a parent `Details` class as those are information not specifically re However, our current implementation is not very secure as one can access every field of a `Student` object just by having access to it or the `StudentAttribute` object, which can be done via accessing the `static masterStudentList` variable.In future updates, we could possibly implement a Facade Pattern to better hide sensitive details. - - - ### Data Commands Component This section refers to `DataHandler.java`, `DataReader.java`, and `DataStorage.java` classes. @@ -200,7 +197,11 @@ Classify serves as an attempt to modernise administrative tasks in education ins |Version| As a ... | I want to ... | So that I can ...| |--------|----------|---------------|------------------| |v1.0|new user|see usage instructions|refer to them when I forget how to use the application| -|v2.0|user|find a to-do item by name|locate a to-do without having to go through the entire list| +|v1.0|existing user|add a student to the database|utilise the functions of the program on a new student. +|v1.0|existing user|be able to easily update personal information for specific students such as contact details and emergency contacts|contact them or their parents easily. +|v1.0|existing user|search for students by name in the system|readily pull up data when asked.| +|v2.0|existing user|store my data in a file|transfer data between computers.| +|v2.0|existing user|sort the students by different attributes|compare them at a glance.| ## Non-Functional Requirements diff --git a/docs/UserGuide.md b/docs/UserGuide.md index be55109397..54de9c1184 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -27,6 +27,8 @@ Within our program, a student can be stored with their We have determined these to be the attributes important to running a working tuition centre. Based on these attributes, our program also has functions to sort students based on grades, subjects, improvements since joining the centre. +
+ ## Quick Start 1. Ensure that you have __Java 11 or above__ installed. @@ -89,7 +91,8 @@ Adds in the most recently deleted student back into the runtime database. Finds a specific deleted student and adds it back into the runtime database. # Usage -//todo add usage guide for our different commands + +**Please note that if any of the following characters are entered in any string prompts, `#, - and ~`, they will be replaced and your command may be deemed invalid.** ### Adding a student: `add` Initialises an interface for adding a student and their relevant details to the database. Allows the user to do add or add [name] @@ -274,7 +277,8 @@ Sort complete! **Q**: What inputs are not allowed? -**A**: The inputs that are banned (which are used for file saving) are `#` and `~`. In the event the program does not understand the saved file due to irresponsible behaviour, it is to be expected and hence the user has been warned. +**A**: The inputs that are banned (which are used for file saving) are `#` and `~`, and in all cases except for dates, `-`. +In the event you choose to continue with using these characters, the user would have to the behaviour that follows (replacing them with other characters) and hence has been warned. ## Command Summary diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index f4625ae0ad..23217b39ee 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -22,7 +22,7 @@ public static void main(String[] args) throws IOException { //@@author blackmirag3 DataHandler.readStudentInfo(StudentList.masterStudentList); DataHandler.readArchive(StudentList.archiveList); - // @@author ParthGandhiNUS + //@@author ParthGandhiNUS UI.printWelcomeMessage(); UI.printUserPrompt(); diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index a5e583fa16..c22e707779 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -65,8 +65,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, StudentList.checkNameNumberPair(StudentList.masterStudentList, name, number); StudentList.checkNameNumberPair(StudentList.recentlyDeletedList, name, number); } catch (NameNumberMatchException e) { - UI.println("Student and Phone number pair found. Please input a new name" - + " or a new phone number"); + UI.println("Student and Phone number pair found. Please restore this student instead."); UI.printDivider(); return; } diff --git a/src/main/java/classify/commands/ArchiveCommands.java b/src/main/java/classify/commands/ArchiveCommands.java index b2c599a42c..fe394a1e48 100644 --- a/src/main/java/classify/commands/ArchiveCommands.java +++ b/src/main/java/classify/commands/ArchiveCommands.java @@ -2,8 +2,10 @@ import classify.data.DataHandler; import classify.student.Student; +import classify.student.StudentList; import classify.ui.UI; import classify.user.InputParsing; +import classify.user.NameNumberMatchException; import java.util.ArrayList; import java.util.Scanner; @@ -30,9 +32,21 @@ public static void unarchiveStudent(ArrayList masterList, ArrayList masterList, ArrayList list, Scanner in, String name) editStudentAttributes(in, student); } - // @@author alalal47 + //@@author alalal47 /** * Displays the attributes of the student that the user has chosen to edit, and prints the options available for * editing. @@ -77,7 +77,7 @@ public static void editStudent(ArrayList list, Scanner in, String name) * @param in The scanner object to read user input. * @param student The student that the user has chosen to edit. */ - // @@author blackmirag3 + //@@author blackmirag3 private static void editStudentAttributes(Scanner in, Student student) { StudentAttributes attributes = student.getAttributes(); ViewStudent.showAttributes(attributes); @@ -125,27 +125,28 @@ private static void editStudentAttributes(Scanner in, Student student) { } } - // @@author alalal47 + + //@@author alalal47 /** * Edits the last payment date for a particular student * * @param in The scanner object to read user input. * @param attributes The attributes object of the student that the user has chosen to edit. */ - // @@author Cryolian + //@@author Cryolian private static void editPaymentDate(Scanner in, StudentAttributes attributes) { UI.println("Current stored date: " + attributes.getLastPaymentDate()); attributes.setLastPaymentDate(InputParsing.readInDate(in)); } - // @@author alalal47 + //@@author alalal47 /** * Edits the last payment date for a particular student * * @param in The scanner object to read user input. * @param attributes The attributes object of the student that the user has chosen to edit. */ - // @@author Cryolian + //@@author Cryolian private static void editRemarks(Scanner in, StudentAttributes attributes) { UI.println(attributes.getRemarks()); UI.printDivider(); @@ -161,14 +162,14 @@ private static void editRemarks(Scanner in, StudentAttributes attributes) { UI.printDivider(); } - // @@author alalal47 + //@@author alalal47 /** * Edits the phone number for a particular student * * @param in The scanner object to read user input. * @param attributes The attributes object of the student that the user has chosen to edit. */ - // @@author Cryolian + //@@author Cryolian private static void editNumber(Scanner in, StudentAttributes attributes) { try { openNumberEditInterface(in, attributes); @@ -182,7 +183,7 @@ private static void editNumber(Scanner in, StudentAttributes attributes) { UI.printDivider(); } - // @@author alalal47 + //@@author alalal47 /** * Displays the interface to guide the user on how to edit the phone number for a particular student. * Displays the current number and instructions to stop editing @@ -190,7 +191,7 @@ private static void editNumber(Scanner in, StudentAttributes attributes) { * @param in The scanner object to read user input. * @param attributes The attributes object of the student that the user has chosen to edit. */ - // @@author Cryolian + //@@author Cryolian private static void openNumberEditInterface(Scanner in, StudentAttributes attributes) throws NameNumberMatchException, NumberFormatException { @@ -202,11 +203,11 @@ private static void openNumberEditInterface(Scanner in, StudentAttributes attrib if (number != attributes.getPhoneNumber()){ StudentList.checkNameNumberPair(StudentList.masterStudentList, attributes.getName(), number); } - // @@author Cryolian + //@@author Cryolian attributes.setPhoneNumber(number); } - // @@author blackmirag3 + //@@author blackmirag3 /** * Prompts the user to edit subject, grade, and classes attended for student. * Continues to prompt the user until user enters blank to exit. @@ -254,7 +255,7 @@ private static void editAttribute(Scanner in, StudentAttributes attributes) { } } - // @@author alalal47 + //@@author alalal47 /** * Removes the subject that the user inputs from a particular student * Continues to prompt the user until user enters blank to exit. @@ -262,7 +263,7 @@ private static void editAttribute(Scanner in, StudentAttributes attributes) { * @param in The scanner object to read user input. * @param attributes The attributes object of the student that the user has chosen to edit. */ - // @@author blackmirag3 + //@@author blackmirag3 private static void deleteAttribute(Scanner in, StudentAttributes attributes) { while (true) { diff --git a/src/main/java/classify/commands/ViewStudent.java b/src/main/java/classify/commands/ViewStudent.java index c69cef1228..75982f274c 100644 --- a/src/main/java/classify/commands/ViewStudent.java +++ b/src/main/java/classify/commands/ViewStudent.java @@ -30,7 +30,7 @@ public static void viewStudent(ArrayList masterStudentList, Scanner in, String name; - //@@ author alalal47 + //@@author alalal47 if (studentName == null) { UI.printStudentNamePrompt(); name = in.nextLine(); diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 6018704284..c8787e592d 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -28,8 +28,6 @@ public class DataReader { public static Scanner in = new Scanner(System.in); - - //@@author ParthGandhiNUS /** * Method restores the previous student list by accessing the * line-by-line information in the Student_Information.txt @@ -79,20 +77,24 @@ public static void restoreStudentList(String studentFileInput, ArrayList mas System.out.println("Student list is null."); } // @@author tayponghee + String name = userCommand[0]; + if (name.isBlank()) { + UI.println("Invalid name found."); + UI.printDivider(); + return; + } switch (userCommand[0]) { case ADD: AddStudent.addStudent(masterStudentList, in, userCommand[1]); @@ -396,7 +402,16 @@ public static String readInString(Scanner in) { if (string.isBlank()) { return DEFAULT_STRING_VALUE; } - return string.trim(); + string = string.replace('#', ' '); + string = string.replace('-', ' '); + string = string.replace('~', ' '); + string = string.trim(); + + if (string.isBlank()) { + return DEFAULT_STRING_VALUE; + } + + return string; } diff --git a/src/main/java/classify/user/UserInput.java b/src/main/java/classify/user/UserInput.java index 2b42a58c1a..3210aa5647 100644 --- a/src/main/java/classify/user/UserInput.java +++ b/src/main/java/classify/user/UserInput.java @@ -13,6 +13,9 @@ public static String[] processInput(String userInput){ if (userInput.trim().contains(" ")) { commandWithName = userInput.split(" ", 2); + commandWithName[1] = commandWithName[1].replace('~', ' '); + commandWithName[1] = commandWithName[1].replace('-', '_'); + commandWithName[1] = commandWithName[1].replace('#', ' ').trim(); } else { commandWithName[0] = userInput.trim(); } From 163165992f29c7243b4d3e9895c0ada2cf2623a7 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 3 Apr 2024 21:52:30 +0800 Subject: [PATCH 207/503] Change gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 6e708338e9..843e5d46b3 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,6 @@ text-ui-test/EXPECTED-UNIX.TXT /*.jar /.vscode -/data/studentInfo/ +/data/ From 9bc0dd88453a6661b4fb8da49441bcaf11683041 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 3 Apr 2024 21:56:59 +0800 Subject: [PATCH 208/503] Fix checkstyle errors --- src/main/java/classify/data/DataReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index c8787e592d..46e38b2174 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -94,7 +94,7 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Wed, 3 Apr 2024 21:57:44 +0800 Subject: [PATCH 209/503] Delete data/archive/student_archive.txt --- data/archive/student_archive.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 data/archive/student_archive.txt diff --git a/data/archive/student_archive.txt b/data/archive/student_archive.txt deleted file mode 100644 index b6aa3949d7..0000000000 --- a/data/archive/student_archive.txt +++ /dev/null @@ -1 +0,0 @@ -parth ~~ Unknown ~~ 99999999 ~~ 2024-04-03 ~~ Unknown ~~ From 8ce43d0d5f0bdcaf58f7117d476d533e74b17f2f Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 3 Apr 2024 22:12:45 +0800 Subject: [PATCH 210/503] Add about us --- docs/AboutUs.md | 10 +++++----- docs/team/cyanamogus.png | Bin 0 -> 20609 bytes docs/team/ghostamogus.jpg | Bin 0 -> 29937 bytes docs/team/magentaamogus.png | Bin 0 -> 19294 bytes docs/team/purpleamogus.png | Bin 0 -> 65427 bytes docs/team/redamogus.png | Bin 0 -> 18395 bytes docs/team/yellowamogus.jpg | Bin 0 -> 37924 bytes 7 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 docs/team/cyanamogus.png create mode 100644 docs/team/ghostamogus.jpg create mode 100644 docs/team/magentaamogus.png create mode 100644 docs/team/purpleamogus.png create mode 100644 docs/team/redamogus.png create mode 100644 docs/team/yellowamogus.jpg diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 51cbdeeeb3..813f3f7a59 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,8 +1,8 @@ # About us Display | Name | Github Profile | Portfolio --------|:---------:|:--------------:|:---------: -![](https://via.placeholder.com/100.png?text=Photo) | Parth Gandhi Yeet Bing Bong | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Joe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Ron John | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | John Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) -![](https://via.placeholder.com/100.png?text=Photo) | Don Roe | [Github](https://github.com/) | [Portfolio](docs/team/johndoe.md) \ No newline at end of file +![](./team/yellowamogus.jpg) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) +![](./team/ghostamogus.jpg) | Siew Shui Hon | [Github](https://github.com/blackmirag3) +![](./team/magentaamogus.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) +![](./team/redamogus.png) | Tay Pong Hee | [Github](https://github.com/tayponghee) +![](./team/cyanamogus.png) | Tan Yi Xin | [Github](https://github.com/Cryolian) \ No newline at end of file diff --git a/docs/team/cyanamogus.png b/docs/team/cyanamogus.png new file mode 100644 index 0000000000000000000000000000000000000000..6c27a7468c8c2f7269d7794b886f0be3df37f115 GIT binary patch literal 20609 zcmb??1yfv2uy%mpzCcK@V2dsqT!Uv>T!LG0cbDJ<53no_K^6_c-QC@SySqEwytnT6 z557}1b*fsPnVz2M({-jNTuDI&8-oPn&6_va;4hLYZ{8q6{c0494CDs+l7qDqh4D*Kt-Ky&b|oLc)pN&P*$3^g_~{C5+wgDskC;P}=N+V6a7X4aGId$gSN^^?oCg>7Wh zZzw(97C%Ez5;alntiNyMB;38j|=I&y7Tx;Nalyi`TaA zJbAXQJeb5b?VoPBtl(Vg31>sX<|j)Z+M3Ub{x<1yP?^Km+L{BQkGcR@N;imVqiD^#k22T7%I>lj*eRMNwX|kP9(!+pz{=D z5FwKgqRmJKXf;8jJ$T1i5VhU8EnB(pm-yW1I-s1bETA*T% z+HEh8&Ge-r%MBXy{AivLM$go!%oxJB7B+*VSz-y+Z7=vNyr zQRX=MO9G6A9)73dRoPya3;B$!IH8tL*y_#wK*7jC$U6IJAMMXWVD*vW+~7+eO*t)? zS|JXD*x+)&g3O?>z~EM961$EP4Di$ki!k;X@T)ar-u}I;N+ZQPumj&ii0TQErPrT$sEr8$ZE{Y7_FIFFg7aEA z4%)aiSq$@>J5G^+Iw_3A^v{T_+3C``-X375W_fBX24$ICZyQ-J*9{(;_)gCweUahi z`0Mn~=z;*|`W$a8aFMn`Jeq1J)(f5#iBUj#fh1!%e7`kfrz%iV6RN~wXw_(~R7{Ij zg)uX}d!hm5G?IM}Bj`AnYE@L0C6?-}4F-kgH@P%e^UG=yj~JEgv!srohg!@~N%t7In$a8i0pv52=(DRc8}`yP6+2P(=iU zuf`CBK&B&0!I&gXVpmo7@QlkmF}2A1{WbYIPp!9~FnENw*djy!JG*b%(d^;19dAk- zc0ulhA-jdI(yH>DdReY@s`x2Z;#ox8KL2raqso;+ooL39Mp~_Ktz4JVGVgBEWdY5l zf!3@?v*zF9ZMT}07I~SVmvE3&1Cj=nOT(dty&n;<*!5wm?%t#&BU;ZtRsI9*?&k9M z374PFdnAiP(MYon(+}$9PY=~Ye@z>$u3@Z?X7<|dbs1Xu2OE^DzuocDa5U(PZxSp^ z3LX)m$ztq(7-X@t@*Nmw9;_EFyxvS`*zhZ{z)A+%kq0-~sH0FZ+Q9<_B6XX#x!03d zvAMBdKERGOS55vNxCvDWXNSt?o1-m9tZ1{bsJCXN?n;`@4;}k)9(V^3zRM5eZ7iB3 zrRWP?f}XO?DWsX_#XQ!1-KF~#jPi~SP4+`xRPc0~eP8jDoXW_#Td{6apU!7Viop2EH2dGXi2Hgw72ox2bBMSaAja-1RVeVB z*ssPljG_f<-USAAJ(2s5;&5k*>^#@GPohm<>iXyp8z*Uv9$MuFm=c8;!BeGhkx$@1 zQS-V@`7HkXj{tZ?JpJJ-c=2ZtrS(k1KiaRS-xgA5hU>G-^TlL%ABOP%?phELOpQV6 zQ}@I$4LQBNoF5B&aF)p1qoJ5E2i{mE0e;Ke!H#&(H)XpHG~0c^rI92QtK}9TszPr* zCPjI7=auhCtE+za!4#YdRmsZx%@bp%@!OXjy9F&BdH$bP3li_;RPa$jZRn7c?oz2D z^1|Wg@6q(^$qwxoi+;D!Dc+_70l{%p7If%Kx|UuM4|9ow}b-Kq4Q)Da6dYAh}qc8SXi z)S=uErpeXSA^kZ5F)jx&R^>{4R7)0r-zI8_s@s5FaN5fWQPKES%3l;bhxxSWuznaZ zX)zC-pG4##3(H-7twxfabk(y{HIwf};Q8cluJYnk-^*>yXIpJKcr<_lq@!L_cl^#z z)(in(H?UMO7~?X_@%db|aW4_!$OsBT%v7sbf3x|kI@a0lt7LQ(x|kXb8X2tBsi@a? z?W0PVedV!XRVX$#SPS*7Ux67x+adhTZfCc7=yyL^ZCTV)Orwp2>576c5j9Zk1!~gd za%oGL|K1Pb@qiQ&V^PP~#m)5I9d(n%9A*lxXfeprqvY|Ct=L1;NbW-g7!})OJS&;=VOC3m>SKU>(xEkyS0S@eSf=C|Xmp;sw`(gu;THX!(f4+vz zI5z2OhLT7YaLN4rb7f<*U!XOZf6&iP=GJ>-Q>E9ia2i^g`G=8SStDY0U(r46c(PV* zW_=`t^?f+HLld#Pw^Mtiq)a5+z2mv1;N8(&Lf!ta)x-L`^oi`O`NB&-sVVQNWv@2< zk1=WRe?d~h*RJ?zD2t8$g2yAi7*TNLV7_T|W;Y`%SJi8$OS$baX6!>^XWw9ZGB;J2&R1>Uc>FDMzg*q!V-e{_n)sxiv4UQ_ zX;#Z8cCALrh>?FUgLG4n@O(~Il8KamvrX4G4;%?$ zJ|Vb@&a}r+|6Z>zjH)~fHGFuHo4`PiV3-jot-B?;Zl{D(u)d~CWhw;GJJV|BM66hk z+%Dd9dQDFtw8Vn8+1(p%liQx1AAW znQk(VB5tS+*y_dQnXSfgKH*e9{m!R9{5c7nI=XNJ4#5B3)Vc_RR628@D?WlZ&wH8Z z^gt*ViveRa6LG<7#uZ>+~2YVtV^qr{(jdwVRBo)ycR8m`7dj@1I%cbR46K#zhNCW zD()dvG#y0m%&nf7_40Tyvk2ma6{}0h@+IEXUiIw#e)p>fY7&wstw~E3>2`zpF$#yX zhn6e(%W9kt%sO7dx^be{$L2IGq$zo0UnTID#i?P@%55tGOa7Vx-+RkoAniUh)vb1p zy+|h}KlvLNB>UaRj_;Br-|^%4H;meWo=Z)r$ivdFV-C6Ahl^L?zjX)F`UHT=D}1`K zkC<5R%b*7pZyt5DKKuBDqC0G(qocZg1f~us2k(BYS;$n#`K%Cxdh;uN(;jWKAklJ% zQO=)PF|aW+e z!j9n1fqax2VL@(u`~4_mQG;Y2(3=#Y+uYMcNAvz%RUnqo)C0=tUE77XBDcn^%9qnUft$IzxwXWT*J^Qk9KRyJ8=>ziHhud6% zU&zK2Q`q(7G6DIP9K_D9U)ju~EbQl9Ur`@Eo29T@Gc{Lh8`^;11!pjO4PJjMa$(x$ zDpe{nQ!TQo)n>HVpHdMfh#X{nDaV+XP(6?R;jY>;1t9h~ayIb6@?pjD!SZtPQLz%7 zz1n*!dX<E;c~^Rb9Hsd1d`pCz=e%d~{o;0RmS zb=|R{D9;4KAo_c9J!EFGFXAR`ysuuo!LdPtl|9pVSy5CXvWK7HXQ2^$>y;zB zW%yHTD|~~|=MCdCQ<@-Ewu}Qbb-_2KjyTt{h1KaU%D*omejKU2^&`8aVL!5zZaznc zOT?)Z6zWb>74I>bPnX(DQ4P=u)}+{zFfW;xB;MM^Zp(KD$tKBuep*!TtEW21c6Bx{Zqj-pw}({fzMB5GOq=6LtcgTgAfrjG z1wQF|`*j%)`honUtzk=`>7mfhm)R-jOgHV}@i&QltNDiergzSWo2>=Nx66_YQbQ_X zv_@TD8j7r_G@>dtX}_;hO~B9I<#%rpcm?x*Q9Xqj_votI#5Z#412tkRU!o1t$IGkF zIe0+en7kEo7JAHiZrqU6nTRMZsqejDO^nl*06e-lh@9$?8F&<0{kw6err*kxC-sFd z$H;P%F$Y9>)_S_;^n)nxn}R!dMFKpRUrcCxU&4H38o&ctUpAL;jOFb6s-=SUlYw7g zYV+cv(v=`7$=rO&LY623i%wT0W~w|GKxZ^}pb%ZDRy$OH%=r^5Si45MYNCJl@{l+C z6_TrEt(SRTDQ}5lx$r94rQ(5EA?Wu_Wg3gV$=B|aOW{m0cUrVvu$@$^vh{gRky7nx zYn$yq)P^tk)9lDL=6nt5zfHn}8SD|2i527(xQY@Rj|~`hXw9dY7CWzSjFN+Yv(Nj& zRQ_12Kf1q={}>J_6qQfs)T`Ojj&GWUpPARQqw{x=`n<0!0Q2h*`B$ytl`e)qdFA$^ z=SLPo=o?63cs-~12;Rtum$iRf5+jQvG^o1(Mj?f`3N;WBcz&Kd>gYm=cNd_OBfLIx zV0I~7cUDC+ih8^pq*QxKypu)#g#N^ zL%s`$GEQpKTJUdkZJ^YxadIMLgM9eO;A*MtmmzSGE|gF_ubjVECQl8+11r>TC;E{l z(YqeP02#Tddd}D(;i{Hvoj7untIKAHHCPEb9UfL{4`TEU#K5V;4x`+#blmc zwro;OZ{w#pdq@5Ou$!SutI9rLi9Mvd*e907NVM9ihq{UT;!pt@*Qhw(6?VlH2DQH5 zr6Yorb@;AA#IjA$b#VI$hoy=dP7EFJ=xV6JI0<xa1R>tjxJW^c_vT)l`XH^66D^H5L;LQ?egx*<5B(Xd$XYw3{@x?c;k!nU_l@B!NH zJJ~Ju0GmINK;0BZM{%_hNwwAx4!HpJ>0fqgq}@;XkJpL`r|soY^-G6jOvT7P8ItI3GMtY zawgad!caD)V9Qfspufud^mURy*^=p-jf#$UOj8~BM3A#u0x@mmd>Nsvbu5@#CL<0| z4%Cv^08p4yeUkw<$+z5O!^*ljrVt^JuW>?hEYUDn)=V#A^YVg>&<3-9yY zT|gb!Q-!M##!)%glIu!dLA@H)d=@+&6V&nOvV2-9nZ7Z+6yL-cQ!C;A`9BTbe;SW2 z5_V-*7?d~dJ#r|Dy7G?LDs|JlFI$b5l8ymzjYh?1g6s-xEb$ zlK}}GWW13EI-tGAG2q-T0-*<}CPM~|&{Gpv4>-uiFc+>njt!a#&1W<;qedB{n1$9CFQ)hb=(77pacitOQ1jxjf9Q_d%DUg7Nm zDGZ~et#r$>6jI)%d$VXC`pY$mbYs7L9>`e-oyVOIK^5-1k0Xi`=Y+ccbvvo{+>R?g zb>JL7XLZqTxRf#aH7AtQ&>K|oaWav z{M2$9id^Sjm)2|YWbttKJW%#Za$VAKuf|vUc?*p8tlvN0f$Gv{$vP~ejj?R-+DCOL zD$B1f6yhK8)<3pRsMFbAblqa~f_Qf>1P4D5o~zLewZchZzj{Nm%bXs!Vpu~&rOEvn zIa@h5-Fv-|RxWeKobFfoqhAwBilssm@^X-#SDrP!$ejb>KZGjyY`xhrDpvB|dg}WF z@_lkA7(W&%2rpUtg-TqjSAqyVyy^R>9@diyGHfjaHCnd0_6{lkZYJ7GOj||9<&KFK zV7&XFAS?dyi;*^bF$^BvRVcwOMMtqf8jT@zF`;#8jkHn@{uwvAQ2V2ejYJ7vJ?L;Y zkC4w2l=ae_wpIT%*$zB4Sxt@^^Zq49{nskGotTeIh!x8mULXuf04}?xF?dC}uKW@9 zqD*GY2q4L*GfG7q%A0+ZPGe=s`aDqg!Aii9k7mf>#|2=DZn@>P-mJBZ-rqb>$bK`T z{yDGc$nMqhXYS#cy6(`=MmpI-B1X#r74$)sjVT@$$k_}(SH30DaeL6&#U%2D zwf*bq@vciW-=XqHb+X_$z75MjghFehg?DY2t0JId!9f+1C#rY(lpY=7o{B&yi;)C! zGO(M2^};SJ8D45WT1j}$66oQzFQEJT zC^S5XHBt3eq^pC}g=XxgHbrw`PxZH)WOwMmD;p$#)4}c5yKR+f4j2}h=#dchG$l)1L-T%za{!unttid4(M&#%qz>V7^}8`8@N13f5&m zb{6@GN?LG()xnAva2Q+mYLNg3Bpg|fHns7d1EQi$nlBk931$-4iV)sypX?Y;IK0~G_Ak&qUpWD zxcdyl(K7{S)(8wE6K7{BUR~`-$XiRSbxtr)6|eL;euX_uGj*NPob(P7&Ilmf=NuZ# z?+RrdRB8hTR2VUyS`xn7IE@483sO<;?Av;L$UO4*b8Zvlt<`6y7{GtuXtZd>IwEO4 z>~TWyS2rmq2;_Sfvuqc-kPFlhq5;iwY1i+0{o!-UNm`W`t7q!^+ag)^3dHnm8zvRy zkri{^uRky$O%aPADd`in=AhKWL> z%O8`u_eP_*-)ru3Ud_{QmMU<*2X|e2z5Z~XfU`J!T3TPMqu<>%h`zfyo?8`d^AQ#C zasH|FH#}a3ek1}BA4coWqM$t^$hXe`v@H)VUs?3gMC8RF>#Y+M?X0CpJN|KcMBeiJ zu<0P$yVE#qw}Ust2vto`)b1;azYcasjOm=OTM18~|6i@E)x@I98uHagmzT>fks$GV zIlG;mwI;>Lovhl-BaDrq1bL{-A@*~KUv1y$B!mt&?0#qWlGWn;U6wR*gHJ^1{Mo|V z8r<7JYY9+g+%VPy6a8i<{7o(eBe&Y`=gU2OeSJhJjA&YN7;WLD^4|?xPRSt0-rBrP z_tu}2%R3ddui7BYH%Gw}OwkM3=ODCStL8AQ02HqW^B&6203D_V^ylauJQ~fGaim3u zjaV01#9FUH>zq9>Xcb5eG!-05jmh|gS|)|Rp)a{qT8dM2G%uM<(p3s{wS6I`mWvh2 zc)j!VB4N+t@$)k<=RV_zshUe01vKxQpw7+~(ObzemYnkvEOpd@<~UG)B_!Ch%7Ui1C59Ugmw=`s5TUmYtnz zl&E2R^pZdux6}a#6rquxsmSK5;fgGk^cC)${aL z@@KH4;}SOgw65tDK{aKVF4_npfmCwuJ9bgop;Am9HmQT5u~T~LO#GvbEfeJn*`)RX z*`pjUl;q9~ofNv&7-K(K-(^g}b4ut2PW=b3q^+)Cb5PICFOZRO?Q}q4?$R*zPJulkPX4Nf8aF-gJphofD;&ZdczwO8L{t2y@WzP#AKUl1q+zC$y^jchlxYVY$%JSU>r z3Pi`+z6;`q^6_2lG@-&tAzFpZ;syYCUxg>#MPn8FNVK6}gvvR3eyBoC#=W-qwwZx~ z;`f(3N57Zl^*zZoV>PaF)(=lagoFC^y$`AmF__rZUeS7jGGM>1f-N7S{MTSrmebph zg7#IXt7O3nB&d=dxSC<#g#~N3GFSr=61AFhxyydm@QZ(N6o(_5z?)Z$1uY-v?1vX# zsw_$KDd0EL*v6Uvb@iy<)hq!IMPgpd)Yj8&lF;`RCPS! zy13s!&qBx=HO68v10}PT=ruC9u0^LMxCip!R)a;A{qU`v8@*90hb6kpyJa`@O#c7z+1+mQkAP za`G_K+Hs@=SPl}Nb_+riNC9jbjE1cQC&=`;_RwBH^<;;ib9IK))3M~rWN6wuM`a&N zhCm>6hu(Hs71rLP7cI;kC$6^Bk74@55Mz$@%%@@Q7Yc*{`elSL7m{%Tm07kOa6}m| z!#}^Jwx#rOBchkn-a!U(C}Tk3f2pdK{d1N7HivvaI0M)QyNg5x6$z{{B*qaH2L-=} z=55$bpXMjHv7xqsf?y9gA-(zuNk5CQfm>14PQWj)Jg!7w4=QX}kPiiOng|A&>bEa@ z+E`nlK84aoz%8I<0pSjMIRSY2_y;H%;Y4}t9~wHO1}OX4B-FN8z>Xx4KBd-%M!^vh z9}3fyMi++FU}gK(sYx>B-(zHb&kV)0)=0jq@#aw5gWG=X1L`X-k|Tl7D8rM~ zz7R6~WD^wzTrybs&&m-p*% zG6JC%S2R}xl|G8b0dtpW)j^3*HD+&rQ$mq21riLj7-pv{fFH?fy+-pvu2)kyZFT!d1K~bo&5~T<}%A- z!sNgn!8i(qcoj9+OK>H0OFlgiDZgLm*1KKW#7y-eg^mX*nGe(UrY-~ppeol!rl(9% z*S9_nUI%s--EMNC%Fp=0!|~zA)k@Gpg0(_1!WHw%cG8r0OZEyqZkjkK@`;EE_H!rd zdJK>&HJ}+@$SqZS3u3PEiH3kNsre|{&;M5okn(c-{PmH|Q>%z`8CP5+5*xOplIVw( zBlK7JYVm!Fqq$`u@bUSG^h7XK>9WDLHU$tBZ=yN{`N0yzTWrw5YYTW{d=zH7O#NDB z@_-Jk?K+&TVNHcYF(D%VK!lL5`uRjwL*PXFr4fWhb7WO zg7NWTIQa?Hz!e=eF0TAE5dEw=c%F6!OHikf#36orsr9) zf!>Vk6bhVUx|#wosfsHHeETk!=hu%C$gu-0nR~sHTa(rQ4yN19(avb-aZ}(Bbw1hY z9>UU4dxp!aPs6HPCNXYfS)65>|>2h-Fd9f%Mo=Z>jI7vZq}EU0E#VX^QKBd z5}k0gKro$j3z=HF6R=lvpq>+mJDgvTl%t#}-xxyyj5x;(%LxnGsG?jAVEX<}aemf5 zoi*F^#11`wH5|c+ox7VcnQ!|b3P+)-%4JpSp??W$*B|P%WihuMCgV>2>wIXp zqI-O;-}t%OP97LoN>SUoxXL-K1cs}5hd-erLo&w7g~t>bJ+`FUWhwfB<%Fr4X|RyA z9R3G2bVMbrsfNtltx3m8i_oCTYFp7b6Tx^wsnj5XYJGyx3c^&6Lj<|ten}3D7;$x{ z7CBb-{nyS{FB8$REMdR@D64n}1K8Oc=re#hP_0U4RrTzU) zD>Vg%WQ3haEvd{kLRGR>J`-4Cd2OW{4BdJCh4wn~C^e?+L@M4PuM=;q09&hjj8UM} zO2w4fGW=j!cFKL-w=VaNQSv2MQZGAFfj!PwAJ*==)x$vxff#ufMw8{Mohl!=MMd_u zN5~j%5%5GRY0Jk2dgxVTa`{wZ$H*kz8LwEH%g3hVccH{^mNun>Nws+a zJ+a*Pn;M2%+T_~MC{oqiaA1jd8d`mo%HshkPGb@ix4$E$%L*D)8Pitqiiro_n-eduvOnqH+bC(Jrum66qGh{tp)6NO z-FR-og(+(`zrbK&m1K3>%(C(5d*h+*J|F$gz)9tx5nN+_yT=s`s4lC;w|dNUvR
xo%052HDRf@Q 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 literal 0 HcmV?d00001 diff --git a/docs/team/ghostamogus.jpg b/docs/team/ghostamogus.jpg new file mode 100644 index 0000000000000000000000000000000000000000..398c961447e5e398ea64bb79e39d871e9045e2bd GIT binary patch literal 29937 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 KBC!AS@P7g37?S${ literal 0 HcmV?d00001 diff --git a/docs/team/magentaamogus.png b/docs/team/magentaamogus.png new file mode 100644 index 0000000000000000000000000000000000000000..b74a803d13f3525f113001b52574fca10170ce69 GIT binary patch literal 19294 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 rQc6?vQxF1#K<`1To4C~1^|G80l=9|Gy;N< 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 VNp~OoPds)@7OhxV6Zu2l{{iqwI8y)s literal 0 HcmV?d00001 diff --git a/docs/team/yellowamogus.jpg b/docs/team/yellowamogus.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d85836bb19f6516aa67d07a516f8257c9786176e GIT binary patch literal 37924 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 JZ~p)Q|Jka%X6XO` literal 0 HcmV?d00001 From 56d818218d52007a36997f291850652d8d037525 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 3 Apr 2024 22:13:36 +0800 Subject: [PATCH 211/503] Change amogus --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 813f3f7a59..5bd89adc47 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -2,7 +2,7 @@ Display | Name | Github Profile | Portfolio --------|:---------:|:--------------:|:---------: ![](./team/yellowamogus.jpg) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) -![](./team/ghostamogus.jpg) | Siew Shui Hon | [Github](https://github.com/blackmirag3) +![](./team/purpleamogus.png) | Siew Shui Hon | [Github](https://github.com/blackmirag3) ![](./team/magentaamogus.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) ![](./team/redamogus.png) | Tay Pong Hee | [Github](https://github.com/tayponghee) ![](./team/cyanamogus.png) | Tan Yi Xin | [Github](https://github.com/Cryolian) \ No newline at end of file From fa7a7a81f875ed86b48b58399b6fd54d11238130 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 22:26:50 +0800 Subject: [PATCH 212/503] Add javadoc --- src/main/java/classify/commands/StudentSorter.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/classify/commands/StudentSorter.java b/src/main/java/classify/commands/StudentSorter.java index 8932c1f61c..b5477424a6 100644 --- a/src/main/java/classify/commands/StudentSorter.java +++ b/src/main/java/classify/commands/StudentSorter.java @@ -146,6 +146,12 @@ private static void listStudentsWithTotalClasses(ArrayList students) { } //@@author alalal47 + /** + * + * Prints out the list of student with their last payment date. + * + * @param students Takes in an arraylist of all the students. + */ private static void listStudentsWithLastPaidDate(ArrayList students) { int i = 1; for (Student student : students) { From 701a3597738a9e440e5214b52e625cafd46f5628 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 22:27:30 +0800 Subject: [PATCH 213/503] Add javadocs for InputParsing --- src/main/java/classify/user/InputParsing.java | 63 +++++++++++++++++-- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index daf95e156c..2d465c3e08 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -47,6 +47,7 @@ public class InputParsing { private static final String LAST_PAID_DATE = "3. Date of last fee payment: "; private static final int NUMBER_TOO_SMALL = 80000000; private static final int NUMBER_TOO_BIG = 1000_000_00; + private static final String CLASSES_ATTENDED_MUST_BE_MORE = "Classes attended must be 0 or more."; public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, ArrayList recentlyDeletedList, @@ -128,6 +129,14 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas } } + + /** + * + * Function which leads to the chooseListType Function + * + * @param masterStudentList List of the students used in the chooseListType function + * @param scanner Scanner used for the chooseListType function + */ //@@author tayponghee public static void parseListCommand(ArrayList masterStudentList, Scanner scanner) { UI.printListCommandStart(); @@ -323,18 +332,37 @@ private static Student findStudentByNumber(ArrayList studentList, Scann return null; } + //@@author ParthGandhiNUS + /** + * + * Returns a true or false depending on user input for number of lines + * + * @param classesAttended Takes in the integer input by the user + * @return True if number of classes attended is greater than 0 and false otherwise. + * + */ //@@author blackmirag3 public static boolean isValidClassesAttended(int classesAttended) { if (classesAttended < 0) { - System.out.println("Classes attended must be 0 or more."); + //@@author ParthGandhiNUS + UI.println(CLASSES_ATTENDED_MUST_BE_MORE); + //@@author blackmirag3 UI.printDivider(); return false; } - return true; } - + //@@author ParthGandhiNUS + /** + * + * Returns a true or false depending on user input for grade input + * + * @param grade Takes in the double input by the user for the subject grade + * @return False if number of subject grade is less than 0 or more than 100 + * Returns true otherwise + */ + //@@author blackmirag3 private static boolean isValidGrade(double grade) { if (grade < 0 || grade > 100) { @@ -372,6 +400,16 @@ public static int promptForPhoneNumber(Scanner in) throws NumberFormatException return number; } + //@@author ParthGandhiNUS + /** + * + * Uses the scanner to read the all the characters input by the user + * + * @param in Scanner takes in the next line input by user + * @return integer value of the characters input by the user + * @throws NumberFormatException in the event that the characters input by the user are not numbers + */ + //@@author Cryolian private static int readInPhoneNumber(Scanner in) throws NumberFormatException { String input = in.nextLine().trim(); @@ -379,10 +417,20 @@ private static int readInPhoneNumber(Scanner in) throws NumberFormatException { return Integer.parseInt(input); } + //@@author ParthGandhiNUS + /** + * + * Returns true or false depending on whether the number is a valid Singapore phone number + * + * @param number Integer number input by user + * @return True if the number is a valid Singapore Number, false otherwise + */ + //@@author Cryolian private static boolean checkNumberValidity(int number) { return number > NUMBER_TOO_SMALL && number < NUMBER_TOO_BIG; } + //@@author ParthGandhiNUS /** * A prompting input to scan in a string from the user input. * @@ -390,6 +438,7 @@ private static boolean checkNumberValidity(int number) { * @return "Unknown" if blank was inputted, or the * trimmed string inputted by the user. */ + //@@author Cryolian public static String readInString(Scanner in) { String string = in.nextLine(); @@ -400,6 +449,8 @@ public static String readInString(Scanner in) { } + + //@@author Cryolian public static LocalDate readInDate(Scanner in) { String userInput; @@ -415,6 +466,8 @@ public static LocalDate readInDate(Scanner in) { return paymentDate; } + + //@@author Cryolian protected static LocalDate parseDateFromString(String string) { if (string.isBlank()) { @@ -434,13 +487,13 @@ protected static LocalDate parseDateFromString(String string) { return paymentDate; } - + //@@author Cryolian private static LocalDate printInvalidDateMessage() { LOGGER.log(Level.WARNING, "Invalid date format entered." + '\n'); UI.printInvalidDateFormatError(); return LocalDate.now().plusDays(2); } - + //@@author Cryolian private static boolean isDateValid(LocalDate paymentDate) { if (paymentDate.isAfter(LocalDate.now().plusDays(1)) || From dfc5e8fe77fdb85fc1bc386283c142c3e9a8c2e8 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 22:27:45 +0800 Subject: [PATCH 214/503] Refactor code for Student.java --- src/main/java/classify/student/Student.java | 49 ++++++++++++++++++--- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 90e2ce848d..2af6c5eaba 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -68,6 +68,14 @@ public boolean hasSubject(String subject) { } //@@author ParthGandhiNUS + /** + * + * This code accesses the current students' Subject details. + * It then uses a Stringbuilder to build the string in the proper format to be used + * for the Student_Information text file + * + * @return Returns a String to store all subject attributes associated with a certain student. + */ public String listOfSubjectAttributes(){ List currentStudent = this.getAttributes().getSubjectGrades(); @@ -84,14 +92,10 @@ public String listOfSubjectAttributes(){ for (int i = 0; i < numberOfSubjects ; i++){ //Subject Name StringBuilder subject = new StringBuilder(currentStudent.get(i).getSubject()); - //Grade information - String gradeInfo = Double.toString(currentStudent.get(i).getGrade()); - StringBuilder gradeInformation = new StringBuilder(gradeInfo); - + StringBuilder gradeInformation = doubleToString(currentStudent.get(i).getGrade()); //Class Attended Information - String classInfo = Integer.toString(currentStudent.get(i).getClassesAttended()); - StringBuilder classInformation = new StringBuilder(classInfo); + StringBuilder classInformation = integerToString(currentStudent.get(i).getClassesAttended()); subjectInfo.append(subject); subjectInfo.append(separateSubjectInfo); @@ -100,10 +104,41 @@ public String listOfSubjectAttributes(){ subjectInfo.append(classInformation); subjectInfo.append(separateSubject); } - return subjectInfo.toString(); } + /** + * + * Converts an double input to StringBuilder form + * + * @param input an integer which needs to be converted to a StringBuilder Format + * @return Stringbuilder format of the double value + */ + public static StringBuilder doubleToString(Double input){ + String outputData = Double.toString(input); + StringBuilder output = new StringBuilder(outputData); + return output; + } + + /** + * Converts an integer input to StringBuilder form + * + * @param input an integer which needs to be converted to a StringBuilder Format + * @return Stringbuilder format of the integer value + */ + public static StringBuilder integerToString(Integer input){ + String outputData = Integer.toString(input); + StringBuilder output = new StringBuilder(outputData); + return output; + } + + /** + * + * Builds a string in the proper storing format + * + * @return a String in the correct format to be stored + * in the Student_Information Text File + */ public String textFileInputString() { return String.format("%s ~~ %s ~~ %s ~~ %s ~~ %s ~~ %s", getName().trim(), From b8a04d4c8f11577bedfd1122d2056661db4cf669 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 22:37:24 +0800 Subject: [PATCH 215/503] Edit Javadocs --- src/main/java/classify/student/Student.java | 3 --- src/main/java/classify/user/InputParsing.java | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 2af6c5eaba..19b7cfd97d 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -69,7 +69,6 @@ public boolean hasSubject(String subject) { //@@author ParthGandhiNUS /** - * * This code accesses the current students' Subject details. * It then uses a Stringbuilder to build the string in the proper format to be used * for the Student_Information text file @@ -108,7 +107,6 @@ public String listOfSubjectAttributes(){ } /** - * * Converts an double input to StringBuilder form * * @param input an integer which needs to be converted to a StringBuilder Format @@ -133,7 +131,6 @@ public static StringBuilder integerToString(Integer input){ } /** - * * Builds a string in the proper storing format * * @return a String in the correct format to be stored diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 009a47d087..c943822c61 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -135,9 +135,8 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas } } - + //ParthGandhiNUS /** - * * Function which leads to the chooseListType Function * * @param masterStudentList List of the students used in the chooseListType function From 69c0223bed1e2e9697b05736646e5a031b190c80 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 3 Apr 2024 22:46:56 +0800 Subject: [PATCH 216/503] Edit javadocs --- src/main/java/classify/commands/StudentSorter.java | 1 - src/main/java/classify/user/InputParsing.java | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/main/java/classify/commands/StudentSorter.java b/src/main/java/classify/commands/StudentSorter.java index b5477424a6..db1e3481bc 100644 --- a/src/main/java/classify/commands/StudentSorter.java +++ b/src/main/java/classify/commands/StudentSorter.java @@ -147,7 +147,6 @@ private static void listStudentsWithTotalClasses(ArrayList students) { //@@author alalal47 /** - * * Prints out the list of student with their last payment date. * * @param students Takes in an arraylist of all the students. diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index c943822c61..1f4129f880 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -339,7 +339,6 @@ private static Student findStudentByNumber(ArrayList studentList, Scann //@@author ParthGandhiNUS /** - * * Returns a true or false depending on user input for number of lines * * @param classesAttended Takes in the integer input by the user @@ -360,7 +359,6 @@ public static boolean isValidClassesAttended(int classesAttended) { } //@@author ParthGandhiNUS /** - * * Returns a true or false depending on user input for grade input * * @param grade Takes in the double input by the user for the subject grade @@ -407,7 +405,6 @@ public static int promptForPhoneNumber(Scanner in) throws NumberFormatException //@@author ParthGandhiNUS /** - * * Uses the scanner to read the all the characters input by the user * * @param in Scanner takes in the next line input by user @@ -424,7 +421,6 @@ private static int readInPhoneNumber(Scanner in) throws NumberFormatException { //@@author ParthGandhiNUS /** - * * Returns true or false depending on whether the number is a valid Singapore phone number * * @param number Integer number input by user From 0c08537a4739abc08d4a76b03327b4c54cd001bd Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 3 Apr 2024 23:11:28 +0800 Subject: [PATCH 217/503] Fix semi bug --- src/main/java/classify/commands/ArchiveCommands.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/ArchiveCommands.java b/src/main/java/classify/commands/ArchiveCommands.java index fe394a1e48..48be46d11d 100644 --- a/src/main/java/classify/commands/ArchiveCommands.java +++ b/src/main/java/classify/commands/ArchiveCommands.java @@ -34,7 +34,7 @@ public static void unarchiveStudent(ArrayList masterList, ArrayList Date: Wed, 3 Apr 2024 23:11:32 +0800 Subject: [PATCH 218/503] Update help function with archive help message --- src/main/java/classify/ui/UI.java | 13 +++++++++++++ src/test/java/classify/user/InputParsingTest.java | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 35dc928ec0..7877919bbe 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -85,6 +85,8 @@ public static void printHelp() { printListHelpMessage(); printByeHelpMessage(); printSortHelpMessage(); + printArchiveHelpMessage(); + printUnarchiveHelpMessage(); System.out.println("help Prints this help message"); } @@ -103,6 +105,17 @@ private static void printUndoHelpMessage() { System.out.println("undo Restores the last student deleted in the current session."); } + private static void printArchiveHelpMessage() { + System.out.println("archive " + + "Removes the specified student from the list and archives them, can be used directly by archive" + + " [name]."); + } + + private static void printUnarchiveHelpMessage() { + System.out.println("unarchive " + + "Removes the specified student from the archive and adds them to the list, can be used directly by" + + " unarchive [name]."); + } //@@ author Cryolian private static void printByeHelpMessage() { System.out.println("bye Exits Classify"); diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index 089506932c..1f5f824373 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -108,6 +108,12 @@ public void testHelpCommand() { + System.lineSeparator() + " Currently available types: name, classes, payment" + System.lineSeparator() + + "archive Removes the specified student from the list and archives them," + + " can be used directly by archive [name]." + + System.lineSeparator() + + "unarchive Removes the specified student from the archive and adds them to the list" + + ", can be used directly by unarchive [name]." + + System.lineSeparator() + "help Prints this help message" + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; From fb38e7f251ed2ef23c9926a44f9f29abe2d4b798 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 3 Apr 2024 23:28:54 +0800 Subject: [PATCH 219/503] Fix bug attempt --- src/main/java/classify/commands/AddStudent.java | 3 ++- .../java/classify/commands/ArchiveCommands.java | 2 +- src/main/java/classify/user/InputParsing.java | 13 +++++++------ 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index c22e707779..42acb5bd90 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -65,7 +65,8 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, StudentList.checkNameNumberPair(StudentList.masterStudentList, name, number); StudentList.checkNameNumberPair(StudentList.recentlyDeletedList, name, number); } catch (NameNumberMatchException e) { - UI.println("Student and Phone number pair found. Please restore this student instead."); + UI.println("Student and Phone number pair found. If not found in the list, " + + "please restore the student instead."); UI.printDivider(); return; } diff --git a/src/main/java/classify/commands/ArchiveCommands.java b/src/main/java/classify/commands/ArchiveCommands.java index 48be46d11d..75cdbdc750 100644 --- a/src/main/java/classify/commands/ArchiveCommands.java +++ b/src/main/java/classify/commands/ArchiveCommands.java @@ -88,7 +88,7 @@ public static void archiveStudent(ArrayList masterList, ArrayList archiveList, String name, Scanner in) { - if (name == null) { + if (name == null || name.isBlank()) { name = Commands.promptName(in); } Student student = InputParsing.findStudentByName(archiveList, name, in); diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 1f4129f880..c1cdeb8598 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -57,12 +57,8 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas System.out.println("Student list is null."); } // @@author tayponghee - String name = userCommand[0]; - if (name.isBlank()) { - UI.println("Invalid name found."); - UI.printDivider(); - return; - } + String name = userCommand[1]; + switch (userCommand[0]) { case ADD: AddStudent.addStudent(masterStudentList, in, userCommand[1]); @@ -281,6 +277,11 @@ public static double promptForGrade(Scanner in) { public static Student findStudentByName(ArrayList masterStudentList, String name, Scanner in) { //@@author Cryolian + + if (name == null || name.isBlank()) { + return null; + } + ArrayList studentsWithMatchingNames = new ArrayList(); for (Student student : masterStudentList) { if (student.getName().equalsIgnoreCase(name)) { From 4376de8171f7e0a5d3eaf20b77d568db08cc8471 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 3 Apr 2024 23:32:52 +0800 Subject: [PATCH 220/503] Fix archive bug --- src/main/java/classify/commands/ArchiveCommands.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/ArchiveCommands.java b/src/main/java/classify/commands/ArchiveCommands.java index 75cdbdc750..50a07e9446 100644 --- a/src/main/java/classify/commands/ArchiveCommands.java +++ b/src/main/java/classify/commands/ArchiveCommands.java @@ -71,7 +71,7 @@ public static void archiveStudent(ArrayList masterList, ArrayList Date: Thu, 4 Apr 2024 21:32:20 +0800 Subject: [PATCH 221/503] Fix StudentSorter class diagram --- .../src/StudentSorter/StudentSorter.png | Bin 47255 -> 46287 bytes .../src/StudentSorter/StudentSorter.puml | 1 + 2 files changed, 1 insertion(+) diff --git a/docs/diagrams/src/StudentSorter/StudentSorter.png b/docs/diagrams/src/StudentSorter/StudentSorter.png index d366eca675acaab5603f39fd5f0aedaa436e939f..42aa526b2ec02ec3d50de50d65e4b989e8ecced0 100644 GIT binary patch literal 46287 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 Hr>^~9UHR4> literal 47255 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 diff --git a/docs/diagrams/src/StudentSorter/StudentSorter.puml b/docs/diagrams/src/StudentSorter/StudentSorter.puml index b27f38fd10..d721e39c73 100644 --- a/docs/diagrams/src/StudentSorter/StudentSorter.puml +++ b/docs/diagrams/src/StudentSorter/StudentSorter.puml @@ -1,4 +1,5 @@ @startuml StudentSorter +skinparam classAttributeIconSize 0 package student { class StudentSorter { From 7b27d6bda2d1bfecb5080918f5b7438e6c4848b7 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Thu, 4 Apr 2024 21:37:25 +0800 Subject: [PATCH 222/503] Remove package name from StudentSorter UML diagram --- .../src/StudentSorter/StudentSorter.puml | 59 +++++++++---------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/docs/diagrams/src/StudentSorter/StudentSorter.puml b/docs/diagrams/src/StudentSorter/StudentSorter.puml index d721e39c73..ee6a1c1927 100644 --- a/docs/diagrams/src/StudentSorter/StudentSorter.puml +++ b/docs/diagrams/src/StudentSorter/StudentSorter.puml @@ -1,40 +1,38 @@ @startuml StudentSorter skinparam classAttributeIconSize 0 -package student { - class StudentSorter { - +NAME:String - +PAYMENT_DATE:String - +TOTAL_CLASSES:String - +ONE:String - +TWO:String - +THREE:String - +INVALID_CHOICE:String - -- - +sortByChoice(ArrayList, String, Scanner) - +isValidChoice(String):boolean - } +class StudentSorter { + + NAME: String + + PAYMENT_DATE: String + + TOTAL_CLASSES: String + + ONE: String + + TWO: String + + THREE: String + + INVALID_CHOICE: String + -- + + sortByChoice(ArrayList, String, Scanner) + + isValidChoice(String): boolean +} - class StudentList { - {static} +masterStudentList:ArrayList - {static} +recentlyDeletedList:ArrayList - +studentList:ArrayList - } +class StudentList { + {static} + masterStudentList: ArrayList + {static} + recentlyDeletedList: ArrayList + + studentList: ArrayList +} - class Student { - +name:String - -totalClassesAttended:int - } +class Student { + + name: String + - totalClassesAttended: int +} - class StudentAttributes { - +subjectGrades:List - } +class StudentAttributes { + + subjectGrades: List +} - class SubjectGrade { - -subject:String - -grade:double - -classesAttended:int - } +class SubjectGrade { + - subject: String + - grade: double + - classesAttended: int } StudentSorter "1" --> "1..*" Student @@ -43,5 +41,4 @@ StudentSorter "1" --> "1" StudentAttributes StudentAttributes "1" --> "0..*" SubjectGrade note "Inconsequential methods and attributes omitted" as N1 - @enduml From 032d5e2ee4f2c03ba9766f240907f0dc2e3dbf46 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Thu, 4 Apr 2024 21:55:58 +0800 Subject: [PATCH 223/503] Improve Data Component DG --- docs/DeveloperGuide.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 8b1e2ad4c0..9fd1f6d2ea 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -74,7 +74,11 @@ All the while these commands are being processed, the runtime database `masterSt To facilitate the management of students within a tuition centre, it is imperative to have easy access and storage of important information regarding said personnel. -Seen below is an UML diagram of the relevant classes dealing with storage. +Seen below is an UML diagram of the relevant classes dealing with storage, which is done in the form of storing the array list in a text file format. + +This text file would have the details of the student's name and their attributes, in the following order: subject, grade, classes taken for that subject, phone number, last paid date and remarks. + +In the following component, the guide would go into detail about the implementation for writing and reading to the text file. ![DataStoringUML](./diagrams/src/DataStoring/DateStoring.png) @@ -108,12 +112,27 @@ This text file is created locally on the users' computer for easy access and ret Currently there is a polling system set in place where every change in the list of students (eg, addition, deletion, modification) would override the current working text file on the users' computer. -We intend to further the functionalities of this component by allowing us to add attributes (phone number, subjects, last fee payment date), +As stated above, all the names and attributes associated with each student will be saved to the main text file, named Student_Information.txt. + +If the user chooses to delete or archive a student, it would be saved to an archive file, named student_archive.txt. If the user chooses to unarchive a student or undo a recent deletion, it will be brought back to the main text file. + +The two text files are will be created under a directory called data, in which two separate file paths will be created if it is not already found on the user's desktop. #### Design Considerations In order to ensure the proper usage of OOP principles (such as encapsulation), we have segregated the 3 classes to read,store and handle the data. +Moreover, the regex used to separate the different types of data in the file type have been chosen in a way which would not affect normal user operation needs. If the user chooses to use the banned characters, the input parser would replace them, as shown below: + +Banned characters: +`#`,`~` and `-` + +- `#` changes to ` `. +- `~` changes to ` `. +- `-` changes to `_`. + +This will prevent the user from messing with the way the program reads and writes to the text files, preventing corruption of the database due to improper usage. + #### Implementation and Rationale ##### DataHandler From 55ec28ec69fa3eb86507d6f69251bbcce3e39198 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Thu, 4 Apr 2024 22:07:15 +0800 Subject: [PATCH 224/503] Add Object Diagram to Data Storage Component --- docs/DeveloperGuide.md | 2 + .../DataStoring/DataStoringObjectDiagram.puml | 47 ++++++++++++++++++ .../src/DataStoring/ObjectDiagram.png | Bin 0 -> 44190 bytes 3 files changed, 49 insertions(+) create mode 100644 docs/diagrams/src/DataStoring/DataStoringObjectDiagram.puml create mode 100644 docs/diagrams/src/DataStoring/ObjectDiagram.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 9fd1f6d2ea..41efaa31a1 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -118,6 +118,8 @@ If the user chooses to delete or archive a student, it would be saved to an arch The two text files are will be created under a directory called data, in which two separate file paths will be created if it is not already found on the user's desktop. +![DataStoringObjectDiagramUML](./diagrams/src/DataStoring/ObjectDiagram.png) + #### Design Considerations In order to ensure the proper usage of OOP principles (such as encapsulation), we have segregated the 3 classes to read,store and handle the data. diff --git a/docs/diagrams/src/DataStoring/DataStoringObjectDiagram.puml b/docs/diagrams/src/DataStoring/DataStoringObjectDiagram.puml new file mode 100644 index 0000000000..3866468bfa --- /dev/null +++ b/docs/diagrams/src/DataStoring/DataStoringObjectDiagram.puml @@ -0,0 +1,47 @@ +@startuml ObjectDiagram + +object DataHandler { + DATA_DIRECTORY_PATH = "data/studentInfo" + DATA_FILE_PATH = "data/studentInfo/Student_Information.txt" + ARCHIVE_DIRECTORY_PATH = "data/archive" + ARCHIVE_FILE_PATH = "data/archive/student_archive.txt" +} + +object DataReader { + in = new Scanner(System.in) +} + +object DataWriter { + NEWLINE = "\n" +} + +object Student { + name = "Woi Ming" + attributes = StudentAttributes +} + +object StudentList { + masterStudentList = ArrayList + recentlyDeletedList = ArrayList + studentList = ArrayList +} + +object StudentAttributes { + subjectGrades = List +} + +object SubjectGrade { + subject = "Programming Methodology I" + grade = 66.6 + classesAttended = 35 +} + +DataHandler "1" --> "1" DataWriter +DataHandler "1" --> "1" DataReader +DataHandler "1" --> "1" StudentList +DataHandler "1" --> "1" StudentAttributes +StudentAttributes "1" --> "0..*" SubjectGrade +StudentList "1" --> "0..*" Student +Student "1" --> "1" StudentAttributes + +@enduml diff --git a/docs/diagrams/src/DataStoring/ObjectDiagram.png b/docs/diagrams/src/DataStoring/ObjectDiagram.png new file mode 100644 index 0000000000000000000000000000000000000000..19108b52b225cac3a388a18729f86f958fc67f34 GIT binary patch literal 44190 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 DDsq3@ literal 0 HcmV?d00001 From 8415350e862268d6bc3ba2d8bb9266adb8134f9d Mon Sep 17 00:00:00 2001 From: tayponghee Date: Thu, 4 Apr 2024 22:15:50 +0800 Subject: [PATCH 225/503] Add non-functional requirements --- docs/DeveloperGuide.md | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 41efaa31a1..f63acc0c26 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -174,7 +174,6 @@ or duplicate names are encountered. The `AddStudent` class contributes to the overall functionality of the application by providing a streamlined process for adding new students and ensuring data integrity within the student database. - ### StudentSorter Component The `StudentSorter` class facilitates sorting of the list of students based on various criterion. @@ -226,7 +225,30 @@ Classify serves as an attempt to modernise administrative tasks in education ins ## Non-Functional Requirements -{Give non-functional requirements} +1. **Performance**: + - The system should respond to user actions within 2 seconds under normal operating conditions. + - It should be able to handle a minimum of 100 concurrent users without significant degradation in performance. + - The system should encompass all basic data types that an administer would need to know about a student to register them for classes in the tuition centre. + +2. **Reliability**: + - In the event the program crashes, the data that was last updated into the storage should not be destroyed. + +3. **Scalability**: + - The system should be designed to accommodate future growth in the number of students and users. + +4. **Usability**: + - The user interface should be intuitive and easy to navigate, requiring minimal training for users to become proficient. + - Error messages should be clear and informative, guiding users on how to resolve issues. + +5. **Compatibility**: + - It should be platform-independent, allowing users to access it from different operating systems. + +6. **Maintainability**: + - The codebase should be well-documented and follow coding standards to facilitate future maintenance and enhancements. + - Logging and monitoring mechanisms should be in place to track system usage and identify potential issues. + +7. **Data Management**: + - File saving should done whenever a change has been made to the Master List. ## Glossary From c690098d9ebd27d52f9cf6975c7253b674ebb211 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sat, 6 Apr 2024 14:03:52 +0800 Subject: [PATCH 226/503] Add capitalisation for first letter of each name, and forced lower case for subsequent letters. --- docs/UserGuide.md | 9 ++++++++- src/main/java/classify/commands/AddStudent.java | 17 +++++++++++++++++ .../classify/commands/ListStudentsCommand.java | 2 -- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 54de9c1184..ebaa8b85fc 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -99,6 +99,13 @@ Initialises an interface for adding a student and their relevant details to the Students of the same name can be added so long as they possess a different phone number. Students with the same phone number can be added so long as they have different names. +The first letter of the student's name will be capitalised, while the 2nd letter onwards will be lowercase, regardless of initial input. + +Example: +- James -> James +- james -> James +- jaMeS -> James + Format: `add` or `add NAME` Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. @@ -143,7 +150,7 @@ view wario Student details: Name: wario -Phone Number: 12345678 +Phone Number: 97655678 Gender: male Last Payment Date: 12/12/2023 Remarks: Unknown diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 42acb5bd90..1070b459dc 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -121,6 +121,7 @@ public static String checkForEmptyName(ArrayList masterStudentList, Sca UI.printEmptyNameMessage(); UI.printDivider(); } else { + name = capitaliseFirstLetter(name); break; } @@ -129,6 +130,22 @@ public static String checkForEmptyName(ArrayList masterStudentList, Sca } + /** + * Capitalises the first letter of a string and converts the rest of the string to lowercase. + * + * @param name The input string to capitalise. + * @return The string with the first letter capitalised and the rest of the letters converted to lowercase. + */ + private static String capitaliseFirstLetter(String name) { + if (!name.isEmpty()) { + String firstLetter = name.substring(0, 1).toUpperCase(); + String restOfName = name.substring(1).toLowerCase(); + return firstLetter + restOfName; + } else { + return name; + } + } + /** * Prompts the user to enter attributes for a student, including subject, grade, * and classes attended. diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 979f423f94..27c3b422a3 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -94,8 +94,6 @@ private static void listAllStudents(ArrayList masterStudentList) { default: UI.println(INVALID_CHOICE); } - //scanner.close(); - UI.printDivider(); } /** From c6637edef8ab8c796fa353c93883fee3cd68cab1 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 7 Apr 2024 14:46:30 +0800 Subject: [PATCH 227/503] Remove extra else statement --- src/main/java/classify/commands/AddStudent.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 1070b459dc..93231b38ac 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -141,9 +141,8 @@ private static String capitaliseFirstLetter(String name) { String firstLetter = name.substring(0, 1).toUpperCase(); String restOfName = name.substring(1).toLowerCase(); return firstLetter + restOfName; - } else { - return name; } + return name; } /** From 97631945a279c72d5925181b6be5602f523e18d4 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 7 Apr 2024 16:01:47 +0800 Subject: [PATCH 228/503] Update tayponghee PPP --- docs/DeveloperGuide.md | 4 +- docs/team/tayponghee.md | 52 +++++++++++++++++++ .../java/classify/commands/AddStudent.java | 3 +- .../java/classify/commands/StudentSorter.java | 2 +- .../classify/student/StudentAttributes.java | 5 +- 5 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 docs/team/tayponghee.md diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index f63acc0c26..0871978163 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -226,9 +226,9 @@ Classify serves as an attempt to modernise administrative tasks in education ins ## Non-Functional Requirements 1. **Performance**: - - The system should respond to user actions within 2 seconds under normal operating conditions. + - The system should respond to user actions within 1 second under normal operating conditions. - It should be able to handle a minimum of 100 concurrent users without significant degradation in performance. - - The system should encompass all basic data types that an administer would need to know about a student to register them for classes in the tuition centre. + - The system should encompass all basic data types that an administrator would need to know about a student to register them for classes in the tuition centre. 2. **Reliability**: - In the event the program crashes, the data that was last updated into the storage should not be destroyed. diff --git a/docs/team/tayponghee.md b/docs/team/tayponghee.md new file mode 100644 index 0000000000..a5f8a15cbf --- /dev/null +++ b/docs/team/tayponghee.md @@ -0,0 +1,52 @@ +# Tay Pong Hee's Project Portfolio Page + +## Project: Classify + +Classify is a desktop application used for Tuition Centres to allow for easier management of their enrolled students. +From allowing users to add new students to sorting them based on their last paid date, Classify is the one-stop app that +all Tuition Centres can employ for ease of student management. To use the app, users can interact with it using CLI. +Overall, the code base has more than 3kLoC, and is written in Java. + +Given below are my contributions to the project: + +- **Feature: Add a student to the master list.** + * The foundational building block of the Classify project. + * Highlights: The User would be allowed to add a student to the Master List in a specified format given by the program, which helps the User understand the proper format for adding them. Moreover, each student would be allowed any number of subjects tagged to their name, which is done through a polling functionality. + * Justification: This allows the User to add all the relevant information from the get-go, and makes it easy for the User to know what are the necessary details at registration. + + +- **Feature: View a student from the master list.** + * Highlights: Differentiates whether a User has input 0 classes attended for a specified subject or simply left it blank. + * Justification: Most of the time, people allude to 0 and leaving it blank as the same thing for that field. However, it is important to note down whether the User has accidentally left it blank i.e. may have lessons attended, or meaningfully filled it as 0, which helps with data analytics of a student's progress. + + +- **Feature: List the students from the master list, based on certain parameters.** + * Highlights: The User would be allowed to specify whether to generate the whole list of students, display them with the total classes attended across all subjects or only list students taking a certain class at the tuition centre. + * Justification: Being able to generate a list of students based on certain parameters would make it easier to narrow down to whom the User is looking for in the database. + + +- **Feature: Sort the students on the master list based on certain parameters.** + * Highlights: Created the sorting algorithms to sort based on lexicographical order and by total classes attended. + * Justification: Being able to sort a student by alphabetical order and total classes attended helps with easily generating a report based on name, and helps with visualising the number of classes taken by all the students, both in ascending order. + * Credits: Used the java.util.Comparator class to easily sort the students based on the above parameters. + + +- **Code contributed:** [Link to Reposense contribution graph](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=tayponghee&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2024-02-23&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) + + +- **Documentation:** + * [Contributions to UG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/UserGuide.md): + * Features for list, sorting, as well as the examples for deletion and view. Compiled all the commands into the summary sheet at the bottom of the UG. + * [Contributions to DG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/DeveloperGuide.md): + * References, InputParsing Component, DataStoring Component, AddStudent Component and StudentSorter Component, as well as the non-functional requirements. + * UMLs contributed: Object diagram for DataStoring, Class diagrams for InputParsing and StudentSorter. Created using the PlantUML software. + * [DataStoring UML](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/diagrams/src/DataStoring/ObjectDiagram.png) + * [InputParsing UML](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/diagrams/src/InputParsing/InputParsing.png) + * [StudentSorter UML](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/diagrams/src/StudentSorter/StudentSorter.png) + + +- **Contributions to Team-Based tasks:** + * Management of assignees for issues + * Updating of non-specific documentation, e.g. non-functional requirements + * Weekly reminders on deadlines for tasks + * Handling of pull requests (Examples: [link 1](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/159) [link 2](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/153) [link 3](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/145)) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 93231b38ac..9bcdd31b13 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -198,10 +198,8 @@ private static boolean checkForValidSubjectResponse(Scanner in, StudentAttribute if (response.equals(YES)) { break; - } else if (response.equals(NO)) { return true; - } else { UI.printInvalidResponse(); } @@ -243,4 +241,5 @@ public static int promptForClassesAttended(Scanner in) { } } } + } diff --git a/src/main/java/classify/commands/StudentSorter.java b/src/main/java/classify/commands/StudentSorter.java index db1e3481bc..1f2ffaa668 100644 --- a/src/main/java/classify/commands/StudentSorter.java +++ b/src/main/java/classify/commands/StudentSorter.java @@ -25,7 +25,7 @@ public class StudentSorter { * Sorts the list of students based on the specified choice. * * @param masterStudentList The list of students to be sorted. - * @param choice The sorting criterion ("1" for name, "2" for total classes). + * @param choice The sorting criterion ("1" for name, "2" for total classes, "3" for last paid date). * @param in The Scanner object for user input. */ public static void sortByChoice(ArrayList masterStudentList, String choice, Scanner in) { diff --git a/src/main/java/classify/student/StudentAttributes.java b/src/main/java/classify/student/StudentAttributes.java index deaa09b36c..5b3ab4ae74 100644 --- a/src/main/java/classify/student/StudentAttributes.java +++ b/src/main/java/classify/student/StudentAttributes.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.List; +//@@author tayponghee public class StudentAttributes extends Details { private Student student; private List subjectGrades; @@ -33,6 +34,7 @@ public void setName(String name) { public String toString() { StringBuilder sb = new StringBuilder(); + //@@author Cryolian sb.append("StudentAttributes{" + "name: '" + student.getName() + '\'' + ", H/P: " + String.valueOf(phoneNumber) + '\'' + @@ -43,7 +45,8 @@ public String toString() { for (SubjectGrade subjectGrade : subjectGrades) { sb.append(subjectGrade.toString()).append(", "); } - + + //@@author tayponghee sb.append("]}"); return sb.toString(); } From 4cabfd3ebbd35b85a86ae792ed14d07554c58cfb Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 7 Apr 2024 16:05:11 +0800 Subject: [PATCH 229/503] Fix gradle checks --- src/main/java/classify/commands/AddStudent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 9bcdd31b13..eb21aabee4 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -142,7 +142,7 @@ private static String capitaliseFirstLetter(String name) { String restOfName = name.substring(1).toLowerCase(); return firstLetter + restOfName; } - return name; + return name; } /** From 28322251414810d78a7bf95b4b9776ad4a36ca95 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sun, 7 Apr 2024 17:33:55 +0800 Subject: [PATCH 230/503] Fix bug caused by delete function adding a null entry to recently deleted list which can be restored to main student list. --- src/main/java/classify/commands/DeleteCommands.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index b64a59768f..fa0c1631db 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -36,6 +36,8 @@ public static void deleteStudent(ArrayList masterStudentList, ArrayList UI.printStudentDeleted(); } else { UI.printStudentNotFound(); + UI.printDivider(); + return; } UI.printDivider(); From f1df3ef6d164f64a755c77f25c0d6242177078fc Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Sun, 7 Apr 2024 21:15:57 +0800 Subject: [PATCH 231/503] Add liability shield for add student name --- docs/UserGuide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index ebaa8b85fc..2731bc0e2d 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -99,6 +99,8 @@ Initialises an interface for adding a student and their relevant details to the Students of the same name can be added so long as they possess a different phone number. Students with the same phone number can be added so long as they have different names. +User is expected to add only student's name as registered in NRIC or passport. + The first letter of the student's name will be capitalised, while the 2nd letter onwards will be lowercase, regardless of initial input. Example: From f5cf6da5ef19643492bbc573843de88b6e53494b Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 7 Apr 2024 21:17:27 +0800 Subject: [PATCH 232/503] Attempt to fix nullpointerexception bug --- src/main/java/classify/commands/AddStudent.java | 4 ++++ src/main/java/classify/student/StudentList.java | 2 +- src/main/java/classify/user/InputParsing.java | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index eb21aabee4..34089d31d7 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -69,6 +69,10 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, "please restore the student instead."); UI.printDivider(); return; + } catch (NullPointerException e) { + UI.println("Null pointer thrown. Something went wrong."); + UI.printDivider(); + return; } student.getAttributes().setPhoneNumber(number); diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 41fd93b6af..45005e9ca2 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -112,7 +112,7 @@ public void removeStudent(String name) { * @throws nameNumberMatchException Thrown if a match is found. */ public static void checkNameNumberPair(ArrayList studentList, String name, int number) - throws NameNumberMatchException { + throws NameNumberMatchException, NullPointerException { for (Student s : studentList) { if (s.getName().equalsIgnoreCase(name) && s.getPhoneNumber() == number) { diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index c1cdeb8598..1b2631c836 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -429,7 +429,7 @@ private static int readInPhoneNumber(Scanner in) throws NumberFormatException { */ //@@author Cryolian private static boolean checkNumberValidity(int number) { - return number > NUMBER_TOO_SMALL && number < NUMBER_TOO_BIG; + return number >= NUMBER_TOO_SMALL && number <= NUMBER_TOO_BIG; } //@@author ParthGandhiNUS From 69340b61b1fec8c1257eb2b70766e4abbfa6fba2 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Sun, 7 Apr 2024 21:34:37 +0800 Subject: [PATCH 233/503] Add liability shield for matching random letter cases under "view student" and "list subject" commands. --- docs/UserGuide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 2731bc0e2d..0d8788430f 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -61,6 +61,7 @@ Removes a student from the master list of students. ### - Produce a list of all the students who takes a subject `list`, enter, then followed by `subject name` Displays a list of all the students with that associated subject taken in the tuition centre. +If user enters different letter cases from subjects stored, the system will still match strings regardless of letter case for user intuitiveness. ### Produce a list of all students `list`, enter, enter, `1` @@ -145,6 +146,7 @@ Views a student's details. Allows the user to do view [name] or just view. Format: `view` or `view NAME` Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. +If user enters different letter cases from name stored data, the system will still match strings regardless of letter case for user intuitiveness. ``` Example: From 569a3a406cb63e8bd849e3a521d5eadff77b75f8 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 7 Apr 2024 21:38:03 +0800 Subject: [PATCH 234/503] Make exiting add interface explicit --- src/main/java/classify/commands/AddStudent.java | 2 +- src/main/java/classify/ui/UI.java | 1 + src/main/java/classify/user/InputParsing.java | 5 ++--- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 34089d31d7..d0399f8063 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -50,7 +50,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, try { number = InputParsing.promptForPhoneNumber(in); } catch (NumberFormatException e) { - UI.printValidNumberError(); + UI.println("Non-number character found."); UI.println("Exiting the adding interface."); UI.printDivider(); return; diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 7877919bbe..9153ade28a 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -277,6 +277,7 @@ public static void printEmptyNameMessage() { public static void printPhoneNumberPrompt() { System.out.println(PHONE_NUMBER_PROMPT); + System.out.println("Enter a non-number to exit interface."); } public static void printValidNumberError() { diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 1b2631c836..0a7db1eed6 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -391,7 +391,7 @@ private static boolean isValidGrade(double grade) { * or 10-digit number if not. * @throws NumberFormatException thrown if invalid number is give */ - public static int promptForPhoneNumber(Scanner in) throws NumberFormatException { + public static int promptForPhoneNumber(Scanner in) throws NumberFormatException{ int number = 0; @@ -429,7 +429,7 @@ private static int readInPhoneNumber(Scanner in) throws NumberFormatException { */ //@@author Cryolian private static boolean checkNumberValidity(int number) { - return number >= NUMBER_TOO_SMALL && number <= NUMBER_TOO_BIG; + return number >= NUMBER_TOO_SMALL && number < NUMBER_TOO_BIG; } //@@author ParthGandhiNUS @@ -459,7 +459,6 @@ public static String readInString(Scanner in) { return string; } - //@@author Cryolian public static LocalDate readInDate(Scanner in) { From 0d4931fbcba6120176aa4c4ec23c3ac4180f8741 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 7 Apr 2024 22:15:06 +0800 Subject: [PATCH 235/503] Add capitalisation for every first letter each name partition --- docs/UserGuide.md | 15 ++++++-- .../java/classify/commands/AddStudent.java | 35 ++++++++++++++----- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 0d8788430f..a6e97e34d9 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -104,10 +104,12 @@ User is expected to add only student's name as registered in NRIC or passport. The first letter of the student's name will be capitalised, while the 2nd letter onwards will be lowercase, regardless of initial input. +However, if the name contains multiple parts, each corresponding first letter after every space will be capitalised as well. + Example: -- James -> James -- james -> James -- jaMeS -> James +- James wong bing xuan -> James Wong Bing Xuan +- james WONG BING XUAN -> James Wong Bing Xuan +- jaMeS WONG binG Xuan -> James Wong Bing Xuan Format: `add` or `add NAME` @@ -148,6 +150,13 @@ Format: `view` or `view NAME` Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. If user enters different letter cases from name stored data, the system will still match strings regardless of letter case for user intuitiveness. +How it works (cases for input): +- In the list: Stored as `James Wong` +- view James Wong -> James Wong +- view james wong -> james wong +- view JAMES WONG -> JAMES WONG + * so, regardless of what the user uses for capitalisation of the name, the program will recognise that uppercase and lowercases should return the same student. + ``` Example: view wario diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 34089d31d7..53890216d7 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -125,7 +125,7 @@ public static String checkForEmptyName(ArrayList masterStudentList, Sca UI.printEmptyNameMessage(); UI.printDivider(); } else { - name = capitaliseFirstLetter(name); + name = splitName(name); break; } @@ -135,20 +135,39 @@ public static String checkForEmptyName(ArrayList masterStudentList, Sca } /** - * Capitalises the first letter of a string and converts the rest of the string to lowercase. + * Capitalizes the first letter of each word in a string. * - * @param name The input string to capitalise. - * @return The string with the first letter capitalised and the rest of the letters converted to lowercase. + * @param name The input string to capitalize. + * @return The string with the first letter of each word capitalized. */ - private static String capitaliseFirstLetter(String name) { + private static String splitName(String name) { if (!name.isEmpty()) { - String firstLetter = name.substring(0, 1).toUpperCase(); - String restOfName = name.substring(1).toLowerCase(); - return firstLetter + restOfName; + StringBuilder result = new StringBuilder(); + String[] words = name.split("\\s"); + return capitaliseFirstLetters(words, result); } return name; } + /** + * Iterates through each word in the input array, capitalizes the first letter, + * and converts every other letter to lowercase. + * + * @param words The array of words to capitalize. + * @param result The StringBuilder object to store the capitalized words. + * @return The string with the first letter of each word capitalized and every other letter in lowercase. + */ + private static String capitaliseFirstLetters(String[] words, StringBuilder result) { + for (String word : words) { + if (!word.isEmpty()) { + result.append(Character.toUpperCase(word.charAt(0))) + .append(word.substring(1).toLowerCase()) + .append(" "); + } + } + return result.toString().trim(); + } + /** * Prompts the user to enter attributes for a student, including subject, grade, * and classes attended. From 87cb212b8d3a04984f6636599dc77fa7284b28d8 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 7 Apr 2024 22:19:04 +0800 Subject: [PATCH 236/503] Fix UI printing for studentsorter --- src/main/java/classify/commands/StudentSorter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/classify/commands/StudentSorter.java b/src/main/java/classify/commands/StudentSorter.java index 1f2ffaa668..eff750f54c 100644 --- a/src/main/java/classify/commands/StudentSorter.java +++ b/src/main/java/classify/commands/StudentSorter.java @@ -80,7 +80,6 @@ public static boolean isValidChoice(String choice) { private static void listStudentsByName(ArrayList masterStudentList) { masterStudentList.sort(StudentComparators.nameComparator); listStudents(masterStudentList); - UI.printDivider(); } /** From fa7401415c418318c20774b1a889aa066162c2a5 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 7 Apr 2024 22:31:25 +0800 Subject: [PATCH 237/503] Add special character prevention --- src/main/java/classify/Classify.java | 6 ++-- .../java/classify/commands/AddStudent.java | 17 +++++++++-- .../classify/commands/ArchiveCommands.java | 5 ++-- .../classify/commands/DeleteCommands.java | 21 +++++++------- .../java/classify/commands/EditStudent.java | 2 ++ src/main/java/classify/data/DataReader.java | 12 ++++++-- src/main/java/classify/ui/UI.java | 2 +- src/main/java/classify/user/InputParsing.java | 28 ++++++++++++++++--- .../user/InvalidCharacterException.java | 10 +++++++ src/main/java/classify/user/UserInput.java | 22 +++++++++------ 10 files changed, 92 insertions(+), 33 deletions(-) create mode 100644 src/main/java/classify/user/InvalidCharacterException.java diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 23217b39ee..e1a6238eee 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -28,11 +28,13 @@ public static void main(String[] args) throws IOException { // Takes in input from the user, and processes input to determine if it contains a command and a name - String[] userCommand = UserInput.processInput(in.nextLine()); + String[] userCommand; + + userCommand = UserInput.processInput(in.nextLine()); // Set up polling for the first word input by the user. // If user's first word is "bye", will exit the while loop. - while (!(userCommand[0].equals("bye"))){ + while (userCommand == null || !(userCommand[0].equals("bye"))){ InputParsing.parseUserCommand(userCommand, StudentList.masterStudentList, StudentList.recentlyDeletedList, StudentList.archiveList, in); userCommand = UserInput.processInput(in.nextLine()); diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index d0399f8063..614e1ddc5f 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -8,6 +8,7 @@ import classify.student.SubjectGrade; import classify.ui.UI; import classify.user.InputParsing; +import classify.user.InvalidCharacterException; import classify.user.NameNumberMatchException; import java.util.ArrayList; import java.util.Scanner; @@ -39,7 +40,12 @@ public class AddStudent { public static void addStudent(ArrayList masterStudentList, Scanner in, String studentName) { String name; - name = checkForEmptyName(masterStudentList, in, studentName); + try { + name = checkForEmptyName(masterStudentList, in, studentName); + } catch (InvalidCharacterException e) { + UI.printDivider(); + return; + } Student student = new Student(name); addSubject(in, student.getAttributes()); @@ -50,7 +56,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, try { number = InputParsing.promptForPhoneNumber(in); } catch (NumberFormatException e) { - UI.println("Non-number character found."); + UI.println("Non-number or blank character found."); UI.println("Exiting the adding interface."); UI.printDivider(); return; @@ -64,6 +70,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, try { StudentList.checkNameNumberPair(StudentList.masterStudentList, name, number); StudentList.checkNameNumberPair(StudentList.recentlyDeletedList, name, number); + StudentList.checkNameNumberPair(StudentList.archiveList, name, number); } catch (NameNumberMatchException e) { UI.println("Student and Phone number pair found. If not found in the list, " + "please restore the student instead."); @@ -105,8 +112,10 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, * before being prompted * @return The valid non-empty name entered by the user. */ - public static String checkForEmptyName(ArrayList masterStudentList, Scanner in, String studentName) { + public static String checkForEmptyName(ArrayList masterStudentList, Scanner in, String studentName) + throws InvalidCharacterException { String name; + while (true) { //@@author alalal47 @@ -125,11 +134,13 @@ public static String checkForEmptyName(ArrayList masterStudentList, Sca UI.printEmptyNameMessage(); UI.printDivider(); } else { + InputParsing.checkForSpecialCharacters(name); name = capitaliseFirstLetter(name); break; } } + return name; } diff --git a/src/main/java/classify/commands/ArchiveCommands.java b/src/main/java/classify/commands/ArchiveCommands.java index 50a07e9446..41e602305b 100644 --- a/src/main/java/classify/commands/ArchiveCommands.java +++ b/src/main/java/classify/commands/ArchiveCommands.java @@ -34,7 +34,8 @@ public static void unarchiveStudent(ArrayList masterList, ArrayList masterList, ArrayList masterStudentList, ArrayList } //@@author alalal47 - Student foundStudent = InputParsing.findStudentByName(masterStudentList, studentName, in); + Student student = InputParsing.findStudentByName(masterStudentList, studentName, in); - if (foundStudent != null) { + if (student != null) { UI.printStudentDeleted(); } else { UI.printStudentNotFound(); @@ -43,11 +43,11 @@ public static void deleteStudent(ArrayList masterStudentList, ArrayList UI.printDivider(); //@@author blackmirag3 if (recentlyDeletedList != null) { - recentlyDeletedList.add(foundStudent); + recentlyDeletedList.add(student); } - masterStudentList.remove(foundStudent); + masterStudentList.remove(student); //@@author alalal47 - assert masterStudentList.contains(foundStudent) == false : "student should be removed"; + assert masterStudentList.contains(student) == false : "student should be removed"; DataHandler.writeStudentInfo(masterStudentList); } @@ -69,9 +69,9 @@ public static void restoreStudent(ArrayList masterStudentList, ArrayLis studentName = promptName(in); } - Student foundStudent = InputParsing.findStudentByName(recentlyDeletedList, studentName, in); + Student student = InputParsing.findStudentByName(recentlyDeletedList, studentName, in); - if (foundStudent != null) { + if (student != null) { UI.printRestoreMessage(); } else { UI.printStudentNotFound(); @@ -79,12 +79,13 @@ public static void restoreStudent(ArrayList masterStudentList, ArrayLis //@@author Cryolian try { - StudentList.checkNameNumberPair(masterStudentList, studentName, foundStudent.getPhoneNumber()); + StudentList.checkNameNumberPair(StudentList.masterStudentList, student.name, student.getPhoneNumber()); + StudentList.checkNameNumberPair(StudentList.archiveList, student.name, student.getPhoneNumber()); //@@author blackmirag3 UI.printDivider(); - masterStudentList.add(foundStudent); - recentlyDeletedList.remove(foundStudent); + masterStudentList.add(student); + recentlyDeletedList.remove(student); //@@author Cryolian } catch (NameNumberMatchException e) { diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index acd71d2f7a..bc1fb0b3e3 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -202,6 +202,8 @@ private static void openNumberEditInterface(Scanner in, StudentAttributes attrib //@@author ParthGandhiNUS if (number != attributes.getPhoneNumber()){ StudentList.checkNameNumberPair(StudentList.masterStudentList, attributes.getName(), number); + StudentList.checkNameNumberPair(StudentList.recentlyDeletedList, attributes.getName(), number); + StudentList.checkNameNumberPair(StudentList.archiveList, attributes.getName(), number); } //@@author Cryolian attributes.setPhoneNumber(number); diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 46e38b2174..0a8b62dcab 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -5,6 +5,7 @@ import classify.student.SubjectGrade; import classify.ui.DataUI; import classify.user.InputParsing; +import classify.user.InvalidCharacterException; import classify.user.NameNumberMatchException; import classify.ui.UI; @@ -52,19 +53,24 @@ public static void restoreStudentList(String studentFileInput, ArrayList masterStudentList, ArrayList recentlyDeletedList, ArrayList archiveList, Scanner in) { - // @@author blackmirag3 + //@@author blackmirag3 if (masterStudentList == null) { System.out.println("Student list is null."); } - // @@author tayponghee - String name = userCommand[1]; + //@@author tayponghee + + if (userCommand == null ) { + UI.printDivider(); + return; + } switch (userCommand[0]) { case ADD: AddStudent.addStudent(masterStudentList, in, userCommand[1]); - // @@author ParthGandhiNUS + //@@author ParthGandhiNUS assert masterStudentList != null; break; @@ -517,4 +521,20 @@ private static boolean isDateValid(LocalDate paymentDate) { } + public static void checkForSpecialCharacters(String string) + throws InvalidCharacterException { + if (string == null) { + return; + } + + if (string.contains("~") + || string.contains("-") + || string.contains("#") + ) { + + throw new InvalidCharacterException(); + + } + } + } diff --git a/src/main/java/classify/user/InvalidCharacterException.java b/src/main/java/classify/user/InvalidCharacterException.java new file mode 100644 index 0000000000..43c2e6d8b3 --- /dev/null +++ b/src/main/java/classify/user/InvalidCharacterException.java @@ -0,0 +1,10 @@ +package classify.user; + +public class InvalidCharacterException extends Exception { + + public InvalidCharacterException() { + super(); + System.out.println("Special character found. Exiting current interface."); + } + +} diff --git a/src/main/java/classify/user/UserInput.java b/src/main/java/classify/user/UserInput.java index 3210aa5647..a1c784c5a0 100644 --- a/src/main/java/classify/user/UserInput.java +++ b/src/main/java/classify/user/UserInput.java @@ -1,5 +1,7 @@ package classify.user; +import classify.ui.UI; + public class UserInput { //@@author alalal47 /** @@ -7,17 +9,21 @@ public class UserInput { * @param userInput : String which the user inputs * @return String[] which contains the command in [0] and name in [1] if the user chose to input it */ - public static String[] processInput(String userInput){ + public static String[] processInput(String userInput) { String[] commandWithName = new String[2]; - if (userInput.trim().contains(" ")) { - commandWithName = userInput.split(" ", 2); - commandWithName[1] = commandWithName[1].replace('~', ' '); - commandWithName[1] = commandWithName[1].replace('-', '_'); - commandWithName[1] = commandWithName[1].replace('#', ' ').trim(); - } else { - commandWithName[0] = userInput.trim(); + try { + if (userInput.trim().contains(" ")) { + commandWithName = userInput.split(" ", 2); + + InputParsing.checkForSpecialCharacters(commandWithName[1]); + + } else { + commandWithName[0] = userInput.trim(); + } + } catch (InvalidCharacterException e) { + return null; } commandWithName[0] = commandWithName[0].toLowerCase(); From 48e5d4f480aa98f2ee11c435e2a3c437dd2a69bf Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 7 Apr 2024 22:50:53 +0800 Subject: [PATCH 238/503] Fix checkstyle errors --- src/main/java/classify/Classify.java | 3 +-- src/main/java/classify/user/InputParsing.java | 22 ++++++++++++++++++- src/main/java/classify/user/UserInput.java | 2 -- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index e1a6238eee..1975f08612 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -3,9 +3,8 @@ import classify.data.DataHandler; import classify.student.StudentList; import classify.user.InputParsing; -import classify.ui.UI; import classify.user.UserInput; - +import classify.ui.UI; import java.io.IOException; import java.util.Scanner; diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 7a4bfc9dd8..6c1b3d8ff8 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -362,6 +362,7 @@ public static boolean isValidClassesAttended(int classesAttended) { } return true; } + //@@author ParthGandhiNUS /** * Returns a true or false depending on user input for grade input @@ -465,6 +466,11 @@ public static String readInString(Scanner in) { } //@@author Cryolian + /** + * Prompts the user for a date in a format of YYYY--MM--DD + * @param in The scanner object to read in the user input. + * @return A valid LocalDate object from the user input. + */ public static LocalDate readInDate(Scanner in) { String userInput; @@ -482,6 +488,13 @@ public static LocalDate readInDate(Scanner in) { //@@author Cryolian + /** + * Converts a string into a date format. If blank is entered, the current date is + * returned. + * + * @param string The String to convert to a LocalDate object. + * @return A date parsed from the string or the current date as a LocalDate object. + */ protected static LocalDate parseDateFromString(String string) { if (string.isBlank()) { @@ -507,6 +520,7 @@ private static LocalDate printInvalidDateMessage() { UI.printInvalidDateFormatError(); return LocalDate.now().plusDays(2); } + //@@author Cryolian private static boolean isDateValid(LocalDate paymentDate) { @@ -521,6 +535,12 @@ private static boolean isDateValid(LocalDate paymentDate) { } + /** + * Checks if a string contains the special characters #,- or ~ + * + * @param string String to check. + * @throws InvalidCharacterException Thrown if the special characters are found. + */ public static void checkForSpecialCharacters(String string) throws InvalidCharacterException { if (string == null) { @@ -530,7 +550,7 @@ public static void checkForSpecialCharacters(String string) if (string.contains("~") || string.contains("-") || string.contains("#") - ) { + ) { throw new InvalidCharacterException(); diff --git a/src/main/java/classify/user/UserInput.java b/src/main/java/classify/user/UserInput.java index a1c784c5a0..796f497157 100644 --- a/src/main/java/classify/user/UserInput.java +++ b/src/main/java/classify/user/UserInput.java @@ -1,7 +1,5 @@ package classify.user; -import classify.ui.UI; - public class UserInput { //@@author alalal47 /** From 9436416e9f05327dd59435ec857e1563d5166a3a Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Mon, 8 Apr 2024 02:11:13 +0800 Subject: [PATCH 239/503] Update edit command for add subject and edit subject --- src/main/java/classify/Classify.java | 5 +- .../java/classify/commands/AddStudent.java | 1 - .../java/classify/commands/EditStudent.java | 202 ++++++++++-------- .../java/classify/commands/ViewStudent.java | 37 ++-- src/main/java/classify/data/DataHandler.java | 15 +- .../classify/student/StudentAttributes.java | 2 +- src/main/java/classify/ui/UI.java | 79 +++++-- src/main/java/classify/user/InputParsing.java | 4 +- 8 files changed, 216 insertions(+), 129 deletions(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 23217b39ee..8d1706726d 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -24,10 +24,8 @@ public static void main(String[] args) throws IOException { DataHandler.readArchive(StudentList.archiveList); //@@author ParthGandhiNUS UI.printWelcomeMessage(); - UI.printUserPrompt(); - - // Takes in input from the user, and processes input to determine if it contains a command and a name + // Takes in input from the user, and processes input to determine if it contains a command and a name String[] userCommand = UserInput.processInput(in.nextLine()); // Set up polling for the first word input by the user. @@ -35,6 +33,7 @@ public static void main(String[] args) throws IOException { while (!(userCommand[0].equals("bye"))){ InputParsing.parseUserCommand(userCommand, StudentList.masterStudentList, StudentList.recentlyDeletedList, StudentList.archiveList, in); + UI.printSubsequentUserPrompt(); userCommand = UserInput.processInput(in.nextLine()); } diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 53890216d7..2a773603ff 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -189,7 +189,6 @@ public static void addSubject(Scanner in, StudentAttributes attributes) { } else if (attributes.findSubject(subject) != null) { // rejects subject if existing subject of same name exists in students' - // attributes UI.printSubjectAlreadyExists(); break; diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index acd71d2f7a..80d835e762 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -3,6 +3,7 @@ import java.util.ArrayList; import java.util.Scanner; +import classify.data.DataHandler; import classify.student.Student; import classify.student.StudentAttributes; import classify.student.StudentList; @@ -11,118 +12,91 @@ import classify.user.NameNumberMatchException; import classify.ui.UI; -public class EditStudent { - private static final String NUMBER = "number"; - private static final String PAYMENT = "payment"; - private static final String REMARKS = "remarks"; - private static final String ADD = "add"; - private static final String EDIT = "edit"; - private static final String DELETE = "delete"; +//@@author blackmirag3 +public class EditStudent extends Commands { + private static final String ONE = "1"; + private static final String TWO = "2"; + private static final String THREE = "3"; + private static final String FOUR = "4"; + private static final String FIVE = "5"; + private static final String SIX = "6"; private static final String DEFAULT_STRING_VALUE = "Unknown"; - //@@author alalal47 - /** - * Prompts the user to input a name for the student whose details are to be edited, if the user has not used the - * command with a name flag. - * - * - * @param list The list of all students. - * @param in The scanner object to read user input. - * @param name The name of the student if the user has entered it when invoking the function. - */ - public static void editStudent(ArrayList list, Scanner in, String name) { - if (list.isEmpty()) { - UI.printEmptyListError(); + public static void editStudent(Scanner in, String name) { + Student student = getStudent(in, name); + if (student == null) { + UI.printStudentNotFound(); return; } + editStudentDetails(in, student); + } - Student student = null; + private static Student getStudent(Scanner in, String name) { - if (name != null) { - student = InputParsing.findStudentByName(list, name, in); - if (student == null) { - UI.printStudentNotFound(); - } + ArrayList list = StudentList.masterStudentList; + if (list.isEmpty()) { + UI.printEmptyListError(); + return null; } - while (student == null) { - - System.out.println("Name of student to edit (enter blank to exit):"); + if (name == null) { + System.out.println("Name of student to edit (blank to exit):"); name = in.nextLine().trim(); + } - if (name.isBlank()) { - System.out.println("Exiting edit."); - return; - } - - student = InputParsing.findStudentByName(list, name, in); - - if (student != null) { - break; - } else { - UI.printStudentNotFound(); - } + //quick exit clause + if (name.isBlank()) { + return null; } - editStudentAttributes(in, student); + return InputParsing.findStudentByName(list, name, in); } - //@@author alalal47 - /** - * Displays the attributes of the student that the user has chosen to edit, and prints the options available for - * editing. - * Allows user to select options for editing, for example, editing the saved phone number. - * The user can exit the edit state by pressing enter. - * - * @param in The scanner object to read user input. - * @param student The student that the user has chosen to edit. - */ - //@@author blackmirag3 - private static void editStudentAttributes(Scanner in, Student student) { + private static void editStudentDetails(Scanner in, Student student) { + StudentAttributes attributes = student.getAttributes(); - ViewStudent.showAttributes(attributes); + ViewStudent.showStudentInfo(student); + UI.printEditPrompt(); while (true) { - UI.printEditPrompt(); String command = in.nextLine().trim(); + if (command.isBlank()) { - System.out.println("Exiting edit"); + System.out.println("Exiting edit."); UI.printDivider(); return; } switch (command) { - case ADD: + case ONE: AddStudent.addSubject(in, attributes); student.setAttributes(attributes); - break; + return; - case EDIT: - editAttribute(in, attributes); - break; + case TWO: + editSubject(in, attributes); + return; - case DELETE: - deleteAttribute(in, attributes); - break; + case THREE: + deleteSubject(in, attributes); + return; - // @@author Cryolian - case NUMBER: + case FOUR: editNumber(in, attributes); - break; + return; - case PAYMENT: + case FIVE: editPaymentDate(in, attributes); - break; + return; - case REMARKS: + case SIX: editRemarks(in, attributes); - break; + return; default: break; } - } } @@ -216,42 +190,79 @@ private static void openNumberEditInterface(Scanner in, StudentAttributes attrib * @param attributes The StudentAttributes object to store the attributes of the * student. */ - private static void editAttribute(Scanner in, StudentAttributes attributes) { + private static void editSubject(Scanner in, StudentAttributes attributes) { - while (true) { + SubjectGrade currentSubject = promptForSubject(in, attributes); + updateSubjectName(in, attributes, currentSubject); + updateSubjectGrade(in, currentSubject); + updateSubjectAttendance(in, currentSubject); + //System.out.println("Subject updated."); + } + + private static void updateSubjectAttendance(Scanner in, SubjectGrade currentSubject) { + + if (currentSubject == null) { + return; + } + int newClassesAttended = AddStudent.promptForClassesAttended(in); + currentSubject.setClassesAttended(newClassesAttended); + } + + private static void updateSubjectGrade(Scanner in, SubjectGrade currentSubject) { + + if (currentSubject == null) { + return; + } + double newGrade = InputParsing.promptForGrade(in); + if (newGrade != -1) { + currentSubject.setGrade(newGrade); + } + } + + private static SubjectGrade promptForSubject(Scanner in, StudentAttributes attributes) { + while (true) { System.out.print("Subject to edit (enter nothing to exit): "); String subjectToFind = in.nextLine().trim(); + //early exit clause if (subjectToFind.isBlank()) { System.out.println("No subject edited."); - return; + return null; } SubjectGrade currentSubject = attributes.findSubject(subjectToFind); + + if (currentSubject == null) { + System.out.println("Subject not found"); + + } else { + return currentSubject; + } + } + } - if (currentSubject != null) { - System.out.print("New subject name (enter nothing to skip): "); - String newName = in.nextLine().trim(); - - if (!newName.isBlank()) { - currentSubject.setSubject(newName); - } - - double newGrade = InputParsing.promptForGrade(in); - - if (newGrade != -1) { - currentSubject.setGrade(newGrade); - } + private static void updateSubjectName(Scanner in, StudentAttributes attributes, + SubjectGrade currentSubject) { + if (currentSubject == null) { + return; + } + + while (true) { + System.out.print("New subject name (enter nothing to skip): "); + String newName = in.nextLine().trim(); - int newClassesAttended = AddStudent.promptForClassesAttended(in); - currentSubject.setClassesAttended(newClassesAttended); - System.out.println("Subject updated."); + //exit clause + if (newName.isBlank()) { + return; + + } else if (attributes.findSubject(newName) != null) { + UI.printSubjectAlreadyExists(); } else { - System.out.println("Subject not found."); + currentSubject.setSubject(newName); + return; } - } } @@ -264,12 +275,13 @@ private static void editAttribute(Scanner in, StudentAttributes attributes) { * @param attributes The attributes object of the student that the user has chosen to edit. */ //@@author blackmirag3 - private static void deleteAttribute(Scanner in, StudentAttributes attributes) { + private static void deleteSubject(Scanner in, StudentAttributes attributes) { while (true) { System.out.println("Subject to delete (enter blank to exit)"); String subjectToDelete = in.nextLine().trim(); + //exit clause if (subjectToDelete.isBlank()) { System.out.println("no subject deleted"); return; diff --git a/src/main/java/classify/commands/ViewStudent.java b/src/main/java/classify/commands/ViewStudent.java index 75982f274c..d94ce155b3 100644 --- a/src/main/java/classify/commands/ViewStudent.java +++ b/src/main/java/classify/commands/ViewStudent.java @@ -4,6 +4,7 @@ import classify.student.StudentAttributes; import classify.student.SubjectGrade; import classify.ui.UI; +import classify.user.ClassifyExceptions; import classify.user.InputParsing; import java.util.ArrayList; @@ -45,24 +46,36 @@ public static void viewStudent(ArrayList masterStudentList, Scanner in, Student foundStudent = InputParsing.findStudentByName(masterStudentList, name, in); if (foundStudent != null) { - logger.log(Level.INFO, "Viewing student details: " + name); - - UI.printDivider(); - UI.printStudentDetails(); - UI.printStudentName(name); - UI.printStudentDetails(foundStudent); - StudentAttributes attributes = foundStudent.getAttributes(); - showAttributes(attributes); - + showStudentInfo(foundStudent); int totalClassesAttended = getTotalClassesAttended(foundStudent); UI.printTotalClassesAttended(totalClassesAttended); - } else { logger.log(Level.WARNING, "Student not found: " + name); UI.printStudentNotFound(); } } + //@@author blackmirag3 + /*** + * Prints all student info, including details and subjects + * @param foundStudent + */ + + //@@author tayponghee + public static void showStudentInfo(Student foundStudent) { + String name; + name = foundStudent.getName(); + logger.log(Level.INFO, "Viewing student details: " + name); + + UI.printDivider(); + UI.printStudentDetails(); + UI.printStudentName(name); + UI.printStudentDetails(foundStudent); + StudentAttributes attributes = foundStudent.getAttributes(); + showAttributes(attributes); + } + + //@@author tayponghee /** * Calculates the total number of classes attended by the student across all subjects. * If the user does not specify the number of classes the student attended for that subject, i.e. @@ -125,8 +138,8 @@ private static void printSubjectAttributes(List subjectGrades) { } else { UI.println(NO_CLASSES_FOUND); } - - UI.printDivider(); + System.out.println(" "); } + UI.printDivider(); } } diff --git a/src/main/java/classify/data/DataHandler.java b/src/main/java/classify/data/DataHandler.java index f229de3e42..6357a64623 100644 --- a/src/main/java/classify/data/DataHandler.java +++ b/src/main/java/classify/data/DataHandler.java @@ -2,6 +2,7 @@ import classify.commands.Commands; import classify.student.Student; +import classify.student.StudentList; import java.io.IOException; import java.util.ArrayList; @@ -20,10 +21,20 @@ public class DataHandler extends Commands { * * @param list ArrayList containing the current students */ - public static void writeStudentInfo(List list){ + public static void writeStudentInfo(List list) { + System.out.println("DEBUG"); DataWriter.writeStudentInfoFile(list, DATA_DIRECTORY_PATH, DATA_FILE_PATH); } + /*** + * Saves master student list to Student_Information.txt + * Calls the writeStudentInfoFile function to update Student_Information.txt + */ + public static void writeStudentInfo() { + System.out.println("DEBUG"); + DataWriter.writeStudentInfoFile(StudentList.masterStudentList, DATA_DIRECTORY_PATH, DATA_FILE_PATH); + } + /** * This accesses Student_Information.txt and calls the restoreStudentList function * @@ -31,7 +42,7 @@ public static void writeStudentInfo(List list){ * @throws IOException When unable to get the Student_Information.txt file or has any input errors */ public static void readStudentInfo(ArrayList list) throws IOException{ - + System.out.println("Trying to load Student info"); DataWriter.createParentFileFolder(DATA_DIRECTORY_PATH); DataReader.initialiseData(list, DATA_FILE_PATH); diff --git a/src/main/java/classify/student/StudentAttributes.java b/src/main/java/classify/student/StudentAttributes.java index 5b3ab4ae74..fdbb960aa4 100644 --- a/src/main/java/classify/student/StudentAttributes.java +++ b/src/main/java/classify/student/StudentAttributes.java @@ -57,7 +57,7 @@ public SubjectGrade findSubject(String subjectName) { for (SubjectGrade subjectGrade : subjectGrades) { String currentSubjectName = subjectGrade.getSubject(); - if (currentSubjectName.equals(subjectName)) { + if (currentSubjectName.equalsIgnoreCase(subjectName)) { return subjectGrade; } } diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 7877919bbe..90d973634b 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -10,9 +10,14 @@ public class UI { "attended across all subjects: "; private static final String EMPTY_SUBJECT_ERROR = "No subjects and grades found for this student."; private static final String NULL_ATTRIBUTE_ERROR = "No attributes found for this student."; - private static final String EDIT_PROMPT = "How would you like to update a student's subject? (enter blank to exit)"; - private static final String EDIT_TYPES_PROMPT = "Add(subject), Edit(subject), Number, Remarks, Payment " - + "or Delete(subject): "; + private static final String EDIT_COMMAND_PROMPT = "How would you like to edit student? Enter index (blank to exit):"; + private static final String EDIT_COMMAND_ADD_SUBJECT_PROMPT = "1. Add subject"; + private static final String EDIT_COMMAND_MODIFY_SUBJECT_PROMPT = "2. Modify subject"; + private static final String EDIT_COMMAND_DELETE_SUBJECT_PROMPT = "3. Delete subject"; + private static final String EDIT_COMMAND_MODIFY_PHONE_NUMBER_PROMPT = "4. Modify phone number"; + private static final String EDIT_COMMAND_MODIFY_REMARKS_PROMPT = "5. Modify remarks"; + private static final String EDIT_COMMAND_MODIFY_PAYMENT_DATE_PROMPT = "6. Modify payment date"; + private static final String EDIT_COMMAND_DELETED_SUBJECT_MESSAGE = "Subject deleted successfully!"; private static final String EMPTY_LIST_ERROR = "Currently no students in list."; private static final String VALID_NUMBER_ERROR = "A valid number was not entered. Please input a valid number. "; private static final String PHONE_NUMBER_PROMPT = "Please input a valid phone number: "; @@ -38,6 +43,7 @@ public class UI { private static final String CLASSIFY_GOODBYE_MESSAGE = "Hope you've had a productive day. See you again! Goodbye!"; private static final String WRONG_INPUT_MESSAGE = "No such command, type \"help\" to view all commands"; //@@author blackmirag3 + private static final String WHAT_ELSE_CAN_I_DO_FOR_YOU_TODAY = "What else can I do for you today?"; private static final String STUDENT_DETAILS_PROMPT = "Enter student details: "; private static final String STUDENT_NAME_PROMPT = "Enter student name: "; private static final String STUDENT_DETAILS_MESSAGE = "Student details: "; @@ -162,6 +168,7 @@ public static void printDivider() { public static void printWelcomeMessage() { printDivider(); System.out.println(WELCOME_TO_CLASSIFY); + System.out.println(WHAT_CAN_I_DO_FOR_YOU_TODAY); } /** @@ -173,8 +180,8 @@ public static void printEndConversation() { } //@@author blackmirag3 - public static void printUserPrompt() { - System.out.println(WHAT_CAN_I_DO_FOR_YOU_TODAY); + public static void printSubsequentUserPrompt() { + System.out.println(WHAT_ELSE_CAN_I_DO_FOR_YOU_TODAY); printDivider(); } public static void printWrongInput() { @@ -194,10 +201,14 @@ public static void printStudentDetails() { System.out.println(STUDENT_DETAILS_MESSAGE); } + /*** + * Print students's details + * @param student Student instance of whom details to print + */ public static void printStudentDetails(Student student) { - System.out.println(STUDENT_PHONE_MESSAGE + student.getAttributes().getPhoneNumber() + "\n"); - System.out.println(STUDENT_GENDER_MESSAGE + student.getAttributes().getGender() + "\n"); - System.out.println(STUDENT_PAYMENT_MESSAGE + student.getAttributes().getLastPaymentDate() + "\n"); + System.out.println(STUDENT_PHONE_MESSAGE + student.getAttributes().getPhoneNumber()); + System.out.println(STUDENT_GENDER_MESSAGE + student.getAttributes().getGender()); + System.out.println(STUDENT_PAYMENT_MESSAGE + student.getAttributes().getLastPaymentDate()); System.out.println(STUDENT_REMARKS_MESSAGE + student.getAttributes().getRemarks() + "\n"); } @@ -211,38 +222,85 @@ public static void printStudentName(Student student) { } //@@author blackmirag3 + + /*** + * Print message for successful subject deletion under edit command. + */ + public static void printSubjectDeleted() { + System.out.println(EDIT_COMMAND_DELETED_SUBJECT_MESSAGE); + } + + /*** + * Print prompt for classes attended + */ public static void printClassesAttendedPrompt() { System.out.println(CLASSES_ATTENDED_PROMPT); } + /*** + * Print attendance count + * @param attendance int containing attendance count + */ public static void printClassesAttended(int attendance) { System.out.println(CLASSES_ATTENDED_MESSAGE + attendance); } + /*** + * Print student not found message. + */ public static void printStudentNotFound() { System.out.println(STUDENT_NOT_FOUND_MESSAGE); } + /*** + * Print student added message. + */ public static void printStudentAdded() { System.out.println(STUDENT_ADDED_MESSAGE); } + /*** + * Print deleted student message. + */ public static void printStudentDeleted() { System.out.println(STUDENT_DELETED_MESSAGE); } + /*** + * Prints student's name + * @param name String containing student's name. + */ public static void printSubjectName(String name) { System.out.println(SUBJECT_MESSAGE + name); } + /*** + * Prints student grades + * @param grades Double containing students grade to print. + */ public static void printStudentGrades(Double grades) { System.out.println(STUDENT_GRADES_MESSAGE + grades); } + /*** + * Prints prompt for user to enter student grade. + */ public static void printStudentGradesPrompt() { System.out.println(STUDENT_GRADES_PROMPT); } + /*** + * Prints prompts for edit student command. + */ + public static void printEditPrompt() { + System.out.println(EDIT_COMMAND_PROMPT); + System.out.println(EDIT_COMMAND_ADD_SUBJECT_PROMPT); + System.out.println(EDIT_COMMAND_MODIFY_SUBJECT_PROMPT); + System.out.println(EDIT_COMMAND_DELETE_SUBJECT_PROMPT); + System.out.println(EDIT_COMMAND_MODIFY_PHONE_NUMBER_PROMPT); + System.out.println(EDIT_COMMAND_MODIFY_PAYMENT_DATE_PROMPT); + System.out.println(EDIT_COMMAND_MODIFY_REMARKS_PROMPT); + } //@@ author tayponghee public static void printStudentList(ArrayList students) { @@ -287,11 +345,6 @@ public static void printEmptyListError() { System.out.println(EMPTY_LIST_ERROR); } - public static void printEditPrompt() { - System.out.println(EDIT_PROMPT); - System.out.println(EDIT_TYPES_PROMPT); - } - public static void printEmptySubjectError() { System.out.println(EMPTY_SUBJECT_ERROR); } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 1b2631c836..8c202f7645 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -19,7 +19,7 @@ import java.util.logging.Level; import java.util.logging.Logger; -public class InputParsing { +public class InputParsing { public static final Logger LOGGER = Logger.getLogger(InputParsing.class.getName()); private static final String EARLIER_POSSIBLE_DATE = "1970-01-01"; private static final String DEFAULT_STRING_VALUE = "Unknown"; @@ -114,7 +114,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas //@@author blackmirag3 case EDIT: - EditStudent.editStudent(masterStudentList, in, userCommand[1]); + EditStudent.editStudent(in, userCommand[1]); break; case ARCHIVE: From ae7694b748740c53901611a08946b4dd9a1f3d74 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Mon, 8 Apr 2024 04:41:27 +0800 Subject: [PATCH 240/503] Fix edit subject command --- docs/UserGuide.md | 58 +++++++++++-------- .../java/classify/commands/EditStudent.java | 11 +++- .../java/classify/commands/ViewStudent.java | 1 - src/main/java/classify/data/DataHandler.java | 2 - src/main/java/classify/ui/UI.java | 3 +- src/main/java/classify/user/InputParsing.java | 8 ++- 6 files changed, 51 insertions(+), 32 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index a6e97e34d9..3deb1495a3 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -173,41 +173,49 @@ Classes Attended: 1 ``` ### - Edit details of a student `edit` -Edit a student's details. Allows the user to do edit [student] or just edit. +Edit a student's details and subjects. Allows the user to do edit [student] or just edit. Format: `edit` or `edit NAME` -Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. +If user has not entered a name, they will be prompted to input a name. +If the name input matches that of an existing student, edit mode will be entered for that student. +A list of actions will be printed and user can enter the respective index to select action to take. +Each action has its own step by step prompts for user to follow. ``` Example: -edit -Name of student to edit (enter blank to exit): -toad +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Welcome to Classify! +What can I do for you today? +>> edit +Name of student to edit (blank to exit): +>> vincent +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Student details: +Name: Vincent + +Phone Number: 99999999 +Gender: Unknown +Last Payment Date: 2024-04-08 +Remarks: Unknown + No subjects and grades found for this student. -How would you like to update a student's subject? (enter blank to exit) -Add(subject), Edit(subject), Number, Remarks, Payment or Delete(subject): -add -Subject (enter nothing to skip): Math +How would you like to edit student?Enter index (blank to exit): +1. Add subject +2. Modify subject +3. Delete subject +4. Modify phone number +6. Modify payment date +5. Modify remarks +>> 1 +Subject (enter nothing to skip): PE Current marks out of 100 (blank to skip) : -95 +>> 1 Enter Classes Attended (blank to skip): -11 +>> 10 Do you want to add another subject and grade? (yes/no) -no -How would you like to update a student's subject? (enter blank to exit) -Add(subject), Edit(subject), Number, Remarks, Payment or Delete(subject): -payment -Current stored date: 12/12/2023 -Please input their last payment date in the format of YYYY-MM-DD. Enter blank to input today's date. - -Apr 03, 2024 8:09:34 PM classify.user.InputParsing parseDateFromString -INFO: Storing today as the last payment date. - -How would you like to update a student's subject? (enter blank to exit) -Add(subject), Edit(subject), Number, Remarks, Payment or Delete(subject): - -Exiting edit +>> no +What else can I do for you today? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index 80d835e762..daad9ce2ee 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -97,6 +97,7 @@ private static void editStudentDetails(Scanner in, Student student) { default: break; } + DataHandler.writeStudentInfo(); } } @@ -255,8 +256,14 @@ private static void updateSubjectName(Scanner in, StudentAttributes attributes, //exit clause if (newName.isBlank()) { return; - - } else if (attributes.findSubject(newName) != null) { + } + + SubjectGrade foundSubject = attributes.findSubject(newName); + + if (foundSubject == currentSubject) { + System.out.println("New subject name same as current."); + + } else if (foundSubject != null) { UI.printSubjectAlreadyExists(); } else { diff --git a/src/main/java/classify/commands/ViewStudent.java b/src/main/java/classify/commands/ViewStudent.java index d94ce155b3..7e73cb4236 100644 --- a/src/main/java/classify/commands/ViewStudent.java +++ b/src/main/java/classify/commands/ViewStudent.java @@ -4,7 +4,6 @@ import classify.student.StudentAttributes; import classify.student.SubjectGrade; import classify.ui.UI; -import classify.user.ClassifyExceptions; import classify.user.InputParsing; import java.util.ArrayList; diff --git a/src/main/java/classify/data/DataHandler.java b/src/main/java/classify/data/DataHandler.java index 6357a64623..02c8f373c9 100644 --- a/src/main/java/classify/data/DataHandler.java +++ b/src/main/java/classify/data/DataHandler.java @@ -22,7 +22,6 @@ public class DataHandler extends Commands { * @param list ArrayList containing the current students */ public static void writeStudentInfo(List list) { - System.out.println("DEBUG"); DataWriter.writeStudentInfoFile(list, DATA_DIRECTORY_PATH, DATA_FILE_PATH); } @@ -31,7 +30,6 @@ public static void writeStudentInfo(List list) { * Calls the writeStudentInfoFile function to update Student_Information.txt */ public static void writeStudentInfo() { - System.out.println("DEBUG"); DataWriter.writeStudentInfoFile(StudentList.masterStudentList, DATA_DIRECTORY_PATH, DATA_FILE_PATH); } diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 90d973634b..a906dc0960 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -10,7 +10,8 @@ public class UI { "attended across all subjects: "; private static final String EMPTY_SUBJECT_ERROR = "No subjects and grades found for this student."; private static final String NULL_ATTRIBUTE_ERROR = "No attributes found for this student."; - private static final String EDIT_COMMAND_PROMPT = "How would you like to edit student? Enter index (blank to exit):"; + private static final String EDIT_COMMAND_PROMPT = "How would you like to edit student?" + + "Enter index (blank to exit):"; private static final String EDIT_COMMAND_ADD_SUBJECT_PROMPT = "1. Add subject"; private static final String EDIT_COMMAND_MODIFY_SUBJECT_PROMPT = "2. Modify subject"; private static final String EDIT_COMMAND_DELETE_SUBJECT_PROMPT = "3. Delete subject"; diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 8c202f7645..b2c8bf3a67 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -460,7 +460,13 @@ public static String readInString(Scanner in) { } - + //@@author blackmirag3 + + /** + * Prompts for date input and parses input into LocalDate type + * @param in Scanner to take in user input + * @return paymentDate containing date input converted from string + */ //@@author Cryolian public static LocalDate readInDate(Scanner in) { From 124a9f2df63df0abf8b9b9bcf925035ab1347b96 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Mon, 8 Apr 2024 09:17:10 +0800 Subject: [PATCH 241/503] Update FAQ --- docs/UserGuide.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index a6e97e34d9..8b02b4749c 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -298,7 +298,11 @@ Sort complete! **Q**: What inputs are not allowed? **A**: The inputs that are banned (which are used for file saving) are `#` and `~`, and in all cases except for dates, `-`. -In the event you choose to continue with using these characters, the user would have to the behaviour that follows (replacing them with other characters) and hence has been warned. + +**Q**: (Follow up from above) Why are other special characters not banned? + +**A**: Due to the ever-changing climate of what is considered a name (and more), we have limited the bans to 3 special characters above only. In the event your name or other identification metrics contains `#`, `~` or `-`, we seek for your understanding. + ## Command Summary From 76878bd62e30be60f4c7a0a9e2f063ca424335db Mon Sep 17 00:00:00 2001 From: alalal47 Date: Mon, 8 Apr 2024 19:40:09 +0800 Subject: [PATCH 242/503] Add PPP wip for alalal47 --- docs/team/alalal47.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 docs/team/alalal47.md diff --git a/docs/team/alalal47.md b/docs/team/alalal47.md new file mode 100644 index 0000000000..4bb92f1ecb --- /dev/null +++ b/docs/team/alalal47.md @@ -0,0 +1,39 @@ +# alalal47 - Project Portfolio Page + +## Overview +Classify is a CLI based desktop application used for Tuition Centres to allow for easier management of their enrolled students. +From allowing users to add new students to sorting them based on their last paid date, Classify is the one-stop app that +all Tuition Centres can employ for ease of student management. + +### Summary of Contributions +- #### Code contributed - [Link to Reposense contribution graph](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=alalal47&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2024-02-23&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) + +- #### Enhancements implemented + - **Feature: Allow User Input to be in the form of command or command [flag]** + - Ensures that experienced Classify users will be to make use of its features more seamlessly, while beginners are guided through each step. + + - **Feature: Delete a student from the master list** + - Along with the add feature, the other crucial feature that composes Classify's basic functionality. + - Above being a simple delete feature, also implements a recently deleted list which is only cleared at the end of every session, allowing the user to restore accidental deletes. + + - **Feature: Restore a student deleted in the current session** + - Works in tandem with the delete function to ensure that users do not have to re-add all the student information in the case of an accidental or unwanted deletion. + + - **Feature: Undo last deletion in the current session** + - A more convenient way for users to use the restore function if they immediately want to reverse a deletion before any other deletes have been made. + +- #### Contributions to the [UG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/UserGuide.md) + - Wrote the Usage guide for the edit, delete, restore, undo and sort features. + +- #### Contributions to the [DG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/DeveloperGuide.md) + - Wrote the instructions for manual testing. + +- #### Contributions to team based tasks + - Created issues on GitHub for tasks that I felt needed to be completed. + - Participated in bug-testing before the releases of jar files. + - Creating shared google docs for user stories and other deliverables before the start of TP. + +- #### Review/mentoring contributions + - **Links to some PRs reviewed** + - [PR1](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/148) + - [PR2](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/164) \ No newline at end of file From 618354a7f518ea8bf9ca87fabf75bac285221bdb Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Tue, 9 Apr 2024 00:30:07 +0800 Subject: [PATCH 243/503] Add basic PPP --- docs/team/parthgandhinus.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 docs/team/parthgandhinus.md diff --git a/docs/team/parthgandhinus.md b/docs/team/parthgandhinus.md new file mode 100644 index 0000000000..8c65210585 --- /dev/null +++ b/docs/team/parthgandhinus.md @@ -0,0 +1,12 @@ +# Gandhi Parth Sanjay's Project Portfolio Page + +## Project: Classify + +Classify is a desktop application used for Tuition Centres to allow for easier management of their enrolled students. +From allowing users to add new students to sorting them based on their last paid date, Classify is the one-stop app that +all Tuition Centres can employ for ease of student management. To use the app, users can interact with it using CLI. +Overall, the code base has more than 3kLoC, and is written in Java. + +Given below are my contributions to the project: + +**Code contributed:** [Link to Reposense contribution graph](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=ParthGandhiNUS&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2024-02-23&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) \ No newline at end of file From 23eb43c4c893d9172de826db6585c9a4e88f8cfd Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Tue, 9 Apr 2024 00:30:31 +0800 Subject: [PATCH 244/503] Update Author Tags --- src/main/java/classify/data/DataHandler.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/classify/data/DataHandler.java b/src/main/java/classify/data/DataHandler.java index f229de3e42..a3d714c823 100644 --- a/src/main/java/classify/data/DataHandler.java +++ b/src/main/java/classify/data/DataHandler.java @@ -9,11 +9,14 @@ //@@author blackmirag3 public class DataHandler extends Commands { + //@@author ParthGandhiNUS private static final String DATA_DIRECTORY_PATH = "data/studentInfo"; private static final String DATA_FILE_PATH = DATA_DIRECTORY_PATH + "/Student_Information.txt"; + //@@author blackmirag3 private static final String ARCHIVE_DIRECTORY_PATH = "data/archive"; private static final String ARCHIVE_FILE_PATH = ARCHIVE_DIRECTORY_PATH + "/student_archive.txt"; + //@@author ParthGandhiNUS /** * Function which is called to generate an arrayList "lines" which updates according to the users' inputs. * Calls the writeStudentInfoFile function to update Student_Information.txt @@ -37,6 +40,7 @@ public static void readStudentInfo(ArrayList list) throws IOException{ DataReader.initialiseData(list, DATA_FILE_PATH); } + //@@author blackmirag3 /** * writes student info arraylist into archive file and creates new archive file if one is not found * From 4e9a156d3a13c8ca97112686eb86ec4190e1108e Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Tue, 9 Apr 2024 00:30:58 +0800 Subject: [PATCH 245/503] Remove magic literals in DataReader file --- src/main/java/classify/data/DataReader.java | 31 +++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 0a8b62dcab..0dc88f9638 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -25,6 +25,15 @@ //@@author ParthGandhiNUS public class DataReader { + private static final String MAIN_REGEX = "~~"; + private static final String SUBJECT_REGEX = "#--#"; + private static final String SUBJECT_INFO_REGEX = "##"; + private static final Integer ZERO = 0; + private static final Integer ONE = 1; + private static final Integer TWO = 2; + private static final Integer THREE = 3; + private static final Integer FOUR = 4; + private static final Integer FIVE = 5; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); public static Scanner in = new Scanner(System.in); @@ -40,19 +49,19 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Tue, 9 Apr 2024 01:04:51 +0800 Subject: [PATCH 246/503] Refactor code --- src/main/java/classify/ui/DataUI.java | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/main/java/classify/ui/DataUI.java b/src/main/java/classify/ui/DataUI.java index e2ce08da0a..53151271f9 100644 --- a/src/main/java/classify/ui/DataUI.java +++ b/src/main/java/classify/ui/DataUI.java @@ -12,6 +12,12 @@ public class DataUI extends UI { private static final String LOAD_DATA_SUCCESS_MESSAGE = "Data loaded sucessfully!"; private static final String UPDATE_SUCCESS_MESSAGE = "Data update success!"; private static final String FILE_IO_ERROR_MESSAGE = "File IO Error."; + private static final String PHONE_NUMBER_PARSE_ERROR = "Error parsing the phone number."; + private static final String NAME_NUMBER_PAIR = "Existing name and number pair found"; + private static final String INVALID_CHARACTER ="Skipping invalid save entry."; + private static final String LAST_PAYMENT_DATE_ERROR ="Error parsing the last payment date."; + private static final String NO_SUBJECT_DATA ="Student does not have any subjects currently!"; + private static final String INDEX_OUT_OF_BOUNDS = "Error reading in subjects data."; //@@author blackmirag3 public static void printLoadSuccess() { @@ -46,4 +52,29 @@ public static void printCreateFailure() { public static void printRetrieveData() { System.out.println(RETRIEVING_DATA_MESSAGE); } + + //@@author ParthGandhiNUS + public static void phoneNumberParsingError() { + System.out.println(PHONE_NUMBER_PARSE_ERROR); + } + + public static void nameNumberPair() { + System.out.println(NAME_NUMBER_PAIR); + } + + public static void invalidCharacterExceptionMessage() { + System.out.println(INVALID_CHARACTER); + } + + public static void lastPaymentDateParseExceptionMessage() { + System.out.println(LAST_PAYMENT_DATE_ERROR); + } + + public static void noSubjectMessage() { + System.out.println(NO_SUBJECT_DATA); + } + + public static void arrayIndexOutOfBoundsMessage() { + System.out.println(INDEX_OUT_OF_BOUNDS); + } } From 11e60f9bdf1398aac16257a9e6ee057fb6d3e0f7 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Tue, 9 Apr 2024 01:06:50 +0800 Subject: [PATCH 247/503] Edit code for reading in students with no subject data --- src/main/java/classify/data/DataReader.java | 41 ++++++++++++--------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 0dc88f9638..459b985d56 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -41,6 +41,7 @@ public class DataReader { /** * Method restores the previous student list by accessing the * line-by-line information in the Student_Information.txt + * All information about the student is updated. * * @param studentFileInput Line-by-line information of strings in the Student_Information.txt * @param masterStudentList The list of all students @@ -60,7 +61,6 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Tue, 9 Apr 2024 09:23:05 +0800 Subject: [PATCH 248/503] Add invalid character checks for reading data --- src/main/java/classify/data/DataReader.java | 32 +++++++++++++-------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 459b985d56..ca2480aa77 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -61,18 +61,22 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Tue, 9 Apr 2024 10:01:55 +0800 Subject: [PATCH 249/503] Add invalid character checks for add and edit --- .../java/classify/commands/AddStudent.java | 2 +- .../java/classify/commands/EditStudent.java | 30 ++++++++++++++++--- src/main/java/classify/ui/UI.java | 1 + src/main/java/classify/user/InputParsing.java | 14 ++++----- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 67a3a425a1..d2f2b8a52a 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -73,7 +73,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, StudentList.checkNameNumberPair(StudentList.archiveList, name, number); } catch (NameNumberMatchException e) { UI.println("Student and Phone number pair found. If not found in the list, " + - "please restore the student instead."); + "please restore or unarchive the student instead."); UI.printDivider(); return; } catch (NullPointerException e) { diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index d77e80ecf2..cdf2a76749 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -1,5 +1,7 @@ package classify.commands; +import static classify.user.InputParsing.readInString; + import java.util.ArrayList; import java.util.Scanner; @@ -87,11 +89,15 @@ private static void editStudentDetails(Scanner in, Student student) { return; case FIVE: - editPaymentDate(in, attributes); + editRemarks(in, attributes); return; case SIX: - editRemarks(in, attributes); + editPaymentDate(in, attributes); + return; + + case "7": + editGender(in, attributes); return; default: @@ -137,6 +143,22 @@ private static void editRemarks(Scanner in, StudentAttributes attributes) { UI.printDivider(); } + private static void editGender(Scanner in, StudentAttributes attributes) { + UI.println(attributes.getGender()); + UI.printDivider(); + UI.println("Enter blank to stop editing."); + + String newGender = InputParsing.readInString(in); + + if (newGender.equals(DEFAULT_STRING_VALUE)) { + return; + } + + attributes.setGender(newGender); + UI.printDivider(); + + } + //@@author alalal47 /** * Edits the phone number for a particular student @@ -253,10 +275,10 @@ private static void updateSubjectName(Scanner in, StudentAttributes attributes, while (true) { System.out.print("New subject name (enter nothing to skip): "); - String newName = in.nextLine().trim(); + String newName = readInString(in); //exit clause - if (newName.isBlank()) { + if (newName.isBlank() || newName.equals(DEFAULT_STRING_VALUE)) { return; } diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 6209c95ac5..0987f9017e 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -301,6 +301,7 @@ public static void printEditPrompt() { System.out.println(EDIT_COMMAND_MODIFY_PHONE_NUMBER_PROMPT); System.out.println(EDIT_COMMAND_MODIFY_PAYMENT_DATE_PROMPT); System.out.println(EDIT_COMMAND_MODIFY_REMARKS_PROMPT); + System.out.println("6. Edit Gender."); } //@@ author tayponghee diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 1aeb60bef9..182a8ec8c4 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -452,12 +452,12 @@ public static String readInString(Scanner in) { if (string.isBlank()) { return DEFAULT_STRING_VALUE; } - string = string.replace('#', ' '); - string = string.replace('-', ' '); - string = string.replace('~', ' '); - string = string.trim(); - - if (string.isBlank()) { + + try { + InputParsing.checkForSpecialCharacters(string); + } catch (Exception e) { + UI.println("Invalid characters found"); + UI.println("Storing 'Unknown' or cancelling edit"); return DEFAULT_STRING_VALUE; } @@ -478,7 +478,7 @@ public static LocalDate readInDate(Scanner in) { UI.promptForLastPaymentDate(); do { - userInput = in.nextLine(); + userInput = in.nextLine().trim(); paymentDate = parseDateFromString(userInput); } while (!isDateValid(paymentDate)); From 2b3f3ef3561675f66f5ad2de261ae8805eeba4c8 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Tue, 9 Apr 2024 10:11:53 +0800 Subject: [PATCH 250/503] Fix printing issue --- src/main/java/classify/ui/UI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 0987f9017e..e02d960734 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -301,7 +301,7 @@ public static void printEditPrompt() { System.out.println(EDIT_COMMAND_MODIFY_PHONE_NUMBER_PROMPT); System.out.println(EDIT_COMMAND_MODIFY_PAYMENT_DATE_PROMPT); System.out.println(EDIT_COMMAND_MODIFY_REMARKS_PROMPT); - System.out.println("6. Edit Gender."); + System.out.println("7. Edit Gender."); } //@@ author tayponghee From 56d31d9e91a18749d678ff59248a61e67fdd0adb Mon Sep 17 00:00:00 2001 From: Cryolian Date: Tue, 9 Apr 2024 10:30:20 +0800 Subject: [PATCH 251/503] Fix major bugs --- .../java/classify/commands/AddStudent.java | 5 +++-- .../classify/commands/DeleteCommands.java | 5 +++-- .../java/classify/commands/EditStudent.java | 19 ++++++++++--------- src/main/java/classify/data/DataReader.java | 1 - src/main/java/classify/user/InputParsing.java | 2 +- 5 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index d2f2b8a52a..703f4c1ed6 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -15,6 +15,7 @@ import java.util.logging.Level; import static classify.user.InputParsing.LOGGER; +import static classify.user.InputParsing.readInString; //@@author tayponghee public class AddStudent { @@ -192,9 +193,9 @@ public static void addSubject(Scanner in, StudentAttributes attributes) { while (true) { //@@ author blackmirag3 System.out.print(SUBJECT_ENTER_NOTHING_TO_SKIP); - String subject = in.nextLine().trim(); + String subject = readInString(in); - if (subject.isBlank()) { + if (subject.isBlank() || subject.equals(InputParsing.DEFAULT_STRING_VALUE)) { UI.printNoSubjectsAdded(); break; diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index 2f45bdfa3a..2494eb7da6 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -53,8 +53,8 @@ public static void deleteStudent(ArrayList masterStudentList, ArrayList } /** - * Removes a student from the list. - * Adds the removed student to a recently deleted list, where the student's information can be recovered + * Restores a student from the list. + * Adds the removed student back from the recently deleted list to the masterlist. * * @param masterStudentList The list of all students. * @param recentlyDeletedList The list of recently deleted students @@ -86,6 +86,7 @@ public static void restoreStudent(ArrayList masterStudentList, ArrayLis UI.printDivider(); masterStudentList.add(student); recentlyDeletedList.remove(student); + DataHandler.writeStudentInfo(); //@@author Cryolian } catch (NameNumberMatchException e) { diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index cdf2a76749..0d88a33aad 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -16,6 +16,7 @@ //@@author blackmirag3 public class EditStudent extends Commands { + private static final String SEVEN = "7"; private static final String ONE = "1"; private static final String TWO = "2"; private static final String THREE = "3"; @@ -58,9 +59,9 @@ private static void editStudentDetails(Scanner in, Student student) { StudentAttributes attributes = student.getAttributes(); ViewStudent.showStudentInfo(student); - UI.printEditPrompt(); while (true) { + UI.printEditPrompt(); String command = in.nextLine().trim(); if (command.isBlank()) { @@ -74,31 +75,31 @@ private static void editStudentDetails(Scanner in, Student student) { case ONE: AddStudent.addSubject(in, attributes); student.setAttributes(attributes); - return; + break; case TWO: editSubject(in, attributes); - return; + break; case THREE: deleteSubject(in, attributes); - return; + break; case FOUR: editNumber(in, attributes); - return; + break; case FIVE: editRemarks(in, attributes); - return; + break; case SIX: editPaymentDate(in, attributes); - return; + break; - case "7": + case SEVEN: editGender(in, attributes); - return; + break; default: break; diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index ca2480aa77..7223bc7224 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -54,7 +54,6 @@ public static void restoreStudentList(String studentFileInput, ArrayList masterStudentList, ArrayList recentlyDeletedList, From cd15c01fbf1d1417c43d5cf43457569287ca7731 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Tue, 9 Apr 2024 10:41:36 +0800 Subject: [PATCH 252/503] Fix bugs --- docs/UserGuide.md | 2 +- src/main/java/classify/data/DataReader.java | 4 ++++ src/main/java/classify/ui/UI.java | 4 ++-- src/main/java/classify/user/InputParsing.java | 4 +++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 4201c44a63..d3f41fa4c2 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -200,7 +200,7 @@ Last Payment Date: 2024-04-08 Remarks: Unknown No subjects and grades found for this student. -How would you like to edit student?Enter index (blank to exit): +How would you like to edit student? Enter index (blank to exit): 1. Add subject 2. Modify subject 3. Delete subject diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 7223bc7224..8370991967 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -48,6 +48,10 @@ public class DataReader { */ public static void restoreStudentList(String studentFileInput, ArrayList masterStudentList ){ + if (studentFileInput.trim().isBlank()) { + return; + } + if (studentFileInput != null){ String [] inputArr = studentFileInput.split(MAIN_REGEX); diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index e02d960734..93edde64c2 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -10,7 +10,7 @@ public class UI { "attended across all subjects: "; private static final String EMPTY_SUBJECT_ERROR = "No subjects and grades found for this student."; private static final String NULL_ATTRIBUTE_ERROR = "No attributes found for this student."; - private static final String EDIT_COMMAND_PROMPT = "How would you like to edit student?" + + private static final String EDIT_COMMAND_PROMPT = "How would you like to edit student? " + "Enter index (blank to exit):"; private static final String EDIT_COMMAND_ADD_SUBJECT_PROMPT = "1. Add subject"; private static final String EDIT_COMMAND_MODIFY_SUBJECT_PROMPT = "2. Modify subject"; @@ -299,8 +299,8 @@ public static void printEditPrompt() { System.out.println(EDIT_COMMAND_MODIFY_SUBJECT_PROMPT); System.out.println(EDIT_COMMAND_DELETE_SUBJECT_PROMPT); System.out.println(EDIT_COMMAND_MODIFY_PHONE_NUMBER_PROMPT); - System.out.println(EDIT_COMMAND_MODIFY_PAYMENT_DATE_PROMPT); System.out.println(EDIT_COMMAND_MODIFY_REMARKS_PROMPT); + System.out.println(EDIT_COMMAND_MODIFY_PAYMENT_DATE_PROMPT); System.out.println("7. Edit Gender."); } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 166e0bd2d5..70e8f42df7 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -440,6 +440,8 @@ private static boolean checkNumberValidity(int number) { //@@author ParthGandhiNUS /** * A prompting input to scan in a string from the user input. + * If special characters are found, the default string value + * is returned. * * @param in The scanner class to scan inputs from. * @return "Unknown" if blank was inputted, or the @@ -455,7 +457,7 @@ public static String readInString(Scanner in) { try { InputParsing.checkForSpecialCharacters(string); - } catch (Exception e) { + } catch (InvalidCharacterException e) { UI.println("Invalid characters found"); UI.println("Storing 'Unknown' or cancelling edit"); return DEFAULT_STRING_VALUE; From ac4c98ea9a925a39f77e2fab6d0930abbf148439 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Tue, 9 Apr 2024 10:46:47 +0800 Subject: [PATCH 253/503] Fix checkstyle errors --- src/main/java/classify/data/DataReader.java | 18 +++++++++--------- src/main/java/classify/user/InputParsing.java | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 8370991967..1beef3461d 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -106,15 +106,15 @@ public static void restoreStudentList(String studentFileInput, ArrayList masterStudentList, ArrayList recentlyDeletedList, From de6f5fe5247806b073480cabef14b49ffdc720c4 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Tue, 9 Apr 2024 10:54:42 +0800 Subject: [PATCH 254/503] Add invalid command printing for edit --- src/main/java/classify/commands/EditStudent.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index 0d88a33aad..e5b540c31d 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -102,6 +102,8 @@ private static void editStudentDetails(Scanner in, Student student) { break; default: + UI.println("No such command found. Please try again"); + UI.printDivider(); break; } DataHandler.writeStudentInfo(); From a53bf1593274b22976fec745b336d0d0d7e05aa5 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Tue, 9 Apr 2024 12:58:03 +0800 Subject: [PATCH 255/503] Fix some UMLs --- .../src/InputParsing/InputParsing.png | Bin 21700 -> 22495 bytes .../src/InputParsing/InputParsing.puml | 55 ++++++++++-------- .../InputParsingSequenceDiagram.png | Bin 25816 -> 17659 bytes .../src/InputParsing/SequenceDiagram.puml | 30 ++++------ .../src/StudentSorter/StudentSorter.puml | 1 + docs/team/Cryolian.md | 0 6 files changed, 43 insertions(+), 43 deletions(-) create mode 100644 docs/team/Cryolian.md diff --git a/docs/diagrams/src/InputParsing/InputParsing.png b/docs/diagrams/src/InputParsing/InputParsing.png index 4c0b341f87f2b43e05e31a8ef2d8a4731ffcc20d..77fb48e265048614dfa9c08192bf13095bb4bb35 100644 GIT binary patch literal 22495 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 literal 21700 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 PGnfpXu6{1-oD!M<%&Wmq diff --git a/docs/diagrams/src/InputParsing/InputParsing.puml b/docs/diagrams/src/InputParsing/InputParsing.puml index 10b0ae5f77..5064531269 100644 --- a/docs/diagrams/src/InputParsing/InputParsing.puml +++ b/docs/diagrams/src/InputParsing/InputParsing.puml @@ -1,40 +1,47 @@ @startuml InputParsing +hide circle +note "Inconsequential methods and attributes omitted" as n1 -class Classify { - +class InputParsing { + findStudentByName(masterStudentList:Student[], name:String) } -package user { - class InputParsing { - findStudentByName(masterStudentList:Student[], name:String) - } +class UserInput { - class Ui { +} - } +class AddStudent { + addStudent(:Student); +} - class UserInput { +class ViewStudent { + viewStudent(:Student); +} - } +class EditStudent { + editStudent(:Student); } -package student { - class AddStudent { - addStudent(); - } +class DeleteCommands{ + deleteStudent(:Student); + restoreStudent(:Student); +} - class ViewStudent { - viewStudent(); - } +class ListStudentCommands { + list(:Student[]); } -Classify ..> InputParsing -Classify ..> UserInput -Classify ..> Ui -UserInput ...l> Ui -InputParsing ...r> Ui -InputParsing ..> student +class ArchiveCommands { + archiveStudent(:Student); + unarchiveStudent(:Student); +} -note "Inconsequential methods and attributes omitted" as N1 +InputParsing ..r> UserInput +InputParsing ..> AddStudent +InputParsing ..> ViewStudent +InputParsing ..> EditStudent +InputParsing ..> DeleteCommands +InputParsing ..> ListStudentCommands +InputParsing ..> ArchiveCommands @enduml diff --git a/docs/diagrams/src/InputParsing/InputParsingSequenceDiagram.png b/docs/diagrams/src/InputParsing/InputParsingSequenceDiagram.png index 552c36974bf4d5e48b71c094d66d17c2eef4cce7..6a9db97dfef35e356bf8e16098d3e87b7d444048 100644 GIT binary patch literal 17659 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 diff --git a/docs/diagrams/src/InputParsing/SequenceDiagram.puml b/docs/diagrams/src/InputParsing/SequenceDiagram.puml index 990cf94359..6eafaca9fc 100644 --- a/docs/diagrams/src/InputParsing/SequenceDiagram.puml +++ b/docs/diagrams/src/InputParsing/SequenceDiagram.puml @@ -2,40 +2,32 @@ hide footbox -actor ":User" as u + participant ":UserInput" as UI participant ":InputParsing" as IP -collections ":Commands" as commands -database "masterStudentList:Student[ ]" as msl -participant ":FileIOCommands" as fioc -database "studentInfo.txt" as studentInfo - +participant ":Command" as commands +participant "DataHandler" as fioc -u -> UI : processInput(String) -activate u +-> UI : processInput(String) activate UI -UI -> u : userCommand:String[ ] +<- UI : userCommand:String[ ] deactivate UI -u -> IP : parseUserCommand(userCommand:String[ ]) +-> IP : parseUserCommand(userCommand:String[ ]) activate IP IP -> commands : command to execute activate commands -commands -> msl : update runtime database -activate msl +note over commands + this command class could refer to + AddStudent, EditStudent, or more +end note commands -> fioc : update stored database activate fioc -fioc -> studentInfo : write in msl -activate studentInfo -studentInfo --> fioc -deactivate studentInfo fioc --> commands deactivate fioc -msl --> commands -deactivate msl commands --> IP deactivate commands -IP --> u +<-- IP deactivate IP @enduml diff --git a/docs/diagrams/src/StudentSorter/StudentSorter.puml b/docs/diagrams/src/StudentSorter/StudentSorter.puml index ee6a1c1927..caba7c4fad 100644 --- a/docs/diagrams/src/StudentSorter/StudentSorter.puml +++ b/docs/diagrams/src/StudentSorter/StudentSorter.puml @@ -1,5 +1,6 @@ @startuml StudentSorter skinparam classAttributeIconSize 0 +hide circle class StudentSorter { + NAME: String diff --git a/docs/team/Cryolian.md b/docs/team/Cryolian.md new file mode 100644 index 0000000000..e69de29bb2 From 2765df75ad9c8a31c35cc4f6ad103f7b10721b4f Mon Sep 17 00:00:00 2001 From: Cryolian Date: Tue, 9 Apr 2024 21:03:57 +0800 Subject: [PATCH 256/503] Rearranged constants --- src/main/java/classify/commands/EditStudent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index e5b540c31d..4b224136cb 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -16,13 +16,13 @@ //@@author blackmirag3 public class EditStudent extends Commands { - private static final String SEVEN = "7"; private static final String ONE = "1"; private static final String TWO = "2"; private static final String THREE = "3"; private static final String FOUR = "4"; private static final String FIVE = "5"; private static final String SIX = "6"; + private static final String SEVEN = "7"; private static final String DEFAULT_STRING_VALUE = "Unknown"; public static void editStudent(Scanner in, String name) { From e1d5d0a3963d2bc95b564cf74c599b5f2781cd1d Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Tue, 9 Apr 2024 21:46:27 +0800 Subject: [PATCH 257/503] Add list archive and recently deleted functionality --- .../classify/commands/ArchiveCommands.java | 4 ++ .../java/classify/commands/EditStudent.java | 2 +- .../commands/ListStudentsCommand.java | 43 +++++++++++++++---- src/main/java/classify/ui/UI.java | 9 ++-- src/main/java/classify/user/InputParsing.java | 7 +-- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/main/java/classify/commands/ArchiveCommands.java b/src/main/java/classify/commands/ArchiveCommands.java index 41e602305b..0000a987f8 100644 --- a/src/main/java/classify/commands/ArchiveCommands.java +++ b/src/main/java/classify/commands/ArchiveCommands.java @@ -99,4 +99,8 @@ private static Student getStudent(ArrayList archiveList, String name, S } return student; } + + public static void viewArchive() { + + } } diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index e5b540c31d..4b224136cb 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -16,13 +16,13 @@ //@@author blackmirag3 public class EditStudent extends Commands { - private static final String SEVEN = "7"; private static final String ONE = "1"; private static final String TWO = "2"; private static final String THREE = "3"; private static final String FOUR = "4"; private static final String FIVE = "5"; private static final String SIX = "6"; + private static final String SEVEN = "7"; private static final String DEFAULT_STRING_VALUE = "Unknown"; public static void editStudent(Scanner in, String name) { diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 27c3b422a3..8257a871ca 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -8,11 +8,18 @@ import java.util.ArrayList; import java.util.Scanner; -//@@ author tayponghee +//@@ author blackmirag3 public class ListStudentsCommand { - private static final String ONE = "1"; - private static final String TWO = "2"; + private static final String LIST_ALL = "1"; + private static final String LIST_ALL_WITH_CLASSES = "2"; + private static final String LIST_ARCHIVE = "3"; + private static final String LIST_DELETED = "4"; + private static final String LIST_OF_STUDENTS_IN_ARCHIVE = + "List of students in archive: "; + private static final String LIST_OF_STUDENTS_IN_RECENTLY_DELETED = + "List of students in recently deleted: "; + //@@author tayponghee private static final String FULL_STUDENT_LIST = "Full Student list:"; private static final String LIST_OF_STUDENTS_WITH_TOTAL_CLASSES_ATTENDED = "List of students with total classes attended:"; @@ -28,11 +35,12 @@ public class ListStudentsCommand { * @param in The user's input. * @param subject Optional subject to filter the list of students. */ - public static void chooseListType(ArrayList masterStudentList, Scanner in, String subject) { + public static void chooseListType(ArrayList masterStudentList, ArrayList archiveList, + ArrayList deletedList,Scanner in, String subject) { if (subject != null && !subject.isEmpty()) { listStudentsBySubject(masterStudentList, subject); } else { - listAllStudents(masterStudentList); + listAllStudents(masterStudentList, archiveList, deletedList); } } @@ -65,15 +73,31 @@ public static void listStudentsBySubject(ArrayList masterStudentList, S * * @param masterStudentList The list of all students. */ - private static void listAllStudents(ArrayList masterStudentList) { - UI.printListAllStudentsChoice(); + public static void listAllStudents(ArrayList masterStudentList, + ArrayList archiveList, ArrayList deletedList ) { + UI.printListAllStudentsChoice(); Scanner scanner = new Scanner(System.in); String choice = scanner.nextLine().trim(); //@@ author blackmirag3 switch (choice) { - case ONE: + + case LIST_ARCHIVE: + UI.println(LIST_OF_STUDENTS_IN_ARCHIVE); + + StudentList.printCurrentArrayList(archiveList); + StudentList.printCurrentArrayMessage(archiveList); + break; + + case LIST_DELETED: + UI.println(LIST_OF_STUDENTS_IN_RECENTLY_DELETED); + + StudentList.printCurrentArrayList(deletedList); + StudentList.printCurrentArrayMessage(deletedList); + break; + + case LIST_ALL: UI.println(FULL_STUDENT_LIST); StudentList.printCurrentArrayList(masterStudentList); @@ -84,7 +108,7 @@ private static void listAllStudents(ArrayList masterStudentList) { break; //@@author tayponghee - case TWO: + case LIST_ALL_WITH_CLASSES: UI.println(LIST_OF_STUDENTS_WITH_TOTAL_CLASSES_ATTENDED); listStudentsWithTotalClasses(masterStudentList); @@ -96,6 +120,7 @@ private static void listAllStudents(ArrayList masterStudentList) { } } + //@@author tayponghee /** * Lists all students in the provided list along with their total classes attended. * If the user had left the classes attended blank for that subject, diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 93edde64c2..9e7e4677af 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -61,6 +61,9 @@ public class UI { private static final String DELETE_UNDONE_MESSAGE = "Last delete undone!"; private static final String STUDENT_RESTORED_MESSAGE = "Student has been restored!"; private static final String NO_RECENT_DELETES = "No recent deletes found!"; + private static final String STUDENTS_IN_ARCHIVE = "3. List of students in archive"; + private static final String STUDENTS_IN_DELETED = "4. List of students in recently deleted"; + private static final String ENTER_ONE_TWO_THREE_FOUR = "Enter your choice (1, 2, 3 or 4):"; //@@ author tayponghee private static final String ADD_SUBJECT = "Do you want to add another subject and grade? (yes/no)"; @@ -76,8 +79,6 @@ public class UI { private static final String CHOOSE_THE_TYPE_OF_LIST_TO_DISPLAY = "Choose the type of list to display: (index only)"; private static final String FULL_STUDENT_LIST = "1. Full student list"; private static final String STUDENTS_WITH_TOTAL_CLASSES = "2. List of students with total classes attended"; - private static final String ENTER_ONE_TWO = "Enter your choice (1 or 2):"; - //@@author alalal47 /** * Displays the help message to teach users how to use Classify. @@ -427,6 +428,8 @@ public static void printListAllStudentsChoice () { System.out.println(CHOOSE_THE_TYPE_OF_LIST_TO_DISPLAY); System.out.println(FULL_STUDENT_LIST); System.out.println(STUDENTS_WITH_TOTAL_CLASSES); - System.out.println(ENTER_ONE_TWO); + System.out.println(STUDENTS_IN_ARCHIVE); + System.out.println(STUDENTS_IN_DELETED); + System.out.println(ENTER_ONE_TWO_THREE_FOUR); } } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 6de174cfca..028dc454e0 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -103,7 +103,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas if (userCommand[1] != null) { UI.printInvalidListCommand(); } else { - parseListCommand(masterStudentList, in); + parseListCommand(masterStudentList, archiveList, recentlyDeletedList, in); } break; @@ -143,10 +143,11 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas * @param scanner Scanner used for the chooseListType function */ //@@author tayponghee - public static void parseListCommand(ArrayList masterStudentList, Scanner scanner) { + public static void parseListCommand(ArrayList masterStudentList, ArrayList archiveList + , ArrayList deletedList, Scanner scanner) { UI.printListCommandStart(); String subject = scanner.nextLine().trim(); - ListStudentsCommand.chooseListType(masterStudentList, scanner, subject); + ListStudentsCommand.chooseListType(masterStudentList, archiveList, deletedList, scanner, subject); } /** From 0beb9fa4e7f1ec3ec2727bb2116361cdece9d300 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Tue, 9 Apr 2024 22:11:27 +0800 Subject: [PATCH 258/503] Change constant names --- .../java/classify/commands/EditStudent.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index 4b224136cb..7399bcd57f 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -16,13 +16,13 @@ //@@author blackmirag3 public class EditStudent extends Commands { - private static final String ONE = "1"; - private static final String TWO = "2"; - private static final String THREE = "3"; - private static final String FOUR = "4"; - private static final String FIVE = "5"; - private static final String SIX = "6"; - private static final String SEVEN = "7"; + private static final String ADD_SUBJECT = "1"; + private static final String EDIT_SUBJECT = "2"; + private static final String DELETE_SUBJECT = "3"; + private static final String EDIT_NUMBER = "4"; + private static final String EDIT_REMARKS = "5"; + private static final String EDIT_PAYMENT_DATE = "6"; + private static final String EDIT_GENDER = "7"; private static final String DEFAULT_STRING_VALUE = "Unknown"; public static void editStudent(Scanner in, String name) { @@ -72,32 +72,32 @@ private static void editStudentDetails(Scanner in, Student student) { switch (command) { - case ONE: + case ADD_SUBJECT: AddStudent.addSubject(in, attributes); student.setAttributes(attributes); break; - case TWO: + case EDIT_SUBJECT: editSubject(in, attributes); break; - case THREE: + case DELETE_SUBJECT: deleteSubject(in, attributes); break; - case FOUR: + case EDIT_NUMBER: editNumber(in, attributes); break; - case FIVE: + case EDIT_REMARKS: editRemarks(in, attributes); break; - case SIX: + case EDIT_PAYMENT_DATE: editPaymentDate(in, attributes); break; - case SEVEN: + case EDIT_GENDER: editGender(in, attributes); break; From 9fd61553c2ce5d7ccacfaecae37065835a8db2d6 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Tue, 9 Apr 2024 22:22:46 +0800 Subject: [PATCH 259/503] Fix small typo --- src/main/java/classify/student/StudentList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 45005e9ca2..dff27a29d9 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -109,7 +109,7 @@ public void removeStudent(String name) { * @param studentList List to check through for the name and number. * @param name Name of the student to find. * @param number Phone number of the student to find. - * @throws nameNumberMatchException Thrown if a match is found. + * @throws NameNumberMatchException Thrown if a match is found. */ public static void checkNameNumberPair(ArrayList studentList, String name, int number) throws NameNumberMatchException, NullPointerException { From 0c1a7650e54b5912111d286da191394df9261512 Mon Sep 17 00:00:00 2001 From: Shui Hon Siew Date: Tue, 9 Apr 2024 22:29:25 +0800 Subject: [PATCH 260/503] Add initial test class implementation --- src/test/java/classify/commands/EditTest.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/test/java/classify/commands/EditTest.java diff --git a/src/test/java/classify/commands/EditTest.java b/src/test/java/classify/commands/EditTest.java new file mode 100644 index 0000000000..8b0296d262 --- /dev/null +++ b/src/test/java/classify/commands/EditTest.java @@ -0,0 +1,4 @@ +package classify.commands; + +public class EditTest { +} From 41ee0038ee17911b3962402844e9407987fda01f Mon Sep 17 00:00:00 2001 From: Cryolian Date: Tue, 9 Apr 2024 22:32:30 +0800 Subject: [PATCH 261/503] Add exceptions to remarks when reading in data --- src/main/java/classify/data/DataReader.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 1beef3461d..c4d6037530 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -75,17 +75,21 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Tue, 9 Apr 2024 23:01:30 +0800 Subject: [PATCH 262/503] Update author tags --- src/main/java/classify/Classify.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 1975f08612..cc1b902eb4 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -18,8 +18,9 @@ public class Classify { * @throws IOException Thrown when error reading file. */ public static void main(String[] args) throws IOException { - //@@author blackmirag3 + //@@author ParthGandhiNUS DataHandler.readStudentInfo(StudentList.masterStudentList); + //@@author blackmirag3 DataHandler.readArchive(StudentList.archiveList); //@@author ParthGandhiNUS UI.printWelcomeMessage(); From d1ba0be1e0dae47748fe2584da49bc3ee904d6e7 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Tue, 9 Apr 2024 23:03:16 +0800 Subject: [PATCH 263/503] Refactor restoreStudentList method to ensure readability --- src/main/java/classify/data/DataReader.java | 79 ++++++++++++--------- 1 file changed, 45 insertions(+), 34 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 459b985d56..4efda606e3 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -28,12 +28,15 @@ public class DataReader { private static final String MAIN_REGEX = "~~"; private static final String SUBJECT_REGEX = "#--#"; private static final String SUBJECT_INFO_REGEX = "##"; - private static final Integer ZERO = 0; - private static final Integer ONE = 1; - private static final Integer TWO = 2; - private static final Integer THREE = 3; - private static final Integer FOUR = 4; - private static final Integer FIVE = 5; + private static final Integer NAME = 0; + private static final Integer SUBJECT_NAME = 0; + private static final Integer GENDER = 1; + private static final Integer GRADE_FOR_SUBJECT = 1; + private static final Integer PHONE_NUMBER = 2; + private static final Integer NUMBER_OF_CLASSES_ATTENDED = 2; + private static final Integer LAST_PAYMENT_DATE = 3; + private static final Integer REMARKS = 4; + private static final Integer SUBJECTS = 5; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); public static Scanner in = new Scanner(System.in); @@ -47,26 +50,21 @@ public class DataReader { * @param masterStudentList The list of all students */ public static void restoreStudentList(String studentFileInput, ArrayList masterStudentList ){ - if (studentFileInput != null){ - String [] inputArr = studentFileInput.split(MAIN_REGEX); //Set Name - Student student = new Student(inputArr[ZERO].trim()); + Student student = new Student(inputArr[NAME].trim()); masterStudentList.add(student); - //Set Gender - student.getAttributes().setGender(inputArr[ONE].trim()); - + student.getAttributes().setGender(inputArr[GENDER].trim()); //Set Phone Number try { - int phoneNumber = Integer.parseInt(inputArr[TWO].trim()); + int phoneNumber = Integer.parseInt(inputArr[PHONE_NUMBER].trim()); StudentList.checkNameNumberPair(StudentList.masterStudentList, student.getName(), phoneNumber); StudentList.checkNameNumberPair(StudentList.archiveList, student.getName(), phoneNumber); student.getAttributes().setPhoneNumber(phoneNumber); InputParsing.checkForSpecialCharacters(student.getName()); - } catch (NumberFormatException e) { DataUI.phoneNumberParsingError(); return; @@ -78,38 +76,25 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Tue, 9 Apr 2024 23:20:53 +0800 Subject: [PATCH 264/503] Add AddStudentTest --- docs/team/tayponghee.md | 4 ++ .../java/classify/student/AddStudentTest.java | 67 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 src/test/java/classify/student/AddStudentTest.java diff --git a/docs/team/tayponghee.md b/docs/team/tayponghee.md index a5f8a15cbf..d5505c64da 100644 --- a/docs/team/tayponghee.md +++ b/docs/team/tayponghee.md @@ -50,3 +50,7 @@ Given below are my contributions to the project: * Updating of non-specific documentation, e.g. non-functional requirements * Weekly reminders on deadlines for tasks * Handling of pull requests (Examples: [link 1](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/159) [link 2](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/153) [link 3](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/145)) + * Contributions to Junit tests + * [StudentAttributesTest] + * [StudentSorterTest] + * [SubjectGradeTest] diff --git a/src/test/java/classify/student/AddStudentTest.java b/src/test/java/classify/student/AddStudentTest.java new file mode 100644 index 0000000000..ca2189eb0f --- /dev/null +++ b/src/test/java/classify/student/AddStudentTest.java @@ -0,0 +1,67 @@ +package classify.student; +//@@author tayponghee + +import classify.commands.AddStudent; +import classify.user.InputParsing; +import classify.user.InvalidCharacterException; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.NoSuchElementException; +import java.util.Scanner; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class AddStudentTest { + + private static final String PARTH = "Parth"; + private static final String BANANA_REPUBLIC = "Banana Republic"; + + @Test + void checkForEmptyNameTestName() throws InvalidCharacterException { + ArrayList masterStudentList = new ArrayList<>(); + Scanner scanner = new Scanner(PARTH + "\n"); + + String name = AddStudent.checkForEmptyName(masterStudentList, scanner, null); + + assertEquals(PARTH, name); + } + + @Test + void checkForEmptyNameTestEmpty() { + ArrayList masterStudentList = new ArrayList<>(); + Scanner scanner = new Scanner("\n"); + + boolean exceptionThrown = false; + try { + AddStudent.checkForEmptyName(masterStudentList, scanner, null); + } catch (NoSuchElementException | InvalidCharacterException e) { + exceptionThrown = true; + } + + assertTrue(exceptionThrown); + } + + @Test + void findStudentByNameNonExisting() { + ArrayList masterStudentList = new ArrayList<>(); + Scanner scanner = new Scanner(BANANA_REPUBLIC + "\n"); + + Student foundStudent = InputParsing.findStudentByName(masterStudentList, PARTH, scanner); + + assertNull(foundStudent); + } + + @Test + void findStudentByNameExisting() { + ArrayList masterStudentList = new ArrayList<>(); + Scanner scanner = new Scanner(BANANA_REPUBLIC + "\n"); + + Student foundStudent = InputParsing.findStudentByName(masterStudentList, BANANA_REPUBLIC, scanner); + + assertNull(foundStudent); + } + +} From 1c535426d094e256924e229ba827dd8346d66f8f Mon Sep 17 00:00:00 2001 From: Cryolian Date: Tue, 9 Apr 2024 23:21:32 +0800 Subject: [PATCH 265/503] Update UMLs --- docs/DeveloperGuide.md | 2 +- .../diagrams/src/DataStoring/DataStoring.puml | 91 +++++++++--------- docs/diagrams/src/DataStoring/DateStoring.png | Bin 32245 -> 24565 bytes .../DataStoring/Student Identification.png | Bin 36585 -> 19904 bytes .../DataStoring/studentIdentification.puml | 48 +++------ .../InputParsingSequenceDiagram.png | Bin 17659 -> 17660 bytes .../src/InputParsing/SequenceDiagram.puml | 2 +- 7 files changed, 63 insertions(+), 80 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 0871978163..4ef5027c7f 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -74,7 +74,7 @@ All the while these commands are being processed, the runtime database `masterSt To facilitate the management of students within a tuition centre, it is imperative to have easy access and storage of important information regarding said personnel. -Seen below is an UML diagram of the relevant classes dealing with storage, which is done in the form of storing the array list in a text file format. +Seen below is an UML diagram of the relevant classes dealing with storing a student's details within the program runtime. This text file would have the details of the student's name and their attributes, in the following order: subject, grade, classes taken for that subject, phone number, last paid date and remarks. diff --git a/docs/diagrams/src/DataStoring/DataStoring.puml b/docs/diagrams/src/DataStoring/DataStoring.puml index 98fca6c10a..06e0cb9ab6 100644 --- a/docs/diagrams/src/DataStoring/DataStoring.puml +++ b/docs/diagrams/src/DataStoring/DataStoring.puml @@ -1,52 +1,51 @@ @startuml DateStoring skinparam classAttributeIconSize 0 -package student { - - class StudentList { - {static} +masterStudentList:Student[] - {static} +recentlyDeletedList:Student[] - +studentList:Student[] - -- - Methods omitted - } - - class Student { - +name:String - -totalClassesAttended:int - -- - Methods omitted - } - - class SubjectGrade { - -subject:String - -grade:double - -classesAttended:int - -- - Methods omitted - } - - class Details { - #gender:String - #phoneNumber:int - #lastPaymentDate:LocalDate - #remarks:String - -- - Methods omitted - } - - class StudentAttributes { - -- - Methods omitted - } - - StudentList o-- Student - - Student "attributes"---> "1" StudentAttributes - - StudentAttributes --down|> Details - StudentAttributes -->"0..*" SubjectGrade - StudentAttributes "student" --> "1" Student +hide circle +class StudentList { + {static} +masterStudentList:Student[] + {static} +recentlyDeletedList:Student[] + +studentList:Student[] + -- + Methods omitted +} + +class Student { + +name:String + -totalClassesAttended:int + -- + Methods omitted +} + +class SubjectGrade { + -subject:String + -grade:double + -classesAttended:int + -- + Methods omitted +} + +class Details { + #gender:String + #phoneNumber:int + #lastPaymentDate:LocalDate + #remarks:String + -- + Methods omitted +} +class StudentAttributes { + -- + Methods omitted } +StudentList o-- Student + +Student "attributes"---> "1" StudentAttributes + +StudentAttributes --down|> Details +StudentAttributes -->"0..*" SubjectGrade +StudentAttributes "student" --> "1" Student + + + @enduml diff --git a/docs/diagrams/src/DataStoring/DateStoring.png b/docs/diagrams/src/DataStoring/DateStoring.png index 433d8f879b8756acd8ab629814981d82907355b6..c7b5de6b790feb5de800813424c8aa239ef215b1 100644 GIT binary patch literal 24565 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 literal 32245 zcmeFZcR1F6|2KXj387>Zp+(ur$}S~)ODKfMUK!aM2#M^--r1W@t5Df{?~JndUccvg z7WKKl*LB?2eILK$xc|BP=lWdU=lk`3&F6SL9?zGjoQx;|9t9o(fglhUyRCpgU_>Dh zn4QNk;V)!DxLfc)^j0D&Ryt@W2KBl&(sQ%2W9V5AG)>R2u2$LHp^d&Ppf zRD60;l-RXy;~Jb#E4^^d^82x&BsHHg+n0I|8*cNG@;s*viMjAJjcuW8s`&WJ7Cedg zfzKoME1u$svU03$v>c>rB^oYUJB%Mcwd+*JdSesoeZ`zwTYvsuC=*AFh&MM{Qe49l zo8N7Vur@hZ?q2Ne%u>T18(e?*s)|dtif8^tyB8tzjL6**i^xf{DbdGm zlcOav?ZzA$xA|UJzNShSdVOq-3HxFlG3)O6Eg@l_Y_0Po0|dmOaoGxt`kcKDHps;( ztCNYS7b?s=3KlX0E^;)5?kd6}@`9cf5|6bcOB6g+S zxduI~!4Jh8YHq3zceg*Wk9?Q>;ZXdTDwcX*Ad|4Z@ zf3e!tOWi2bh%DRoi!-LRx3T8us>x6U!of!T_D!Xy8Z!~N5AJsK?$?mK=NxA+4D%0q zE&QA(`bKgJw`BVJso-}L;qo#m!>6^Pd4^Z?9;Vod+-j*!)fOM9vivABp613nb@%oe znVw;}y(ppWf;sJoe4_B&Cc(MNO(&rrl|Oo#DAooebIUWV-SY)Zu@E4#JJGFJ@la5S)Jb=f$-}!nW%pUyRFc}Tdv%Bx2UK{ z(`ENAKLNtk;bJedkWf_nTK|(K&&o@ROEs6Hj#Kl85?-gHyL0^{!ZrM2@9cDDc_N0q zjZJ|cH+x+OYm&}jfl0Uu0%5Lm8`6lEJ>o`%Gtz0b0sNuxyNiW)qAK_vKda`MdS(;JgXQ8^_F%oi`lNr!WB8g;&Y^=f0S z&rCJ))0B=S9%7h&$dpKE=c-u%Ar)_bFuglA-p<5V8ke1+4=%AJPJ5d_9GB*h^Nlq% zBM!rp{l&S~8YyY6(0^C?vH|_}JMVV4*Y^t*=$}6@Hny4Re)~N{(|Hr#cbrTJ*@*r2 zP0Xt+Lw&o?tlSA^mqciDEWnXy;G;Do3yX}TWL!6_*T*N+QZg8b<1HsUZ76vx<3%Tv zKR9i#d3t(2xN$qTDk^r`n~ZG z%|PigF;BazJlKe zh=p?+wnsO>lr`IL^(07=d*K{EEvKL$yf)$;C_XJpd^!#`)B zM{*_5j5|!;|MpZ@re>x_si4!=dp=v4noP~|y+Mchbd6GbD=Q8YY5{u=e*X7&%x~Vj z$#^e=q<;k#jLWz?OT?SZn~a&*E0|St?#GWGlaoC~7Nc)3iW=H!%68`?=#mhweQGlk zmJeYc6sgnCqPFF*O+sFu32H%tI!r^~Vz2%AFO@uxivUUH_yPJFurpKWK}EC?dr=dOTS^&i$&0+W-Q=($txL zU;F{mc77rtixN>W{?-d0&Uz8Qg2g9O1R_L~fu)-OF}x&Jjg7=WJfKb~0(;CMs|t<%{{(owoxenW_chGwgehe5l&s5?E%gqfcHBqib$ z0%?F6hBP^gRv{-%rU}iWm`c*ZNWh)O`-KZHSOxnRX6d#h*>peidf3kN8njJFYqOgt zJsZeFjWQ8Gpl{Z2q~l~}`Pp`sr@ctrM;!S$K}QRX`1E!{V`DF5j;+ zT+|jFCd4@CZesrZiA1R|zl_1Vd&xd7a=U(6&1q>&*?i`g4?p;%H$6T+{#MtUf*~VC z2f5U5Kg9&1V(0pc6{XI&?>SA*f4csVdlt2Nlb_$)^lkNYW;Kpy3ubpFe9=x^tTL7a6oA8WC@kqQc_ar z>FGB&H;aplC4-q_LOH>KTsI%SAujHDfj;Ke`3WsMLlF~$tYX6shA?UT1iB+OZEw(L zq28d-A$$lqSMl|E?p%gFw?Hn^R-J;K;~G0sEC`?}gFguf=DYhg)1A^Y?R0$wCUM0dh*Qrb zWo7x9EZM|u($}H<;nH}WME%9<-vp5-kv6ln_4PB&F_mES(j*&>&LmQyjF@_8o9QV! z>8!o_ynRX8Hun2N+mUQFqapjt^BlWUJz3ZJKkV-ArMrcVCYGP1p<%UABQrCbfBqb^ z;2kV!p{Y8pGJE4QESzpV_(J1*p17*MLbJ!4(b3VcpXu3r<7N{50s=11elo5w?L`^Y zHaDKxJEy*gUf?~}sFrJ6x+P&tnEC}|;I>nt#poC5_t!1f=LW{|PhFO|bm`J@ z8o>wj9~6@s2TL8EJbA+GQubC89HF7Nm)FvUA}#Ek_LsfXJeHThIgKkSDCpIPS}cAS zF_d{S2yp>z6T`9aowAp_$Ait<5*uoR7!8iSi;Qd(3>kK~N_k*IwPcWQr7y(ArMaZ~ zWxI?vbGr}FG=IF4PEkv4A4Ri%fp(L3zC>ufMU;kly%0}CL_{%BYH@XSb!El4Jz3t^ zm?>P|zre8L!`)mx>AEP*&&di264RaOU1_S7_*dB2-cmp?@DOH)N%O%2ew!H;2?ZiJ zPvF`D{qN;cmS-y5^IixN?|Js@+1*s-yYGz#UiAEB+I+s%*5VO36vdXa@9N9yZLiHP z@+k%!ZpXxY%A4$8BW2fG%kF%0uMFQ37%*#%7ypM1)hnQsrp6(lZb!~*=BLdUn9hIQ zjhqvDy6`YqOCQe#jY5T?vu#R<-G2T%}CbrGH{>l^i{0G3A04f zKho6|5f!za?A7hhTa@Hx*i7|RO z`Tyz5-wAt7el$jCOW?ejZQ$Bk*A*qQ;mD>GorMkl%Ph@B50sRYR4Lg#C^FZodUX;8 z3KpoWtV}UUMi>8MPfNH*t-4yR+fazwWkWmc{5Z}ZxH--nD)rnBZV z?!MZKO{Jx#MxiNfGLKKrV%!od62x$~+n{%l{Ka^kfNdGha#VDd0p-DxBqt9XJ$~AJ zuAj&9ta`>R_v10|0xee=NT0uW@uMMJwCnOXd_#tvi8ix8=FOLjU{Pan$)}}pnGy2&(IdIDCr(rhb-S6}&D0Puy+_S)^^tYAbRemhw|8!C zuEE38R8;Euh8^+omy`oKMs%D5CYil}qE1NY@%! zx$ZoIKcD`RwOAYc#haWpv8F3l#JgR79e+wC`b`1w@((=oh*SshV9LSFN# z;kACPjuY+J*q9h=%r94wE$!a?qOg!#`e~1zv$HegZb2&c{8j(Mv)K7Kgisf+@-V3U z=xB`ix^p?%W=!GGer4OlJ-csc$Ut!Fr^Liihv{#NANUq5{@}-qLnlHnBQE}qP3KFs zH@QIoo$lMWZzZTk5MO*KMcW1kkhX2QF5jy>U%q@fQt81c;%HV&xyfOX$SB0X;AJiR z^^SD%ETlJ|D=SqsMhAQ7%31SM)wh2wWaGWVh3qZ}N9@CFs;a7T1jKHhOfl)n(PfH? zh>(8w;chBJNP>U-bQYXQNS5;g%X&BXd$ znb$r(x~EvmxW`A!8SZ|_GaayR2;+3T3<+$zpAE<3#9J6y$$mCS9*Pxi7MU*^tM!)&U8bn@H?>RG*wf6rL@t6?05OByp-)TE6BX1?5#BY zfH^a|K(tG}mH422DI@N^=kmy>BrjXR1a*OxdGM)ct}Qm^Ip+?xX2I=KhUpJ%#U&3r zXTm*A&Q=~AFQO}5_5Atsn=g)bq^Y(I4eh69mT5O61PSCZM;ASAqAoD?6^6|O=Wa9T z>ggQ?U9#2P-sE#%ResShh&XN~3$rqbEuUb^Hl$s_{9)IY3l-f;q z)cg&NE)*EFxi>K;-(71iasBQ=;|!;?!T-~zPdz<7!qP`2d%H8g;E}EJ8m5X!5Y>Dh zA9(ax7_`Igy1UPKlK)Kt$_R1uf7;e-G0I-k_nL?{;^|O88r{ZDYrXRKHZ_p z@3^p8z|S;KC#m-NAmVB_J>JKv4dXKE_#kpG&QB>dtpI;ApM-{Hevm=DKx+R4<3Xz6yq5=Qoq!Fh7kY{0tQsW#hCv-R=SzcSB6vl* z#tMg=9hwBzv({tMSef?*VlCJ2n__$0qk5B0B>st4vpD2mnz5)2q(@nEi%(vpjNLo( z={dbD?PPK@fI%oJwd1pvR9q7#f*gcHO^Y!l2&tKmr$*MLbe~ya*6{H^7R|U%`o`0f zsp+0#p_i+d>vylRr+*>i;>=64`+&|X7pn#xbrekzI?LV0;L4084T&iVt( z;|BY0nz44xE5~tWY+UP%LM){3~tr$*iNcN1W| zl;^y1Y|T-F2yw{c{~yD=0=>Mmj&)s=FcG50!yn&*-T= zw~2G9 z@bmLSMF7R-Bf>Xs+$auV(~Rk_EokW}5&p?<%okRKd$0~MdWH0giS^;!zPev`((*2V^8KXFD~8KS<_cb5#g`3uS>b6nLt z+ACWVBqz_6mX?OFYDW6`0U++QC)RBtAwQ)Ol_;_+_Y85ceUf`-AsUT|iD5c*@?VOqL+H8}Pa0X~y91y{TOLTOC>-|q8G-lnuwuZATCtHgN96x<^ zxWD+x*meI=zw@{Bk1&*S=9qUgDf3C^-@?ZHGcfKgFqVDb-4)GuHY~=uDrc@0Se()h zRwAh}V|WG;BhsL5eaK}9Km%H3*U_(>fJQI5tVtb&KcY9hm3;rDd&3 zQ;r~SAD@I_pabGP8S3sE55C+GQV;wxLtW$eHY9{xs9MLQ!}KXr>EtzEm>jQhdKP+m zt!%Y(Rfb6^Hpw>-2Ww^AJ^QmI4&a*$H=BpW&bVdQsnkioax;oF=}b}d5dQ($>)j7Z z^4j^7)b}58t53*J%gsJiF{V0}-D}W$U8&;mRCCSTdFkQNw&3G*^5uAb|4WqyQ;w1G z%lfpf5J8K z{a^E*Ji%m?vgpz9^<@K7mH}K}pC8h+8`ZpN zU#T-G9b(tc8%W{ft6D+BMUxtlC^G)n&JdeD>U!(&g#D*P>>uX^g_H6;nRs=Glj=3T zuPLh{a>atbN~x)ZZ9KyD3iLDpkTnxMRrgDem`U#X9dC1hs zlDkHQ;6)?PM=hs2nZrEhy0dS6Q*>WaVi?27BKq~S(@2cVD6IJC>*`+J&N8eUmr)>5 zh55oe`l}SEp9~*gaN>S=1^w4E!-aSia;V|B22{K!Iqd=Q9;G=oB%|7R2vKx1?{Q|1 z9!J?ig6l*u%P)WZ0;cj9x-ov}+6i=9cHqg*p_^I;Q+N|SvLBEwzd(FFm;hV>xJdX;%}_&RFk-q*h8dD0jqWQH*(s;8%S=Z^cv za|9u3@f%W__eZ{`QWp`_)YN>($GnbS{Ul6eG5eDrjij02 z`F0ifKE0HtxUnF9@kjdojZfq>rW-b=b`wIcX+>1>+05n{EYoG5Nj{eqZh_ilJfyij z{|o9N`b>AjuK{|c%qXj$sz?c>tMo=?8~=!%;phjR#58 z5xafZ$2xdzCPO14m~GU80YQ0vn(Z^dWo>P3U0t?Q?I|+^e5|aQIo5R^8Ufl8lr}SU z0EhjaUApZ51IB?NgMlyXO7}qXvA^5-2idUtzd<&15d5E#4gN!2R5&*5gebFbb% z*npVPJBu=MGS!!CkcFG2(}a#p*Qe(`*tRL|x0FepH`|RaXb9&f2Qugv$OD;4Pn;;x z#}7jLJ5QA3t4$$OrO~aR5)emF!t^3!h(6Q>><#T!qZ@P@#4iG{?v2E zOWPku|C%)J9Pvk1fvaYu*VfF=ZhgsuE!LHM_tvKH{PL(q{3XpF5$it$w|>Tr?|DA$^D*q!BgDmP!|(vefv_py{_ z-QnXtMA_M8;eXpdZpoBkeI_z8YA$xpo?bxYMs4?1vb0Z1i>1)DC*mBMtsbCopjT8> z0|`bU7HwZx2a0AYGdulSl;^)a-47rQ(5n);Bceb*Xw*h@c#Pfyli=(X77;;3Lo)6{d5?4|<7h^W^cN(aQ?w!#Zf|*+Bmvk0RNJhWhc8jvP+O=B&-g zXSb6V?|?YuslENy))v4ZLFtnd69Nv#sL6m}q?jHc7>2dswFzJT-zcRThHOpY3-;$-o zsK~7?Tmjtu998Aw=-15)`8tUMr3;_&g?1LOQh2UjJz<0OMg$#Kz=r`OAK@9; zVVOpKMV&^_QN@$nY>-JHMB;FZiWqVeosrmsoXU}tEWnCR=6!djrqH#Mb&3_TTs@W} zX~KXc6$w0T-jJ!mCm|<){P=NO@>O2mkHGUmGAa=%gz)Ma2-&XNHEPR zb}Q9&rQZ)h!%W;WN6&hrPrSve0az`or7>~ZM1$ydrq=6MuKeuI)?s3;?&}LTc=fHR z=`tIAcAl)3BJ)t0lY?%jF?}gEMB#tl*B=fJ3zLY;djJ0H9+f@kcGh)TTHP!boLMEO3-F1IUnGwRT@==5phnoO_y1 zK{nEFU=vauek9w38-r7^x!Xg}8{qwO`ENPn_1=DgdEvZtyg2!o~73iCVa|Sky%zM^y)~Y!(8!v*|xrnbi|YVe(Zx|CjlUk zDk_tMU09t)i8wf|7Wa{y2CXmM-*Fu0x1BpHEf2~&>umRb{J>R_D^dxo3F6e0IL8l0 z(xP2xnMoswJ^i5MDciYoD9RYp)5fNz{gpOZkST0^!l60VF?S4hru~Q;x&8WF!{yCe zmct`=^HRM!?`5^%9as~Ei~;`ZObO*Iq1P>9eSL|1ia*-S+OPbSpXTKv%T;;~Dg%gA zW`+2!=mI=G+gEr`TUk1tM)zF-s1!Wh+;nwyd&Ja~l)oyaqUf()^_w>_2pBe3!{VDFa=}6m2n< z;8vQ#FJHgr^1IkLrgfHk)cU{sP3T3u&3crG`m&vhf=N=VGVn~lGKL_pUZ1M?9m9x? zz3urPqR@7h^IB|@w9ytr<@>wy`^pU7d5mQ=6r)TiZAUSGN&#FMiVxi97Bp30Qj>8s{MJ!sk*A#tDn@RS2*z{<+%JXqBkPQr3N zznUp18us#zmp`WCy;kQy?ma9_OnvvdBbTHT(}BoPT{*dCV4_r< zBqx6yXH-s;L$9GWNIyVUM#XD&n$s}QC*G%nEuB$lty^cO_!I=AN?sf4%h_uCj#SP8 zg`^GKsv7Au`CI%fP&*;;R~&f z_ASsY{gH4C@`ccKD1Xh%koxR2on9EIa5O(5B{gBDXAwqc7#q_jE+!W3!b|bd-NPfd z1iekt_U+uH_gt|Loxa-47gl0b5M{v8029>#nn#!YJ>x~wvNyriOa_UYK#kZrI4GV9 zqc-iyaU;z(G~9jk__1OlIDuNxC@z1)R2{q^kfP{|cG6hA7jlW@7faab!QH25-Rro0 ztJwvYgD!y%75&-eJGW0QQ%MBu(799qEcrXNWwyZzf}HwS@`^Vz(RjGA{;NpnKSnc; zxM_wn4%@o=-vm1U`(MA_Y072lV5;|EOL^J;Fl-Q;B_knO0p%!eO?!L$@bJU)^c6#E z{kIDI(rnNewOix;2EGwF0?Y$rbpeQv7alKPj*X9J*Mry&6BDzx^z|m*xN?C{;{>Vj z53RnIs!NBXX`kWJtqrtWp2)5T-+Eapv_kVs=eo@LupAdT%Y%&yETUuUIw6A%gR#y- z*7@6C*xPyIse@V6C2%HZXG77s$IoE?KJw3#;C4*A;|sRP`RF`egEuRg4B1(f9NsMs5n zg5hNH3f=5ytz4B^jt;_(@xzHp?rBi4e^P!3LC^i1xu%S?{TPiqUN$HEws&BrV-Cqu zYQ~R3iCs4d!4!x)_s1+Py4B5^H&29!=#M=@?X2uoz>S8CrZg_c>8(ur?=PebV9Ow zOWQW59~4dWBtnNw`fUfc$`%0#|3G!zI~@xJep7l(sU1$1aktMgBBG=b%Iyos>QV>z z)TK}DpkAyio&UJfxJWw&iu{djb}Bph07{Y`SyZ zhg@!2u0gd^A@yha#6RY+yPyxW6c8Mkesp&$LG`sSGPOr~)^v?5XgfpF>{?S?XH2`k zWBqflLBqjV%VZXu11kyv-!R=_$N$UYWm@Mew0G>lKfhytOt`Oeaaa&!&m*J0LS%=y zSdhOzG4TUSOG{!uHv1KQw!5m|YHChu5>%j<3j=3id%k?gVZIb_$ zCNhK^H5y#SXs(|I=T4GKdWoGqfaDA{HOrr8C^>d{5a?u@yNn8y)u7B6a@pUV zRnYODhvccM7omd2n9ttO){Y$*WeN)hZvBotWlNGQ&6?XFXsb#$C&KsB@m%qKO^#F; zN6j2-ipjvopcJ3e{7)CSha4-pTsFr;qMWxpO)$@)GmcdVqeH&%uUx{rS)6R0;08f1 zCp)`hz2S=;Yj9#P(ktPtgbEg(tWE~B4;h|n1umM#gV=a?@heTx7^H@&&G!MS{Ila;MU(za7y&n^74QSg>yLvD-GMmVbq5^@KTD;RyjCxFt$)m(!emp zvP?X4f#~O>(K}C zVljb%mu3r8bM?GVrNe#zK};6nYQRSmClZXfWgpk#Mk!lgVVp9*R`|M_nhTTSU*HWo&PoVRCz z2A&3av;WHadegUW(PvVZ7N7eoouiz3VDp~p4hWH-Gzr{0m|=EK2n&e>R!$V_z`mK; zqPcGV5Hv*TI-JOs=1h=C?{2N?L^+#wXFXf70yPIj$4b2>T3RCkvVy8Geo(G#KCoe*StT#|!bNKFgxhk!cgp6!! zd)r$TVSE8aPOSj9xm?fQ^h(vC*k(3t;i5947G(kme(J(Iggbk)Fv;EXS{Ti*ezgxY zAuI}=o^|wo2vNlV+OpYiLOKQoNV;sPSelwc@LwYJn7<5Za~%lkyK5~7V<5dku^(gz zbj^pW2AEC_$V=H$U-h|s1K-=8;^9dXp$E$WrkD#gKFvcOC7;YhoY25#Etqaz)CRx73R(7(87eWro}7j& zF#h}Cv$m!wk0){@2#@_d1O|;y9T;J7)zw%QVqarO7NNSgc6#miYE8yo9%fV)c_S6xrk(RVb02TbELrj&T^E~+PhHfUz9ECcP2lZ zW5C`0S(>w^g-{p)`n*5O=v_Ix)+)*R$uwH{S6ASBtYsS)^b-I2131h9DAW79?O70g z!Y7;l8bc(1Pqqyp8b5%Rl{^1yD}OTuZ5cTX>)NAlP|8MsI2qL=HkGW|H$>2m+uovR z;3(nQjgEVoo`(|&e~Yx6cn4_CpLqv4x*aglu!@oPQz@W*Qv0*Oug|b6C@R9EEH2h$ zG%I|A6<}$ovOp~%;F6I74u7Wg(&fuQ_ur_W8uq*#*XKwdx?B3nO&u-(BT z{dH(yhwB300&C~8JFRI^sCO_xaG5Jm|L3hr#SfV$RJi?Fl^jsky?l8DHY1d=t$;!K zvkotOog9j@EOYr9r7yy(@tDlO76az)~AMU3d$UkAV zRO@@|pmebX5Lx)tZ{w7cljBZE#h^Dkj#4=c*uumeSURu|;{d-`rgHn6WbLVdSF@sR@D73dRs@BgT&OaeY)$a~^DzJz2+x{O3D~zkyLfY$?$^d1`|$%(FR+I_ zg=U&jf=;j(xPI-vY!xOV!Hww9{E*DDEkhv8V4=c)z0_Z15eKsaeLK57@bGt2IKvg1 z?%+K>WtXdA&$<4JD>>K`Hd8|Ly@6@-r4fP!{bl8c5yHa4z{yposb6=bdNNFiZWpH+ z2okU_UaClytcN!(EprY!Ux9Ibfkhc`S5&ECE~5K3%CcQ|g<8d#zCzjhUJ*yf9oQmp z?0$8g@FC!iZ|oaNV3DB`s!)!wXSMb^{Ghf{}j8VZD9PhQfS)vj>G z;Io;5r9b!*$f8Oha@Ou-0o3icLHxD!SYk3V8d(pY!60Fw-U~Xx;X4@Q;W0o~`22iE z^=pt>mgBWWMc3Jk$eHgK>_AcJ;gl0r$a5Q)Iq!bN3ZcZ9L&XLVnS)BSNpL$YH2pfL zkf20Fo6L3TSAbn1k3WS{phWQ5!tn}3i#xIc0GiF$ZxQx{+9rS;RTH~e2+v+`2EL5V zNW`u4VoXh;Lqd%ft)>c=U?^jcEu+-l_uXQ&$=Q)*hMFiM} zMb$va8it|18mZoi$st(^rOPfx-PJj|b%`<&wU2??Q-J^iz(%2^Zx;baDwMSS5Un)q z`>gt2#sj;R7ExHWZ9wmGFZpn9ug{|jQ_GyT;XL@Ji5nVDp`s~=P56I7$A^T>apS)e zM+qCyBH|bD%)b?y583^QfbF?>#=j9cU*-T!LHR?W>42KJgwL0+tfeao+S=bCpclrF zd_yg;1;0VsEz|L=_;3$Cl-AbK$y7()sl3x0(oAFyS|H*m5p>gJue`i?op-L^(qbu_yWvU5bNEH27(B}ja<9LMtx zhs-J@MD!Eb)s6U76Wj##Po^xeVGiGix(Q9NK=3{r8yo1g#@T^df&Ie~rzEH$=TDNg zzHue-LRevIkuOyfM5X%vsB-JlrCLTNaZ*AWL8%%LM`Z%wFQH(_UFI@OjNa?pBOQK$ zfq9@i%vdO(5^^UZB-ERKPCqkPii8M~qfLn^@e&T-KiH z#UBeM9KpfiHtIA6R7#tc0E+Lgv$4s8XM__8YA*ytm8*~?F+N8r!FAN^kt+qyYVSWq zD3Sbn&P0YUElG;ZH|}YDV=y_}ifo?V&&M*CMMok!-M}J(O@$7{>TZhDLu&ZhDeT!V zF`GvVgm8dn_i!_ps(*BEg>nfnu)jt^c#)OWcOq#`S`w_OCk+DviE})PqKPK#lBm8_osuoDn zDsS9SBKxqa!#@HrNnBw{hYDsJ;wwy9FlO|K(ZBXGK?Vf|I)>#>24%9!J=)qZ0@^5yQgR*w}kt zzZ@;Zk6bgwJR?1OGeOD2P{Ao1e^?I2fX*!y(q`{`uwR-iV{`hLFyENP6}Aw~s}wMG z%iJCF@XIEJU0=#&KC8L>JY^IjP6Lk>8DnUMZyYvq1ZgsuLtCWY*MY31$zLS;Ae)}d zJVa^^`X_PJreUWq8IX{WxNza3ad}tbTC{Sz@^(@(pY0qBGsZ&Gk<&+-;bo+t)_OLZIGs*DX%hwuad=Z|fKXrE?^)BTQ?(%ou)t@s%EH{$xn55v$`RDz+@-(w1 zh!hq%^KY=8hT7(7C;CDfP(}(wjist`Yh_g?|6J_;nfu^y08f!VQ7d0wiC;|bSbMl| zi~8Eju=Zg4VHR;oU?fxa!DRXO_T)a+(E;l~l}ci#Bu7Ao47;MjJp(!jQ2L{MlVHug zTvKhIU|xRGbRYTL_-SI>6eH{>>y z6fh5oPXMY7IC1T8;LFz5)(QeOejL|@5-4tbe0<2?Iw8Y?$TBe@VX*^b7!+K_Vj?UdD z>HgHS)jJ1bra)PS1w6kg*H9pAKu=rai$g?x9BS7#0Z|7!9;mba{(f4?V7Yn@2zb+kdyDW^feRx3Z3Q9 zJ^e>jbtvpc2nHIx+Lb<=xx2eVwVi?|pd3|892s!NfARDZH%K8>s9aJ=_q(qD?as&e z&^?9vK|CeCOI|%iuUTUsLc%E_^|h_QEh}({TgdK9&wFuLdGgyLB6d4=ca#1L0auPw z%cqjn&ijs3&p*Z*oYRzk)$uXGm979>Yplh1JE-LesXmN#$au^v&XNGWkZUk5_UT{)k1;)K?)r#yx7kSL) zqJG%g({e#lwTmyO7z6koo;Y+Roi=eiy^xGX{oH@FHD}$)a*7)5)}Rdh%3nYFRR%sX zTlttZ+{lDuEn4BjMMrl0(|=rVyD1)EC@n25>KBnRp@NI0zC-)l_l#=v(dFEc5{nw) zPh1a7NwyZZmi2@CsB zNLV0a1x*32EXHA6(qIZlb-r{x(oafSnt+gy%pX%jLxU+XDU>ngDsQ;av)SiD#)6%% zT0HO$CNWlz+ujD1Z7(gUOn|ooH!!a8#nH`@vG2~~WxSZ>tXX{pD1Z9xsf@c#K;Q_r zSmzzYd$OTdpOwEJMZ3&yILS~n3y3O1`srF!Q#4P9pFuIIQmQhufPlJz3J~d_9ipL$ zLTQ#}djZyslZfO!!)1Khx;xLH4U{4Uncy51mw$;&#OI09fj-T$npEHw`-hZGh}h=6 zLLhHvl7YOC(u=?LQQ-?5B5*J{Qnznc0dUo=E0z1N4l#$0#CEcE9N3s(A%cW4KtbMt z%hZ&Bln>DGq%p`V1nic^z_YYuU}0gY-fQ;@BPS(=Y_ztk>z?@1zbh)LrNQlUJE$t+ zJa%Y^frTvxQ$JAZz>N(TXRWWVKel`BF8`w`>hWrjLfLcTw(6!|)kQVJp5=fapaONa znicTr5+w$0bjnfgGVzybgJWSD761sB2ff>kMX-`88q6oO^V^j8{vN#vcUW!pmoEwn zkj}K;4jT6a$%37E^S4)K-?S;r7sDln$H%K>7gg?u-2>L=uIDnW`0nf1$Gt#<0`y#! z?Kio9!v>%Gv-ExcT7OgoUIJ>kCc>{QbQPO7nJe^(`4{Ihx{+!x@I4tKK|?{iEvBqUZd-E6cI@@+@T#ZPHCU#Ka2 z)&e{t`{Twdi;z;M2fYml(22-PwoSIV+Nlr_tky1@+keX%%=hoGc)XXHhv%JkSS;Qq zEbtk2Jy1=(&AaBbwSv0%L$)#*vKNL7`P{ze*!UYn82Ys-V;}`L5DnzF96P2O)Nybj zh!xxo(hxjPfhO#OU%@SXP=J50K2l!= z`U(XFg~RNsUQ$LzCWl8%N{U3W@jKyMFBgYlxR8q=kBnn)MZ^sh%obP)yf>7)18Yj2 zUGY>u39cnuK;?p%h*~tMVr&7-QD|r=9Bpsx#^>&0nWbw0s75oPIao3fm{AHk7KK`0 z0A&(BF774(!|*Oz^Ww^&>9{DOqM`y9{iqB-&>usIFxl`CXe`T55l+L4M2LZ3Vaxo0 z;yf3?g-{eLCSnf_0Ez(sBm`CSD~){fudr=j0Zs`w#mJyQTYSV7G(;`-6s#r4RiB^$ zf#JqQz~Ogq+zG z94IIC?s4SF+=^K=z6$j=)!rP}cpW#gR36enXa*8%A2SaGI;~&W-vl57E`BI{x~QF9 z;RsbcRzI6Z09)3^FxNq4zZLtBKRw3=%7lYQhUqFT#E90oC$W;yIEE=ud*`lS-+(eq z?PscR+frJ2`927Rt1*W&P&=ZS4~BD5dgZ}fL>jDZ*jldoup_F`{)q1GZZzxEw%jHw z7ULQe-d09_Eu#A9VwRQEsu zsFc*}6tYuC8&R9A!RH&gdhfd3QoM>B{ZEh(0$NkWWKM)0up1?}DFk-YD4GhN0Ux4h zd_uwk6($%m)~_GH(v|PdnrRnUvRQnu0t&%Xb@(Xyv)DkY;^E?^tQ0<=XJUfSa2{GT-C#dfAAzk!`=Y)w042N<>(h5SP`W}vt0n`C zAja=^Pra83bnB0a2`}vEYv^}z&!@P#yZaAUVRGx#_|wku+gmfDCWhg>mH1^kIxp4r zQP|a7orEw2B#ITf=-wDRZj5;N3aoVl8B>K>_y|l0s)A)s*d$v8rUmLNd|VPFPyqS; zgzs?K7Qo_QlU}F{f8k%OIt8@STjDnTIdG^6F0mjshi8==9v?W+Q$YQ*6)s8xdfrE6 zco4Stl}ne#lA@ezzkSp1$`}ArAbID6HDGNJt!kSLhy8j7zymJF4Rbbp(;?@nlqCI< zPRN^3oEH-h#1g=rTjaaqqfWiDcytmIEas3V>A8rv?J)naO;MJ!>{a`n=cDWu*60Bq z2OsK2rwITu8GiriFz41wfr+sk=Xc@I1Dtm+22)xxJ4`GAjd_i4f|ZMOT2t+B3ji^H z0t~24X$1zCpY2$Ix*{^>77iQ!12lUc@&j6!A3$;kSIHFtNbpnaRAt|OOQ@N?b?MNSQiGsH#KBJBbC~!ctOpf0l z2`Bs2t5=ZPgcW$}p50LR-8*xAua&A(vhCoyA?N^3mf^~k6GkfXQ1i`3s{^(YQdi>K z=sB;Yt}4*#*E0q;L$K!w@-&!ubc}{;Ln= zI*Q=0J`45R4r6aclV!6JJGgc}Gk4xxZ1dDj7?wOAbQFd1Rl>!g%b*8Ht%9r)P;9uR z$1f^Mwvvrvyk!XZR_|&Tpa&D+b_k%>yum#IH?^;>A1v|YZuW6ayp-Fhr9RWBxwk~l z^?3`3TsYbf3QCScG&c_yr-4hIoZsIa+V`wZ*a2n&#a2UPQH2@(8HxyQ2@6BH`lYeO z1V8k?3?G50*e6~7CWc8cbLLfmSmAojsH{2ctOigKk)1v*=CXOIj6~sAD*7Hw%C%E1 zw`=O^QjP7Z;rs?lCj0`-{a09U44^*9gYt;Y1$U0GfKdWv-BY+K>K@_Q3YftA`G#(+Zc3Oa z+faW@T4?fvj?noqxE%+o`i=J=5qE!ud0QKPLG)endsl7>$X>i2HMx%9to`p*IG!8y(UKtPJ>VfMvFq z>R78O^mKtniPytN@LvCoOm_vNNxph9P=^E|TT543CEJo@@A-4c@513&pXpI7$S95$ z&)ZPIj{e?^FYaj4^ZzyW-SJev@Bi7^N+Ek^B*#3F%v417i0n6th&cA%BH0;bWY4lW zsBjPxZ=q85NXMSpzSq(F`}=%;zt7|MeSH7yk#n!tec#u0J+J5WyibfqwD_a3gSeZl zq?D9Puqz?$b;|{|BqV>|L(V|$EwM0EPv9@=OYOql2|&x#!oqETaMM|RRu$6nKu{K! zM=Z6I1%RK%yso%@0AsH`+t-L&$VF)=YwQA|NE!@Vz#sp+B* z6wzJ=yE&3a3R_C8iZ~~7IY9QKC6bXPBAi(51~?i!)fa-J{!>RZSXOxy$I*LC4Sc2~ z@DrbCq>I!Sj@J6sN|d_P*EGoPeF+PEP2o83s>lHKTHnFv;>W0k!JI1p##7lwotIg_ z;cvgwGo_XM2Vag#DqUS)KdYm!`AAWd6e{WU&5_?RG2RZC+_+&oZ^TY^rS=}RVsG49 z&eYU22KP(-YhYH(0d;B!qBZ)Kub8AB)ARi)@kZvu!%hE=7%axuqEbiqr$I-|UT3X8 zgZQAk2DEwoy7I>!L%u8at0jE{HJWvPqmle;_P?#)Hu9AHd_Sh$sP#Q1g#jvP4NJla zZ*pC!y+BX@<&8z#|EVAA*LJJFnGVP^Q~WeJIs4bVoK{tDMSAHaGYwtx9A|)3K%O{`XjWqsNg$v zlC0c3Jp4rGfY&Pu5_)I84^i#~=;`TkN}l5yqRbWe9k?GPqBbUZ9JqVQ$v0%EH#N7Y zYx^zJ2ND_b@6U>gZI4Mh6+2bSsxKP7jPC-=NkW4t)FnH;y*z5Ht6Oc}5(Ipkh8|Wp zzw$3$ytsGo-oyDSt6a2#*(Jj^?nJY-8L}EqUIxR_7pX53tdD;PxgBh+UXrQvEIX{# zJ#z3m^mlArlB^lX;FHedz8TH1207R5AG^p^t)!$R#K+RYLSPD+85^gY3_49h8u$@- z!4SsZt9_WN#u(y>-QF&*)5+IZ2(>sH1BU*&5zF)ieWa~E-Ro+9+qB;+)bFbhyl#us zW*+NF;|IbNa%NsRk8il`ArpA{dB_cp>)|qk$+@B0#s%O?*lMGeTWmOfGyw->3JNcI zrXcwFrrhiIBsrPRd*C#MPF;CZ9LZ+Cwl?E?Z99H-beO=gZ&G>bhF3W6x-2iI0Uw~*4B{+AL6)x zwN0TCkv*-iqeEaK(_ad_kPl=_3XljgF&Tv%2$gM%Sr21~1(sO&IGSRs)}yV;LiE~3 z;|Nn>bMs+ECuqzno2+?{{iQ_tl&op?0Q9pR=!Wa{RYS%qH=hv)n1$ zU;`06dU03k+jiYp7}r&{qcyH^wTyFOGBkR{FpkuH!S#wG;qgA zXL)IH@!;=ge&XQo0o7$3s?2c;C%a%s<>$}~<-zquMGw|zy0RkK9cpT7*2~|Jtmew6 z0%9_IiP$0qeZKrswfj*s6Yr!UgKS}v(J)}tlhn>f2c9%FV6f}6vQ90Zt)R7V$E4Alr|_AqG~RQrD1b9NzbMJn9WUBrEAuH9SBrUTF&l- zBwyQK+b;&f zpAxPF>PNXi0D=@2efX_X$IQ4?0xq=%H+ZRq}gQ;_D7&2SDqPy zXnv1Cr6Vj__ho0{B7I({QT}mont`o{1VpCik&+XE8szWJ3X$pe2!>eo$qMrU}EX1v4FX} zU3vP)V}^Xk{*B7tqd}r-+H!7zpR`YT+VfybH)k7nWSw?Ku1!;fLHw7^JI2J$~rotw%Ee_dv(Xc&)>`56!>^D6Buz;=iaC>CnWOyU zd5|2jO3E~GuyK2uPQ!9167uN9?_9dlF`+XpGuwy35>M-#Op@-BiHXT-@?8*iXkPK9 z_WBKpg;hCBY+%y@GFOdFL~S%fz!NK{n#`XzJBnyH_;ozU$O{>03$=?#g<41!^H^Tu zfq1w5ECD^ACBvyPpN(EoVf=0*Qm)USe<`5iL$_2%_O-gGkZHCLe6c<7{*@1aUO!TU z`=BB=a8z2Zj>+}y(JNOqG4YDo*xo;M3=IuMRN6Z@5Sd(ss1Tf2R^LsnirXo^6ApB_ zLRYU|4H$$c5~d+w?H2;UfFwgbjTvS5q_=P122+y#yBY$?nVG-hFn+i9b4{K+(8*Ag z-xcE^rN=jL1^oknIO`=pp4UfqT%yoHYNo!BlIqhd3f2@3>-t&J1ACa>%m?okf#{j@ z=ZQ?Rfu}F!M*A`!f;Oo31eBVxRrM7i6>&1)CbUQ}F|L79$7ln?QHCmWlvPtJwj+h8glYP`ew|-S zgoJn)v8*;y(rGUh1}<0l9lVf7^^?S>{eXIEUw~b>iSN7fEwW9OrJIp4tmvX_$y&aqnB7UoE?*Lo6!6Ic(x67Dx}=2sSp3S@BtHCW^!4vO z?iDE&DJ;J-x@E$j6FT&CP4)heIt?2eb)O_*e{;MGGA}QWMb7UY2DA#+Qw#KA6p&Mm z_q;2MYhe?gp49-WY4;wR@4$h|i>8A;Dac`fjIDxco(Y1>`zeq;=PVfb3iQL4<9+6e z&U3TB_1Y?qXwN?#WD?0~ZajfMZJkGzN8BJNU#IE)PZQaCNdC)YZ*Z~gdg{vjJdH|} zse&S%rev^5q+(Ggo?RYQF^_HrTKfk1pXsI#UF$sO8p`g0W=e(njbn%pum2bv)C3Hnd>xh$7WTxkv--i3-@By$G*3}uPLGF8C9=+36wABK9#5!KA|&pc`)7~MvO`qu0Z#=`5JC(q_|Cm^ zwuY`3w0wcO+h%MJ>O;U2Yv(wd7X~BQ(;w}4#zw6qInRuH3kBhXtAiLks}u??`?YYR zXvxPFgp1z3W!*dAERxwZyz}pYm!mgvw}ECJ{P^n`MyFk?4#WltUlq?uB1&H{fcnP<8Y!a)?TRW?} z;OK?=52<6R{A#mFs(~{E2=!&-S~a=^ZyXliK#CVFt$YC986_yg&%yO6p3QwaIUZx{ zY<@po@-Cd<)z@gL{(*s4=OX}zo{|xl#{j5=hQcswQ^G`L+8a0lQ{DK)w=lDWA%_T& z%}c3dyhTj&cT7xJT>EPsM+M{p=*=WtQK-Ob;8Iyle)#a=3Z#_)a|U+C)@mCy&N@Ze zK-Ge;?={y2cy|Xs$2<;0rKV<>DtVaYsL*RF)$flie3zepqidqqwEs6Fce$RFp=dZU zEP{*62FUt?xea|4nY&Xg!pUg~K`x+MZLJjmu!97CI|c)&alqyWTsOS)x{i*HupLxY zy8#(jj(=<(2A_l)OEm+C+r%9)sCyD3)DL!G16-~24QPa2g&mQ6nfW%v5_ zgPDG==)tGIxZskr+g7drmWAY=f~Y)(K}2z`0;MJU5umj)=5GoU(j`3BPZNojn}3^f zsEBeASkvOm6o!0CYz`PM_|;EbR?&sMTdrPFi@fed?_Ax5Q=5`_Yn}4GbZV1mdzzhjjQZ@CXO24F zva`28E=q?p)U743rR(nIR&H2fxjFwg@bCcktn!~OdZ;~oE6)dos`+^3E5h2-ff+sl z>v#Df{sa$NW6^N#Qpe`(e>Izfn0nnwAsbed?slhBUPEabxVGT&lRR31$F9bKlk2}0 zWfo!CZ1~_FT~-WgHMHAm%_d;g4lUV1ePa3J(ONFj#9oYyAP<)Hh&mk}OMx#+{Oe46 zkjVpPC6OnSJ5UI5=( zOx{Bx*iNl*wG1s1P50+d&Ber_=8B#;8r~(kb?a8_zuG<@Sb2fHDNR9wR~I*&Ni$R% zb;Acu7wK;KQ(SK$&7!ZX3&jnu%gWT3Dc$m%DNv>KW`&k>gI*_{zz6%-`VMOop7vQw zs}AZ3q@KvQ&d2^>T2!58z#0m_?e|O7`TTD)6~Gd+)TN~{&g0coSM!at64u~Gp1d9^ zog!6Z+MC5lD-f1~z91szFwXStH{*fQn=h8}=)0H~F;CD6b&e1-B9aLo5GY{0_bUgk zph}17vF5nJm@rL~9Ar6;Gc{3ZVs4sg3H=(C+bf9Q{Xqyl0NyKH#r-u97dlbm*LTj)%Wg|kvq-}cClYmsYP~J#& z#EXkCRUE7?8I6`6HPS_^VCVXzSlYtjK6~3BV)>j;=|V$$XBIAR?dy9884K%BPEE^_ z{fld>A0rHnZEbAwcdot5s;pdxg6?Ycf^&w~^T+liGHRJ6;@T>9-y_MPTal3}!)oW| z`g(@TbYs*40s^`7jgmLKll|V|_6@1f$@LY!IdYSTsbP|ZHRFB8zRDyp!vYF^L%Q|( zg~-wks0!=t>WcI9U`$U>FI)C{Q81SGV+4=-^G`cropj8X7;;V9&ijJZ_ouxqEji0S z$J9cn_Y+3igdTkX|JH+N20Mp9zK*WBu?&nF`QMKwvT`_V7xY4uP7$=h%RoRcose)? zLbYBwJ)?J^2*%->2NjRZk1CDk+YL1YtoeQI6_O7g6=(-YU%lZ?7bRJ)6mU^K`3e&L z@xoR1$GV#k&ZSl?aoo}Gh%k9YVLd}E9|`V}2%z&2=yZ|InlcM&qLP8a4Ssa^1msje zN`+pf_|63#M~6JT$2!KO9a|%7T7&;AmoHSkzI^%enD5I|d#h^OU%&1Dxk9U$f6kr9 zvz|$=uCBh%cHUcsRPUlI_axr_=!zc_dfeW2i_66(ip&n{Gfq^*?a)dWzue)&E;8)j zB}{Z?xshL=Dd^-7eRzq$8OD4_z0FL#AV(oZMM>3wmil{gu13uFJjlv6{-CuK12Q6ym-i)yVod(L9p!*j|t_HeHoVWXI?d`ei+_ zu&u!-PMS`;rwi-t=co#o$KB&RQ4l;A+1lhYLK5Q^EfC zZ+8qv`#1J~|5RUKO7!L@$;xwiY?nZFB=0?Wb-A9Pj;4O&)7AFNK6cDHThpQ*v?WQ; zyF!ZA8B%la6kk()|HrTGjTuJrW!~t<<7>Hd$6;WIjgMSOWX(6|2hn3O@bWA8=w-=a z1pL|AyeA83#dkhuok712ueHVM!zNL}Ag*%_uGv$A(o!`l-E8-TDW=B(cQjp0dS8KX zt?}}rYTlv#_n#-E*SC=UaRY;+x2YFY;gYp_c8v}mi36PAHx^QlGX>04tZid2qt5*E zsdr&^!(Bz{+DGzvh#!egoDJ1UGeG#u3VuWH{ilP9dD6g|EzMcy&=Kx245j{RF#3V* zYv#Ya3a-H0cHs-s{zo!DIG|3_8Kk3{A}kG71pc}wqB5G&KSgrlX8e|n-GT=RMD3;El^{@6(}c2GVXixdfn} z7g$joQS($wvgiQHwQ|uYS69CFR%TqF4#uSihJ)WteJe5|n!krT?-DN6UGKy(W__ks zm0ePjj)@x{v7~6_wsf#cR2Rt1$hdrw%g)YjAVd1$S{%Av?1&evhqQNIz&e38C#O}n zs0u%Mv^=PMWzpOGQi~%4BrNMwSy@?@J^0@DKwL2AnXG`Dl$zGBk+6}G5!`*y9@L?p zDf@DW@*l7yI<~~PX<3k{XM0A+PrmHcWJ;x)cDE(!`*IfI!;4{s$lHpk0|VML{e^{m z^V~oK`Y>75CX;45f~%(l-*3$IvpOO_tXr$dDIB**ABLVf&jGxcy>}QUhcgrajVj?{ z<59JFVn1ALeBJjXHnyNRL3)sE1Ak)NoL@kK0zY+1_%Z`-xp3D8cxa|L=m?y^H8LDp zq@*)S@sg_lXOB!3&Uv#(rAwpiz;%r;Eh++(S}UH+L;Ah^_`y?OnIGiq=X~$Yd1j?c zr(pA?BQNlJ_>?(ncDcXZcnL?PN6p*Y8}g3}R?+13bZ+_2!bz0b(nq6|f-Dh3>erBM zgwMu@%BrhfAvZ0ma~GbsnpHhu`2Lfhf*msl-jZX(ES>epI}nZq(2QmWczA$S*45NR z%GAtNxOpj3=vlmX7`XoJj?k;7|T|A@}6XBcgKMR_R}w+4LAja)ycT4k+f!aFpGcj6kqD`7g2a~P=}9@ak% zYN=czwAnt)@JLB74xD@ zsD}$UquQ>Ju4FuOhQl&k;@QiBi@5^1j9gaUS(rgk<$i93A?MF7vo;f*365XSAA z|K!J{BPQAjRDQj8GTBH;%ZM$GwTm_xto9b#6E#U6d3Q44Ff>lYlBSJDuS;j+oL4H9 z6Hu~tZl7v65QFt!*bLDPO|X0AA$y6kV$)rQ9J$0^y4IACHf&3@v7 z{`#OysA)byh?PO9AxH?#1JfGxu)2Pw3t9GBEp3J{6f44+FeGldyz%giIt#mEx#Qw8 z)f0vL#eHivXpy&^GgvxvcX!0*R4fPJnbYUx3Yi)kl`rgD8@cMVod9%T1l-(>H?6hR zDUAW?e7&PEddbcG^K%smiHEoYQt5Z-wPnr3@M7rc=;+|dpB=n%?0@=PSZrG9Q^qwY zlC}A_|Cbh*kXegDD_ArgU7i*Mt-=jZOY;S39c+&z;z~(+`?BK{tP`W-j`HX!4ngSC-iq-1dZ+~Hq1 zh4)>?bsB9k?5(b_i9|oH%LrMk`Na!bWdV3nzRJ0s>9>t zZxGRI_d}sE3x?^x$>>X%+7KN%=P&Cc!z`k23f?Pqq-bM!re6gu4w9-FM%?L6121Y%`3xEd{XSHiQx_Zen4)xM@+SAF(|T Xk<;jluP=oM*iWe_-??6{Xdd)m8oTgt diff --git a/docs/diagrams/src/DataStoring/Student Identification.png b/docs/diagrams/src/DataStoring/Student Identification.png index 40f804e1eee5b7a939cc0233e4e0bfbf8df9214c..046087c9c5fc4902c4be6c0040e3eb50d3428373 100644 GIT binary patch literal 19904 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 DP^L$i diff --git a/docs/diagrams/src/DataStoring/studentIdentification.puml b/docs/diagrams/src/DataStoring/studentIdentification.puml index 01e09f22e0..383141b6be 100644 --- a/docs/diagrams/src/DataStoring/studentIdentification.puml +++ b/docs/diagrams/src/DataStoring/studentIdentification.puml @@ -1,62 +1,46 @@ @startuml Student Identification footbox off -participant Class as class -participant findStudentByName as fsbname -database "masterStudentList:Student[ ]" as msl -participant findStudentByNumber as fsbnumber -participant User as user +participant InputParsing as fsbname +participant StudentList as msl - -class -> fsbname : name:String -activate class - -note left - Class here refers to a function - or class that calls - the findStudentByName function -end note +-> fsbname : findStudentByName() activate fsbname fsbname -> msl : name:String activate msl - msl -> fsbname : students:Student[N] + msl --> fsbname : students:Student[N] deactivate msl alt N == 0 - fsbname -> class : null + <-- fsbname : null else N == 1 - fsbname -> class : :Student + <-- fsbname : :Student else N > 1 - fsbname -> fsbnumber : students:Student[N] - activate fsbnumber + fsbname -> fsbname : students:Student[N] + activate fsbname - fsbnumber -> user : promptForPhoneNumber():int - activate user - user -> fsbnumber : number:int - deactivate user + <- fsbname : promptForPhoneNumber():int + --> fsbname : number:int - alt number matches - fsbnumber -> fsbname : :Student - fsbname -> class : :Student + opt number matches + fsbname --> fsbname : :Student + <-- fsbname : :Student else - fsbnumber -> fsbname : null - deactivate fsbnumber + fsbname --> fsbname : null + deactivate fsbname - fsbname -> class : null + <-- fsbname : null deactivate fsbname end end - -deactivate class - @enduml \ No newline at end of file diff --git a/docs/diagrams/src/InputParsing/InputParsingSequenceDiagram.png b/docs/diagrams/src/InputParsing/InputParsingSequenceDiagram.png index 6a9db97dfef35e356bf8e16098d3e87b7d444048..722132eb11c29fd922c2f6b963e5e52e12e6b88c 100644 GIT binary patch delta 3574 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 commands : command to execute activate commands note over commands this command class could refer to - AddStudent, EditStudent, or more + AddStudent, EditStudent, or more. end note commands -> fioc : update stored database activate fioc From db384fda886672ef2e898bfd911520c959287e0d Mon Sep 17 00:00:00 2001 From: Cryolian Date: Tue, 9 Apr 2024 23:23:55 +0800 Subject: [PATCH 266/503] Add logging message --- src/main/java/classify/data/DataReader.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index e069ef19a5..99b98c92e9 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -107,9 +107,7 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Tue, 9 Apr 2024 23:31:55 +0800 Subject: [PATCH 267/503] Add ViewStudent test, not in full --- .../classify/student/ViewStudentTest.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/test/java/classify/student/ViewStudentTest.java diff --git a/src/test/java/classify/student/ViewStudentTest.java b/src/test/java/classify/student/ViewStudentTest.java new file mode 100644 index 0000000000..f18f51af7f --- /dev/null +++ b/src/test/java/classify/student/ViewStudentTest.java @@ -0,0 +1,39 @@ +package classify.student; + +import classify.commands.ViewStudent; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ViewStudentTest { + + private static final String XIAOMING = "Xiao Ming"; + + @Test + void viewStudentTest() { + InputStream in = new ByteArrayInputStream(XIAOMING.getBytes()); + Scanner scanner = new Scanner(in); + + ArrayList masterStudentList = new ArrayList<>(); + Student student = new Student(XIAOMING); + StudentAttributes attributes = new StudentAttributes(student); + List subjectGrades = new ArrayList<>(); + subjectGrades.add(new SubjectGrade("Computer Science", 85.0, 20)); + attributes.addSubjectGrade(subjectGrades.get(0)); + student.setAttributes(attributes); + masterStudentList.add(student); + + ViewStudent.viewStudent(masterStudentList, scanner, null); + + assertEquals(XIAOMING, student.getName()); + assertEquals(85.0, student.getAttributes().getSubjectGrades().get(0).getGrade()); + assertEquals(20, student.getAttributes().getSubjectGrades().get(0).getClassesAttended()); + //currently, does not include the details like phone number and last paid date. + } +} From 004ecc247ebb8b41c3f32b9d5de4f9dd65162a46 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Tue, 9 Apr 2024 23:36:39 +0800 Subject: [PATCH 268/503] Update PPP --- docs/team/tayponghee.md | 8 +++++--- src/test/java/classify/student/ViewStudentTest.java | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/docs/team/tayponghee.md b/docs/team/tayponghee.md index d5505c64da..52c9185a7a 100644 --- a/docs/team/tayponghee.md +++ b/docs/team/tayponghee.md @@ -51,6 +51,8 @@ Given below are my contributions to the project: * Weekly reminders on deadlines for tasks * Handling of pull requests (Examples: [link 1](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/159) [link 2](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/153) [link 3](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/145)) * Contributions to Junit tests - * [StudentAttributesTest] - * [StudentSorterTest] - * [SubjectGradeTest] + * [StudentAttributesTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/student/StudentAttributesTest.java) + * [StudentSorterTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/student/StudentSorterTest.java) + * [SubjectGradeTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/student/SubjectGradeTest.java) + * [AddStudentTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/student/AddStudentTest.java) + * [ViewStudentTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/student/ViewStudentTest.java) diff --git a/src/test/java/classify/student/ViewStudentTest.java b/src/test/java/classify/student/ViewStudentTest.java index f18f51af7f..4b55b7a7cf 100644 --- a/src/test/java/classify/student/ViewStudentTest.java +++ b/src/test/java/classify/student/ViewStudentTest.java @@ -1,4 +1,5 @@ package classify.student; +//@@author tayponghee import classify.commands.ViewStudent; import org.junit.jupiter.api.Test; From b9c769756fa4c63e1989f293cdcf6d76f4472550 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 10 Apr 2024 00:08:37 +0800 Subject: [PATCH 269/503] Add ppp, Edit DG diagrams --- docs/DeveloperGuide.md | 4 +- docs/diagrams/src/DataStoring/DataStoring.png | Bin 0 -> 25166 bytes .../diagrams/src/DataStoring/DataStoring.puml | 1 + docs/diagrams/src/DataStoring/DateStoring.png | Bin 24565 -> 0 bytes ...fication.png => StudentIdentification.png} | Bin .../InputParsingSequenceDiagram.png | Bin 17660 -> 17623 bytes .../src/InputParsing/SequenceDiagram.puml | 6 +-- docs/team/Cryolian.md | 46 ++++++++++++++++++ 8 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 docs/diagrams/src/DataStoring/DataStoring.png delete mode 100644 docs/diagrams/src/DataStoring/DateStoring.png rename docs/diagrams/src/DataStoring/{Student Identification.png => StudentIdentification.png} (100%) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 4ef5027c7f..71b9e2a82e 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -80,7 +80,7 @@ This text file would have the details of the student's name and their attributes In the following component, the guide would go into detail about the implementation for writing and reading to the text file. -![DataStoringUML](./diagrams/src/DataStoring/DateStoring.png) +![DataStoringUML](./diagrams/src/DataStoring/DataStoring.png) #### Design considerations @@ -96,7 +96,7 @@ Since both classes are referencing each other, it was easy for us to link it wit Please see the diagram below to see how identifying a student works. -![studentIdentification](./diagrams/src/DataStoring/Student%20Identification.png) +![studentIdentification](./diagrams/src/DataStoring/StudentIdentification.png) We created a parent `Details` class as those are information not specifically related to students. It can thus be repurposed in future updates should we wish to expand this application into a personnel management system, which would include employees of the tuition centre. diff --git a/docs/diagrams/src/DataStoring/DataStoring.png b/docs/diagrams/src/DataStoring/DataStoring.png new file mode 100644 index 0000000000000000000000000000000000000000..b47a5fd2ba6b0789ad276b1ec374f0e5233001cf GIT binary patch literal 25166 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 literal 0 HcmV?d00001 diff --git a/docs/diagrams/src/DataStoring/DataStoring.puml b/docs/diagrams/src/DataStoring/DataStoring.puml index 06e0cb9ab6..b9d3bc402d 100644 --- a/docs/diagrams/src/DataStoring/DataStoring.puml +++ b/docs/diagrams/src/DataStoring/DataStoring.puml @@ -4,6 +4,7 @@ hide circle class StudentList { {static} +masterStudentList:Student[] {static} +recentlyDeletedList:Student[] + {static} +archiveList:Student[] +studentList:Student[] -- Methods omitted diff --git a/docs/diagrams/src/DataStoring/DateStoring.png b/docs/diagrams/src/DataStoring/DateStoring.png deleted file mode 100644 index c7b5de6b790feb5de800813424c8aa239ef215b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24565 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 diff --git a/docs/diagrams/src/DataStoring/Student Identification.png b/docs/diagrams/src/DataStoring/StudentIdentification.png similarity index 100% rename from docs/diagrams/src/DataStoring/Student Identification.png rename to docs/diagrams/src/DataStoring/StudentIdentification.png diff --git a/docs/diagrams/src/InputParsing/InputParsingSequenceDiagram.png b/docs/diagrams/src/InputParsing/InputParsingSequenceDiagram.png index 722132eb11c29fd922c2f6b963e5e52e12e6b88c..6db0b839efdc9484d7b6a9c590ddaa4ac03a21c0 100644 GIT binary patch literal 17623 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 literal 17660 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 diff --git a/docs/diagrams/src/InputParsing/SequenceDiagram.puml b/docs/diagrams/src/InputParsing/SequenceDiagram.puml index 0671dcd233..e08454ff5c 100644 --- a/docs/diagrams/src/InputParsing/SequenceDiagram.puml +++ b/docs/diagrams/src/InputParsing/SequenceDiagram.puml @@ -3,9 +3,9 @@ hide footbox -participant ":UserInput" as UI -participant ":InputParsing" as IP -participant ":Command" as commands +participant "UserInput" as UI +participant "InputParsing" as IP +participant "Command" as commands participant "DataHandler" as fioc -> UI : processInput(String) diff --git a/docs/team/Cryolian.md b/docs/team/Cryolian.md index e69de29bb2..263c5b90a8 100644 --- a/docs/team/Cryolian.md +++ b/docs/team/Cryolian.md @@ -0,0 +1,46 @@ +# Tan Yi Xin (Cryolian)'s Project Portfolio Page + +## Project: Classify + +Classify is a desktop application used for Tuition Centres to allow for easier management of their enrolled students. +From allowing users to add new students to sorting them based on their last paid date, Classify is the one-stop app that +all Tuition Centres can employ for ease of student management. To use the app, users can interact with it using CLI. +Overall, the code base has more than 3kLoC, and is written in Java. + +Given below are my contributions to the project: + +- **Foundation for the project.** + * Coded out the foundation for the project, which included the Student, Details, StudentList classes. + * Directed the vision of the project, by guiding my group as to how they wanted to implement their assigned functions. + * In charge of learning the architecture and workings of the full code base, to be able to easily identify bug sources and fix them. This also helped when my fellow group members asked about how to go about implementing their functions. + +- **Maintenance of commonly used functions and exceptions.** + * findStudentByName, which was later heavily refactored when students of the same name were allowed to be added which different phone numbers. + * readInString, which would detect when characters used in our save files were used. This function was later used when adding and editing students. + * checkForInvalidCharacters, a function for checking for validity of strings, was also implemented to ensure maximum compatibility with our saving functions. + +- **Extensive bugfinding and fixing** + * Took charge of finding and fixing bugs in my teammates' code, especially since they usually coded without reference to existing changes other members have implemented. + * Took charge of most of the exception handling and throwing when calling features implemented by other members. + +- **Code contributed:** [Link to Reposense contribution graph](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=Cryolian&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2024-02-23&tabOpen=true&tabType=authorship&tabAuthor=Cryolian&tabRepo=AY2324S2-CS2113-T13-3%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code~other&authorshipIsBinaryFileTypeChecked=false&authorshipIsIgnoredFilesChecked=false) + * Majority of my code was done to ensure my group member's code worked well with each other. I focused on making sure everything worked smoothly, and fixing bugs and exceptions, rather than adding features. Essentially acted as the scrum master. + + +- **Documentation:** + * [Contributions to UG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/UserGuide.md): + * Added introduction, quick list of commands, example code and specifications for feature Add Student. + * [Contributions to DG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/DeveloperGuide.md): + * Student Details component, Target user profile, User Stories, and majority of the UMLs. + * UMLs contributed: Class diagrams for Data Storing and Input Parsing, Sequence diagrams for Input Parsing and Student Identification. Created using the PlantUML software. + * [DataStoring UML](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/diagrams/src/DataStoring/DataStoring.png) + * [InputParsing UML](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/diagrams/src/InputParsing/InputParsing.png) + * [InputParsing Sequence Diagram](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/diagrams/src/InputParsing/InputParsingSequenceDiagram.png) + * [Student Identification UML](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/diagrams/src/DataStoring/StudentIdentification.png) + + +- **Contributions to Team-Based tasks:** + * Helped with team administration, ensuring deadlines were met, and doing the team tasks such as enabling assertions and ensuring CI compliance. + * Helped to regularly review code for my team (Exmaples: [Link 1](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/228) [Link 2](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/156) [Link 3](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/99)). While the comments may seem minimal, majority of changes were requested when coding together on discord, or when asked for help through the telegram group chat with the group. + * Created the V1.0 and V2.0 releases on github. + From 460614b476960e18742167bfc0d3d742dc317c2a Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 10 Apr 2024 00:35:48 +0800 Subject: [PATCH 270/503] Add user stories --- docs/DeveloperGuide.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 71b9e2a82e..c559ce65e5 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -219,9 +219,20 @@ Classify serves as an attempt to modernise administrative tasks in education ins |v1.0|new user|see usage instructions|refer to them when I forget how to use the application| |v1.0|existing user|add a student to the database|utilise the functions of the program on a new student. |v1.0|existing user|be able to easily update personal information for specific students such as contact details and emergency contacts|contact them or their parents easily. +|v1.0|existing user|track when a student last paid their fees|know whether to remind their parents about payment. +|v1.0|existing user|track the number of classes a student has attended|track their participation and corresponding fees to pay. |v1.0|existing user|search for students by name in the system|readily pull up data when asked.| +|v1.0|existing user|input remarks for any student|check for any special considerations. |v2.0|existing user|store my data in a file|transfer data between computers.| |v2.0|existing user|sort the students by different attributes|compare them at a glance.| +|v2.0|existing user|quickly archive and unarchive students|easily remove them from the database when they take long absences or go on holidays. +|v2.0|existing user|delete a student from the database|stop tracking them when they have outgrown the age limits of the tuition. +|v2.0|existing user|undo a delete action|quickly recover a student that I may have accidentally deleted +|v2.0|existing user|add students with different names|add students with the same name without a numerical identifier behind. +|v2.0|existing user|sort all students by classes attended|track who will likely score the highest in their national examinations. +|v2.0|existing user|edit subject details for students|stop tracking these subjects when they are no longer being taken. +|v2.0|existing user|sort students by their subjects taken|know who exactly are taking those subjects + ## Non-Functional Requirements From e21307b0824b6b773268e1eefab144eafabad2dc Mon Sep 17 00:00:00 2001 From: Cryolian <102575848+Cryolian@users.noreply.github.com> Date: Wed, 10 Apr 2024 00:40:12 +0800 Subject: [PATCH 271/503] Rename Cryolian.md to cryolian.md --- docs/team/{Cryolian.md => cryolian.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/team/{Cryolian.md => cryolian.md} (100%) diff --git a/docs/team/Cryolian.md b/docs/team/cryolian.md similarity index 100% rename from docs/team/Cryolian.md rename to docs/team/cryolian.md From 669527d1d19ee3af02c09c42cedd490ca4fa8358 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 02:02:33 +0800 Subject: [PATCH 272/503] Remove redundant throwing of exception --- src/main/java/classify/data/DataWriter.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/classify/data/DataWriter.java b/src/main/java/classify/data/DataWriter.java index 5e42ac1d67..6162e1ae6d 100644 --- a/src/main/java/classify/data/DataWriter.java +++ b/src/main/java/classify/data/DataWriter.java @@ -50,9 +50,8 @@ public static void writeStudentInfoFile(List list, String folderPath, * Used to create the parent folder for a certain file * * @param parentPath Path file containing the path of folder we want to make the text file in - * @throws IOException Triggers whenever the input for the path or creation of the directory is improper */ - public static void createParentFileFolder (String parentPath) throws IOException { + public static void createParentFileFolder (String parentPath) { try{ Path path = Paths.get(parentPath); Files.createDirectories(path); @@ -61,7 +60,6 @@ public static void createParentFileFolder (String parentPath) throws IOException //Ignore this error as this should not cause any issues, we dont want replicas of the same file } catch (IOException e){ DataUI.printCreateFailure(); - throw e; } } } From 4655f9830e937ddb33db5f2b7f99afd53c8f4acc Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 02:03:18 +0800 Subject: [PATCH 273/503] Add UI functions for Process Functionality --- src/main/java/classify/ui/UI.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 9e7e4677af..fb0c952c49 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -95,6 +95,7 @@ public static void printHelp() { printSortHelpMessage(); printArchiveHelpMessage(); printUnarchiveHelpMessage(); + printProcessTextFileInput(); System.out.println("help Prints this help message"); } @@ -181,6 +182,12 @@ public static void printEndConversation() { printDivider(); } + public static void printProcessTextFileInput(){ + System.out.println("Process " + + "Processes a text file which has been added by a user" + + " Process "); + } + //@@author blackmirag3 public static void printSubsequentUserPrompt() { System.out.println(WHAT_ELSE_CAN_I_DO_FOR_YOU_TODAY); From 4d9b9aaf2c820511fe0b6977c5dae110f7ebbd05 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 02:04:22 +0800 Subject: [PATCH 274/503] Add Process functionalities ot Main and Inputparsing classes --- src/main/java/classify/Classify.java | 2 ++ src/main/java/classify/user/InputParsing.java | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 6a3e706480..b6f8ad0fab 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -2,6 +2,7 @@ import classify.data.DataHandler; import classify.student.StudentList; +import classify.textfilecode.TextFileHandler; import classify.user.InputParsing; import classify.user.UserInput; import classify.ui.UI; @@ -23,6 +24,7 @@ public static void main(String[] args) throws IOException { //@@author blackmirag3 DataHandler.readArchive(StudentList.archiveList); //@@author ParthGandhiNUS + TextFileHandler.createTextFileDirectory(); UI.printWelcomeMessage(); // Takes in input from the user, and processes input to determine if it contains a command and a name diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 028dc454e0..9441735217 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -9,6 +9,7 @@ import classify.commands.ViewStudent; import classify.data.DataHandler; import classify.student.Student; +import classify.textfilecode.TextFileHandler; import classify.ui.UI; import java.time.LocalDate; @@ -25,6 +26,7 @@ public class InputParsing { private static final String EARLIER_POSSIBLE_DATE = "1970-01-01"; private static final String BYE = "bye"; private static final String LIST = "list"; + private static final String PROCESS_FILE = "process"; private static final String ADD = "add"; private static final String VIEW = "view"; private static final String DELETE = "delete"; @@ -106,6 +108,10 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas parseListCommand(masterStudentList, archiveList, recentlyDeletedList, in); } break; + + case PROCESS_FILE: + TextFileHandler.process(masterStudentList, in, userCommand[1]); + break; //@@ author tayponghee case SORT: From 544c94ad5396dde0ec0d985623c5744d26c9fda0 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 02:05:52 +0800 Subject: [PATCH 275/503] Add TextFileReader Class --- .../classify/textfilecode/TextFileReader.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/main/java/classify/textfilecode/TextFileReader.java diff --git a/src/main/java/classify/textfilecode/TextFileReader.java b/src/main/java/classify/textfilecode/TextFileReader.java new file mode 100644 index 0000000000..d31884817f --- /dev/null +++ b/src/main/java/classify/textfilecode/TextFileReader.java @@ -0,0 +1,42 @@ +package classify.textfilecode; + +import java.io.File; +//@@author ParthGandhiNUS +public class TextFileReader { + /** + * Extracted method to convert Path from String to File form. + * Also calls the get currentFiles method. + * + * @param pathnameString String contaning the filepath + */ + public static void printCurrentInputFolder(String pathnameString){ + File currentDirectory = new File (pathnameString); + getCurrentFiles(currentDirectory); + } + + /** + * Prints out all the files in the path of currentDirectory + * + * @param currentDirectory File where we are querying for the files + */ + private static void getCurrentFiles(File currentDirectory){ + File[] fileList = currentDirectory.listFiles(); + + if (fileList.length == 0 || fileList == null){ + System.out.println("No files in your Input Folder!\n" + + "Please add some new files in the correct format!"); + } else { + assert fileList != null; + + Integer index = 1; + for (File newFile : fileList){ + if (newFile.isFile() && TextFileParser.textFileChecker(newFile.getName())){ + System.out.println(index +". " + newFile.getName()); + index++; + } + } + System.out.println(""); + } + } + +} From acd476fdf42c387a27420ebcbfea0c62bf6f7400 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 02:06:10 +0800 Subject: [PATCH 276/503] Add TextFileHandler Class --- .../textfilecode/TextFileHandler.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/main/java/classify/textfilecode/TextFileHandler.java diff --git a/src/main/java/classify/textfilecode/TextFileHandler.java b/src/main/java/classify/textfilecode/TextFileHandler.java new file mode 100644 index 0000000000..6f4f1ae46b --- /dev/null +++ b/src/main/java/classify/textfilecode/TextFileHandler.java @@ -0,0 +1,42 @@ +package classify.textfilecode; + +import java.io.IOException; +import java.nio.file.FileAlreadyExistsException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Scanner; + +import classify.student.Student; +import classify.ui.UI; + +//@@author ParthGandhiNUS +public class TextFileHandler { + private static final String CURRENT_FILES = "Current Files in your Input Folder:"; + private static final String INPUT_TEXT_FILE_DIRECTORY = "./data/inputFolder"; + private static final String IO_EXCEPTION_MESSAGE_FOR_TEXT_FILE = "Something went horribly wrong while creating your data folder!"; + + public static void process(ArrayList masterStudentList, Scanner in, String textFileName) { + + createTextFileDirectory(); + // Print out the current files in your folder + UI.println(CURRENT_FILES); + TextFileReader.printCurrentInputFolder(INPUT_TEXT_FILE_DIRECTORY); + } + + /** + * Used to create the parent folder for a text file for Inputting + */ + public static void createTextFileDirectory(){ + //Folder Creation if folder not there + try{ + Path path = Paths.get(INPUT_TEXT_FILE_DIRECTORY); + Files.createDirectories(path); + } catch (FileAlreadyExistsException ignored){ + //Ignore this error as this should not cause any issues, we dont want replicas of the same file + } catch (IOException e){ + UI.println(IO_EXCEPTION_MESSAGE_FOR_TEXT_FILE); + } + } +} From 98b9fa527939efa1a4f53e0a7010cc33694bec42 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 02:06:23 +0800 Subject: [PATCH 277/503] Add TextFileParser Class --- .../classify/textfilecode/TextFileParser.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/main/java/classify/textfilecode/TextFileParser.java diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java new file mode 100644 index 0000000000..958a0f2e41 --- /dev/null +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -0,0 +1,36 @@ +package classify.textfilecode; + +import java.util.Scanner; + +//@@author ParthGandhiNUS +public class TextFileParser { + + /** + * Boolean that checks for the filetype of the files. + * Returns true if filetype is .txt, false otherwise. + * + * @param textFileName Name of the file + * @return True or False depending on the filetype of file + */ + public static Boolean textFileChecker(String textFileName){ + String type = ""; + int i = textFileName.lastIndexOf('.'); + if (i >= 0) { + type = textFileName.substring(i+1); + } + + if (type.equals("txt")) { + return true; + } + return false; + } + + /** + * Basically prints the prompt for the user to select valid file + */ + public static void promptForFileSelection(Scanner in){ + System.out.println("Please enter the number of the file you'd like to process:"); + } + + //private void +} From 8f68c7d5fb0374279d6f54bed38fd2b75cc050ba Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 02:58:42 +0800 Subject: [PATCH 278/503] Add findMatchingFile Method --- .../classify/textfilecode/TextFileParser.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index 958a0f2e41..af722eec7c 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -33,4 +33,23 @@ public static void promptForFileSelection(Scanner in){ } //private void + private static Integer findMatchingFile(File[] filelist, String userInput) { + String input = userInput.toLowerCase().trim(); + for (int i = 0; i < filelist.length; i++){ + String fileName = filelist[i].getName().toLowerCase().trim(); + int dotIndex = fileName.lastIndexOf('.'); + String fileNameWithoutType = fileName.substring(0,dotIndex); + + // Return match with the type + if (input.equals(fileName)){ + return i; + } + + // Return match without the type + if (input.equals(fileNameWithoutType)){ + return i; + } + } + return -1; + } } From 872e0dde4fb2d39ad301971c5bffff7c1ab52d19 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 02:59:21 +0800 Subject: [PATCH 279/503] Add parseUserSelection Method --- .../classify/textfilecode/TextFileParser.java | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index af722eec7c..0c577fa629 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -1,9 +1,11 @@ package classify.textfilecode; +import java.io.File; import java.util.Scanner; //@@author ParthGandhiNUS public class TextFileParser { + private static final String FILESELECTIONPROMPT = "Please enter the exact name of the file you'd like to process:"; /** * Boolean that checks for the filetype of the files. @@ -28,11 +30,32 @@ public static Boolean textFileChecker(String textFileName){ /** * Basically prints the prompt for the user to select valid file */ - public static void promptForFileSelection(Scanner in){ - System.out.println("Please enter the number of the file you'd like to process:"); + public static void promptForFileSelection(){ + System.out.println(FILESELECTIONPROMPT); + } + + public static void promptForFileSelectionAgain(){ + System.out.println("Please try again!"); + System.out.println(FILESELECTIONPROMPT); + } + + public static void parseUserSelection(File currentDirectory,Scanner in){ + File[] fileList = currentDirectory.listFiles(); + String userinput = in.nextLine(); + + int matchIndex = findMatchingFile(fileList, userinput); + + if (matchIndex == -1){ + System.out.println("No Match Found!"); + promptForFileSelectionAgain(); + parseUserSelection(TextFileHandler.currentDirectory, in); + return; + } + + //Basically now need to parse the file selected + } - //private void private static Integer findMatchingFile(File[] filelist, String userInput) { String input = userInput.toLowerCase().trim(); for (int i = 0; i < filelist.length; i++){ From 15d82168e5139ae406334a6187aceaad1cfaab34 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 02:59:53 +0800 Subject: [PATCH 280/503] Update TextFileHandler Class with new functionalities --- src/main/java/classify/textfilecode/TextFileHandler.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/textfilecode/TextFileHandler.java b/src/main/java/classify/textfilecode/TextFileHandler.java index 6f4f1ae46b..42af72c9ca 100644 --- a/src/main/java/classify/textfilecode/TextFileHandler.java +++ b/src/main/java/classify/textfilecode/TextFileHandler.java @@ -1,5 +1,6 @@ package classify.textfilecode; +import java.io.File; import java.io.IOException; import java.nio.file.FileAlreadyExistsException; import java.nio.file.Files; @@ -16,13 +17,15 @@ public class TextFileHandler { private static final String CURRENT_FILES = "Current Files in your Input Folder:"; private static final String INPUT_TEXT_FILE_DIRECTORY = "./data/inputFolder"; private static final String IO_EXCEPTION_MESSAGE_FOR_TEXT_FILE = "Something went horribly wrong while creating your data folder!"; + public static final File currentDirectory = new File (INPUT_TEXT_FILE_DIRECTORY); public static void process(ArrayList masterStudentList, Scanner in, String textFileName) { - createTextFileDirectory(); // Print out the current files in your folder UI.println(CURRENT_FILES); TextFileReader.printCurrentInputFolder(INPUT_TEXT_FILE_DIRECTORY); + TextFileParser.promptForFileSelection(); + TextFileParser.parseUserSelection(currentDirectory, in); } /** From 7c95a2fefaeea9a25376aaaaa8387fbf7fadd6b7 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 04:53:43 +0800 Subject: [PATCH 281/503] Update test case --- src/test/java/classify/user/InputParsingTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index 1f5f824373..0c5109f59e 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -114,6 +114,8 @@ public void testHelpCommand() { "unarchive Removes the specified student from the archive and adds them to the list" + ", can be used directly by unarchive [name]." + System.lineSeparator() + + "process Processes a text file which has been added by a user" + + System.lineSeparator() + "help Prints this help message" + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; From 4403cb052eba260d5eec84539295a94ffb378f2c Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 04:54:22 +0800 Subject: [PATCH 282/503] Clean up TextFileHandler --- .../classify/textfilecode/TextFileHandler.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/classify/textfilecode/TextFileHandler.java b/src/main/java/classify/textfilecode/TextFileHandler.java index 42af72c9ca..d1824b7644 100644 --- a/src/main/java/classify/textfilecode/TextFileHandler.java +++ b/src/main/java/classify/textfilecode/TextFileHandler.java @@ -1,5 +1,8 @@ package classify.textfilecode; +import classify.student.Student; +import classify.ui.UI; + import java.io.File; import java.io.IOException; import java.nio.file.FileAlreadyExistsException; @@ -9,23 +12,21 @@ import java.util.ArrayList; import java.util.Scanner; -import classify.student.Student; -import classify.ui.UI; - //@@author ParthGandhiNUS public class TextFileHandler { private static final String CURRENT_FILES = "Current Files in your Input Folder:"; private static final String INPUT_TEXT_FILE_DIRECTORY = "./data/inputFolder"; - private static final String IO_EXCEPTION_MESSAGE_FOR_TEXT_FILE = "Something went horribly wrong while creating your data folder!"; - public static final File currentDirectory = new File (INPUT_TEXT_FILE_DIRECTORY); + private static final String IO_EXCEPTION_MESSAGE_FOR_TEXT_FILE = "Something went horribly wrong while creating " + + "your data folder!"; + public static final File CURRENT_DIRECTORY = new File (INPUT_TEXT_FILE_DIRECTORY); - public static void process(ArrayList masterStudentList, Scanner in, String textFileName) { + public static void process(ArrayList masterStudentList, Scanner in) { createTextFileDirectory(); // Print out the current files in your folder UI.println(CURRENT_FILES); TextFileReader.printCurrentInputFolder(INPUT_TEXT_FILE_DIRECTORY); TextFileParser.promptForFileSelection(); - TextFileParser.parseUserSelection(currentDirectory, in); + TextFileParser.parseUserSelection(CURRENT_DIRECTORY, in, masterStudentList); } /** @@ -37,7 +38,7 @@ public static void createTextFileDirectory(){ Path path = Paths.get(INPUT_TEXT_FILE_DIRECTORY); Files.createDirectories(path); } catch (FileAlreadyExistsException ignored){ - //Ignore this error as this should not cause any issues, we dont want replicas of the same file + //Ignore this error as this should not cause any issues, we don't want replicas of the same file } catch (IOException e){ UI.println(IO_EXCEPTION_MESSAGE_FOR_TEXT_FILE); } From 0e533a18ffc16a98177a665d82e4c21f2f2cfcd1 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 04:54:41 +0800 Subject: [PATCH 283/503] Update UI Class --- src/main/java/classify/ui/UI.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index fb0c952c49..0c07c7f12f 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -183,9 +183,8 @@ public static void printEndConversation() { } public static void printProcessTextFileInput(){ - System.out.println("Process " + - "Processes a text file which has been added by a user" + - " Process "); + System.out.println("process " + + "Processes a text file which has been added by a user"); } //@@author blackmirag3 From a65ff3e7675e81728c5451bbada72dc132db1e80 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 04:55:02 +0800 Subject: [PATCH 284/503] Updater InputParsing --- src/main/java/classify/user/InputParsing.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 9441735217..d22c565bae 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -111,6 +111,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas case PROCESS_FILE: TextFileHandler.process(masterStudentList, in, userCommand[1]); + DataHandler.writeStudentInfo(masterStudentList); break; //@@ author tayponghee From b2483b3baa5b607c804bf34364a597525dc101a6 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 04:55:21 +0800 Subject: [PATCH 285/503] Update parsing of text files --- .../classify/textfilecode/TextFileParser.java | 169 +++++++++++++++--- 1 file changed, 145 insertions(+), 24 deletions(-) diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index 0c577fa629..d2c645866a 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -1,12 +1,45 @@ package classify.textfilecode; +import classify.data.DataReader; +import classify.student.Student; +import classify.student.StudentList; +import classify.student.SubjectGrade; +import classify.ui.DataUI; +import classify.ui.UI; +import classify.user.InputParsing; +import classify.user.InvalidCharacterException; +import classify.user.NameNumberMatchException; + +import java.io.BufferedReader; +import java.io.IOException; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.time.LocalDate; +import java.time.format.DateTimeParseException; +import java.util.ArrayList; import java.util.Scanner; //@@author ParthGandhiNUS public class TextFileParser { - private static final String FILESELECTIONPROMPT = "Please enter the exact name of the file you'd like to process:"; - + private static final String MAIN_REGEX = "~~"; + private static final String SUBJECT_INFO_REGEX = "##"; + private static final String FILE_SELECTION_PROMPT = "Please enter the exact name of the file " + + "you'd like to process:"; + private static final String REQUEST_TO_TRY_AGAIN = "Please try again!"; + private static final String TEXT_TYPE = "txt"; + private static final Character DOT = '.'; + private static final String NO_MATCH_FOUND = "No Match Found!"; + private static final String ERROR_ACCESSING_THE_FILE = "Something went wrong while accessing the file"; + private static final Integer NAME = 0; + private static final Integer GENDER = 1; + private static final Integer PHONE_NUMBER = 2; + private static final Integer LAST_PAYMENT_DATE = 3; + private static final Integer REMARKS = 4; + private static final Integer SUBJECTS = 5; + private static final Integer GRADE_FOR_SUBJECT = 0; + private static final Integer NUMBER_OF_CLASSES_ATTENDED = 1; + private static final String INPUT_TEXT_FILE_DIRECTORY = "./data/inputFolder"; /** * Boolean that checks for the filetype of the files. * Returns true if filetype is .txt, false otherwise. @@ -16,51 +49,139 @@ public class TextFileParser { */ public static Boolean textFileChecker(String textFileName){ String type = ""; - int i = textFileName.lastIndexOf('.'); + int i = textFileName.lastIndexOf(DOT); if (i >= 0) { type = textFileName.substring(i+1); } - - if (type.equals("txt")) { - return true; - } - return false; + + return type.equals(TEXT_TYPE); } /** - * Basically prints the prompt for the user to select valid file + * Prints the prompt for the user to select valid file */ public static void promptForFileSelection(){ - System.out.println(FILESELECTIONPROMPT); + System.out.println(FILE_SELECTION_PROMPT); } + /** + * Prints the prompt for the user to select valid file after entering a wrong input before. + */ public static void promptForFileSelectionAgain(){ - System.out.println("Please try again!"); - System.out.println(FILESELECTIONPROMPT); + System.out.println(REQUEST_TO_TRY_AGAIN); + System.out.println(FILE_SELECTION_PROMPT); } + + public static void parseUserSelection(File currentDirectory, Scanner in, ArrayList masterStudentList){ + File[] fileList = currentDirectory.listFiles(); + String userInput = in.nextLine(); - public static void parseUserSelection(File currentDirectory,Scanner in){ - File[] fileList = currentDirectory.listFiles(); - String userinput = in.nextLine(); - - int matchIndex = findMatchingFile(fileList, userinput); + assert fileList != null; + int matchIndex = findMatchingFile(fileList, userInput); if (matchIndex == -1){ - System.out.println("No Match Found!"); + System.out.println(NO_MATCH_FOUND); promptForFileSelectionAgain(); - parseUserSelection(TextFileHandler.currentDirectory, in); + parseUserSelection(TextFileHandler.CURRENT_DIRECTORY, in, masterStudentList); return; } - //Basically now need to parse the file selected + parseTextFile(fileList, matchIndex, masterStudentList); } - private static Integer findMatchingFile(File[] filelist, String userInput) { + private static void parseTextFile(File[] fileList, Integer matchIndex, ArrayList masterStudentList){ + String fileNameString = fileList[matchIndex].getName().trim(); + String fullFilePath = INPUT_TEXT_FILE_DIRECTORY + "/" + fileNameString; + try { + FileReader textfileReader = new FileReader(fullFilePath); + BufferedReader line = new BufferedReader(textfileReader); + UI.println("Fetching the data from " + fileNameString + "."); + fetchDataFromTextFile(line, masterStudentList); + + } catch (FileNotFoundException e) { + UI.println(ERROR_ACCESSING_THE_FILE); + } + + } + + private static void fetchDataFromTextFile(BufferedReader line, ArrayList masterStudentList) { + try{ + String firstLine = line.readLine(); + String [] subjectInfoStrings = firstLine.split("Subject:"); + String subjectName = subjectInfoStrings[1].trim(); + + while (line.ready()){ + String input = line.readLine(); + decodeTextFile(input, subjectName, masterStudentList); + } + } catch (IOException e) { + UI.println(ERROR_ACCESSING_THE_FILE); + } + } + + private static void decodeTextFile (String textFileInput, String subjectName, + ArrayList masterStudentList){ + if (textFileInput.trim().isBlank()){ + return; + } + String [] inputArr = textFileInput.split(MAIN_REGEX); + + //Set Name + Student student = new Student(inputArr[NAME].trim()); + masterStudentList.add(student); + //Set Gender + student.getAttributes().setGender(inputArr[GENDER].trim()); + //Set Phone Number + try { + + InputParsing.checkForSpecialCharacters(student.getName()); + InputParsing.checkForSpecialCharacters(student.getGender()); + int phoneNumber = Integer.parseInt(inputArr[PHONE_NUMBER].trim()); + StudentList.checkNameNumberPair(StudentList.masterStudentList, student.getName(), phoneNumber); + StudentList.checkNameNumberPair(StudentList.archiveList, student.getName(), phoneNumber); + student.getAttributes().setPhoneNumber(phoneNumber); + } catch (NumberFormatException e) { + DataUI.phoneNumberParsingError(); + return; + } catch (NameNumberMatchException e) { + DataUI.nameNumberPair(); + return; + } catch (InvalidCharacterException e) { + DataUI.invalidCharacterExceptionMessage(); + return; + } + //Set Last Payment Date + try { + LocalDate inputLastPaymentDate = DataReader.convertStringInput(inputArr[LAST_PAYMENT_DATE].trim()); + student.getAttributes().setLastPaymentDate(inputLastPaymentDate); + } catch (DateTimeParseException e) { + DataUI.lastPaymentDateParseExceptionMessage(); + } + //Set remarks + student.getAttributes().setRemarks(inputArr[REMARKS].trim()); + + String [] subjectInformation = inputArr[SUBJECTS].trim().split(SUBJECT_INFO_REGEX); + //Set grades + double subjectGrades = Double.parseDouble(subjectInformation[GRADE_FOR_SUBJECT].trim()); + //Set Classes Attended + int subjectClassesAttended = Integer.parseInt(subjectInformation[NUMBER_OF_CLASSES_ATTENDED].trim()); + SubjectGrade newSubject = new SubjectGrade(subjectName, subjectGrades, subjectClassesAttended); + student.getAttributes().addSubjectGrade(newSubject); + } + + /** + * This method returns the index of file which matches the user's input for file to be processed + * + * @param fileList List of files in current directory + * @param userInput User's input + * @return Returns the index of the match found or else returns -1. + */ + private static Integer findMatchingFile(File[] fileList, String userInput) { String input = userInput.toLowerCase().trim(); - for (int i = 0; i < filelist.length; i++){ - String fileName = filelist[i].getName().toLowerCase().trim(); - int dotIndex = fileName.lastIndexOf('.'); + for (int i = 0; i < fileList.length; i++){ + String fileName = fileList[i].getName().toLowerCase().trim(); + int dotIndex = fileName.lastIndexOf(DOT); String fileNameWithoutType = fileName.substring(0,dotIndex); // Return match with the type From 03e0276a41657a4eededda0f0bde53ea8130505a Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 04:58:36 +0800 Subject: [PATCH 286/503] Update Expected.Txt --- text-ui-test/EXPECTED.TXT | 1 - 1 file changed, 1 deletion(-) diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index f402f407a2..4d0a6e0c75 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -7,6 +7,5 @@ Creating a new data file... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Welcome to Classify! What can I do for you today? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Hope you've had a productive day. See you again! Goodbye! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From a8902bea3fb8a4ad6b98831fc288daf2050162ae Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 04:59:02 +0800 Subject: [PATCH 287/503] Update InputParsing Class --- src/main/java/classify/user/InputParsing.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index d22c565bae..b9feaa3e36 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -110,7 +110,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas break; case PROCESS_FILE: - TextFileHandler.process(masterStudentList, in, userCommand[1]); + TextFileHandler.process(masterStudentList, in); DataHandler.writeStudentInfo(masterStudentList); break; From 65fe37f678f78998ef37f8aad835c04b2c0aea14 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 10 Apr 2024 11:19:53 +0800 Subject: [PATCH 288/503] Add repeated student checks to undo --- .../java/classify/commands/DeleteCommands.java | 15 +++++++++++++++ src/main/java/classify/student/StudentList.java | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index 2494eb7da6..8b57f440d8 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -114,6 +114,21 @@ public static void undoDelete(ArrayList masterStudentList, ArrayList studentList, String name, int number) throws NameNumberMatchException, NullPointerException { + + if (studentList == null || studentList.isEmpty()) { + return; + } for (Student s : studentList) { if (s.getName().equalsIgnoreCase(name) && s.getPhoneNumber() == number) { From 08939e38744bd34b00028defe971b284d3e65954 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 10 Apr 2024 16:19:46 +0800 Subject: [PATCH 289/503] Add checkNameNumberPair junit --- .../java/classify/student/StudentList.java | 24 +++++++++++++ .../classify/student/StudentListTest.java | 36 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 src/test/java/classify/student/StudentListTest.java diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 776e6f8bff..bf5cf7f8f5 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -132,4 +132,28 @@ public static void checkNameNumberPair(ArrayList studentList, String na } + /** + * Function checks if a name and number pair already exists in a given list. + * Throws an exception if it does. + * @param studentList List to check through for the name and number. + * @param name Name of the student to find. + * @param number Phone number of the student to find. + * @throws nameNumberMatchException Thrown if a match is found. + */ + public static void checkNameNumberPair(StudentList studentList, String name, int number) + throws NameNumberMatchException, NullPointerException { + + if (studentList.studentList == null || studentList.studentList.isEmpty()) { + return; + } + + for (Student s : studentList.studentList) { + if (s.getName().equalsIgnoreCase(name) && s.getPhoneNumber() == number) { + throw new NameNumberMatchException("Student with the same " + + "name and phone number found."); + } + } + + } + } diff --git a/src/test/java/classify/student/StudentListTest.java b/src/test/java/classify/student/StudentListTest.java new file mode 100644 index 0000000000..2c3dbccc86 --- /dev/null +++ b/src/test/java/classify/student/StudentListTest.java @@ -0,0 +1,36 @@ +//@@author Cryolian +package classify.student; + +import classify.user.NameNumberMatchException; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class StudentListTest { + + @Test + void checkNameNumberPairTest() { + StudentList studentList = new StudentList(); + + Student alpha = new Student("alpha"); + alpha.getAttributes().setPhoneNumber(99999999); + + studentList.addStudent(alpha); + + boolean exceptionThrown = false; + + try { + StudentList.checkNameNumberPair(studentList, alpha.getName() , alpha.getPhoneNumber()); + } catch (NameNumberMatchException e) { + exceptionThrown = true; + } catch (NullPointerException e) { + + } + + assertEquals(studentList.studentList.get(0), alpha); + assertTrue(exceptionThrown); + } + +} From e0c2012dfd20ea7498b33f9e60ec09241a9c5d79 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 10 Apr 2024 16:39:17 +0800 Subject: [PATCH 290/503] Add findStudentByNameTest --- docs/team/tayponghee.md | 6 ++--- .../{student => commands}/AddStudentTest.java | 4 +-- .../StudentSorterTest.java | 7 +++-- .../ViewStudentTest.java | 7 +++-- .../java/classify/user/InputParsingTest.java | 26 +++++++++++++++++++ 5 files changed, 41 insertions(+), 9 deletions(-) rename src/test/java/classify/{student => commands}/AddStudentTest.java (96%) rename src/test/java/classify/{student => commands}/StudentSorterTest.java (94%) rename src/test/java/classify/{student => commands}/ViewStudentTest.java (90%) diff --git a/docs/team/tayponghee.md b/docs/team/tayponghee.md index 52c9185a7a..d55ef61ae4 100644 --- a/docs/team/tayponghee.md +++ b/docs/team/tayponghee.md @@ -52,7 +52,7 @@ Given below are my contributions to the project: * Handling of pull requests (Examples: [link 1](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/159) [link 2](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/153) [link 3](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/145)) * Contributions to Junit tests * [StudentAttributesTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/student/StudentAttributesTest.java) - * [StudentSorterTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/student/StudentSorterTest.java) + * [StudentSorterTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/StudentSorterTest.java) * [SubjectGradeTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/student/SubjectGradeTest.java) - * [AddStudentTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/student/AddStudentTest.java) - * [ViewStudentTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/student/ViewStudentTest.java) + * [AddStudentTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/AddStudentTest.java) + * [ViewStudentTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/ViewStudentTest.java) diff --git a/src/test/java/classify/student/AddStudentTest.java b/src/test/java/classify/commands/AddStudentTest.java similarity index 96% rename from src/test/java/classify/student/AddStudentTest.java rename to src/test/java/classify/commands/AddStudentTest.java index ca2189eb0f..9159c0fbba 100644 --- a/src/test/java/classify/student/AddStudentTest.java +++ b/src/test/java/classify/commands/AddStudentTest.java @@ -1,7 +1,7 @@ -package classify.student; +package classify.commands; //@@author tayponghee -import classify.commands.AddStudent; +import classify.student.Student; import classify.user.InputParsing; import classify.user.InvalidCharacterException; import org.junit.jupiter.api.Test; diff --git a/src/test/java/classify/student/StudentSorterTest.java b/src/test/java/classify/commands/StudentSorterTest.java similarity index 94% rename from src/test/java/classify/student/StudentSorterTest.java rename to src/test/java/classify/commands/StudentSorterTest.java index 7c89fb8c6a..1bde38fd3c 100644 --- a/src/test/java/classify/student/StudentSorterTest.java +++ b/src/test/java/classify/commands/StudentSorterTest.java @@ -1,8 +1,11 @@ -package classify.student; +//@@author tayponghee +package classify.commands; import org.junit.jupiter.api.Test; -import classify.commands.StudentSorter; +import classify.student.Student; +import classify.student.StudentAttributes; +import classify.student.SubjectGrade; import java.util.ArrayList; diff --git a/src/test/java/classify/student/ViewStudentTest.java b/src/test/java/classify/commands/ViewStudentTest.java similarity index 90% rename from src/test/java/classify/student/ViewStudentTest.java rename to src/test/java/classify/commands/ViewStudentTest.java index 4b55b7a7cf..dd4e18965f 100644 --- a/src/test/java/classify/student/ViewStudentTest.java +++ b/src/test/java/classify/commands/ViewStudentTest.java @@ -1,7 +1,10 @@ -package classify.student; +package classify.commands; //@@author tayponghee -import classify.commands.ViewStudent; +import classify.student.Student; +import classify.student.StudentAttributes; +import classify.student.SubjectGrade; + import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index 1f5f824373..89c6cb7a96 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -1,6 +1,7 @@ package classify.user; import classify.student.Student; +import classify.student.StudentList; import org.junit.jupiter.api.Test; @@ -161,4 +162,29 @@ public void testParseDateFromString() { assertEquals(date, LocalDate.now().plusDays(2)); } + + @Test + public void findStudentByNameMultipleTest() { + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outputStream)); + + String userInputName = "Alpha"; + String userInputNumber = "88888888"; + + System.setIn(new ByteArrayInputStream((userInputNumber).getBytes())); + Scanner scanner = new Scanner(System.in); + + StudentList studentList = new StudentList(); + Student alpha1 = new Student("Alpha"); + Student alpha2 = new Student("Alpha"); + + alpha1.getAttributes().setPhoneNumber(99999999); + studentList.addStudent(alpha1); + alpha2.getAttributes().setPhoneNumber(88888888); + studentList.addStudent(alpha2); + + Student target = InputParsing.findStudentByName(studentList.studentList, userInputName, scanner); + assertEquals(alpha2, target); + } } From b9308622b1e7c5238090546d428743314bb13639 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 10 Apr 2024 16:59:28 +0800 Subject: [PATCH 291/503] Add special character name test --- src/test/java/classify/commands/AddStudentTest.java | 12 ++++++++++++ src/test/java/classify/user/InputParsingTest.java | 1 + 2 files changed, 13 insertions(+) diff --git a/src/test/java/classify/commands/AddStudentTest.java b/src/test/java/classify/commands/AddStudentTest.java index 9159c0fbba..9da2f6dac8 100644 --- a/src/test/java/classify/commands/AddStudentTest.java +++ b/src/test/java/classify/commands/AddStudentTest.java @@ -2,6 +2,7 @@ //@@author tayponghee import classify.student.Student; +import classify.student.StudentList; import classify.user.InputParsing; import classify.user.InvalidCharacterException; import org.junit.jupiter.api.Test; @@ -64,4 +65,15 @@ void findStudentByNameExisting() { assertNull(foundStudent); } + //@@author Cryolian + @Test + void addSpecialCharactersTest() { + StudentList studentList = new StudentList(); + Scanner scanner = new Scanner("muli----"); + + AddStudent.addStudent(studentList.studentList, scanner, null); + assertTrue(studentList.studentList.size() == 0); + + } + } diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index 89c6cb7a96..e9f3cb7a87 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -187,4 +187,5 @@ public void findStudentByNameMultipleTest() { Student target = InputParsing.findStudentByName(studentList.studentList, userInputName, scanner); assertEquals(alpha2, target); } + } From 7707e7a750650d3bb3f7d95186da20314835a270 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 10 Apr 2024 17:03:51 +0800 Subject: [PATCH 292/503] Fix checkstyle violations --- src/test/java/classify/student/StudentListTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/classify/student/StudentListTest.java b/src/test/java/classify/student/StudentListTest.java index 2c3dbccc86..ed7b2d161d 100644 --- a/src/test/java/classify/student/StudentListTest.java +++ b/src/test/java/classify/student/StudentListTest.java @@ -26,7 +26,7 @@ void checkNameNumberPairTest() { } catch (NameNumberMatchException e) { exceptionThrown = true; } catch (NullPointerException e) { - + exceptionThrown = false; //wrong exception thrown } assertEquals(studentList.studentList.get(0), alpha); From e4cb57f0e271c14beb1720c0c95ce268d78b3320 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 10 Apr 2024 17:18:49 +0800 Subject: [PATCH 293/503] Remove view_subject command --- src/main/java/classify/user/InputParsing.java | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 028dc454e0..56a4fa1673 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -35,7 +35,6 @@ public class InputParsing { private static final String SORT = "sort"; private static final String ARCHIVE = "archive"; private static final String UNARCHIVE = "unarchive"; - private static final String VIEW_SUBJECT = "view_subject"; private static final String ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK = "Enter the subject name (type 'exit' to go back):"; private static final String EXIT = "exit"; @@ -112,10 +111,6 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas sortStudents(masterStudentList, in, userCommand[1]); break; - case VIEW_SUBJECT: - handleViewSubjectCommand(masterStudentList, in, userCommand[1]); - break; - //@@author blackmirag3 case EDIT: EditStudent.editStudent(in, userCommand[1]); @@ -189,26 +184,6 @@ private static void sortStudents(ArrayList masterStudentList, Scanner i } } - /** - * Lets the user check view a list of students with that corresponding subject. - * If the user types view_subject [subject], it will only generate the list of - * students with that subject, - * then exit. - * If the user types view_subject, the user can continuously view all students - * that - * have that subject, until they exit the command. - * - * @param masterStudentList The list of all students. - * @param in The user's input. - */ - private static void handleViewSubjectCommand(ArrayList masterStudentList, Scanner in, String subject) { - if (subject != null && !subject.isEmpty()) { - ListStudentsCommand.listStudentsBySubject(masterStudentList, subject); - } else { - findStudentsWithSubject(masterStudentList, in); - } - } - /** * Finds students with the specified subject and displays them to the user. * Continuously prompts the user to enter a subject name until they choose to From 8d6285e0904d2e8ead2d736f98e753d3a96259dd Mon Sep 17 00:00:00 2001 From: Cryolian Date: Wed, 10 Apr 2024 17:24:12 +0800 Subject: [PATCH 294/503] Remove unused method --- src/main/java/classify/user/InputParsing.java | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 56a4fa1673..a221261095 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -184,35 +184,6 @@ private static void sortStudents(ArrayList masterStudentList, Scanner i } } - /** - * Finds students with the specified subject and displays them to the user. - * Continuously prompts the user to enter a subject name until they choose to - * exit. - * - * @param masterStudentList The list of all students. - * @param in The scanner object to read user input. - */ - private static void findStudentsWithSubject(ArrayList masterStudentList, Scanner in) { - while (true) { - System.out.println(ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK); - String input = in.nextLine().trim(); - - if (input.equalsIgnoreCase(EXIT)) { - System.out.println(EXITED_THE_COMMAND); - UI.printDivider(); - return; - } - - if (!input.isEmpty()) { - ListStudentsCommand.listStudentsBySubject(masterStudentList, input); - return; - } else { - System.out.println("Please enter a valid subject name."); - } - } - } - - //@@author blackmirag3 /** * Prompts for grade from user input and checks format From 8389515cb4971c08e2d225081def32ccbe78ea29 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 10 Apr 2024 17:29:06 +0800 Subject: [PATCH 295/503] Update UG --- docs/UserGuide.md | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index d3f41fa4c2..1ca084370f 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -42,44 +42,51 @@ java -jar ./Classify.jar ## Features -### - Add a student `add` +### - Add a student Initialises the process of adding in a student. -### - View details of a student `view` +### - View details of a student Prints out the details of a given student in the interface. -### - Edit details of a student `edit` +### - Edit details of a student Initialises the process of editing both academic and non-academic details of a student. -### - Delete a student from the working list `delete` - +### - Delete a student from the working list Removes a student from the master list of students. -### - Produce a list of all the students who takes a subject `list`, enter, then followed by `subject name` +### - Produce a list of all the students who takes a subject Displays a list of all the students with that associated subject taken in the tuition centre. If user enters different letter cases from subjects stored, the system will still match strings regardless of letter case for user intuitiveness. -### Produce a list of all students `list`, enter, enter, `1` +### Produce a list of all students Displays a list of all the students at the tuition centre with no other parameters shown. -### Produce a list of all students with total classes attended `list`, enter, enter, `2` +### Produce a list of all students with total classes attended Displays a list of all the students with their total classes attended at the tuition centre. -### - Sort the list lexicographically, from A to Z `sort name` +### Produce a list of students moved to archive + +Displays a list of all the students that are moved to archive. + +### Produce a list of students that were recently deleted + +Displays a list of all students who were recently deleted. + +### - Sort the list lexicographically, from A to Z Sorts the masterlist of students from A to Z. When the user types list, it will generate the updated sorted list. -### - Sort the list by total classes attended `sort classes` +### - Sort the list by total classes attended Sorts the masterlist of students from the lowest number of classes attended to highest. When the user types list, it will generate the updated sorted list. -### - Sort the list by latest fee payment date `sort payment` +### - Sort the list by latest fee payment date Sorts the masterlist of students from the oldest date to the most recent. When the user types list, it will generate the updated sorted list. From c3d2cc388978ca08c3adafcca4b5971d0e31de93 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 10 Apr 2024 17:29:17 +0800 Subject: [PATCH 296/503] Update UG --- docs/UserGuide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 1ca084370f..363139e1a3 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -90,11 +90,11 @@ Sorts the masterlist of students from the lowest number of classes attended to h Sorts the masterlist of students from the oldest date to the most recent. When the user types list, it will generate the updated sorted list. -### - Undo the most recent delete action `undo` +### - Undo the most recent delete action Adds in the most recently deleted student back into the runtime database. -### - Restore a specific deleted student `restore` +### - Restore a specific deleted student Finds a specific deleted student and adds it back into the runtime database. From 84c9b59530f793304483c541aae43172b73f015f Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 10 Apr 2024 18:00:50 +0800 Subject: [PATCH 297/503] Add list by phone number --- docs/UserGuide.md | 4 ++ .../commands/ListStudentsCommand.java | 40 +++++++++++++++++++ src/main/java/classify/ui/UI.java | 4 +- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 363139e1a3..ce67882e16 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -78,6 +78,10 @@ Displays a list of all the students that are moved to archive. Displays a list of all students who were recently deleted. +### Produce a list of students with their phone numbers + +Displays a list of all students with their phone numbers. + ### - Sort the list lexicographically, from A to Z Sorts the masterlist of students from A to Z. When the user types list, it will generate the updated sorted list. diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 8257a871ca..44ef155130 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -25,6 +25,11 @@ public class ListStudentsCommand { "List of students with total classes attended:"; private static final String INVALID_CHOICE = "Invalid choice!"; private static final String TOTAL_CLASSES_ATTENDED = " - Total Classes Attended: "; + private static final String LIST_PHONE_NUMBERS = "5"; + private static final String LIST_OF_STUDENTS_WITH_PHONE_NUMBERS = "List of students with phone numbers:"; + private static final String PHONE_NUM = " - Phone Number: "; + private static final String INVALID_PHONE_NUMBER = " - Invalid Phone Number! Save file may be corrupt."; + /** * Lets the user view a list of students, optionally filtered by subject. @@ -115,6 +120,12 @@ public static void listAllStudents(ArrayList masterStudentList, UI.printDivider(); break; + case LIST_PHONE_NUMBERS: + UI.println(LIST_OF_STUDENTS_WITH_PHONE_NUMBERS); + listStudentsWithPhoneNumbers(masterStudentList); + UI.printDivider(); + break; + default: UI.println(INVALID_CHOICE); } @@ -146,4 +157,33 @@ private static void listStudentsWithTotalClasses(ArrayList masterStuden i++; } } + + /** + * Lists all students with their phone numbers. + * + * @param masterStudentList The list of all students. + */ + private static void listStudentsWithPhoneNumbers(ArrayList masterStudentList) { + int i = 1; + for (Student student : masterStudentList) { + int phoneNumber = student.getAttributes().getPhoneNumber(); + if (isValidPhoneNumber(phoneNumber)) { + System.out.println(i + "." + student.getName() + PHONE_NUM + phoneNumber); + } else { + System.out.println(i + "." + student.getName() + INVALID_PHONE_NUMBER); + } + i++; + } + } + + /** + * Checks if a phone number is valid. + * + * @param phoneNumber The phone number to be checked. + * @return true if the phone number is valid, false otherwise. + */ + private static boolean isValidPhoneNumber(int phoneNumber) { + return (phoneNumber >= 80000000 && phoneNumber <= 99999999); + } + } diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 9e7e4677af..c7c477e47a 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -63,7 +63,7 @@ public class UI { private static final String NO_RECENT_DELETES = "No recent deletes found!"; private static final String STUDENTS_IN_ARCHIVE = "3. List of students in archive"; private static final String STUDENTS_IN_DELETED = "4. List of students in recently deleted"; - private static final String ENTER_ONE_TWO_THREE_FOUR = "Enter your choice (1, 2, 3 or 4):"; + private static final String ENTER_ONE_TWO_THREE_FOUR = "Enter your choice (1, 2, 3, 4 or 5):"; //@@ author tayponghee private static final String ADD_SUBJECT = "Do you want to add another subject and grade? (yes/no)"; @@ -79,6 +79,7 @@ public class UI { private static final String CHOOSE_THE_TYPE_OF_LIST_TO_DISPLAY = "Choose the type of list to display: (index only)"; private static final String FULL_STUDENT_LIST = "1. Full student list"; private static final String STUDENTS_WITH_TOTAL_CLASSES = "2. List of students with total classes attended"; + private static final String LIST_OF_STUDENTS_WITH_PHONE_NUMBER_SHOWN = "5. List of students with phone number shown"; //@@author alalal47 /** * Displays the help message to teach users how to use Classify. @@ -430,6 +431,7 @@ public static void printListAllStudentsChoice () { System.out.println(STUDENTS_WITH_TOTAL_CLASSES); System.out.println(STUDENTS_IN_ARCHIVE); System.out.println(STUDENTS_IN_DELETED); + System.out.println(LIST_OF_STUDENTS_WITH_PHONE_NUMBER_SHOWN); System.out.println(ENTER_ONE_TWO_THREE_FOUR); } } From 76a4f57df5458b0bf2b4e0785983d96208996490 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 10 Apr 2024 18:02:28 +0800 Subject: [PATCH 298/503] Fix gradle checks --- src/main/java/classify/ui/UI.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index c7c477e47a..da70a69bf8 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -79,7 +79,8 @@ public class UI { private static final String CHOOSE_THE_TYPE_OF_LIST_TO_DISPLAY = "Choose the type of list to display: (index only)"; private static final String FULL_STUDENT_LIST = "1. Full student list"; private static final String STUDENTS_WITH_TOTAL_CLASSES = "2. List of students with total classes attended"; - private static final String LIST_OF_STUDENTS_WITH_PHONE_NUMBER_SHOWN = "5. List of students with phone number shown"; + private static final String LIST_OF_STUDENTS_WITH_PHONE_NUMBER_SHOWN = + "5. List of students with phone number shown"; //@@author alalal47 /** * Displays the help message to teach users how to use Classify. From 51bc92cf172e9b12ce2b974196f8da05598f8a3c Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 10 Apr 2024 18:22:29 +0800 Subject: [PATCH 299/503] Add some Junit tests for list command --- .../commands/ListStudentsCommand.java | 2 +- .../commands/ListStudentsCommandTest.java | 62 +++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 src/test/java/classify/commands/ListStudentsCommandTest.java diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 44ef155130..a0e4617560 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -163,7 +163,7 @@ private static void listStudentsWithTotalClasses(ArrayList masterStuden * * @param masterStudentList The list of all students. */ - private static void listStudentsWithPhoneNumbers(ArrayList masterStudentList) { + public static void listStudentsWithPhoneNumbers(ArrayList masterStudentList) { int i = 1; for (Student student : masterStudentList) { int phoneNumber = student.getAttributes().getPhoneNumber(); diff --git a/src/test/java/classify/commands/ListStudentsCommandTest.java b/src/test/java/classify/commands/ListStudentsCommandTest.java new file mode 100644 index 0000000000..361ea7ffec --- /dev/null +++ b/src/test/java/classify/commands/ListStudentsCommandTest.java @@ -0,0 +1,62 @@ +package classify.commands; + +import classify.student.Student; +import classify.student.StudentAttributes; +import org.junit.jupiter.api.Test; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ListStudentsWithPhoneNumbersTest { + + private static final String YIXIN = "Yi Xin"; + private static final String GERARD = "Gerard"; + + @Test + void testListStudentsWithValidNumbers() { + ArrayList students = new ArrayList<>(); + Student student1 = new Student(YIXIN); + StudentAttributes attributes1 = new StudentAttributes(student1); + attributes1.setPhoneNumber(87654321); + student1.setAttributes(attributes1); + students.add(student1); + + ArrayList expectedOutput = new ArrayList<>(); + expectedOutput.add("1." + YIXIN + " - Phone Number: 87654321"); + + assertEquals(expectedOutput, captureOutput(() -> ListStudentsCommand.listStudentsWithPhoneNumbers(students))); + } + + @Test + void testListStudentsWithInvalidNumbers() { + ArrayList students = new ArrayList<>(); + Student student1 = new Student(GERARD); + StudentAttributes attributes1 = new StudentAttributes(student1); + attributes1.setPhoneNumber(1234567); + student1.setAttributes(attributes1); + students.add(student1); + + ArrayList expectedOutput = new ArrayList<>(); + expectedOutput.add("1." + GERARD + " - Invalid Phone Number! Save file may be corrupt."); + + assertEquals(expectedOutput, captureOutput(() -> ListStudentsCommand.listStudentsWithPhoneNumbers(students))); + } + + private List captureOutput(Runnable action) { + List output = new ArrayList<>(); + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + PrintStream printStream = new PrintStream(byteArrayOutputStream); + PrintStream originalOut = System.out; + System.setOut(printStream); + + action.run(); + + System.out.flush(); + System.setOut(originalOut); + output.add(byteArrayOutputStream.toString().trim()); + return output; + } +} From 3902d510db5e6afde42eaf0642f82c5b130df463 Mon Sep 17 00:00:00 2001 From: Tay Pong Hee <110646458+tayponghee@users.noreply.github.com> Date: Wed, 10 Apr 2024 18:24:25 +0800 Subject: [PATCH 300/503] Update ListStudentsCommandTest.java --- src/test/java/classify/commands/ListStudentsCommandTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/classify/commands/ListStudentsCommandTest.java b/src/test/java/classify/commands/ListStudentsCommandTest.java index 361ea7ffec..90ca435188 100644 --- a/src/test/java/classify/commands/ListStudentsCommandTest.java +++ b/src/test/java/classify/commands/ListStudentsCommandTest.java @@ -1,4 +1,5 @@ package classify.commands; +//@@author tayponghee import classify.student.Student; import classify.student.StudentAttributes; From 5aaaf7c8366028ad1d66944c1f477a19a034febf Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 18:46:16 +0800 Subject: [PATCH 301/503] Refactor DataReader class to make it more readable --- src/main/java/classify/data/DataReader.java | 56 +++++++++++++++------ 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 99b98c92e9..ce1092b6df 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -62,11 +62,8 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Wed, 10 Apr 2024 19:43:07 +0800 Subject: [PATCH 302/503] Update UG with archive, unarchive and touch up list with new features that were added. Fix grammar issues and add newlines to improve readability. --- docs/UserGuide.md | 199 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 184 insertions(+), 15 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index ce67882e16..dffd2c427c 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -57,42 +57,48 @@ Initialises the process of editing both academic and non-academic details of a s ### - Delete a student from the working list Removes a student from the master list of students. +### - Add a student to the archive +Removes a student from the master list of students and adds them to the archive. + +### - Unarchive a student +Removes a student from the archive and adds them to the master list of students. + ### - Produce a list of all the students who takes a subject Displays a list of all the students with that associated subject taken in the tuition centre. If user enters different letter cases from subjects stored, the system will still match strings regardless of letter case for user intuitiveness. -### Produce a list of all students +### - Produce a list of all students Displays a list of all the students at the tuition centre with no other parameters shown. -### Produce a list of all students with total classes attended +### - Produce a list of all students with total classes attended Displays a list of all the students with their total classes attended at the tuition centre. -### Produce a list of students moved to archive +### - Produce a list of students in the archive -Displays a list of all the students that are moved to archive. +Displays a list of all the students that have been moved to archive. -### Produce a list of students that were recently deleted +### - Produce a list of students that were recently deleted Displays a list of all students who were recently deleted. -### Produce a list of students with their phone numbers +### - Produce a list of students with their phone numbers Displays a list of all students with their phone numbers. ### - Sort the list lexicographically, from A to Z -Sorts the masterlist of students from A to Z. When the user types list, it will generate the updated sorted list. +Sorts the master list of students from A to Z. When the user types list, it will generate the updated sorted list. ### - Sort the list by total classes attended -Sorts the masterlist of students from the lowest number of classes attended to highest. When the user types list, it will generate the updated sorted list. +Sorts the master list of students from the lowest number of classes attended to highest. When the user types list, it will generate the updated sorted list. ### - Sort the list by latest fee payment date -Sorts the masterlist of students from the oldest date to the most recent. When the user types list, it will generate the updated sorted list. +Sorts the master list of students from the oldest date to the most recent. When the user types list, it will generate the updated sorted list. ### - Undo the most recent delete action @@ -102,6 +108,15 @@ Adds in the most recently deleted student back into the runtime database. Finds a specific deleted student and adds it back into the runtime database. +### - Display help message + +Prints a message with instructions on how to use the features of Classify. + +### - Exit Classify + +Exits the program. + + # Usage **Please note that if any of the following characters are entered in any string prompts, `#, - and ~`, they will be replaced and your command may be deemed invalid.** @@ -166,7 +181,7 @@ How it works (cases for input): - view James Wong -> James Wong - view james wong -> james wong - view JAMES WONG -> JAMES WONG - * so, regardless of what the user uses for capitalisation of the name, the program will recognise that uppercase and lowercases should return the same student. + * Regardless of what capitalisation the user uses for the name, the program will recognise that upper and lower cases should return the same student. ``` Example: @@ -235,7 +250,8 @@ Deletes the student from the list. Allows the user to do delete [student] or jus Format: `delete` or `delete NAME` -Depending on whether the user entered the student's name or not during the command, a field will be printed out in the terminal, awaiting a user input. +Depending on whether the user entered the student's name or not during the command, +a field will be printed out in the terminal, awaiting a user input. ``` Example: @@ -250,7 +266,8 @@ Restores a student deleted in the current session. Allows the user to do restore Format: `restore` or `restore NAME` -Depending on whether the user entered the student's name or not during the command, a field will be printed out in the terminal, awaiting a user input. +Depending on whether the user entered the student's name or not during the command, +a field will be printed out in the terminal, awaiting a user input. ``` Example: @@ -261,7 +278,7 @@ Student has been restored! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` -### - Undo a delete and restore the deleted student to the working list +### - Undo a delete and restore the deleted student to the working list `undo` Undoes the latest delete. Used by typing `undo` Format: `undo` @@ -272,12 +289,128 @@ undo Last delete undone! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` + +### - Display the list of students `list` +Displays the list of all students, or students with a specified subject. +The user can further specify if they would like to display the full student list, +the list with the total classes attended, as well as the list of students in the archive or in the recently deleted list. + +Format: `list` + +Allows the user to specify a subject, then displays all students with that subject. +If the field is left blank, students will be displayed regardless of the subjects they have. +The user can then select by index, from 4 additional options to either display all students in the master list, +all students in the master list as well as the total number of classes they have attended. +Alternatively, the user can choose to display either the students in the recently deleted list or the archive. + +``` +Example: +list +Enter subject name (leave blank for all students): +math +Students with the subject "math": +- Toad +- Wario +- Mario +- Luigi +- Moyai +- Peach +- Daisy +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +list +Enter subject name (leave blank for all students): + +Choose the type of list to display: (index only) +1. Full student list +2. List of students with total classes attended +3. List of students in archive +4. List of students in recently deleted +5. List of students with phone number shown +Enter your choice (1, 2, 3, 4 or 5): +2 +List of students with total classes attended: +1.Toad - Total Classes Attended: 13 +2.Wario - Total Classes Attended: 14 +3.Mario - Total Classes Attended: 15 +4.Luigi - Total Classes Attended: 16 +5.Moyai - Total Classes Attended: 17 +6.Peach - Total Classes Attended: 18 +7.Daisy - Total Classes Attended: 19 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +list +Enter subject name (leave blank for all students): + +Choose the type of list to display: (index only) +1. Full student list +2. List of students with total classes attended +3. List of students in archive +4. List of students in recently deleted +5. List of students with phone number shown +Enter your choice (1, 2, 3, 4 or 5): +4 +List of students in recently deleted: +1.Toad +2.Peach +3.Moyai +4.Mario +Currently, there are 4 students in the list. +``` + +### - Move a student from the master list to the archive `archive` +Adds a student to the archive and deletes them from the master list. Allows the user to do archive [name] or just archive. + +Format: `archive`, `archive NAME` + +Depending on whether the user entered the student's name or not during the command, +a field will be printed out in the terminal, awaiting a user input. + +``` +Example: +archive wario +Archive List: +Analysing Inputs... +Directory loaded successfully! +Data update success! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Runtime Database: +Analysing Inputs... +Directory loaded successfully! +Data update success! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` + +### - Move a student from the archive back to the master list `unarchive` +Removes a student from the archive and adds them back to the master list. Allows the user to do unarchive [name] or just unarchive. + +Format: `unarchive`, `unarchive NAME` + +Depending on whether the user entered the student's name or not during the command, +a field will be printed out in the terminal, awaiting a user input. + +``` +Example: +unarchive wario +Archive List: +Analysing Inputs... +Directory loaded successfully! +Data update success! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Runtime List: +Analysing Inputs... +Directory loaded successfully! +Data update success! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` + ### - Sort the list of students `sort` -Sorts the list of students based on the following input. Allows the user to do sort [type] or just sort +Sorts the list of students based on the following input. Allows the user to do sort [type] or just sort. Format: `sort`, `sort name`, `sort classes` or `sort payment` -Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. +Depending on whether the user entered the student's name or not during the command, +fields will be printed out in the terminal, awaiting a user input each time. ``` Example: @@ -304,6 +437,42 @@ sort payment Sort complete! ``` +### - Display instructions on how to use Classify `help` +Prints instructions which detail how to use all the features of Classify. + +Format: `help` + +``` +Example: +help +add Adds a student to the student list, expects a name, grade and lessons attended, can be used directly with a name e.g. add [name] +edit Edits a students details, expects a name, can be used directly with a name e.g. edit [name] +view Views a students details, expects a name, can be used directly with a name e.g. add [name] +delete Deletes a student from the student list, expects a name, can be used directly with a name e.g. add [name] +restore Restore a student deleted within the current session, expects a name, can be used directly by restore [name]. +undo Restores the last student deleted in the current session. +list Displays the list of all students + Currently available types: Whole student list, with total classes attended or by certain subject only +bye Exits Classify +sort Sorts the student list by the input parameter, expects an attribute to sort by, can be used directly by sort [type]. + Currently available types: name, classes, payment +archive Removes the specified student from the list and archives them, can be used directly by archive [name]. +unarchive Removes the specified student from the archive and adds them to the list, can be used directly by unarchive [name]. +help Prints this help message +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` + +### - Exit Classify `bye` +Exits the Classify program. + +Format: `bye` +``` +Example: +bye +Hope you've had a productive day. See you again! Goodbye! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` + ## FAQ **Q**: How do I transfer my data to another computer? From c8c472c7b887931f242d7099355b9ed89da5cbce Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 20:53:33 +0800 Subject: [PATCH 303/503] Edit codebase further to resolve review issues --- src/main/java/classify/data/DataReader.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index ce1092b6df..fd7669e8a2 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -109,6 +109,7 @@ private static void requiredDataChecks(Student student, int phoneNumber) throws NameNumberMatchException { InputParsing.checkForSpecialCharacters(student.getName()); InputParsing.checkForSpecialCharacters(student.getGender()); + InputParsing.checkForSpecialCharacters(student.getAttributes().getRemarks()); StudentList.checkNameNumberPair(StudentList.masterStudentList, student.getName(), phoneNumber); StudentList.checkNameNumberPair(StudentList.archiveList, student.getName(), phoneNumber); } @@ -126,11 +127,12 @@ private static void addDifferentSubjectData(String[] inputArr, Student student) if (numberOfSubjects == 1 && allSubjects[0].isEmpty()){ DataUI.noSubjectMessage(); - } else { - for (String allSubject : allSubjects) { - SubjectGrade newSubject = getAllSubjectInformation(allSubject); - student.getAttributes().addSubjectGrade(newSubject); - } + return; + } + + for (String allSubject : allSubjects) { + SubjectGrade newSubject = getAllSubjectInformation(allSubject); + student.getAttributes().addSubjectGrade(newSubject); } } From 63232e319dea5e7459e1d186bbcc8f851595a86a Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 10 Apr 2024 21:03:43 +0800 Subject: [PATCH 304/503] Update UG, list numbering, and Junit --- docs/UserGuide.md | 37 +++++++++++++++---- .../commands/ListStudentsCommand.java | 8 ++-- src/main/java/classify/ui/UI.java | 12 +++--- .../java/classify/user/InputParsingTest.java | 5 ++- 4 files changed, 45 insertions(+), 17 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index dffd2c427c..8c4a169ee3 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -324,9 +324,9 @@ Enter subject name (leave blank for all students): Choose the type of list to display: (index only) 1. Full student list 2. List of students with total classes attended -3. List of students in archive -4. List of students in recently deleted -5. List of students with phone number shown +3. List of students with phone number shown +4. List of students in archive +5. List of students in recently deleted Enter your choice (1, 2, 3, 4 or 5): 2 List of students with total classes attended: @@ -345,11 +345,32 @@ Enter subject name (leave blank for all students): Choose the type of list to display: (index only) 1. Full student list 2. List of students with total classes attended -3. List of students in archive -4. List of students in recently deleted -5. List of students with phone number shown +3. List of students with phone number shown +4. List of students in archive +5. List of students in recently deleted Enter your choice (1, 2, 3, 4 or 5): -4 +3 +List of students with phone numbers: +1.Toad - Phone Number: 91234567 +2.Wario - Phone Number: 97654321 +3.Mario - Phone Number: 81234567 +4.Luigi - Phone Number: 87654321 +5.Moyai - Phone Number: 88776655 +6.Peach - Phone Number: 99887766 +7.Daisy - Phone Number: 88997766 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +list +Enter subject name (leave blank for all students): + +Choose the type of list to display: (index only) +1. Full student list +2. List of students with total classes attended +3. List of students with phone number shown +4. List of students in archive +5. List of students in recently deleted +Enter your choice (1, 2, 3, 4 or 5): +5 List of students in recently deleted: 1.Toad 2.Peach @@ -452,7 +473,7 @@ delete Deletes a student from the student list, expects a n restore Restore a student deleted within the current session, expects a name, can be used directly by restore [name]. undo Restores the last student deleted in the current session. list Displays the list of all students - Currently available types: Whole student list, with total classes attended or by certain subject only + Currently available types: Whole student list, with total classes attended, with phone number, the archived list, the recently deleted list or by certain subject only. bye Exits Classify sort Sorts the student list by the input parameter, expects an attribute to sort by, can be used directly by sort [type]. Currently available types: name, classes, payment diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index a0e4617560..89a35c84d0 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -13,8 +13,8 @@ public class ListStudentsCommand { private static final String LIST_ALL = "1"; private static final String LIST_ALL_WITH_CLASSES = "2"; - private static final String LIST_ARCHIVE = "3"; - private static final String LIST_DELETED = "4"; + private static final String LIST_ARCHIVE = "4"; + private static final String LIST_DELETED = "5"; private static final String LIST_OF_STUDENTS_IN_ARCHIVE = "List of students in archive: "; private static final String LIST_OF_STUDENTS_IN_RECENTLY_DELETED = @@ -25,7 +25,7 @@ public class ListStudentsCommand { "List of students with total classes attended:"; private static final String INVALID_CHOICE = "Invalid choice!"; private static final String TOTAL_CLASSES_ATTENDED = " - Total Classes Attended: "; - private static final String LIST_PHONE_NUMBERS = "5"; + private static final String LIST_PHONE_NUMBERS = "3"; private static final String LIST_OF_STUDENTS_WITH_PHONE_NUMBERS = "List of students with phone numbers:"; private static final String PHONE_NUM = " - Phone Number: "; private static final String INVALID_PHONE_NUMBER = " - Invalid Phone Number! Save file may be corrupt."; @@ -117,12 +117,14 @@ public static void listAllStudents(ArrayList masterStudentList, UI.println(LIST_OF_STUDENTS_WITH_TOTAL_CLASSES_ATTENDED); listStudentsWithTotalClasses(masterStudentList); + StudentList.printCurrentArrayMessage(masterStudentList); UI.printDivider(); break; case LIST_PHONE_NUMBERS: UI.println(LIST_OF_STUDENTS_WITH_PHONE_NUMBERS); listStudentsWithPhoneNumbers(masterStudentList); + StudentList.printCurrentArrayMessage(masterStudentList); UI.printDivider(); break; diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index da70a69bf8..fdbfc4eebd 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -61,8 +61,8 @@ public class UI { private static final String DELETE_UNDONE_MESSAGE = "Last delete undone!"; private static final String STUDENT_RESTORED_MESSAGE = "Student has been restored!"; private static final String NO_RECENT_DELETES = "No recent deletes found!"; - private static final String STUDENTS_IN_ARCHIVE = "3. List of students in archive"; - private static final String STUDENTS_IN_DELETED = "4. List of students in recently deleted"; + private static final String STUDENTS_IN_ARCHIVE = "4. List of students in archive"; + private static final String STUDENTS_IN_DELETED = "5. List of students in recently deleted"; private static final String ENTER_ONE_TWO_THREE_FOUR = "Enter your choice (1, 2, 3, 4 or 5):"; //@@ author tayponghee private static final String ADD_SUBJECT = @@ -80,7 +80,7 @@ public class UI { private static final String FULL_STUDENT_LIST = "1. Full student list"; private static final String STUDENTS_WITH_TOTAL_CLASSES = "2. List of students with total classes attended"; private static final String LIST_OF_STUDENTS_WITH_PHONE_NUMBER_SHOWN = - "5. List of students with phone number shown"; + "3. List of students with phone number shown"; //@@author alalal47 /** * Displays the help message to teach users how to use Classify. @@ -134,7 +134,9 @@ private static void printByeHelpMessage() { private static void printListHelpMessage() { System.out.println("list Displays the list of all students"); System.out.println(" Currently available types: Whole student list, with " + - "total classes attended or by certain subject only"); + "with total classes attended, with phone number, "); + System.out.println(" the archived list, the recently deleted list or " + + "by certain subject only."); } private static void printDeleteHelpMessage() { @@ -430,9 +432,9 @@ public static void printListAllStudentsChoice () { System.out.println(CHOOSE_THE_TYPE_OF_LIST_TO_DISPLAY); System.out.println(FULL_STUDENT_LIST); System.out.println(STUDENTS_WITH_TOTAL_CLASSES); + System.out.println(LIST_OF_STUDENTS_WITH_PHONE_NUMBER_SHOWN); System.out.println(STUDENTS_IN_ARCHIVE); System.out.println(STUDENTS_IN_DELETED); - System.out.println(LIST_OF_STUDENTS_WITH_PHONE_NUMBER_SHOWN); System.out.println(ENTER_ONE_TWO_THREE_FOUR); } } diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index e9f3cb7a87..bfb8d03c8b 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -100,7 +100,10 @@ public void testHelpCommand() { "list Displays the list of all students" + System.lineSeparator() + " Currently available types: Whole student list, with " + - "total classes attended or by certain subject only" + "with total classes attended, with phone number, " + + System.lineSeparator() + + " the archived list, the recently deleted list or " + + "by certain subject only." + System.lineSeparator() + "bye Exits Classify" + System.lineSeparator() + From 4c0c9b7d82f3dccd274ed76820fd1c35890c07a9 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 21:03:53 +0800 Subject: [PATCH 305/503] Move remarks setter to be before the checks --- src/main/java/classify/data/DataReader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index fd7669e8a2..b6293f2565 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -60,6 +60,8 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Wed, 10 Apr 2024 21:22:55 +0800 Subject: [PATCH 306/503] Make changes according to points raised during review --- .../classify/textfilecode/TextFileParser.java | 72 +++++-------------- 1 file changed, 18 insertions(+), 54 deletions(-) diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index d2c645866a..611b1eb5c3 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -1,29 +1,22 @@ package classify.textfilecode; -import classify.data.DataReader; import classify.student.Student; -import classify.student.StudentList; import classify.student.SubjectGrade; -import classify.ui.DataUI; import classify.ui.UI; import classify.user.InputParsing; import classify.user.InvalidCharacterException; -import classify.user.NameNumberMatchException; import java.io.BufferedReader; -import java.io.IOException; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; -import java.time.LocalDate; -import java.time.format.DateTimeParseException; +import java.io.IOException; import java.util.ArrayList; import java.util.Scanner; //@@author ParthGandhiNUS public class TextFileParser { private static final String MAIN_REGEX = "~~"; - private static final String SUBJECT_INFO_REGEX = "##"; private static final String FILE_SELECTION_PROMPT = "Please enter the exact name of the file " + "you'd like to process:"; private static final String REQUEST_TO_TRY_AGAIN = "Please try again!"; @@ -32,13 +25,7 @@ public class TextFileParser { private static final String NO_MATCH_FOUND = "No Match Found!"; private static final String ERROR_ACCESSING_THE_FILE = "Something went wrong while accessing the file"; private static final Integer NAME = 0; - private static final Integer GENDER = 1; - private static final Integer PHONE_NUMBER = 2; - private static final Integer LAST_PAYMENT_DATE = 3; - private static final Integer REMARKS = 4; - private static final Integer SUBJECTS = 5; - private static final Integer GRADE_FOR_SUBJECT = 0; - private static final Integer NUMBER_OF_CLASSES_ATTENDED = 1; + private static final Integer GRADE_FOR_SUBJECT = 1; private static final String INPUT_TEXT_FILE_DIRECTORY = "./data/inputFolder"; /** * Boolean that checks for the filetype of the files. @@ -111,9 +98,13 @@ private static void fetchDataFromTextFile(BufferedReader line, ArrayList masterStudentList){ + Integer classesAttended, ArrayList masterStudentList){ if (textFileInput.trim().isBlank()){ return; } String [] inputArr = textFileInput.split(MAIN_REGEX); - //Set Name - Student student = new Student(inputArr[NAME].trim()); - masterStudentList.add(student); - //Set Gender - student.getAttributes().setGender(inputArr[GENDER].trim()); - //Set Phone Number - try { + try{ + //Set Name + Student student = new Student(inputArr[NAME].trim()); InputParsing.checkForSpecialCharacters(student.getName()); - InputParsing.checkForSpecialCharacters(student.getGender()); - int phoneNumber = Integer.parseInt(inputArr[PHONE_NUMBER].trim()); - StudentList.checkNameNumberPair(StudentList.masterStudentList, student.getName(), phoneNumber); - StudentList.checkNameNumberPair(StudentList.archiveList, student.getName(), phoneNumber); - student.getAttributes().setPhoneNumber(phoneNumber); - } catch (NumberFormatException e) { - DataUI.phoneNumberParsingError(); - return; - } catch (NameNumberMatchException e) { - DataUI.nameNumberPair(); - return; + //Set grades + double subjectGrades = Double.parseDouble(inputArr[GRADE_FOR_SUBJECT].trim()); + //Put Everything together + SubjectGrade newSubject = new SubjectGrade(subjectName, subjectGrades, classesAttended); + masterStudentList.add(student); + student.getAttributes().addSubjectGrade(newSubject); } catch (InvalidCharacterException e) { - DataUI.invalidCharacterExceptionMessage(); - return; + UI.println("Invalid character found in subject. Skipping subsequent entries."); } - //Set Last Payment Date - try { - LocalDate inputLastPaymentDate = DataReader.convertStringInput(inputArr[LAST_PAYMENT_DATE].trim()); - student.getAttributes().setLastPaymentDate(inputLastPaymentDate); - } catch (DateTimeParseException e) { - DataUI.lastPaymentDateParseExceptionMessage(); - } - //Set remarks - student.getAttributes().setRemarks(inputArr[REMARKS].trim()); - - String [] subjectInformation = inputArr[SUBJECTS].trim().split(SUBJECT_INFO_REGEX); - //Set grades - double subjectGrades = Double.parseDouble(subjectInformation[GRADE_FOR_SUBJECT].trim()); - //Set Classes Attended - int subjectClassesAttended = Integer.parseInt(subjectInformation[NUMBER_OF_CLASSES_ATTENDED].trim()); - SubjectGrade newSubject = new SubjectGrade(subjectName, subjectGrades, subjectClassesAttended); - student.getAttributes().addSubjectGrade(newSubject); } /** From 376f2d3f46e6e9fafac43ba3a31350d7a82fc429 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 21:34:59 +0800 Subject: [PATCH 307/503] Add Javadocs --- .../classify/textfilecode/TextFileParser.java | 40 ++++++++++++++++--- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index 611b1eb5c3..bc38e2922d 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -58,8 +58,16 @@ public static void promptForFileSelectionAgain(){ System.out.println(REQUEST_TO_TRY_AGAIN); System.out.println(FILE_SELECTION_PROMPT); } - - public static void parseUserSelection(File currentDirectory, Scanner in, ArrayList masterStudentList){ + + /** + * Take in users' input for the file they want to process and enter parseTextFile Method. + * If file is not found, user is prompted for other files. + * + * @param currentDirectory Directory containing the contents inside inputFolder + * @param in Scanner to scan users' inputs + * @param masterStudentList StudentList where students will be added. + */ + public static void parseUserSelection(File currentDirectory, Scanner in, ArrayList masterStudentList){ File[] fileList = currentDirectory.listFiles(); String userInput = in.nextLine(); @@ -72,11 +80,16 @@ public static void parseUserSelection(File currentDirectory, Scanner in, ArrayLi parseUserSelection(TextFileHandler.CURRENT_DIRECTORY, in, masterStudentList); return; } - parseTextFile(fileList, matchIndex, masterStudentList); - } + /** + * Selects data from the correct file and starts reading it. + * + * @param fileList List of all the text files in the inputFolder directory + * @param matchIndex index of the matching file in the list of Files + * @param masterStudentList StudentList where students will be added. + */ private static void parseTextFile(File[] fileList, Integer matchIndex, ArrayList masterStudentList){ String fileNameString = fileList[matchIndex].getName().trim(); String fullFilePath = INPUT_TEXT_FILE_DIRECTORY + "/" + fileNameString; @@ -92,6 +105,12 @@ private static void parseTextFile(File[] fileList, Integer matchIndex, ArrayList } + /** + * Parse the students' subject name and classes attended before going over all the students taking this class + * + * @param line Every line of the file selected by user + * @param masterStudentList StudentList where students will be added. + */ private static void fetchDataFromTextFile(BufferedReader line, ArrayList masterStudentList) { try{ String firstLine = line.readLine(); @@ -104,14 +123,23 @@ private static void fetchDataFromTextFile(BufferedReader line, ArrayList masterStudentList){ if (textFileInput.trim().isBlank()){ return; From 083d876e823769c2f5277b77c9c59383dd68fb23 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 21:49:24 +0800 Subject: [PATCH 308/503] Make private class public --- src/main/java/classify/commands/AddStudent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 703f4c1ed6..dfc13e9188 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -152,7 +152,7 @@ public static String checkForEmptyName(ArrayList masterStudentList, Sca * @param name The input string to capitalize. * @return The string with the first letter of each word capitalized. */ - private static String splitName(String name) { + public static String splitName(String name) { if (!name.isEmpty()) { StringBuilder result = new StringBuilder(); String[] words = name.split("\\s"); From 2c7f723f594cbdb38b16310344db83fe61f70ad8 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 21:50:14 +0800 Subject: [PATCH 309/503] Use convention for capitalised names --- src/main/java/classify/data/DataReader.java | 3 ++- src/main/java/classify/textfilecode/TextFileParser.java | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index b6293f2565..8429166aca 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -1,5 +1,6 @@ package classify.data; +import classify.commands.AddStudent; import classify.student.Student; import classify.student.StudentList; import classify.student.SubjectGrade; @@ -57,7 +58,7 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Wed, 10 Apr 2024 22:24:36 +0800 Subject: [PATCH 310/503] Add PPP files for blackmirag3 --- docs/team/blackmirag3.md | 28 ++++++++++++++++++++++++++++ src/main/java/classify/Classify.java | 2 -- 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 docs/team/blackmirag3.md diff --git a/docs/team/blackmirag3.md b/docs/team/blackmirag3.md new file mode 100644 index 0000000000..7ee2735810 --- /dev/null +++ b/docs/team/blackmirag3.md @@ -0,0 +1,28 @@ +#Siew Shui Hon's (blackmirag3) Project Portfolio Page + +## Project: Classify + +Classify is a desktop application used for Tuition Centres to allow for easier management of their enrolled students. +From allowing users to add new students to sorting them based on their last paid date, Classify is the one-stop app that +all Tuition Centres can employ for ease of student management. To use the app, users can interact with it using CLI. + +Below are my specific contributions to the project: + +- **Foundation for the project.** + * + +- **Maintenance of commonly used functions and exceptions.** + * + +- **Extensive bugfinding and fixing** + * + +- **Code contributed:** [Link to Reposense contribution graph](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=blackmirag3&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2024-02-23&tabOpen=true&tabType=authorship&tabAuthor=blackmirag3&tabRepo=AY2324S2-CS2113-T13-3%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code&authorshipIsBinaryFileTypeChecked=false&authorshipIsIgnoredFilesChecked=false) + * Majority of my code was done to ensure my group member's code worked well with each other. I focused on making sure everything worked smoothly, and fixing bugs and exceptions, rather than adding features. Essentially acted as the scrum master. + + +- **Documentation:** + * + +- **Contributions to Team-Based tasks:** + * diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 6a3e706480..ce90e112c6 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -20,9 +20,7 @@ public class Classify { public static void main(String[] args) throws IOException { //@@author ParthGandhiNUS DataHandler.readStudentInfo(StudentList.masterStudentList); - //@@author blackmirag3 DataHandler.readArchive(StudentList.archiveList); - //@@author ParthGandhiNUS UI.printWelcomeMessage(); // Takes in input from the user, and processes input to determine if it contains a command and a name From 262a04544839fbc8604baac022ad9d164eb0ec38 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 22:26:37 +0800 Subject: [PATCH 311/503] Add required exceptions and minimise usage of magic literals --- src/main/java/classify/data/DataReader.java | 20 ++++++++++++++----- .../classify/textfilecode/TextFileParser.java | 11 +++++++--- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 8429166aca..395b37e5c4 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -39,6 +39,9 @@ public class DataReader { private static final Integer REMARKS = 4; private static final Integer SUBJECTS = 5; private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); + private static final String INVALID_CHAR_MESSAGE = "Invalid character found."; + private static final String INVALID_NUMBER_MESSAGE = "Invalid Number format found."; + private static final String ARRAY_INDEX_MESSAGE = "Error reading in subjects."; public static Scanner in = new Scanner(System.in); @@ -89,9 +92,9 @@ public static void restoreStudentList(String studentFileInput, ArrayList masterStudentList) { try{ String firstLine = line.readLine(); - String [] subjectInfoStrings = firstLine.split("Subject:"); + String [] subjectInfoStrings = firstLine.split(SUBJECT_REGEX); String subjectName = subjectInfoStrings[1].trim(); String secondLine = line.readLine(); - String [] classInfoStrings = secondLine.split("Classes Attended:"); + String [] classInfoStrings = secondLine.split(CLASSES_ATTENDED_REGEX); int totalClassesAttended = Integer.parseInt(classInfoStrings[1].trim()); while (line.ready()){ @@ -162,6 +165,8 @@ private static void deconstructTextFile (String textFileInput, String subjectNam student.getAttributes().addSubjectGrade(newSubject); } catch (InvalidCharacterException e) { UI.println(INVALID_CHAR_MESSAGE); + } catch (NumberFormatException e) { + UI.println(INVALID_NUMBER_MESSAGE); } } From 328f4b667a8140270d3d83cfb2613cd27683308d Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Wed, 10 Apr 2024 22:33:31 +0800 Subject: [PATCH 312/503] Follow convention used for UI class --- src/main/java/classify/ui/UI.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 638a3b8150..bc3b0e993f 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -97,7 +97,7 @@ public static void printHelp() { printSortHelpMessage(); printArchiveHelpMessage(); printUnarchiveHelpMessage(); - printProcessTextFileInput(); + printProcessTextFileInputMessage(); System.out.println("help Prints this help message"); } @@ -186,7 +186,7 @@ public static void printEndConversation() { printDivider(); } - public static void printProcessTextFileInput(){ + public static void printProcessTextFileInputMessage(){ System.out.println("process " + "Processes a text file which has been added by a user"); } From 6945fed268329467c490d463f7bd82dd69669b71 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 10 Apr 2024 23:10:19 +0800 Subject: [PATCH 313/503] Remove old command from UG --- docs/UserGuide.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 8c4a169ee3..93e030a97d 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -545,9 +545,6 @@ Sorts the list by the last fee payment date of a student. If the word `payment` ### `sort ` Sorts the list by the number of classes a student has attended. If the word `classes` is not specified in the initial command, the program will prompt the user for an appropriate flag. -### `view_subject ` -Lists all the students associated with that subject. If the user specifies the subject in the initial command, the list will be generated and the command will be terminated. If the user does not specify the subject, the programme will continuously prompt the user for a subject, until they choose to terminate the command. - ### `archive ` Archives specified student. Removes student from current list and adds student to archive. From 8ecf6160d6326aeac152e45c2d4b4c2d14a19578 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 10 Apr 2024 23:13:02 +0800 Subject: [PATCH 314/503] Update command summary in UG --- docs/UserGuide.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 93e030a97d..5ea7434191 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -527,6 +527,15 @@ Displays the list of students that is registered in the tuition centre. ### `list`, press enter, press enter, [2] Displays the list of students that is registered in the tuition centre with the total number of classes taken. +### `list`, press enter, press enter, [3] +Displays the list of students that is registered in the tuition centre with their phone numbers beside their names + +### `list`, press enter, press enter, [4] +Displays the list of students who were archived. + +### `list`, press enter, press enter, [5] +Displays the list of students who were recently deleted from the master list. + ### `view ` Views a students details. If the name of the student is not specified in the initial command, the program will prompt the user for the name. From 24f2d420f242738ab57d247f31e48818cf6152c1 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 10 Apr 2024 23:22:48 +0800 Subject: [PATCH 315/503] Fix class name --- src/test/java/classify/commands/ListStudentsCommandTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/classify/commands/ListStudentsCommandTest.java b/src/test/java/classify/commands/ListStudentsCommandTest.java index 90ca435188..a0ca8fb4dc 100644 --- a/src/test/java/classify/commands/ListStudentsCommandTest.java +++ b/src/test/java/classify/commands/ListStudentsCommandTest.java @@ -11,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -class ListStudentsWithPhoneNumbersTest { +class ListStudentsCommandTest { private static final String YIXIN = "Yi Xin"; private static final String GERARD = "Gerard"; From 38087d0e7706e57d88de0a9984efccd086a97daf Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 10 Apr 2024 23:31:20 +0800 Subject: [PATCH 316/503] Add javadocs to Junit --- .../classify/commands/AddStudentTest.java | 20 +++++++++++++++++-- .../commands/ListStudentsCommandTest.java | 18 ++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/test/java/classify/commands/AddStudentTest.java b/src/test/java/classify/commands/AddStudentTest.java index 9da2f6dac8..b97c62dc39 100644 --- a/src/test/java/classify/commands/AddStudentTest.java +++ b/src/test/java/classify/commands/AddStudentTest.java @@ -20,6 +20,11 @@ class AddStudentTest { private static final String PARTH = "Parth"; private static final String BANANA_REPUBLIC = "Banana Republic"; + /** + * Test case to verify the behavior of the checkForEmptyName method when a non-empty name is provided. + * This test checks if the method correctly handles non-empty name input and returns the provided name. + * @throws InvalidCharacterException if an invalid character is encountered during name validation. + */ @Test void checkForEmptyNameTestName() throws InvalidCharacterException { ArrayList masterStudentList = new ArrayList<>(); @@ -30,6 +35,10 @@ void checkForEmptyNameTestName() throws InvalidCharacterException { assertEquals(PARTH, name); } + /** + * Test case to verify the behavior of the checkForEmptyName method when an empty name is provided. + * This test checks if the method correctly throws an exception when an empty name is encountered. + */ @Test void checkForEmptyNameTestEmpty() { ArrayList masterStudentList = new ArrayList<>(); @@ -45,26 +54,33 @@ void checkForEmptyNameTestEmpty() { assertTrue(exceptionThrown); } + /** + * Test case to find a student by name when the student does not exist. + * This test checks if the method correctly returns null when the student with the given name is not found. + */ @Test void findStudentByNameNonExisting() { ArrayList masterStudentList = new ArrayList<>(); Scanner scanner = new Scanner(BANANA_REPUBLIC + "\n"); - Student foundStudent = InputParsing.findStudentByName(masterStudentList, PARTH, scanner); assertNull(foundStudent); } + /** + * Test case to find a student by name when the student exists. + * This test checks if the method correctly returns the found student when the student with the given name exists. + */ @Test void findStudentByNameExisting() { ArrayList masterStudentList = new ArrayList<>(); Scanner scanner = new Scanner(BANANA_REPUBLIC + "\n"); - Student foundStudent = InputParsing.findStudentByName(masterStudentList, BANANA_REPUBLIC, scanner); assertNull(foundStudent); } + //@@author Cryolian @Test void addSpecialCharactersTest() { diff --git a/src/test/java/classify/commands/ListStudentsCommandTest.java b/src/test/java/classify/commands/ListStudentsCommandTest.java index a0ca8fb4dc..335bc87798 100644 --- a/src/test/java/classify/commands/ListStudentsCommandTest.java +++ b/src/test/java/classify/commands/ListStudentsCommandTest.java @@ -16,6 +16,11 @@ class ListStudentsCommandTest { private static final String YIXIN = "Yi Xin"; private static final String GERARD = "Gerard"; + /** + * Test case to verify listing students with valid phone numbers. + * This test checks if the method listStudentsWithPhoneNumbers(list) + * correctly lists students with valid phone numbers. + */ @Test void testListStudentsWithValidNumbers() { ArrayList students = new ArrayList<>(); @@ -31,6 +36,11 @@ void testListStudentsWithValidNumbers() { assertEquals(expectedOutput, captureOutput(() -> ListStudentsCommand.listStudentsWithPhoneNumbers(students))); } + /** + * Test case to verify listing students with invalid phone numbers. + * This test checks if the method listStudentsWithPhoneNumbers(List) + * correctly handles students with invalid phone numbers. + */ @Test void testListStudentsWithInvalidNumbers() { ArrayList students = new ArrayList<>(); @@ -42,10 +52,16 @@ void testListStudentsWithInvalidNumbers() { ArrayList expectedOutput = new ArrayList<>(); expectedOutput.add("1." + GERARD + " - Invalid Phone Number! Save file may be corrupt."); - + assertEquals(expectedOutput, captureOutput(() -> ListStudentsCommand.listStudentsWithPhoneNumbers(students))); } + /** + * Captures the output generated by the given action. + * + * @param action The action whose output needs to be captured. + * @return A list containing the captured output. + */ private List captureOutput(Runnable action) { List output = new ArrayList<>(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); From adaf34aed18712ce34c2d537788f701e341fdb21 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 10 Apr 2024 23:50:32 +0800 Subject: [PATCH 317/503] Add to ListStudentsCommandTest --- .../commands/ListStudentsCommand.java | 2 +- .../commands/ListStudentsCommandTest.java | 60 +++++++++++++++++-- 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 89a35c84d0..03f95da1ff 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -141,7 +141,7 @@ public static void listAllStudents(ArrayList masterStudentList, * * @param masterStudentList The list of all students. */ - private static void listStudentsWithTotalClasses(ArrayList masterStudentList) { + static void listStudentsWithTotalClasses(ArrayList masterStudentList) { int i = 1; for (Student student : masterStudentList) { int totalClassesAttended = 0; diff --git a/src/test/java/classify/commands/ListStudentsCommandTest.java b/src/test/java/classify/commands/ListStudentsCommandTest.java index 335bc87798..efc66ba2c2 100644 --- a/src/test/java/classify/commands/ListStudentsCommandTest.java +++ b/src/test/java/classify/commands/ListStudentsCommandTest.java @@ -3,6 +3,7 @@ import classify.student.Student; import classify.student.StudentAttributes; +import classify.student.SubjectGrade; import org.junit.jupiter.api.Test; import java.io.ByteArrayOutputStream; import java.io.PrintStream; @@ -15,6 +16,8 @@ class ListStudentsCommandTest { private static final String YIXIN = "Yi Xin"; private static final String GERARD = "Gerard"; + private static final String SCIENCE = "Science"; + private static final String MATH = "Math"; /** * Test case to verify listing students with valid phone numbers. @@ -52,15 +55,61 @@ void testListStudentsWithInvalidNumbers() { ArrayList expectedOutput = new ArrayList<>(); expectedOutput.add("1." + GERARD + " - Invalid Phone Number! Save file may be corrupt."); - + assertEquals(expectedOutput, captureOutput(() -> ListStudentsCommand.listStudentsWithPhoneNumbers(students))); } /** - * Captures the output generated by the given action. + * Test case to verify listing students with total classes attended. + * This test ensures that the method listStudentsWithTotalClasses(list) + * correctly lists students along with their total classes attended. + */ + @Test + void testListStudentsWithTotalClasses() { + ArrayList students = new ArrayList<>(); + Student student1 = new Student(YIXIN); + StudentAttributes attributes1 = new StudentAttributes(student1); + SubjectGrade mathGrade = new SubjectGrade(MATH, 10, 10); + SubjectGrade scienceGrade = new SubjectGrade(SCIENCE, 12,-1); + attributes1.getSubjectGrades().add(mathGrade); + attributes1.getSubjectGrades().add(scienceGrade); + student1.setAttributes(attributes1); + students.add(student1); + + ArrayList expectedOutput = new ArrayList<>(); + expectedOutput.add("1." + YIXIN + " - Total Classes Attended: 10"); + + assertEquals(expectedOutput, captureOutput(() -> ListStudentsCommand.listStudentsWithTotalClasses(students))); + } + + /** + * Test case to verify listing students by subject. + * This test ensures that the method listStudentsBySubject(list, subject) + * correctly lists students with the specified subject. + */ + @Test + void testListStudentsBySubject() { + ArrayList students = new ArrayList<>(); + Student student1 = new Student(YIXIN); + StudentAttributes attributes1 = new StudentAttributes(student1); + SubjectGrade mathGrade = new SubjectGrade(MATH, 10,10); + attributes1.getSubjectGrades().add(mathGrade); + student1.setAttributes(attributes1); + students.add(student1); + + ArrayList expectedOutput = new ArrayList<>(); + expectedOutput.add("Students with the subject " + '"' + MATH + '"' + ":"); + expectedOutput.add("- " + YIXIN); + expectedOutput.add("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); + + assertEquals(expectedOutput, captureOutput(() -> ListStudentsCommand.listStudentsBySubject(students, MATH))); + } + + /** + * Captures the output generated by a given action. * * @param action The action whose output needs to be captured. - * @return A list containing the captured output. + * @return A list containing the captured output lines. */ private List captureOutput(Runnable action) { List output = new ArrayList<>(); @@ -73,7 +122,10 @@ private List captureOutput(Runnable action) { System.out.flush(); System.setOut(originalOut); - output.add(byteArrayOutputStream.toString().trim()); + String[] lines = byteArrayOutputStream.toString().split(System.lineSeparator()); + for (String line : lines) { + output.add(line.trim()); + } return output; } } From 502ff717c22d364757fd5a5b79c1a91efa21c7d5 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 10 Apr 2024 23:51:59 +0800 Subject: [PATCH 318/503] Add javadocs --- src/test/java/classify/commands/StudentSorterTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/classify/commands/StudentSorterTest.java b/src/test/java/classify/commands/StudentSorterTest.java index 1bde38fd3c..c6ba34992c 100644 --- a/src/test/java/classify/commands/StudentSorterTest.java +++ b/src/test/java/classify/commands/StudentSorterTest.java @@ -21,6 +21,10 @@ public class StudentSorterTest { public static final String SCIENCE = "Science"; public static final String MATH = "Math"; + /** + * A test class to verify the sorting functionality provided by the StudentSorter class. + * It contains test cases to ensure the proper sorting of students based on different criteria. + */ @Test public void testSortByChoice() { ArrayList students = new ArrayList<>(); From f81207251b1b72e50bb765727d4d7e1da4e59052 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 10 Apr 2024 23:53:11 +0800 Subject: [PATCH 319/503] Fix java docs --- src/test/java/classify/commands/StudentSorterTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/classify/commands/StudentSorterTest.java b/src/test/java/classify/commands/StudentSorterTest.java index c6ba34992c..ae89c0998a 100644 --- a/src/test/java/classify/commands/StudentSorterTest.java +++ b/src/test/java/classify/commands/StudentSorterTest.java @@ -22,8 +22,8 @@ public class StudentSorterTest { public static final String MATH = "Math"; /** - * A test class to verify the sorting functionality provided by the StudentSorter class. - * It contains test cases to ensure the proper sorting of students based on different criteria. + * Test case to verify the sorting of students by different criteria. + * It tests the sorting functionality based on specified sorting choices. */ @Test public void testSortByChoice() { From b50ce856158e528a74dc01e679e616ec5ac62fb7 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Wed, 10 Apr 2024 23:57:43 +0800 Subject: [PATCH 320/503] Add javadocs to StudentAttributesTest --- .../student/StudentAttributesTest.java | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/test/java/classify/student/StudentAttributesTest.java b/src/test/java/classify/student/StudentAttributesTest.java index 65a297f7fb..0fb84e3ec8 100644 --- a/src/test/java/classify/student/StudentAttributesTest.java +++ b/src/test/java/classify/student/StudentAttributesTest.java @@ -13,6 +13,10 @@ public class StudentAttributesTest { public static final String JANE_SMITH = "Jane Smith"; public static final String SCIENCE = "Science"; + /** + * Test case to verify the addition of a subject grade to the StudentAttributes. + * It checks if the subject grade is successfully added to the attributes. + */ @Test public void testAddSubjectGrade() { Student student = new Student(JOHN_DOE); @@ -25,6 +29,10 @@ public void testAddSubjectGrade() { assertTrue(subjectGrades.contains(subjectGrade)); } + /** + * Test case to verify getting the name of the student from the StudentAttributes. + * It checks if the correct name is returned. + */ @Test public void testGetName() { Student student = new Student(JOHN_DOE); @@ -33,6 +41,10 @@ public void testGetName() { assertEquals(JOHN_DOE, attributes.getName()); } + /** + * Test case to verify setting the name of the student in the StudentAttributes. + * It checks if the name is correctly set. + */ @Test public void testSetName() { Student student = new Student(JOHN_DOE); @@ -43,24 +55,40 @@ public void testSetName() { assertEquals(JANE_SMITH, attributes.getName()); } + /** + * Test case to verify getting the subject of the subject grade. + * It checks if the correct subject is returned. + */ @Test public void testGetSubject() { SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); assertEquals(MATH, subjectGrade.getSubject()); } + /** + * Test case to verify getting the grade of the subject grade. + * It checks if the correct grade is returned. + */ @Test public void testGetGrade() { SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); assertEquals(90.5, subjectGrade.getGrade()); } + /** + * Test case to verify getting the number of classes attended of the subject grade. + * It checks if the correct number of classes attended is returned. + */ @Test public void testGetClassesAttended() { SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); assertEquals(20, subjectGrade.getClassesAttended()); } + /** + * Test case to verify setting the subject of the subject grade. + * It checks if the subject is correctly set. + */ @Test public void testSetSubject() { SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); @@ -68,13 +96,21 @@ public void testSetSubject() { assertEquals(SCIENCE, subjectGrade.getSubject()); } + /** + * Test case to verify setting the grade of the subject grade. + * It checks if the grade is correctly set. + */ @Test public void testSetGrade() { SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); subjectGrade.setGrade(85.0); assertEquals(85.0, subjectGrade.getGrade()); } - + + /** + * Test case to verify setting the number of classes attended of the subject grade. + * It checks if the number of classes attended is correctly set. + */ @Test public void testSetClassesAttended() { SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); From 1ca381ee7ad083372d55eff6a5d7b0fe458ab17e Mon Sep 17 00:00:00 2001 From: shui <78994143+blackmirag3@users.noreply.github.com> Date: Thu, 11 Apr 2024 00:24:37 +0800 Subject: [PATCH 321/503] Add edit integration test --- src/main/java/classify/ui/UI.java | 2 +- src/test/java/classify/commands/EditTest.java | 68 +++++++++++++++++++ .../java/classify/user/InputParsingTest.java | 21 ++++++ 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index bc3b0e993f..ac47278928 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -51,7 +51,7 @@ public class UI { private static final String STUDENT_NAME_MESSAGE = "Name: "; private static final String CLASSES_ATTENDED_PROMPT = "Enter Classes Attended (blank to skip): "; private static final String CLASSES_ATTENDED_MESSAGE = "Classes Attended: "; - private static final String STUDENT_NOT_FOUND_MESSAGE = "Student not found!"; + private static final String STUDENT_NOT_FOUND_MESSAGE = "No student found to edit!"; private static final String STUDENT_ADDED_MESSAGE = "Student added successfully!"; private static final String STUDENT_DELETED_MESSAGE = "Student removed successfully!"; private static final String SUBJECT_MESSAGE = "Subject: "; diff --git a/src/test/java/classify/commands/EditTest.java b/src/test/java/classify/commands/EditTest.java index 8b0296d262..ad53b3eb69 100644 --- a/src/test/java/classify/commands/EditTest.java +++ b/src/test/java/classify/commands/EditTest.java @@ -1,4 +1,72 @@ package classify.commands; +import classify.student.Student; +import classify.student.StudentList; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.AfterEach; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Scanner; +import static org.junit.jupiter.api.Assertions.assertEquals; + public class EditTest { + private static final String BYE = "bye"; + private static ArrayList masterList; + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + /** + * Initialises masterList by referencing static masterStudentList to run edit commands on + */ + @BeforeAll + public static void initialiseList() { + masterList = StudentList.masterStudentList; + } + + /** + * Clears master student list before each test + * Redirect system output to a PrintStream for capturing test output + */ + @BeforeEach + public void setUp() { + masterList.clear(); + System.setOut(new PrintStream(outputStream)); + } + + /** + * Clears static masterStudentList + */ + @AfterEach + public void tearDown() { + masterList.clear(); + } + + /** + * Tests edit command where masterList is not empty and user tries to find a student that does not exist + */ + @Test + public void testEditNoStudentFound() { + + String testStudent = "adam"; + Student student = new Student(testStudent); + ArrayList students = StudentList.masterStudentList; + students.add(student); + + String testInput = "not adam"; + System.setIn(new ByteArrayInputStream(testInput.getBytes())); + + EditStudent.editStudent(new Scanner(System.in), null); + + //Initial function call where programme prompts for student name + System.setOut(System.out); + String printedOutput = outputStream.toString(); + String expectedOutput = "Name of student to edit (blank to exit):" + System.lineSeparator() + + "No student found to edit!" + System.lineSeparator(); + assertEquals(printedOutput, expectedOutput); + } } diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index 2c78949832..a16096363d 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -61,6 +61,27 @@ public void testUnknownCommand() { assertEquals(expectedOutput.trim(), printedOutput); } + @Test + public void testEditCommand() { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outputStream)); + + ArrayList students = new ArrayList<>(); + ArrayList recentlyDeletedList = new ArrayList<>(); + ArrayList archiveList = new ArrayList<>(); + String [] commands = new String[2]; + commands[0] = "edit"; + + InputParsing.parseUserCommand(commands, students, recentlyDeletedList, archiveList, new Scanner(System.in)); + + System.setOut(System.out); + String printedOutput = outputStream.toString(); + String expectedOutput = "Currently no students in list." + System.lineSeparator() + + "No student found to edit!" + System.lineSeparator(); + + assertEquals(expectedOutput, printedOutput); + } + //@@author alalal47 @Test public void testHelpCommand() { From 8badc478580868aa99cc719e8d110625758020a9 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Thu, 11 Apr 2024 01:55:41 +0800 Subject: [PATCH 322/503] Update UI class for Process --- src/main/java/classify/ui/UI.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index bc3b0e993f..08cc7d9daa 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -188,7 +188,8 @@ public static void printEndConversation() { public static void printProcessTextFileInputMessage(){ System.out.println("process " + - "Processes a text file which has been added by a user"); + "Processes a text file containing a list of students taking the same subject and the same number " + + "of classes."); } //@@author blackmirag3 From a5307e770bebc87be2ee5aeca0cce22548deab9c Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Thu, 11 Apr 2024 01:56:08 +0800 Subject: [PATCH 323/503] Update User Guide and add TOC --- docs/UserGuide.md | 282 +++++++++++++++++++++++++--------------------- 1 file changed, 151 insertions(+), 131 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 8c4a169ee3..137d557a34 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -1,5 +1,28 @@ # User Guide for **Classify** +## Table of Contents +- [Preface](#preface) +- [Introduction](#introduction) +- [Quick Start](#quick-start) +- [Features](#features) +- [Usage](#usage) - Pressing the buttons below will lead you to the correct section. + - [`Add`](#adding-a-student-add) + - [`View`](#view-details-of-a-student-view) + - [`Delete`](#delete-a-student-from-the-working-list-delete) + - [`Edit`](#edit-details-of-a-student-edit) + - [`List`](#display-the-list-of-students-list) + - [`Sort`](#sort-the-list-of-students-sort) + - [`Process`](#process-a-list-of-students-from-a-text-file-process) + - [`Archive`](#move-a-student-from-the-master-list-to-the-archive-archive) + - [`Unarchive`](#move-a-student-from-the-archive-back-to-the-master-list-unarchive) + - [`Undo`](#undo-a-delete-and-restore-the-deleted-student-to-the-working-list-undo) + - [`Restore`](#restore-a-student-to-the-working-list-restore) + - [`Help`](#display-instructions-on-how-to-use-classify-help) + - [`Bye`](#exit-classify-bye) +- [Command Summary](#command-summary) +- [FAQ](/docs/UserGuide.md/#faq) +--- + ## Preface With the increased competitiveness of cohorts in Singapore, tuition centres have become more prevalent than ever before. @@ -11,6 +34,8 @@ In such a fast-growing market, it is important that these tuition centres use be These systems enable tutors and administrative staff to focus on more pressing issues and work on catering to every students' needs instead of being swamped with paperwork. +--- + ## Introduction Classify is a student management system meant to assist administrative staff of private tuition centres. @@ -27,8 +52,10 @@ Within our program, a student can be stored with their We have determined these to be the attributes important to running a working tuition centre. Based on these attributes, our program also has functions to sort students based on grades, subjects, improvements since joining the centre. +---
+ ## Quick Start 1. Ensure that you have __Java 11 or above__ installed. @@ -39,10 +66,11 @@ We have determined these to be the attributes important to running a working tui java -jar ./Classify.jar ``` 5. Run the command ```help``` within the program to get a quick view of the available commands. +--- ## Features -### - Add a student +### - Add a student Initialises the process of adding in a student. @@ -108,6 +136,10 @@ Adds in the most recently deleted student back into the runtime database. Finds a specific deleted student and adds it back into the runtime database. +### - Process a list of students from a text file + +Enables users to add multiple students taking the same subject and having the same number of classes attended all at once. + ### - Display help message Prints a message with instructions on how to use the features of Classify. @@ -116,7 +148,7 @@ Prints a message with instructions on how to use the features of Classify. Exits the program. - +--- # Usage **Please note that if any of the following characters are entered in any string prompts, `#, - and ~`, they will be replaced and your command may be deemed invalid.** @@ -168,7 +200,7 @@ NUMBER . ``` -### - View details of a student `view` +### View details of a student `view` Views a student's details. Allows the user to do view [name] or just view. Format: `view` or `view NAME` @@ -198,7 +230,24 @@ Current marks out of 100: 100.0 Classes Attended: 1 ``` -### - Edit details of a student `edit` +### Delete a student from the working list `delete` +Deletes the student from the list. Allows the user to do delete [student] or just delete. + +Format: `delete` or `delete NAME` + +Depending on whether the user entered the student's name or not during the command, +a field will be printed out in the terminal, awaiting a user input. + +``` +Example: +delete + +Enter student name: +wario +Student removed successfully! +``` + +### Edit details of a student `edit` Edit a student's details and subjects. Allows the user to do edit [student] or just edit. Format: `edit` or `edit NAME` @@ -245,52 +294,7 @@ What else can I do for you today? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` -### - Delete a student from the working list `delete` -Deletes the student from the list. Allows the user to do delete [student] or just delete. - -Format: `delete` or `delete NAME` - -Depending on whether the user entered the student's name or not during the command, -a field will be printed out in the terminal, awaiting a user input. - -``` -Example: -delete - -Enter student name: -wario -Student removed successfully! -``` -### - Restore a student to the working list `restore` -Restores a student deleted in the current session. Allows the user to do restore [student] or just restore. - -Format: `restore` or `restore NAME` - -Depending on whether the user entered the student's name or not during the command, -a field will be printed out in the terminal, awaiting a user input. - -``` -Example: -restore -Enter student name: -mario -Student has been restored! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``` - -### - Undo a delete and restore the deleted student to the working list `undo` -Undoes the latest delete. Used by typing `undo` - -Format: `undo` - -``` -Example: -undo -Last delete undone! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``` - -### - Display the list of students `list` +### Display the list of students `list` Displays the list of all students, or students with a specified subject. The user can further specify if they would like to display the full student list, the list with the total classes attended, as well as the list of students in the archive or in the recently deleted list. @@ -379,7 +383,43 @@ List of students in recently deleted: Currently, there are 4 students in the list. ``` -### - Move a student from the master list to the archive `archive` +### Sort the list of students `sort` +Sorts the list of students based on the following input. Allows the user to do sort [type] or just sort. + +Format: `sort`, `sort name`, `sort classes` or `sort payment` + +Depending on whether the user entered the student's name or not during the command, +fields will be printed out in the terminal, awaiting a user input each time. + +``` +Example: +sort +Sort by: (Choose index) +1. Name (A to Z) +2. Total number of classes attended: +3. Date of last fee payment: +1 +List of Students: +1. mario +2. toad +3. wario +Currently, there are 3 students in the list. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Sort complete! + +sort payment +1.toad - Date of last payment: 2015-10-21 +2.mario - Date of last payment: 2024-03-30 +3.wario - Date of last payment: 2024-03-30 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Sort complete! +``` + +### Process a list of students from a text file `process` +Reads a text file in the inputFolder folder inside data. + +### Move a student from the master list to the archive `archive` Adds a student to the archive and deletes them from the master list. Allows the user to do archive [name] or just archive. Format: `archive`, `archive NAME` @@ -402,7 +442,7 @@ Data update success! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` -### - Move a student from the archive back to the master list `unarchive` +### Move a student from the archive back to the master list `unarchive` Removes a student from the archive and adds them back to the master list. Allows the user to do unarchive [name] or just unarchive. Format: `unarchive`, `unarchive NAME` @@ -425,40 +465,36 @@ Data update success! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` -### - Sort the list of students `sort` -Sorts the list of students based on the following input. Allows the user to do sort [type] or just sort. - -Format: `sort`, `sort name`, `sort classes` or `sort payment` +### Undo a delete and restore the deleted student to the working list `undo` +Undoes the latest delete. Used by typing `undo` -Depending on whether the user entered the student's name or not during the command, -fields will be printed out in the terminal, awaiting a user input each time. +Format: `undo` ``` Example: -sort -Sort by: (Choose index) -1. Name (A to Z) -2. Total number of classes attended: -3. Date of last fee payment: -1 -List of Students: -1. mario -2. toad -3. wario -Currently, there are 3 students in the list. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +undo +Last delete undone! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Sort complete! +``` -sort payment -1.toad - Date of last payment: 2015-10-21 -2.mario - Date of last payment: 2024-03-30 -3.wario - Date of last payment: 2024-03-30 +### Restore a student to the working list `restore` +Restores a student deleted in the current session. Allows the user to do restore [student] or just restore. + +Format: `restore` or `restore NAME` + +Depending on whether the user entered the student's name or not during the command, +a field will be printed out in the terminal, awaiting a user input. + +``` +Example: +restore +Enter student name: +mario +Student has been restored! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Sort complete! ``` -### - Display instructions on how to use Classify `help` +### Display instructions on how to use Classify `help` Prints instructions which detail how to use all the features of Classify. Format: `help` @@ -479,11 +515,12 @@ sort Sorts the student list by the input parameter, expec Currently available types: name, classes, payment archive Removes the specified student from the list and archives them, can be used directly by archive [name]. unarchive Removes the specified student from the archive and adds them to the list, can be used directly by unarchive [name]. +process Processes a text file containing a list of students taking the same subject and the same number of classes. help Prints this help message ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` -### - Exit Classify `bye` +### Exit Classify `bye` Exits the Classify program. Format: `bye` @@ -493,7 +530,42 @@ bye Hope you've had a productive day. See you again! Goodbye! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` +--- + + +## Command Summary +This section provides a quick overview of all the commands used in our Classify. + + +|Command|Description| View Command| +|--|--|--| +|**General**| | +|`add `| - Adds a student into the list.
- If the name of the student is not specified in the initial command,
the program will prompt the user for the name.|[Add](#adding-a-student-add)| +|`view `|Views a students details.
If the name of the student is not specified in the initial command, the program will prompt the user for the name.|[View](#view-details-of-a-student-view)| +|`delete `|Deletes the student from the list.
If the name of the student is not specified in the initial command, the program will prompt the user for the name.|[Delete](#delete-a-student-from-the-working-list-delete)| +|`edit `|Allows the user to edit the details of the student.
If the name of the student is not specified in the initial command, the program will prompt the user for the name.|[Edit](#edit-details-of-a-student-edit)| +|**List**| | +|`list`, press enter,
[subject]|Displays the list of students that has taken that subject.|[List](#display-the-list-of-students-list)| +|`list`, press enter,
press enter, [1]|Displays the list of students that is registered in the tuition centre.|[List](#display-the-list-of-students-list)| +|`list`, press enter,
press enter, [2]|Displays the list of students that is registered in the tuition centre with the total number of classes taken.|[List](#display-the-list-of-students-list)| +|**Sort**| | +|`sort `|Sorts the list lexicographically.
If the word `name` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| +|`sort `|Sorts the list by the last fee payment date of a student.
If the word `payment` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| +|`sort `|Sorts the list by the number of classes a student has attended.
If the word `classes` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| +|`view_subject `|Lists all the students associated with that subject.
If the user specifies the subject in the initial command, the list will be generated and the command will be terminated.
If the user does not specify the subject, the programme will continuously prompt the user for a subject,
until they choose to terminate the command.|[Need To FIX](#produce-a-list-of-all-the-students-who-takes-a-subject)| +|**Process**| | +|`process`, press enter,
``| Processes a text file containing a list of students taking the same subject and having attended the same number of lessons.
Adds all of them into the current list with their individual grades for the subject.
Will need to manually input their other attributes (eg. phone number, gender, etc) |[Process](#process-a-list-of-students-from-a-text-file-process)| +|**Archive**| | +|`archive `|Archives specified student. Removes student from current list and adds student to archive.|[Archive](#move-a-student-from-the-master-list-to-the-archive-archive)| +|`unarchive `|Unarchives specified student. Moves student from archive to current list.|[Unarchive](#move-a-student-from-the-archive-back-to-the-master-list-unarchive)| +|`undo`|Undoes the last deleted entry.|[Undo](#undo-a-delete-and-restore-the-deleted-student-to-the-working-list-undo)| +|`restore `|Restores the student from the current session|[Restore](#restore-a-student-to-the-working-list-restore)| +|**Others**| | +|`help`|Generates the list of commands.|[Help](#display-instructions-on-how-to-use-classify-help)| +|`bye`|Terminates the program.|[Bye](#exit-classify-bye)| + +--- ## FAQ **Q**: How do I transfer my data to another computer? @@ -512,56 +584,4 @@ Hope you've had a productive day. See you again! Goodbye! **A**: Due to the ever-changing climate of what is considered a name (and more), we have limited the bans to 3 special characters above only. In the event your name or other identification metrics contains `#`, `~` or `-`, we seek for your understanding. - -## Command Summary - -### `add ` -Adds a student into the list. If the name of the student is not specified in the initial command, the program will prompt the user for the name. - -### `list`, press enter, [subject] -Displays the list of students that has taken that subject. - -### `list`, press enter, press enter, [1] -Displays the list of students that is registered in the tuition centre. - -### `list`, press enter, press enter, [2] -Displays the list of students that is registered in the tuition centre with the total number of classes taken. - -### `view ` -Views a students details. If the name of the student is not specified in the initial command, the program will prompt the user for the name. - -### `delete ` -Deletes the student from the list. If the name of the student is not specified in the initial command, the program will prompt the user for the name. - -### `edit ` -Allows the user to edit the details of the student. If the name of the student is not specified in the initial command, the program will prompt the user for the name. - -### `sort ` -Sorts the list lexicographically. If the word `name` is not specified in the initial command, the program will prompt the user for an appropriate flag. - -### `sort ` -Sorts the list by the last fee payment date of a student. If the word `payment` is not specified in the initial command, the program will prompt the user for an appropriate flag. - -### `sort ` -Sorts the list by the number of classes a student has attended. If the word `classes` is not specified in the initial command, the program will prompt the user for an appropriate flag. - -### `view_subject ` -Lists all the students associated with that subject. If the user specifies the subject in the initial command, the list will be generated and the command will be terminated. If the user does not specify the subject, the programme will continuously prompt the user for a subject, until they choose to terminate the command. - -### `archive ` -Archives specified student. Removes student from current list and adds student to archive. - -### `unarchive ` -Unarchives specified student. Moves student from archive to current list. - -### `undo` -Undoes the last deleted entry. - -### `restore ` -Restores the student from the current session. - -### `help` -Generates the list of commands. - -### `bye` -Terminates the program. +--- \ No newline at end of file From 70a36dba3d16bcbbbbe17c1f928c64a49d6f70ff Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Thu, 11 Apr 2024 01:56:17 +0800 Subject: [PATCH 324/503] Update Test Case --- src/test/java/classify/user/InputParsingTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index 2c78949832..79715ff9c5 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -118,7 +118,8 @@ public void testHelpCommand() { "unarchive Removes the specified student from the archive and adds them to the list" + ", can be used directly by unarchive [name]." + System.lineSeparator() + - "process Processes a text file which has been added by a user" + "process Processes a text file containing a list of students taking the same"+ + " subject and the same number of classes." + System.lineSeparator() + "help Prints this help message" + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; From 4c8679660e7cf9636007f093f99ad4d10aeab61a Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Thu, 11 Apr 2024 02:04:48 +0800 Subject: [PATCH 325/503] Update UG after the merged changes --- docs/UserGuide.md | 66 ++++------------------------------------------- 1 file changed, 5 insertions(+), 61 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index f5435c716d..b37ac215ca 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -549,11 +549,14 @@ This section provides a quick overview of all the commands used in our Classify. |`list`, press enter,
[subject]|Displays the list of students that has taken that subject.|[List](#display-the-list-of-students-list)| |`list`, press enter,
press enter, [1]|Displays the list of students that is registered in the tuition centre.|[List](#display-the-list-of-students-list)| |`list`, press enter,
press enter, [2]|Displays the list of students that is registered in the tuition centre with the total number of classes taken.|[List](#display-the-list-of-students-list)| -|**Sort**| | +|`list`, press enter,
press enter, [3]|Displays the list of students that is registered in the tuition centre with their phone numbers beside their names|[List](#display-the-list-of-students-list)| +|`list`, press enter,
press enter, [4]|Displays the list of students who were archived.|[List](#display-the-list-of-students-list)| +|`list`, press enter,
press enter, [5]|Displays the list of students who were recently deleted from the master list.|[List](#display-the-list-of-students-list) | +|**Sort**| [List](#display-the-list-of-students-list)| |`sort `|Sorts the list lexicographically.
If the word `name` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| |`sort `|Sorts the list by the last fee payment date of a student.
If the word `payment` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| |`sort `|Sorts the list by the number of classes a student has attended.
If the word `classes` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| -|`view_subject `|Lists all the students associated with that subject.
If the user specifies the subject in the initial command, the list will be generated and the command will be terminated.
If the user does not specify the subject, the programme will continuously prompt the user for a subject,
until they choose to terminate the command.|[Need To FIX](#produce-a-list-of-all-the-students-who-takes-a-subject)| +|`view_subject `|Lists all the students associated with that subject.
If the user specifies the subject in the initial command, the list will be generated and the command will be terminated.
If the user does not specify the subject, the programme will continuously prompt the user for a subject,
until they choose to terminate the command.|[NEED TO FIX](#produce-a-list-of-all-the-students-who-takes-a-subject)| |**Process**| | |`process`, press enter,
``| Processes a text file containing a list of students taking the same subject and having attended the same number of lessons.
Adds all of them into the current list with their individual grades for the subject.
Will need to manually input their other attributes (eg. phone number, gender, etc) |[Process](#process-a-list-of-students-from-a-text-file-process)| |**Archive**| | @@ -585,62 +588,3 @@ This section provides a quick overview of all the commands used in our Classify. **A**: Due to the ever-changing climate of what is considered a name (and more), we have limited the bans to 3 special characters above only. In the event your name or other identification metrics contains `#`, `~` or `-`, we seek for your understanding. --- - -## Command Summary - -### `add ` -Adds a student into the list. If the name of the student is not specified in the initial command, the program will prompt the user for the name. - -### `list`, press enter, [subject] -Displays the list of students that has taken that subject. - -### `list`, press enter, press enter, [1] -Displays the list of students that is registered in the tuition centre. - -### `list`, press enter, press enter, [2] -Displays the list of students that is registered in the tuition centre with the total number of classes taken. - -### `list`, press enter, press enter, [3] -Displays the list of students that is registered in the tuition centre with their phone numbers beside their names - -### `list`, press enter, press enter, [4] -Displays the list of students who were archived. - -### `list`, press enter, press enter, [5] -Displays the list of students who were recently deleted from the master list. - -### `view ` -Views a students details. If the name of the student is not specified in the initial command, the program will prompt the user for the name. - -### `delete ` -Deletes the student from the list. If the name of the student is not specified in the initial command, the program will prompt the user for the name. - -### `edit ` -Allows the user to edit the details of the student. If the name of the student is not specified in the initial command, the program will prompt the user for the name. - -### `sort ` -Sorts the list lexicographically. If the word `name` is not specified in the initial command, the program will prompt the user for an appropriate flag. - -### `sort ` -Sorts the list by the last fee payment date of a student. If the word `payment` is not specified in the initial command, the program will prompt the user for an appropriate flag. - -### `sort ` -Sorts the list by the number of classes a student has attended. If the word `classes` is not specified in the initial command, the program will prompt the user for an appropriate flag. - -### `archive ` -Archives specified student. Removes student from current list and adds student to archive. - -### `unarchive ` -Unarchives specified student. Moves student from archive to current list. - -### `undo` -Undoes the last deleted entry. - -### `restore ` -Restores the student from the current session. - -### `help` -Generates the list of commands. - -### `bye` -Terminates the program. From 7e8a4c42214533fc22d484aff30efa1df5eddf4a Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Thu, 11 Apr 2024 02:07:54 +0800 Subject: [PATCH 326/503] Add required page-breaks --- docs/UserGuide.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index b37ac215ca..cbec1e249e 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -23,6 +23,8 @@ - [FAQ](/docs/UserGuide.md/#faq) --- +
+ ## Preface With the increased competitiveness of cohorts in Singapore, tuition centres have become more prevalent than ever before. @@ -36,6 +38,8 @@ These systems enable tutors and administrative staff to focus on more pressing i --- +
+ ## Introduction Classify is a student management system meant to assist administrative staff of private tuition centres. @@ -53,8 +57,6 @@ Within our program, a student can be stored with their We have determined these to be the attributes important to running a working tuition centre. Based on these attributes, our program also has functions to sort students based on grades, subjects, improvements since joining the centre. --- -
- ## Quick Start @@ -67,6 +69,7 @@ java -jar ./Classify.jar ``` 5. Run the command ```help``` within the program to get a quick view of the available commands. --- +
## Features @@ -149,6 +152,9 @@ Prints a message with instructions on how to use the features of Classify. Exits the program. --- + +
+ # Usage **Please note that if any of the following characters are entered in any string prompts, `#, - and ~`, they will be replaced and your command may be deemed invalid.** @@ -532,7 +538,7 @@ Hope you've had a productive day. See you again! Goodbye! ``` --- - +
## Command Summary This section provides a quick overview of all the commands used in our Classify. @@ -569,6 +575,9 @@ This section provides a quick overview of all the commands used in our Classify. |`bye`|Terminates the program.|[Bye](#exit-classify-bye)| --- + +
+ ## FAQ **Q**: How do I transfer my data to another computer? From 54ad47573fe5132a98ba511769341bd913714a33 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Thu, 11 Apr 2024 02:39:39 +0800 Subject: [PATCH 327/503] Add exclamation mark for disclaimer --- docs/UserGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index cbec1e249e..7161b96297 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -157,7 +157,7 @@ Exits the program. # Usage -**Please note that if any of the following characters are entered in any string prompts, `#, - and ~`, they will be replaced and your command may be deemed invalid.** +:exclamation: **Please note that if any of the following characters are entered in any string prompts, `#, - and ~`, they will be replaced and your command may be deemed invalid.**:exclamation: ### Adding a student: `add` Initialises an interface for adding a student and their relevant details to the database. Allows the user to do add or add [name] From 7698301907cbc739d2c94f5cc852f18d731d071f Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Thu, 11 Apr 2024 16:30:44 +0800 Subject: [PATCH 328/503] Update functionality for Process command --- docs/UserGuide.md | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 7161b96297..db3939b0cb 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -423,7 +423,47 @@ Sort complete! ``` ### Process a list of students from a text file `process` -Reads a text file in the inputFolder folder inside data. +Reads a text file in the inputFolder folder located inside the data folder. + +:exclamation: The text file which is being processed **MUST** follow the format shown here[insert stuff here]. + +Format: `process`, press enter, `filename` (without filetype) **or** `filename.txt` (with filetype) + +The processed file will add the students into the masterStudentList with relevant attributes for subject name, grades, and classes attended. + +:exclamation: All other student attributes (eg. gender, phone number, remarks, etc) must be updated by the user. + +#### Without Filetype +``` +process +Current Files in your Input Folder: +1. mathclass.txt +2. scienceclass.txt + +Please enter the exact name of the file you'd like to process: +mathclass +Fetching the data from mathclass.txt. +Analysing Inputs... +Directory loaded successfully! +Data update success! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` + +#### With Filetype +``` +process +Current Files in your Input Folder: +1. mathclass.txt +2. scienceclass.txt + +Please enter the exact name of the file you'd like to process: +scienceclass.txt +Fetching the data from scienceclass.txt. +Analysing Inputs... +Directory loaded successfully! +Data update success! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ### Move a student from the master list to the archive `archive` Adds a student to the archive and deletes them from the master list. Allows the user to do archive [name] or just archive. From 651e60449d87681fcaaa347763777008cab6a34e Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Thu, 11 Apr 2024 16:40:18 +0800 Subject: [PATCH 329/503] Remove view_subject functionality in UG command summary --- docs/UserGuide.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index db3939b0cb..4042488f0f 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -602,7 +602,6 @@ This section provides a quick overview of all the commands used in our Classify. |`sort `|Sorts the list lexicographically.
If the word `name` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| |`sort `|Sorts the list by the last fee payment date of a student.
If the word `payment` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| |`sort `|Sorts the list by the number of classes a student has attended.
If the word `classes` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| -|`view_subject `|Lists all the students associated with that subject.
If the user specifies the subject in the initial command, the list will be generated and the command will be terminated.
If the user does not specify the subject, the programme will continuously prompt the user for a subject,
until they choose to terminate the command.|[NEED TO FIX](#produce-a-list-of-all-the-students-who-takes-a-subject)| |**Process**| | |`process`, press enter,
``| Processes a text file containing a list of students taking the same subject and having attended the same number of lessons.
Adds all of them into the current list with their individual grades for the subject.
Will need to manually input their other attributes (eg. phone number, gender, etc) |[Process](#process-a-list-of-students-from-a-text-file-process)| |**Archive**| | From 1d8620fbf8a6ba20bae4e4ae33069d7084bd0c84 Mon Sep 17 00:00:00 2001 From: shui <78994143+blackmirag3@users.noreply.github.com> Date: Thu, 11 Apr 2024 21:50:42 +0800 Subject: [PATCH 330/503] Update UG --- docs/UserGuide.md | 266 ++++++++++++------ src/main/java/classify/ui/UI.java | 2 +- src/test/java/classify/commands/EditTest.java | 1 + 3 files changed, 182 insertions(+), 87 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 4042488f0f..5387dcc2c4 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -184,7 +184,7 @@ Thus, please be informed and educated that our software only works in countries To be specific, this is referring to a city-state republic in South East Asia, that lies in the timezone GMT +8 in the Straits of Johor. Some may debate that our time zone is actually GMT+7.5 or GMT+7, but it was changed to facilitate business deals and decisions with other financial hubs in the region thanks to our capitalistic overlords. -Example: +#### Example: ``` add wario @@ -206,7 +206,8 @@ NUMBER . ``` -### View details of a student `view` +### View details of a student `view` + Views a student's details. Allows the user to do view [name] or just view. Format: `view` or `view NAME` @@ -221,8 +222,8 @@ How it works (cases for input): - view JAMES WONG -> JAMES WONG * Regardless of what capitalisation the user uses for the name, the program will recognise that upper and lower cases should return the same student. +#### Example: ``` -Example: view wario Student details: @@ -235,6 +236,21 @@ Subject: subject Current marks out of 100: 100.0 Classes Attended: 1 ``` +For any student that exists within the programme's master, archive and recently deleted list, the user cannot add new students with a name-phone number pair that matches that of the existing student. + +The following is an example of trying to add a new student that matches the name and phone number of an already existing student. +``` +Example: + +add awesomesjh +Subject (enter nothing to skip): +No subjects added. +Please input a valid phone number: +Enter a non-number or blank to exit interface. +88888888 +Student and Phone number pair found. If not found in the list, please restore or unarchive the student instead. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ### Delete a student from the working list `delete` Deletes the student from the list. Allows the user to do delete [student] or just delete. @@ -244,8 +260,8 @@ Format: `delete` or `delete NAME` Depending on whether the user entered the student's name or not during the command, a field will be printed out in the terminal, awaiting a user input. +#### Delete example: ``` -Example: delete Enter student name: @@ -259,12 +275,24 @@ Edit a student's details and subjects. Allows the user to do edit [student] or j Format: `edit` or `edit NAME` If user has not entered a name, they will be prompted to input a name. +Once programme received name input, the student master list will be searched for the name. + If the name input matches that of an existing student, edit mode will be entered for that student. -A list of actions will be printed and user can enter the respective index to select action to take. -Each action has its own step by step prompts for user to follow. +If 2 students with the same name is found, the user will be prompted to enter the desired student's phone number to select them. + +In edit mode, a list of actions will be printed and user can enter the respective index to select action to take. +The following actions can be executed: +- Add new subject to student +- Modify student's existing subject +- Delete student's existing subject +- Modify student's phone number +- Modify student's payment date +- Modify student's remarks +Each action has its own step by step prompts for user to follow, as seen in examples below. + +#### Edit examples: ``` -Example: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Welcome to Classify! What can I do for you today? @@ -299,6 +327,67 @@ Do you want to add another subject and grade? (yes/no) What else can I do for you today? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` +If no student is found in the master student list, edit mode will not be entered and the programme will resume as per normal. + + +#### No student found to edit: +``` +edit +Name of student to edit (blank to exit): +tim lau kar meeng +No student found to edit! +What else can I do for you today? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` + +### Delete a student from the working list `delete` +Deletes the student from the list. Allows the user to do delete [student] or just delete. + +Format: `delete` or `delete NAME` + +Depending on whether the user entered the student's name or not during the command, +a field will be printed out in the terminal, awaiting a user input. + +#### Example: +``` +delete + +Enter student name: +wario +Student removed successfully! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` + +### Restore a student to the working list `restore` +Restores a student deleted in the current session. Allows the user to do restore [student] or just restore. + +Format: `restore` or `restore NAME` + +Depending on whether the user entered the student's name or not during the command, +a field will be printed out in the terminal, awaiting a user input. + +#### Example: +``` +restore +Enter student name: +mario +Student has been restored! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` + +### Undo a delete and restore the deleted student to the working list `undo` +Undoes the latest "delete student". Used by typing `undo` + +This command does not undo changes from the "edit" command. + +Format: `undo` + +``` +Example: +undo +Last delete undone! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ### Display the list of students `list` Displays the list of all students, or students with a specified subject. @@ -309,12 +398,14 @@ Format: `list` Allows the user to specify a subject, then displays all students with that subject. If the field is left blank, students will be displayed regardless of the subjects they have. + The user can then select by index, from 4 additional options to either display all students in the master list, all students in the master list as well as the total number of classes they have attended. + Alternatively, the user can choose to display either the students in the recently deleted list or the archive. +#### Example: ``` -Example: list Enter subject name (leave blank for all students): math @@ -373,6 +464,22 @@ List of students with phone numbers: list Enter subject name (leave blank for all students): +Choose the type of list to display: (index only) +1. Full student list +2. List of students with total classes attended +3. List of students with phone number shown +4. List of students in archive +5. List of students in recently deleted +Enter your choice (1, 2, 3, 4 or 5): +4 +List of students in archive: +1.Timothy +Currently, there is 1 student in the list. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +list +Enter subject name (leave blank for all students): + Choose the type of list to display: (index only) 1. Full student list 2. List of students with total classes attended @@ -388,6 +495,65 @@ List of students in recently deleted: 4.Mario Currently, there are 4 students in the list. ``` +### Move a student from the master list to the archive `archive` +Adds a student to the archive and deletes them from the master list. Allows the user to do archive [name] or just archive. + +Format: `archive`, `archive NAME` + +Depending on whether the user entered the student's name or not during the command, +a field will be printed out in the terminal, awaiting a user input. + +For any archived student, the user will be unable to add a student with the same name and contact number pair as the archived. + +#### Archive example: +``` +archive wario +Archive List: +Analysing Inputs... +Directory loaded successfully! +Data update success! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Runtime Database: +Analysing Inputs... +Directory loaded successfully! +Data update success! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` + +### Move a student from the archive back to the master list `unarchive` +Removes a student from the archive and adds them back to the master list. Allows the user to do unarchive [name] or just unarchive. + +Format: `unarchive`, `unarchive NAME` + +Depending on whether the user entered the student's name or not during the command, +a field will be printed out in the terminal, awaiting a user input. + +If a student that exists in the archive data file matches the name and phone number of an already existing student, the archived student cannot be unarchived and will be overwritten subsequently. + +#### Valid student in archive: + +``` +unarchive wario +Archive List: +Analysing Inputs... +Directory loaded successfully! +Data update success! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Runtime List: +Analysing Inputs... +Directory loaded successfully! +Data update success! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` + +#### Invalid student: + +``` +unarchive yeeter +No student found! +What else can I do for you today? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ### Sort the list of students `sort` Sorts the list of students based on the following input. Allows the user to do sort [type] or just sort. @@ -397,8 +563,9 @@ Format: `sort`, `sort name`, `sort classes` or `sort payment` Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. +#### Example: + ``` -Example: sort Sort by: (Choose index) 1. Name (A to Z) @@ -433,7 +600,7 @@ The processed file will add the students into the masterStudentList with relevan :exclamation: All other student attributes (eg. gender, phone number, remarks, etc) must be updated by the user. -#### Without Filetype +#### Without Filetype: ``` process Current Files in your Input Folder: @@ -449,7 +616,7 @@ Data update success! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` -#### With Filetype +#### With Filetype: ``` process Current Files in your Input Folder: @@ -465,88 +632,15 @@ Data update success! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` -### Move a student from the master list to the archive `archive` -Adds a student to the archive and deletes them from the master list. Allows the user to do archive [name] or just archive. - -Format: `archive`, `archive NAME` - -Depending on whether the user entered the student's name or not during the command, -a field will be printed out in the terminal, awaiting a user input. - -``` -Example: -archive wario -Archive List: -Analysing Inputs... -Directory loaded successfully! -Data update success! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Runtime Database: -Analysing Inputs... -Directory loaded successfully! -Data update success! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``` - -### Move a student from the archive back to the master list `unarchive` -Removes a student from the archive and adds them back to the master list. Allows the user to do unarchive [name] or just unarchive. - -Format: `unarchive`, `unarchive NAME` - -Depending on whether the user entered the student's name or not during the command, -a field will be printed out in the terminal, awaiting a user input. - -``` -Example: -unarchive wario -Archive List: -Analysing Inputs... -Directory loaded successfully! -Data update success! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Runtime List: -Analysing Inputs... -Directory loaded successfully! -Data update success! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``` - -### Undo a delete and restore the deleted student to the working list `undo` -Undoes the latest delete. Used by typing `undo` - -Format: `undo` -``` -Example: -undo -Last delete undone! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``` - -### Restore a student to the working list `restore` -Restores a student deleted in the current session. Allows the user to do restore [student] or just restore. - -Format: `restore` or `restore NAME` - -Depending on whether the user entered the student's name or not during the command, -a field will be printed out in the terminal, awaiting a user input. - -``` -Example: -restore -Enter student name: -mario -Student has been restored! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``` ### Display instructions on how to use Classify `help` Prints instructions which detail how to use all the features of Classify. Format: `help` +#### Example: ``` -Example: help add Adds a student to the student list, expects a name, grade and lessons attended, can be used directly with a name e.g. add [name] edit Edits a students details, expects a name, can be used directly with a name e.g. edit [name] @@ -635,4 +729,4 @@ This section provides a quick overview of all the commands used in our Classify. **A**: Due to the ever-changing climate of what is considered a name (and more), we have limited the bans to 3 special characters above only. In the event your name or other identification metrics contains `#`, `~` or `-`, we seek for your understanding. ---- + diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 7d160b20b6..36838faa25 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -51,7 +51,7 @@ public class UI { private static final String STUDENT_NAME_MESSAGE = "Name: "; private static final String CLASSES_ATTENDED_PROMPT = "Enter Classes Attended (blank to skip): "; private static final String CLASSES_ATTENDED_MESSAGE = "Classes Attended: "; - private static final String STUDENT_NOT_FOUND_MESSAGE = "No student found to edit!"; + private static final String STUDENT_NOT_FOUND_MESSAGE = "No student found!"; private static final String STUDENT_ADDED_MESSAGE = "Student added successfully!"; private static final String STUDENT_DELETED_MESSAGE = "Student removed successfully!"; private static final String SUBJECT_MESSAGE = "Subject: "; diff --git a/src/test/java/classify/commands/EditTest.java b/src/test/java/classify/commands/EditTest.java index ad53b3eb69..cc945ca550 100644 --- a/src/test/java/classify/commands/EditTest.java +++ b/src/test/java/classify/commands/EditTest.java @@ -15,6 +15,7 @@ import java.util.Scanner; import static org.junit.jupiter.api.Assertions.assertEquals; +//Integration testing for "edit" implementation within Classify public class EditTest { private static final String BYE = "bye"; private static ArrayList masterList; From d27c5f4f2044365994674ef415c4dbb543a7e057 Mon Sep 17 00:00:00 2001 From: shui <78994143+blackmirag3@users.noreply.github.com> Date: Thu, 11 Apr 2024 22:12:59 +0800 Subject: [PATCH 331/503] Fix formatting for UG --- docs/UserGuide.md | 242 ++++++++++++++++-------------- src/main/java/classify/ui/UI.java | 21 +-- 2 files changed, 137 insertions(+), 126 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 5387dcc2c4..7ed09fd648 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -10,17 +10,17 @@ - [`View`](#view-details-of-a-student-view) - [`Delete`](#delete-a-student-from-the-working-list-delete) - [`Edit`](#edit-details-of-a-student-edit) + - [`Restore`](#restore-a-student-to-the-working-list-restore) + - [`Undo`](#undo-a-delete-and-restore-the-deleted-student-to-the-working-list-undo) - [`List`](#display-the-list-of-students-list) - [`Sort`](#sort-the-list-of-students-sort) - [`Process`](#process-a-list-of-students-from-a-text-file-process) - [`Archive`](#move-a-student-from-the-master-list-to-the-archive-archive) - [`Unarchive`](#move-a-student-from-the-archive-back-to-the-master-list-unarchive) - - [`Undo`](#undo-a-delete-and-restore-the-deleted-student-to-the-working-list-undo) - - [`Restore`](#restore-a-student-to-the-working-list-restore) - [`Help`](#display-instructions-on-how-to-use-classify-help) - [`Bye`](#exit-classify-bye) - [Command Summary](#command-summary) -- [FAQ](/docs/UserGuide.md/#faq) +- [FAQ](#faq) ---
@@ -184,7 +184,7 @@ Thus, please be informed and educated that our software only works in countries To be specific, this is referring to a city-state republic in South East Asia, that lies in the timezone GMT +8 in the Straits of Johor. Some may debate that our time zone is actually GMT+7.5 or GMT+7, but it was changed to facilitate business deals and decisions with other financial hubs in the region thanks to our capitalistic overlords. -#### Example: +#### Example usage: ``` add wario @@ -222,7 +222,7 @@ How it works (cases for input): - view JAMES WONG -> JAMES WONG * Regardless of what capitalisation the user uses for the name, the program will recognise that upper and lower cases should return the same student. -#### Example: +#### Example usage: ``` view wario @@ -239,9 +239,9 @@ Classes Attended: 1 For any student that exists within the programme's master, archive and recently deleted list, the user cannot add new students with a name-phone number pair that matches that of the existing student. The following is an example of trying to add a new student that matches the name and phone number of an already existing student. -``` -Example: +#### Example usage: +``` add awesomesjh Subject (enter nothing to skip): No subjects added. @@ -260,7 +260,7 @@ Format: `delete` or `delete NAME` Depending on whether the user entered the student's name or not during the command, a field will be printed out in the terminal, awaiting a user input. -#### Delete example: +#### Example usage: ``` delete @@ -275,23 +275,26 @@ Edit a student's details and subjects. Allows the user to do edit [student] or j Format: `edit` or `edit NAME` If user has not entered a name, they will be prompted to input a name. -Once programme received name input, the student master list will be searched for the name. +Once programme received name input, the student master list will be searched for the name. Name search is not case-sensitive. If the name input matches that of an existing student, edit mode will be entered for that student. If 2 students with the same name is found, the user will be prompted to enter the desired student's phone number to select them. -In edit mode, a list of actions will be printed and user can enter the respective index to select action to take. -The following actions can be executed: -- Add new subject to student -- Modify student's existing subject -- Delete student's existing subject -- Modify student's phone number -- Modify student's payment date -- Modify student's remarks +In edit mode, a list of actions will be printed and user can choose from a list of actions to take. +The following actions (listed along with their indexes) can be executed: +- 1 Add new subject to student +- 2 Modify student's existing subject +- 3 Delete student's existing subject +- 4 Modify student's phone number +- 5 Modify student's remarks +- 6 Modify student's payment date +- 7 Modify student's gender + +The user can enter the action's index to execute the respective action, e.g. user can input "1" to add new subject. -Each action has its own step by step prompts for user to follow, as seen in examples below. +Each action has its own step by step prompts for user to follow, as seen in below. -#### Edit examples: +#### Example usages: ``` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Welcome to Classify! @@ -303,7 +306,7 @@ Name of student to edit (blank to exit): Student details: Name: Vincent -Phone Number: 99999999 +Phone Number: 83227277 Gender: Unknown Last Payment Date: 2024-04-08 Remarks: Unknown @@ -314,8 +317,9 @@ How would you like to edit student? Enter index (blank to exit): 2. Modify subject 3. Delete subject 4. Modify phone number -6. Modify payment date 5. Modify remarks +6. Modify payment date +7. Edit Gender. >> 1 Subject (enter nothing to skip): PE Current marks out of 100 (blank to skip) : @@ -348,7 +352,7 @@ Format: `delete` or `delete NAME` Depending on whether the user entered the student's name or not during the command, a field will be printed out in the terminal, awaiting a user input. -#### Example: +#### Example usage: ``` delete @@ -366,7 +370,7 @@ Format: `restore` or `restore NAME` Depending on whether the user entered the student's name or not during the command, a field will be printed out in the terminal, awaiting a user input. -#### Example: +#### Example usage: ``` restore Enter student name: @@ -378,8 +382,6 @@ Student has been restored! ### Undo a delete and restore the deleted student to the working list `undo` Undoes the latest "delete student". Used by typing `undo` -This command does not undo changes from the "edit" command. - Format: `undo` ``` @@ -389,6 +391,8 @@ Last delete undone! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` +Note: This command does not undo changes from the `edit` command. + ### Display the list of students `list` Displays the list of all students, or students with a specified subject. The user can further specify if they would like to display the full student list, @@ -404,7 +408,7 @@ all students in the master list as well as the total number of classes they have Alternatively, the user can choose to display either the students in the recently deleted list or the archive. -#### Example: +#### Example usage: ``` list Enter subject name (leave blank for all students): @@ -495,65 +499,6 @@ List of students in recently deleted: 4.Mario Currently, there are 4 students in the list. ``` -### Move a student from the master list to the archive `archive` -Adds a student to the archive and deletes them from the master list. Allows the user to do archive [name] or just archive. - -Format: `archive`, `archive NAME` - -Depending on whether the user entered the student's name or not during the command, -a field will be printed out in the terminal, awaiting a user input. - -For any archived student, the user will be unable to add a student with the same name and contact number pair as the archived. - -#### Archive example: -``` -archive wario -Archive List: -Analysing Inputs... -Directory loaded successfully! -Data update success! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Runtime Database: -Analysing Inputs... -Directory loaded successfully! -Data update success! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``` - -### Move a student from the archive back to the master list `unarchive` -Removes a student from the archive and adds them back to the master list. Allows the user to do unarchive [name] or just unarchive. - -Format: `unarchive`, `unarchive NAME` - -Depending on whether the user entered the student's name or not during the command, -a field will be printed out in the terminal, awaiting a user input. - -If a student that exists in the archive data file matches the name and phone number of an already existing student, the archived student cannot be unarchived and will be overwritten subsequently. - -#### Valid student in archive: - -``` -unarchive wario -Archive List: -Analysing Inputs... -Directory loaded successfully! -Data update success! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Runtime List: -Analysing Inputs... -Directory loaded successfully! -Data update success! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``` - -#### Invalid student: - -``` -unarchive yeeter -No student found! -What else can I do for you today? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``` ### Sort the list of students `sort` Sorts the list of students based on the following input. Allows the user to do sort [type] or just sort. @@ -563,7 +508,7 @@ Format: `sort`, `sort name`, `sort classes` or `sort payment` Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. -#### Example: +#### Example usage: ``` sort @@ -631,7 +576,70 @@ Directory loaded successfully! Data update success! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` +### Move a student from the master list to the archive `archive` +Adds a student to the archive and deletes them from the master list. Allows the user to do archive [name] or just archive. + +Format: `archive`, `archive NAME` + +Depending on whether the user entered the student's name or not during the command, +a field will be printed out in the terminal, awaiting a user input. + +For any archived student, the user will be unable to add a student with the same name and contact number pair as the archived. + + +#### Example usage: +``` +archive wario +Archive List: +Analysing Inputs... +Directory loaded successfully! +Data update success! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Runtime Database: +Analysing Inputs... +Directory loaded successfully! +Data update success! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` +The user can then view currently archived students using the `list` command. + +### Move a student from the archive back to the master list `unarchive` +Removes a student from the archive and adds them back to the master list. Allows the user to do unarchive [name] or just unarchive. + +Format: `unarchive`, `unarchive NAME` + +Depending on whether the user entered the student's name or not during the command, +a field will be printed out in the terminal, awaiting a user input. + +The user can then view currently archived students using the `list` command. + +#### Valid student in archive: + +``` +unarchive wario +Archive List: +Analysing Inputs... +Directory loaded successfully! +Data update success! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Runtime List: +Analysing Inputs... +Directory loaded successfully! +Data update success! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` + +#### Invalid student: + +``` +unarchive yeeter +No student found! +What else can I do for you today? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` +If a student that exists in the archive data file matches the name and phone number of an already existing student, +the archived student will not be loaded into the archive list and will be overwritten subsequently. ### Display instructions on how to use Classify `help` @@ -639,7 +647,7 @@ Prints instructions which detail how to use all the features of Classify. Format: `help` -#### Example: +#### Example usage: ``` help add Adds a student to the student list, expects a name, grade and lessons attended, can be used directly with a name e.g. add [name] @@ -664,8 +672,9 @@ help Prints this help message Exits the Classify program. Format: `bye` + +#### Example usage: ``` -Example: bye Hope you've had a productive day. See you again! Goodbye! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -678,34 +687,35 @@ Hope you've had a productive day. See you again! Goodbye! This section provides a quick overview of all the commands used in our Classify. -|Command|Description| View Command| -|--|--|--| -|**General**| | -|`add `| - Adds a student into the list.
- If the name of the student is not specified in the initial command,
the program will prompt the user for the name.|[Add](#adding-a-student-add)| -|`view `|Views a students details.
If the name of the student is not specified in the initial command, the program will prompt the user for the name.|[View](#view-details-of-a-student-view)| -|`delete `|Deletes the student from the list.
If the name of the student is not specified in the initial command, the program will prompt the user for the name.|[Delete](#delete-a-student-from-the-working-list-delete)| -|`edit `|Allows the user to edit the details of the student.
If the name of the student is not specified in the initial command, the program will prompt the user for the name.|[Edit](#edit-details-of-a-student-edit)| -|**List**| | -|`list`, press enter,
[subject]|Displays the list of students that has taken that subject.|[List](#display-the-list-of-students-list)| -|`list`, press enter,
press enter, [1]|Displays the list of students that is registered in the tuition centre.|[List](#display-the-list-of-students-list)| -|`list`, press enter,
press enter, [2]|Displays the list of students that is registered in the tuition centre with the total number of classes taken.|[List](#display-the-list-of-students-list)| -|`list`, press enter,
press enter, [3]|Displays the list of students that is registered in the tuition centre with their phone numbers beside their names|[List](#display-the-list-of-students-list)| -|`list`, press enter,
press enter, [4]|Displays the list of students who were archived.|[List](#display-the-list-of-students-list)| -|`list`, press enter,
press enter, [5]|Displays the list of students who were recently deleted from the master list.|[List](#display-the-list-of-students-list) | -|**Sort**| [List](#display-the-list-of-students-list)| -|`sort `|Sorts the list lexicographically.
If the word `name` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| -|`sort `|Sorts the list by the last fee payment date of a student.
If the word `payment` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| -|`sort `|Sorts the list by the number of classes a student has attended.
If the word `classes` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| -|**Process**| | -|`process`, press enter,
``| Processes a text file containing a list of students taking the same subject and having attended the same number of lessons.
Adds all of them into the current list with their individual grades for the subject.
Will need to manually input their other attributes (eg. phone number, gender, etc) |[Process](#process-a-list-of-students-from-a-text-file-process)| -|**Archive**| | -|`archive `|Archives specified student. Removes student from current list and adds student to archive.|[Archive](#move-a-student-from-the-master-list-to-the-archive-archive)| -|`unarchive `|Unarchives specified student. Moves student from archive to current list.|[Unarchive](#move-a-student-from-the-archive-back-to-the-master-list-unarchive)| -|`undo`|Undoes the last deleted entry.|[Undo](#undo-a-delete-and-restore-the-deleted-student-to-the-working-list-undo)| -|`restore `|Restores the student from the current session|[Restore](#restore-a-student-to-the-working-list-restore)| -|**Others**| | -|`help`|Generates the list of commands.|[Help](#display-instructions-on-how-to-use-classify-help)| -|`bye`|Terminates the program.|[Bye](#exit-classify-bye)| +| Command |Description| View Command| +|-----------------------------------------------|--|--| +| **General** | | +| `add ` | - Adds a student into the list.
- If the name of the student is not specified in the initial command,
the program will prompt the user for the name.|[Add](#adding-a-student-add)| +| `view ` |Views a students details.
If the name of the student is not specified in the initial command, the program will prompt the user for the name.|[View](#view-details-of-a-student-view)| +| `delete ` |Deletes the student from the list.
If the name of the student is not specified in the initial command, the program will prompt the user for the name.|[Delete](#delete-a-student-from-the-working-list-delete)| +| `edit ` |Allows the user to edit the details of the student.
If the name of the student is not specified in the initial command, the program will prompt the user for the name.|[Edit](#edit-details-of-a-student-edit)| +| **Listing** | | +| `list`, press enter,
[subject] |Displays the list of students that has taken that subject.|[List](#display-the-list-of-students-list)| +| `list`, press enter,
press enter, [1] |Displays the list of students that is registered in the tuition centre.|[List](#display-the-list-of-students-list)| +| `list`, press enter,
press enter, [2] |Displays the list of students that is registered in the tuition centre with the total number of classes taken.|[List](#display-the-list-of-students-list)| +| `list`, press enter,
press enter, [3] |Displays the list of students that is registered in the tuition centre with their phone numbers beside their names|[List](#display-the-list-of-students-list)| +| `list`, press enter,
press enter, [4] |Displays the list of students who were archived.|[List](#display-the-list-of-students-list)| +| `list`, press enter,
press enter, [5] |Displays the list of students who were recently deleted from the master list.|[List](#display-the-list-of-students-list) | +| **Sorting** | [List](#display-the-list-of-students-list)| +| `sort ` |Sorts the list lexicographically.
If the word `name` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| +| `sort ` |Sorts the list by the last fee payment date of a student.
If the word `payment` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| +| `sort ` |Sorts the list by the number of classes a student has attended.
If the word `classes` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| +| **Processing** | | +| `process`, press enter,
`` | Processes a text file containing a list of students taking the same subject and having attended the same number of lessons.
Adds all of them into the current list with their individual grades for the subject.
Will need to manually input their other attributes (eg. phone number, gender, etc) |[Process](#process-a-list-of-students-from-a-text-file-process)| +| **Archiving** | | +| `archive ` |Archives specified student. Removes student from current list and adds student to archive.|[Archive](#move-a-student-from-the-master-list-to-the-archive-archive)| +| `unarchive ` |Unarchives specified student. Moves student from archive to current list.|[Unarchive](#move-a-student-from-the-archive-back-to-the-master-list-unarchive)| +| **Recently Deleted** | | +| `undo` |Undoes the last deleted entry.|[Undo](#undo-a-delete-and-restore-the-deleted-student-to-the-working-list-undo)| +| `restore ` |Restores the student from the current session|[Restore](#restore-a-student-to-the-working-list-restore)| +| **Others** | | +| `help` |Generates the list of commands.|[Help](#display-instructions-on-how-to-use-classify-help)| +| `bye` |Terminates the program.|[Bye](#exit-classify-bye)| --- diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 36838faa25..b9fac11e7d 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -10,15 +10,6 @@ public class UI { "attended across all subjects: "; private static final String EMPTY_SUBJECT_ERROR = "No subjects and grades found for this student."; private static final String NULL_ATTRIBUTE_ERROR = "No attributes found for this student."; - private static final String EDIT_COMMAND_PROMPT = "How would you like to edit student? " + - "Enter index (blank to exit):"; - private static final String EDIT_COMMAND_ADD_SUBJECT_PROMPT = "1. Add subject"; - private static final String EDIT_COMMAND_MODIFY_SUBJECT_PROMPT = "2. Modify subject"; - private static final String EDIT_COMMAND_DELETE_SUBJECT_PROMPT = "3. Delete subject"; - private static final String EDIT_COMMAND_MODIFY_PHONE_NUMBER_PROMPT = "4. Modify phone number"; - private static final String EDIT_COMMAND_MODIFY_REMARKS_PROMPT = "5. Modify remarks"; - private static final String EDIT_COMMAND_MODIFY_PAYMENT_DATE_PROMPT = "6. Modify payment date"; - private static final String EDIT_COMMAND_DELETED_SUBJECT_MESSAGE = "Subject deleted successfully!"; private static final String EMPTY_LIST_ERROR = "Currently no students in list."; private static final String VALID_NUMBER_ERROR = "A valid number was not entered. Please input a valid number. "; private static final String PHONE_NUMBER_PROMPT = "Please input a valid phone number: "; @@ -44,6 +35,16 @@ public class UI { private static final String CLASSIFY_GOODBYE_MESSAGE = "Hope you've had a productive day. See you again! Goodbye!"; private static final String WRONG_INPUT_MESSAGE = "No such command, type \"help\" to view all commands"; //@@author blackmirag3 + private static final String EDIT_COMMAND_PROMPT = "How would you like to edit student? " + + "Enter index (blank to exit):"; + private static final String EDIT_COMMAND_ADD_SUBJECT_PROMPT = "1. Add subject"; + private static final String EDIT_COMMAND_MODIFY_SUBJECT_PROMPT = "2. Modify subject"; + private static final String EDIT_COMMAND_DELETE_SUBJECT_PROMPT = "3. Delete subject"; + private static final String EDIT_COMMAND_MODIFY_PHONE_NUMBER_PROMPT = "4. Modify phone number"; + private static final String EDIT_COMMAND_MODIFY_REMARKS_PROMPT = "5. Modify remarks"; + private static final String EDIT_COMMAND_MODIFY_PAYMENT_DATE_PROMPT = "6. Modify payment date"; + private static final String EDIT_COMMAND_DELETED_SUBJECT_MESSAGE = "Subject deleted successfully!"; + private static final String EDIT_COMMAND_MODIFY_GENDER_PROMPT = "7. Edit Gender"; private static final String WHAT_ELSE_CAN_I_DO_FOR_YOU_TODAY = "What else can I do for you today?"; private static final String STUDENT_DETAILS_PROMPT = "Enter student details: "; private static final String STUDENT_NAME_PROMPT = "Enter student name: "; @@ -313,7 +314,7 @@ public static void printEditPrompt() { System.out.println(EDIT_COMMAND_MODIFY_PHONE_NUMBER_PROMPT); System.out.println(EDIT_COMMAND_MODIFY_REMARKS_PROMPT); System.out.println(EDIT_COMMAND_MODIFY_PAYMENT_DATE_PROMPT); - System.out.println("7. Edit Gender."); + System.out.println(EDIT_COMMAND_MODIFY_GENDER_PROMPT); } //@@ author tayponghee From e625df37fc0386c8dc3e1f9d5e586cfa384402f1 Mon Sep 17 00:00:00 2001 From: shui <78994143+blackmirag3@users.noreply.github.com> Date: Thu, 11 Apr 2024 22:20:06 +0800 Subject: [PATCH 332/503] Update expected test case output --- src/test/java/classify/commands/EditTest.java | 2 +- src/test/java/classify/user/InputParsingTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/classify/commands/EditTest.java b/src/test/java/classify/commands/EditTest.java index cc945ca550..ceaeb2eddb 100644 --- a/src/test/java/classify/commands/EditTest.java +++ b/src/test/java/classify/commands/EditTest.java @@ -67,7 +67,7 @@ public void testEditNoStudentFound() { System.setOut(System.out); String printedOutput = outputStream.toString(); String expectedOutput = "Name of student to edit (blank to exit):" + System.lineSeparator() + - "No student found to edit!" + System.lineSeparator(); + "No student found!" + System.lineSeparator(); assertEquals(printedOutput, expectedOutput); } } diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index ab22e97d2a..d05b4dc49c 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -77,7 +77,7 @@ public void testEditCommand() { System.setOut(System.out); String printedOutput = outputStream.toString(); String expectedOutput = "Currently no students in list." + System.lineSeparator() + - "No student found to edit!" + System.lineSeparator(); + "No student found!" + System.lineSeparator(); assertEquals(expectedOutput, printedOutput); } From 50069173fc84e8ad598cf7e13cfd419516ad9366 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 12 Apr 2024 00:23:39 +0800 Subject: [PATCH 333/503] Make private class public for usage in other parts of codebaase --- src/main/java/classify/user/InputParsing.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 0981ef4c89..9b8d443ec2 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -266,7 +266,7 @@ public static Student findStudentByName(ArrayList masterStudentList, St * * @param studentList List of students to look for. * @param in Scanner to parse in the user input. - * @return Student with rigth name and number pair. + * @return Student with right name and number pair. */ private static Student findStudentByNumber(ArrayList studentList, Scanner in) { assert studentList.size() > 1 : "List should contain more than one Student"; @@ -387,7 +387,7 @@ private static int readInPhoneNumber(Scanner in) throws NumberFormatException { * @return True if the number is a valid Singapore Number, false otherwise */ //@@author Cryolian - private static boolean checkNumberValidity(int number) { + public static boolean checkNumberValidity(int number) { return number >= NUMBER_TOO_SMALL && number < NUMBER_TOO_BIG; } From 6e81f637dd3448b53bc723eab7e72fdee99228ec Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 12 Apr 2024 00:25:28 +0800 Subject: [PATCH 334/503] Update process command workflow to reduce double counting in MasterStudentList and SubjectLists --- .../classify/textfilecode/TextFileParser.java | 148 +++++++++++++++--- 1 file changed, 128 insertions(+), 20 deletions(-) diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index 592d126cff..9b97a5e5e8 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -13,6 +13,7 @@ import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; +import java.util.List; import java.util.Scanner; //@@author ParthGandhiNUS @@ -26,12 +27,15 @@ public class TextFileParser { private static final String NO_MATCH_FOUND = "No Match Found!"; private static final String ERROR_ACCESSING_THE_FILE = "Something went wrong while accessing the file"; private static final Integer NAME = 0; - private static final Integer GRADE_FOR_SUBJECT = 1; + private static final Integer PHONE_NUMBER = 1; + private static final Integer GRADE_FOR_SUBJECT = 2; private static final String INPUT_TEXT_FILE_DIRECTORY = "./data/inputFolder"; private static final String INVALID_CHAR_MESSAGE = "Invalid character found."; private static final String INVALID_NUMBER_MESSAGE = "Invalid Number format found."; private static final String SUBJECT_REGEX = "Subject:"; private static final String CLASSES_ATTENDED_REGEX = "Classes Attended:"; + private static final String INVALID_PHONE_NUMBER_MESSAGE="'s phone number is not a valid Singapore phone number." + + " Please edit this students' phone number with the edit command!"; /** * Boolean that checks for the filetype of the files. @@ -89,6 +93,33 @@ public static void parseUserSelection(File currentDirectory, Scanner in, ArrayLi parseTextFile(fileList, matchIndex, masterStudentList); } + /** + * This method returns the index of file which matches the user's input for file to be processed + * + * @param fileList List of files in current directory + * @param userInput User's input + * @return Returns the index of the match found or else returns -1. + */ + private static Integer findMatchingFile(File[] fileList, String userInput) { + String input = userInput.toLowerCase().trim(); + for (int i = 0; i < fileList.length; i++){ + String fileName = fileList[i].getName().toLowerCase().trim(); + int dotIndex = fileName.lastIndexOf(DOT); + String fileNameWithoutType = fileName.substring(0,dotIndex); + + // Return match with the type + if (input.equals(fileName)){ + return i; + } + + // Return match without the type + if (input.equals(fileNameWithoutType)){ + return i; + } + } + return -1; + } + /** * Selects data from the correct file and starts reading it. * @@ -155,14 +186,18 @@ private static void deconstructTextFile (String textFileInput, String subjectNam try{ //Set Name - Student student = new Student(AddStudent.splitName(inputArr[NAME].trim())); + String studentNameString = AddStudent.splitName(inputArr[NAME].trim()); + Student student = new Student(studentNameString); InputParsing.checkForSpecialCharacters(student.getName()); + //Set phone_number + int phoneNumber = Integer.parseInt(inputArr[PHONE_NUMBER].trim()); //Set grades double subjectGrades = Double.parseDouble(inputArr[GRADE_FOR_SUBJECT].trim()); //Put Everything together SubjectGrade newSubject = new SubjectGrade(subjectName, subjectGrades, classesAttended); - masterStudentList.add(student); - student.getAttributes().addSubjectGrade(newSubject); + //Adding the student / Subject in existing student + masterStudentListAddition(masterStudentList, studentNameString, student, phoneNumber, + subjectName, newSubject); } catch (InvalidCharacterException e) { UI.println(INVALID_CHAR_MESSAGE); } catch (NumberFormatException e) { @@ -171,29 +206,102 @@ private static void deconstructTextFile (String textFileInput, String subjectNam } /** - * This method returns the index of file which matches the user's input for file to be processed + * This method checks for a current student in the list. + * It adds a new student and the applicable attributes if a student with the same name and number + * is not found in the list. + * It adds a new subject attributes if a student with the same name and number is found in the list. * - * @param fileList List of files in current directory - * @param userInput User's input - * @return Returns the index of the match found or else returns -1. + * @param masterStudentList StudentList where students will be added + * @param studentNameString Name of the student + * @param student Instance of Student + * @param phoneNumber Phone number of the student + * @param newSubject Instance of subject to be added */ - private static Integer findMatchingFile(File[] fileList, String userInput) { - String input = userInput.toLowerCase().trim(); - for (int i = 0; i < fileList.length; i++){ - String fileName = fileList[i].getName().toLowerCase().trim(); - int dotIndex = fileName.lastIndexOf(DOT); - String fileNameWithoutType = fileName.substring(0,dotIndex); - - // Return match with the type - if (input.equals(fileName)){ - return i; + private static void masterStudentListAddition(ArrayList masterStudentList, String studentNameString, + Student student,int phoneNumber, String subjectName, + SubjectGrade newSubject) { + if (matchingNameNumber (masterStudentList, studentNameString, phoneNumber)){ + Integer indexOfStudent = matchingStudentIndex(masterStudentList, studentNameString, phoneNumber); + if (!(matchingSubject(masterStudentList, subjectName, indexOfStudent))){ + masterStudentList.get(indexOfStudent).getAttributes().addSubjectGrade(newSubject); } + } else { + masterStudentList.add(student); + addPhoneNumber(studentNameString, student, phoneNumber); + student.getAttributes().addSubjectGrade(newSubject); + } + } - // Return match without the type - if (input.equals(fileNameWithoutType)){ + /** + * Adds the phone number field for a new student or returns a message for invalid phone number + * + * @param studentNameString Name of the student + * @param student Instance of Student + * @param phoneNumber Phone number of the student + */ + private static void addPhoneNumber(String studentNameString, Student student, int phoneNumber) { + if (InputParsing.checkNumberValidity(phoneNumber)){ + student.getAttributes().setPhoneNumber(phoneNumber); + } else { + UI.println(studentNameString + INVALID_PHONE_NUMBER_MESSAGE); + } + } + + /** + * Function returns the index of the matching student in the masterStudentList. + * + * @param masterStudentList List to check through for the name and number + * @param name Name of the student to find + * @param number Phone number of the student to find. + * @return Index of the student in masterStudentList + */ + private static Integer matchingStudentIndex (ArrayList masterStudentList, String name, int number){ + Integer listSize = masterStudentList.size(); + + for (int i = 0; i < listSize; i++) { + if (masterStudentList.get(i).getName().equalsIgnoreCase(name) && + masterStudentList.get(i).getPhoneNumber() == number) { return i; } } return -1; } + + /** + * Checks if the subject we are trying to add is already a subject that the student is taking. + * Returns true if student takes that subject and false otherwise. + * + * @param masterStudentList List to obtain student + * @param subjectName name of the subject that is getting added + * @return True if subject is found attributed to that particular student. False otherwise. + */ + private static boolean matchingSubject(ArrayList masterStudentList, String subjectName, + Integer indexOfStudent) { + List studentSubjects = masterStudentList.get(indexOfStudent).getAttributes().getSubjectGrades(); + for (SubjectGrade subject : studentSubjects){ + if (subject.getSubject().equalsIgnoreCase(subjectName)) { + return true; + } + } + return false; + } + + + //@@author Cryolian + /** + * Function checks if a name and number pair already exists in a given list. + * + * @param masterStudentList List to check through for the name and number + * @param name Name of the student to find + * @param number Phone number of the student to find. + * @return True if a student with the same name and number is found in the list,false otherwise. + */ + private static boolean matchingNameNumber (ArrayList masterStudentList, String name, int number) { + for (Student student : masterStudentList) { + if (student.getName().equalsIgnoreCase(name) && student.getPhoneNumber() == number) { + return true; + } + } + return false; + } } From b4e1a2840b17004d157a478ac5bd9d138ffb51b4 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 12 Apr 2024 01:11:42 +0800 Subject: [PATCH 335/503] Fix bug for the max number of classes attended --- src/main/java/classify/user/InputParsing.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index a221261095..bd8733cd91 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -47,6 +47,7 @@ public class InputParsing { private static final int NUMBER_TOO_SMALL = 80000000; private static final int NUMBER_TOO_BIG = 1000_000_00; private static final String CLASSES_ATTENDED_MUST_BE_MORE = "Classes attended must be 0 or more."; + private static final String CLASSES_ATTENDED_MUST_BE_LESS = "Classes attended must be less than 500."; public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, ArrayList recentlyDeletedList, @@ -297,13 +298,16 @@ private static Student findStudentByNumber(ArrayList studentList, Scann * @return True if number of classes attended is greater than 0 and false otherwise. * */ - //@@author blackmirag3 public static boolean isValidClassesAttended(int classesAttended) { if (classesAttended < 0) { - //@@author ParthGandhiNUS UI.println(CLASSES_ATTENDED_MUST_BE_MORE); - //@@author blackmirag3 + UI.printDivider(); + return false; + } + + if (classesAttended > 500) { + UI.println(CLASSES_ATTENDED_MUST_BE_LESS); UI.printDivider(); return false; } From fafd7f30a83098e990d2d21a308b851900a19344 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 12 Apr 2024 01:14:06 +0800 Subject: [PATCH 336/503] Fix small bug --- src/main/java/classify/textfilecode/TextFileParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index 9b97a5e5e8..78ace1c58f 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -256,7 +256,7 @@ private static void addPhoneNumber(String studentNameString, Student student, in * @return Index of the student in masterStudentList */ private static Integer matchingStudentIndex (ArrayList masterStudentList, String name, int number){ - Integer listSize = masterStudentList.size(); + int listSize = masterStudentList.size(); for (int i = 0; i < listSize; i++) { if (masterStudentList.get(i).getName().equalsIgnoreCase(name) && From 672f2f11c6847ecacc99e61ae5d4c9f1707a79cd Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 12 Apr 2024 01:33:38 +0800 Subject: [PATCH 337/503] Add handling for cases of file corruption that are not handled by our other methods. Add option for user to delete file in cases where they are unable to manually rectify corruption by editing the info file(that they messed up) --- src/main/java/classify/data/DataHandler.java | 9 ++++ src/main/java/classify/data/DataReader.java | 56 ++++++++++++++++++-- src/main/java/classify/data/DataWriter.java | 18 ++++++- src/main/java/classify/ui/DataUI.java | 52 +++++++++++++++++- src/main/java/classify/ui/UI.java | 5 +- 5 files changed, 131 insertions(+), 9 deletions(-) diff --git a/src/main/java/classify/data/DataHandler.java b/src/main/java/classify/data/DataHandler.java index 01c871c00b..00695d0ae6 100644 --- a/src/main/java/classify/data/DataHandler.java +++ b/src/main/java/classify/data/DataHandler.java @@ -71,4 +71,13 @@ public static void readArchive(ArrayList list) throws IOException { DataWriter.createParentFileFolder(ARCHIVE_DIRECTORY_PATH); DataReader.initialiseData(list, ARCHIVE_FILE_PATH); } + + //@@author alalal47 + /** + * This accesses Student_Information.txt and calls the emptyDataFile function. + * Only used in cases of data corruption that cannot be resolved by the user. + */ + public static void deleteStudentInfo() { + DataWriter.emptyDataFile(DATA_DIRECTORY_PATH, DATA_FILE_PATH); + } } diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 395b37e5c4..896a8afb42 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -186,7 +186,7 @@ public static LocalDate convertStringInput(String input) throws DateTimeParseExc /** * Initialises student array list from specified data file. * Creates new data file if data file not found - * + * If corruption is detected, prompts user to manually rectify it or gives the option to empty the file. * * @param list ArrayList containing Students * @param filePath String containing path to data file @@ -205,14 +205,60 @@ public static void initialiseData(ArrayList list, DataUI.printRetrieveData(); //@@author ParthGandhiNUS - while (line.ready()) { - restoreStudentList(line.readLine(), list); + try { + while (line.ready()) { + restoreStudentList(line.readLine(), list); + line.close(); + } + //@@author alalal47 + } catch (ArrayIndexOutOfBoundsException e) { + DataUI.printFileCorruptedMessage(); + DataUI.printDataDeletionPromptMessage(); + promptDataDeletion(); + UI.printDivider(); + } catch (IOException e) { + DataUI.printFileCorruptedMessage(); + DataUI.printDataDeletionPromptMessage(); + promptDataDeletion(); + UI.printDivider(); } - line.close(); - + } + //@@author ParthGandhiNUS DataUI.printLoadSuccess(); UI.printDivider(); + } + + //@@author alalal47 + /** + * Function is called in the case of file corruption, and is not localised in a data entry, + * in a way that is skipped and handled by our other exceptions and checks. + * Prompts the user to manually fix any errors they may have introduced by manual editing, + * then to restart Classify. + * Or, provides users the option to wipe all existing data in the case that they are unable to. + */ + private static void promptDataDeletion() { + String input = in.nextLine(); + if (checkDeletionRequestInput(input)) { + DataUI.printDataDeletionFinalConfirmationMessage(); + input = in.nextLine(); + if (deletionRequestFinalConfirmation(input)) { + DataHandler.deleteStudentInfo(); + } else { + DataUI.printDeletionConfirmationInputMismatchMessage(); + promptDataDeletion(); + } + } else { + DataUI.printDeletionInputMismatchMessage(); + promptDataDeletion(); } } + + private static boolean checkDeletionRequestInput(String input) { + return input.equals("YES"); + } + + private static boolean deletionRequestFinalConfirmation(String input) { + return input.equals("CONFIRM"); + } } diff --git a/src/main/java/classify/data/DataWriter.java b/src/main/java/classify/data/DataWriter.java index 6162e1ae6d..1dd7bd9f36 100644 --- a/src/main/java/classify/data/DataWriter.java +++ b/src/main/java/classify/data/DataWriter.java @@ -51,7 +51,7 @@ public static void writeStudentInfoFile(List list, String folderPath, * * @param parentPath Path file containing the path of folder we want to make the text file in */ - public static void createParentFileFolder (String parentPath) { + public static void createParentFileFolder(String parentPath) { try{ Path path = Paths.get(parentPath); Files.createDirectories(path); @@ -62,4 +62,20 @@ public static void createParentFileFolder (String parentPath) { DataUI.printCreateFailure(); } } + + //@@author alalal47 + /** + * Used to delete the contents of the file containing student information. + * Only used in the case of corruption that cannot be resolved by the user. + */ + public static void emptyDataFile(String folderPath, String filePath) { + try { + createParentFileFolder(folderPath); + FileWriter overwriteBlank = new FileWriter(filePath); + overwriteBlank.write(""); + DataUI.printFileDeletionCompleteMessage(); + } catch (IOException e) { + DataUI.printFileIOError(); + } + } } diff --git a/src/main/java/classify/ui/DataUI.java b/src/main/java/classify/ui/DataUI.java index 53151271f9..9caa511d0a 100644 --- a/src/main/java/classify/ui/DataUI.java +++ b/src/main/java/classify/ui/DataUI.java @@ -9,7 +9,7 @@ public class DataUI extends UI { private static final String DIRECTORY_SUCCESS_MESSAGE = "Directory loaded successfully!"; private static final String CREATE_FAILURE_MESSAGE = "Unable to create a new file/directory!"; private static final String RETRIEVING_DATA_MESSAGE = "Retrieving data..."; - private static final String LOAD_DATA_SUCCESS_MESSAGE = "Data loaded sucessfully!"; + private static final String LOAD_DATA_SUCCESS_MESSAGE = "Data loaded successfully!"; private static final String UPDATE_SUCCESS_MESSAGE = "Data update success!"; private static final String FILE_IO_ERROR_MESSAGE = "File IO Error."; private static final String PHONE_NUMBER_PARSE_ERROR = "Error parsing the phone number."; @@ -19,6 +19,25 @@ public class DataUI extends UI { private static final String NO_SUBJECT_DATA ="Student does not have any subjects currently!"; private static final String INDEX_OUT_OF_BOUNDS = "Error reading in subjects data."; + //@@author alalal47 + private static final String CORRUPTION_DETECTED = "Possible corruption in the data file was detected after it" + + " was retrieved!"; + private static final String CORRUPTION_FURTHER_ACTIONS = "Please check the data in Student_Information.txt and " + + "rectify any erroneous entries. Then restart Classify."; + private static final String CORRUPTION_DELETION_ACTION = "Alternatively, you may choose to delete all data and" + + " resume usage of Classify."; + private static final String CORRUPTION_DELETION_PERMISSION = "Would you like to delete all data? Type YES if so."; + private static final String CORRUPTION_DELETION_PERMISSION_STRING_MISMATCH = "YES was not entered, please enter " + + "YES to delete all data or"; + private static final String DELETION_FINAL_CHECK_STRING_MISMATCH = "CONFIRM was not entered, please enter " + + "YES to delete all data or"; + private static final String CORRUPTION_DELETION_CONFIRMATION = "Are you sure you want to delete all data?\n" + + "Type CONFIRM if so."; + private static final String CORRUPTION_DELETION_CONFIRMATION_WARNING = "WARNING! THIS ACTION IS IRREVERSIBLE!"; + private static final String DELETION_COMPLETED = "All existing student information has been deleted!"; + private static final String IMPORTANT_TEXT_BORDER = "-----------------------------------------------------" + + "-----------------------------------------------------"; + //@@author blackmirag3 public static void printLoadSuccess() { System.out.println(LOAD_DATA_SUCCESS_MESSAGE); @@ -77,4 +96,35 @@ public static void noSubjectMessage() { public static void arrayIndexOutOfBoundsMessage() { System.out.println(INDEX_OUT_OF_BOUNDS); } + + //@@author alalal47 + public static void printFileCorruptedMessage() { + System.out.println(IMPORTANT_TEXT_BORDER); + System.out.println(CORRUPTION_DETECTED); + System.out.println(CORRUPTION_FURTHER_ACTIONS); + System.out.println(CORRUPTION_DELETION_ACTION); + System.out.println(IMPORTANT_TEXT_BORDER); + } + + public static void printDataDeletionPromptMessage() { + System.out.println(CORRUPTION_DELETION_PERMISSION); + } + + public static void printDataDeletionFinalConfirmationMessage() { + System.out.println(CORRUPTION_DELETION_CONFIRMATION); + System.out.println(CORRUPTION_DELETION_CONFIRMATION_WARNING); + } + + public static void printDeletionInputMismatchMessage() { + System.out.println(CORRUPTION_DELETION_PERMISSION_STRING_MISMATCH); + System.out.println(CORRUPTION_FURTHER_ACTIONS); + } + + public static void printDeletionConfirmationInputMismatchMessage() { + System.out.println(DELETION_FINAL_CHECK_STRING_MISMATCH); + System.out.println(CORRUPTION_FURTHER_ACTIONS); + } + public static void printFileDeletionCompleteMessage() { + System.out.println(DELETION_COMPLETED); + } } diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 7d160b20b6..f43349c0c7 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -64,6 +64,7 @@ public class UI { private static final String STUDENTS_IN_ARCHIVE = "4. List of students in archive"; private static final String STUDENTS_IN_DELETED = "5. List of students in recently deleted"; private static final String ENTER_ONE_TWO_THREE_FOUR = "Enter your choice (1, 2, 3, 4 or 5):"; + //@@ author tayponghee private static final String ADD_SUBJECT = "Do you want to add another subject and grade? (yes/no)"; @@ -415,7 +416,7 @@ public static void printSubjectAlreadyExists() { System.out.println(SUBJECT_ALREADY_EXISTS); } - public static void printWrongNumberFormat () { + public static void printWrongNumberFormat() { System.out.println(WRONG_NUMBER_FORMAT); } @@ -435,7 +436,7 @@ public static void printNoStudentsWithSubject(String subject) { System.out.println(NO_STUDENTS_FOUND_WITH_THE_SUBJECT + subject); } - public static void printListAllStudentsChoice () { + public static void printListAllStudentsChoice() { System.out.println(CHOOSE_THE_TYPE_OF_LIST_TO_DISPLAY); System.out.println(FULL_STUDENT_LIST); System.out.println(STUDENTS_WITH_TOTAL_CLASSES); From 9ccd417c79a88007221f704d734e7a3225fa30bf Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 12 Apr 2024 01:38:57 +0800 Subject: [PATCH 338/503] Fix wrong indentation for comment --- src/main/java/classify/data/DataReader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 896a8afb42..ad0952b6cb 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -223,7 +223,7 @@ public static void initialiseData(ArrayList list, UI.printDivider(); } } - //@@author ParthGandhiNUS + //@@author ParthGandhiNUS DataUI.printLoadSuccess(); UI.printDivider(); } From 7271f8f55b4b6001a2a0454b85a54d140db40f5c Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 12 Apr 2024 01:44:35 +0800 Subject: [PATCH 339/503] Fix incorrect indentation --- src/main/java/classify/data/DataReader.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index ad0952b6cb..1ff90d92a6 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -223,9 +223,9 @@ public static void initialiseData(ArrayList list, UI.printDivider(); } } - //@@author ParthGandhiNUS - DataUI.printLoadSuccess(); - UI.printDivider(); + //@@author ParthGandhiNUS + DataUI.printLoadSuccess(); + UI.printDivider(); } //@@author alalal47 From 193c7bfb6940441766ec4cc33e996880f46c284e Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 10:20:37 +0800 Subject: [PATCH 340/503] Update README file to match our product --- docs/README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/README.md b/docs/README.md index bbcc99c1e7..fc31e90a65 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,6 +1,17 @@ -# Duke +# Classify -{Give product intro here} +Classify is a CLI based program that allows for tuition centres to more effectively manage their enrolled students. +Aimed towards administrative staff, Classify is a simple tool which has functionalities such as: +- Adding a student to the database +- Viewing a student +- Editing the details of a student post addition +- Listing the entire student master list based on certain parameters +- Sorting the entire student master list based on certain parameters +- Deleting and archiving students from the master list +- Undoing the deletion and restoration from the archived database +- Saving the entries to a text file for ease of data migration + +Do check out our User Guide to see how to run the program locally on your own PC! Useful links: * [User Guide](UserGuide.md) From b4e52598d34a7f0bd48315f7893ec18580f789db Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 10:26:47 +0800 Subject: [PATCH 341/503] Update PPP --- docs/team/tayponghee.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/team/tayponghee.md b/docs/team/tayponghee.md index d55ef61ae4..45094549d4 100644 --- a/docs/team/tayponghee.md +++ b/docs/team/tayponghee.md @@ -56,3 +56,4 @@ Given below are my contributions to the project: * [SubjectGradeTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/student/SubjectGradeTest.java) * [AddStudentTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/AddStudentTest.java) * [ViewStudentTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/ViewStudentTest.java) + * [ListStudentsCommandTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/ListStudentsCommandTest.java) From fc97952198c8268d2274bfba2a228e5267685aa3 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 10:39:29 +0800 Subject: [PATCH 342/503] Update Junit tests --- .../classify/commands/DeleteCommandsTest.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/test/java/classify/commands/DeleteCommandsTest.java diff --git a/src/test/java/classify/commands/DeleteCommandsTest.java b/src/test/java/classify/commands/DeleteCommandsTest.java new file mode 100644 index 0000000000..d3896cc5f4 --- /dev/null +++ b/src/test/java/classify/commands/DeleteCommandsTest.java @@ -0,0 +1,74 @@ +package classify.commands; + +import classify.student.Student; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.Scanner; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class DeleteCommandsTest { + + private static final String TEST_STUDENT = "Test Student"; + + /** + * Test case to verify the functionality of deleting a student. + * This test checks if the deleteStudent method correctly removes a student from the master student list + * and adds it to the recently deleted list. + */ + @Test + void testDeleteStudent() { + ArrayList masterStudentList = new ArrayList<>(); + ArrayList recentlyDeletedList = new ArrayList<>(); + Scanner scanner = new Scanner(System.in); + + Student testStudent = new Student(TEST_STUDENT); + masterStudentList.add(testStudent); + + DeleteCommands.deleteStudent(masterStudentList, recentlyDeletedList, scanner, TEST_STUDENT); + + assertFalse(masterStudentList.contains(testStudent)); + assertTrue(recentlyDeletedList.contains(testStudent)); + } + + /** + * Test case to verify the functionality of restoring a student. + * This test checks if the restoreStudent method correctly adds a student back to the master student list + * and removes it from the recently deleted list. + */ + @Test + void testRestoreStudent() { + ArrayList masterStudentList = new ArrayList<>(); + ArrayList recentlyDeletedList = new ArrayList<>(); + Scanner scanner = new Scanner(System.in); + + Student testStudent = new Student(TEST_STUDENT); + recentlyDeletedList.add(testStudent); + + DeleteCommands.restoreStudent(masterStudentList, recentlyDeletedList, scanner, TEST_STUDENT); + + assertTrue(masterStudentList.contains(testStudent)); + assertFalse(recentlyDeletedList.contains(testStudent)); + } + + /** + * Test case to verify the functionality of undoing a student deletion. + * This test checks if the undoDelete method correctly restores the latest deleted student + * from the recently deleted list to the master student list. + */ + @Test + void testUndoDelete() { + ArrayList masterStudentList = new ArrayList<>(); + ArrayList recentlyDeletedList = new ArrayList<>(); + + Student testStudent = new Student(TEST_STUDENT); + recentlyDeletedList.add(testStudent); + + DeleteCommands.undoDelete(masterStudentList, recentlyDeletedList); + + assertTrue(masterStudentList.contains(testStudent)); + assertFalse(recentlyDeletedList.contains(testStudent)); + } +} From ca903f9364e0748110336f312ec3df4c7b6e6d52 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 10:40:39 +0800 Subject: [PATCH 343/503] Delete unused package --- src/main/java/classify/classgroup/Class.java | 61 ------------------- .../java/classify/classgroup/ClassList.java | 26 -------- 2 files changed, 87 deletions(-) delete mode 100644 src/main/java/classify/classgroup/Class.java delete mode 100644 src/main/java/classify/classgroup/ClassList.java diff --git a/src/main/java/classify/classgroup/Class.java b/src/main/java/classify/classgroup/Class.java deleted file mode 100644 index ccfe60ccb7..0000000000 --- a/src/main/java/classify/classgroup/Class.java +++ /dev/null @@ -1,61 +0,0 @@ -package classify.classgroup; - -// import classify.student.StudentList; -// import classify.student.Student; - -/** - * Class meant to represent a class for students. - */ -public class Class { - - //@@author Cryolian - public int ageOfStudents; - public String className; - public String subject; - // public StudentList studentList = new StudentList(); - - /** - * Constructor for a class of Students. - * @param ageOfStudents Age of the students in the class. - * @param className Name of the class. - */ - public Class(int ageOfStudents, String className) { - this.ageOfStudents = ageOfStudents; - this.className = className; - assert this.ageOfStudents == ageOfStudents : "class attribute should be equal to constructor"; - assert this.className == className : "class attribute should be equal to constructor"; - } - - /** - * Get the age of the students attending the class. - * @return The age of the students as an integer. - */ - public int getAgeOfStudents() { - return ageOfStudents; - } - - public void setAgeOfStudents(int ageOfStudents) { - this.ageOfStudents = ageOfStudents; - } - - public String getClassName() { - return className; - } - - public void setClassName(String className) { - this.className = className; - } - - public String getSubject() { - return subject; - } - - public void setSubject(String subject) { - this.subject = subject; - } - - @Override - public String toString() { - return this.className; - } -} diff --git a/src/main/java/classify/classgroup/ClassList.java b/src/main/java/classify/classgroup/ClassList.java deleted file mode 100644 index f94f57bff8..0000000000 --- a/src/main/java/classify/classgroup/ClassList.java +++ /dev/null @@ -1,26 +0,0 @@ -package classify.classgroup; - -import java.util.ArrayList; - -public class ClassList { - - //@@author Cryolian - public ArrayList classList; - - public ClassList() { - this.classList = new ArrayList<>(); - } - - public void addClass(Class classToAdd) { - classList.add(classToAdd); - } - - public void removeClass(int id) { - classList.remove(id); - } - - public void removeClass(Class classToRemove) { - classList.remove(classToRemove); - } - -} From 46eac07254a45513993291f7dd98badaf3817be1 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 10:53:40 +0800 Subject: [PATCH 344/503] Remove unneccessary test class, update inputparsingtest --- .../classify/commands/DeleteCommands.java | 2 +- src/main/java/classify/ui/UI.java | 5 ++ .../classify/classgroup/ClassListTest.java | 5 -- .../java/classify/classgroup/ClassTest.java | 12 ----- .../java/classify/user/InputParsingTest.java | 46 +++++++++++++++++++ 5 files changed, 52 insertions(+), 18 deletions(-) delete mode 100644 src/test/java/classify/classgroup/ClassListTest.java delete mode 100644 src/test/java/classify/classgroup/ClassTest.java diff --git a/src/main/java/classify/commands/DeleteCommands.java b/src/main/java/classify/commands/DeleteCommands.java index 8b57f440d8..af7406ea09 100644 --- a/src/main/java/classify/commands/DeleteCommands.java +++ b/src/main/java/classify/commands/DeleteCommands.java @@ -35,7 +35,7 @@ public static void deleteStudent(ArrayList masterStudentList, ArrayList if (student != null) { UI.printStudentDeleted(); } else { - UI.printStudentNotFound(); + UI.printStudentToDeleteNotFound(); UI.printDivider(); return; } diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index f43349c0c7..b0a9b6d1cc 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -82,6 +82,7 @@ public class UI { private static final String STUDENTS_WITH_TOTAL_CLASSES = "2. List of students with total classes attended"; private static final String LIST_OF_STUDENTS_WITH_PHONE_NUMBER_SHOWN = "3. List of students with phone number shown"; + private static final String STUDENT_NOT_FOUND_CANNOT_BE_DELETED = "Student not found! Cannot be deleted."; //@@author alalal47 /** * Displays the help message to teach users how to use Classify. @@ -436,6 +437,10 @@ public static void printNoStudentsWithSubject(String subject) { System.out.println(NO_STUDENTS_FOUND_WITH_THE_SUBJECT + subject); } + public static void printStudentToDeleteNotFound() { + System.out.println(STUDENT_NOT_FOUND_CANNOT_BE_DELETED); + } + public static void printListAllStudentsChoice() { System.out.println(CHOOSE_THE_TYPE_OF_LIST_TO_DISPLAY); System.out.println(FULL_STUDENT_LIST); diff --git a/src/test/java/classify/classgroup/ClassListTest.java b/src/test/java/classify/classgroup/ClassListTest.java deleted file mode 100644 index 092d1fb325..0000000000 --- a/src/test/java/classify/classgroup/ClassListTest.java +++ /dev/null @@ -1,5 +0,0 @@ -package classify.classgroup; - -public class ClassListTest { - -} diff --git a/src/test/java/classify/classgroup/ClassTest.java b/src/test/java/classify/classgroup/ClassTest.java deleted file mode 100644 index ad2a3c1eba..0000000000 --- a/src/test/java/classify/classgroup/ClassTest.java +++ /dev/null @@ -1,12 +0,0 @@ -package classify.classgroup; - -import static org.junit.jupiter.api.Assertions.assertEquals; - - -public class ClassTest { - public void classConstructorTest() { - Class newClass = new Class(17,"J1 Physics"); - assertEquals(17, newClass.getAgeOfStudents()); - assertEquals("J1 Physics",newClass.getClassName()); - } -} diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index ab22e97d2a..f04e681f30 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -43,6 +43,52 @@ public void testByeCommand() { assertEquals(expectedOutput.trim(), printedOutput); } + @Test + public void testListCommandWithInvalidArgument() { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outputStream)); + + ArrayList masterStudentList = new ArrayList<>(); + ArrayList recentlyDeletedList = new ArrayList<>(); + ArrayList archiveList = new ArrayList<>(); + String[] commands = new String[2]; + commands[0] = "list"; + commands[1] = "random_argument"; + InputParsing.parseUserCommand(commands, masterStudentList, recentlyDeletedList, + archiveList, new Scanner(System.in)); + + System.setOut(System.out); + + String printedOutput = outputStream.toString().trim(); + String expectedOutput = "Type 'list' only!"; + + + assertEquals(expectedOutput.trim(), printedOutput); + } + + @Test + public void testDeleteCommandWithNonExistentStudent() { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outputStream)); + + ArrayList masterStudentList = new ArrayList<>(); + ArrayList recentlyDeletedList = new ArrayList<>(); + ArrayList archiveList = new ArrayList<>(); + String[] commands = new String[2]; + commands[0] = "delete"; + commands[1] = "NonExistentStudent"; + InputParsing.parseUserCommand(commands, masterStudentList, recentlyDeletedList, + archiveList, new Scanner(System.in)); + + System.setOut(System.out); + + String printedOutput = outputStream.toString().trim(); + String expectedOutput = "Student not found! Cannot be deleted." + + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; + + assertEquals(expectedOutput.trim(), printedOutput); + } + //@@author blackmirag3 @Test public void testUnknownCommand() { From 980a777d3f9e4e4dedec90c667994a2d1c16d4c7 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 11:03:31 +0800 Subject: [PATCH 345/503] Update StudentAttributesTest --- .../student/StudentAttributesTest.java | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/test/java/classify/student/StudentAttributesTest.java b/src/test/java/classify/student/StudentAttributesTest.java index 0fb84e3ec8..acc6c6ab80 100644 --- a/src/test/java/classify/student/StudentAttributesTest.java +++ b/src/test/java/classify/student/StudentAttributesTest.java @@ -1,4 +1,5 @@ package classify.student; +//@@author tayponghee import org.junit.jupiter.api.Test; import java.util.List; @@ -117,5 +118,39 @@ public void testSetClassesAttended() { subjectGrade.setClassesAttended(25); assertEquals(25, subjectGrade.getClassesAttended()); } -} + /** + * Test case to verify finding a subject grade by subject name. + * It checks if the correct subject grade is returned. + */ + @Test + public void testFindSubject() { + Student student = new Student(JOHN_DOE); + StudentAttributes attributes = new StudentAttributes(student); + SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); + + attributes.addSubjectGrade(subjectGrade); + + SubjectGrade foundSubject = attributes.findSubject(MATH); + + assertEquals(subjectGrade, foundSubject); + } + + /** + * Test case to verify deleting a subject grade by subject name. + * It checks if the subject grade is successfully deleted. + */ + @Test + public void testDeleteSubject() { + Student student = new Student(JOHN_DOE); + StudentAttributes attributes = new StudentAttributes(student); + SubjectGrade subjectGrade = new SubjectGrade(MATH, 90.5, 20); + + attributes.addSubjectGrade(subjectGrade); + + attributes.deleteSubject(MATH); + + assertTrue(attributes.getSubjectGrades().isEmpty()); + } + +} From 3aceab6d1943af7eb24c5e72f4dc81e204fa69a9 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 11:05:38 +0800 Subject: [PATCH 346/503] Update PPP --- docs/team/tayponghee.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/team/tayponghee.md b/docs/team/tayponghee.md index 45094549d4..f40463a0c9 100644 --- a/docs/team/tayponghee.md +++ b/docs/team/tayponghee.md @@ -57,3 +57,5 @@ Given below are my contributions to the project: * [AddStudentTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/AddStudentTest.java) * [ViewStudentTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/ViewStudentTest.java) * [ListStudentsCommandTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/ListStudentsCommandTest.java) + * [DeleteCommandsTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/DeleteCommandsTest.java) + * [InputParsingTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/ListStudentsCommandTest.java)) From 40fb4936425a5d8817c86a1c0f3f72456f17df57 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 11:06:39 +0800 Subject: [PATCH 347/503] Remove extraneous bracket --- docs/team/tayponghee.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/team/tayponghee.md b/docs/team/tayponghee.md index f40463a0c9..2fcaf887b0 100644 --- a/docs/team/tayponghee.md +++ b/docs/team/tayponghee.md @@ -58,4 +58,4 @@ Given below are my contributions to the project: * [ViewStudentTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/ViewStudentTest.java) * [ListStudentsCommandTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/ListStudentsCommandTest.java) * [DeleteCommandsTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/DeleteCommandsTest.java) - * [InputParsingTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/ListStudentsCommandTest.java)) + * [InputParsingTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/commands/ListStudentsCommandTest.java) From a8cbd065b68ee2c757148aa6ed192c30b0af9d6a Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 11:37:58 +0800 Subject: [PATCH 348/503] Add classes attended for the specific subject in the list command --- .../commands/ListStudentsCommand.java | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 03f95da1ff..3ad8c8963c 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -1,11 +1,13 @@ package classify.commands; import classify.student.Student; +import classify.student.StudentAttributes; import classify.student.StudentList; import classify.student.SubjectGrade; import classify.ui.UI; import java.util.ArrayList; +import java.util.List; import java.util.Scanner; //@@ author blackmirag3 @@ -61,7 +63,14 @@ public static void listStudentsBySubject(ArrayList masterStudentList, S for (Student student : masterStudentList) { if (student.hasSubject(subject)) { - System.out.println("- " + student.getName()); + int classesAttended = getClassesAttendedForSubject(student, subject); + if (classesAttended >= 0) { + UI.println("- " + student.getName() + + " - Classes Attended for " + subject + ": " + classesAttended); + } + else{ + UI.println("- " + student.getName() + " - " + "No Classes Attended found for " + subject); + } found = true; } } @@ -73,6 +82,33 @@ public static void listStudentsBySubject(ArrayList masterStudentList, S UI.printDivider(); } + /** + * Gets the total number of classes attended by a student for the specified subject. + * + * @param student The student. + * @param subject The subject to check for classes attended. + * @return The number of classes attended for the specified subject. + */ + private static int getClassesAttendedForSubject(Student student, String subject) { + int classesAttended = 0; + + StudentAttributes attributes = student.getAttributes(); + List subjectGrades = attributes.getSubjectGrades(); + + for (SubjectGrade subjectGrade : subjectGrades) { + if (subjectGrade.getSubject().equalsIgnoreCase(subject)) { + if (subjectGrade.getClassesAttended() >= 0){ + classesAttended += subjectGrade.getClassesAttended(); + } + else { + classesAttended = -1; + } + } + } + + return classesAttended; + } + /** * Lists all students in the provided list, giving the user the option to choose the type of list to display. * From 52dc1623d1e8c6d9799ea413681d52e1c9a14d8f Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 11:42:24 +0800 Subject: [PATCH 349/503] Update UG --- docs/UserGuide.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 4042488f0f..35c558d29b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -313,19 +313,23 @@ The user can then select by index, from 4 additional options to either display a all students in the master list as well as the total number of classes they have attended. Alternatively, the user can choose to display either the students in the recently deleted list or the archive. +Do note that there is a difference between 0 and no classes attended found. If the program displays 0 classes attended, +it means that the user entered the field 0 when adding the student. +If it says no classes found, it means the user skipped that field when adding the student. + ``` Example: list Enter subject name (leave blank for all students): math Students with the subject "math": -- Toad -- Wario -- Mario -- Luigi -- Moyai -- Peach -- Daisy +- Toad - Classes Attended for math: 12 +- Wario - Classes Attended for math: 5 +- Mario - Classes Attended for math: 8 +- Luigi - Classes Attended for math: 0 +- Moyai - Classes Attended for math: 11 +- Peach - No Classes Attended found for math +- Daisy - No Classes Attended found for math ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ list From de40d46e6f5651c6abf64afc2b28cd2e78fe6710 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 11:45:47 +0800 Subject: [PATCH 350/503] Fix gradle checks and Junit tests --- src/main/java/classify/commands/ListStudentsCommand.java | 8 +++----- .../java/classify/commands/ListStudentsCommandTest.java | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 3ad8c8963c..f323322538 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -67,8 +67,7 @@ public static void listStudentsBySubject(ArrayList masterStudentList, S if (classesAttended >= 0) { UI.println("- " + student.getName() + " - Classes Attended for " + subject + ": " + classesAttended); - } - else{ + } else { UI.println("- " + student.getName() + " - " + "No Classes Attended found for " + subject); } found = true; @@ -99,9 +98,8 @@ private static int getClassesAttendedForSubject(Student student, String subject) if (subjectGrade.getSubject().equalsIgnoreCase(subject)) { if (subjectGrade.getClassesAttended() >= 0){ classesAttended += subjectGrade.getClassesAttended(); - } - else { - classesAttended = -1; + } else { + classesAttended = -1; } } } diff --git a/src/test/java/classify/commands/ListStudentsCommandTest.java b/src/test/java/classify/commands/ListStudentsCommandTest.java index efc66ba2c2..1ef855a025 100644 --- a/src/test/java/classify/commands/ListStudentsCommandTest.java +++ b/src/test/java/classify/commands/ListStudentsCommandTest.java @@ -99,7 +99,7 @@ void testListStudentsBySubject() { ArrayList expectedOutput = new ArrayList<>(); expectedOutput.add("Students with the subject " + '"' + MATH + '"' + ":"); - expectedOutput.add("- " + YIXIN); + expectedOutput.add("- " + YIXIN + " - " + "Classes Attended for Math: 10"); expectedOutput.add("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); assertEquals(expectedOutput, captureOutput(() -> ListStudentsCommand.listStudentsBySubject(students, MATH))); From 8aab9cad0164d123fff789a1389d8b719c18862b Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 12 Apr 2024 11:52:16 +0800 Subject: [PATCH 351/503] Fix file always corrupted bug --- src/main/java/classify/data/DataReader.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 1ff90d92a6..49eb13c489 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -208,8 +208,8 @@ public static void initialiseData(ArrayList list, try { while (line.ready()) { restoreStudentList(line.readLine(), list); - line.close(); } + line.close(); //@@author alalal47 } catch (ArrayIndexOutOfBoundsException e) { DataUI.printFileCorruptedMessage(); @@ -223,10 +223,11 @@ public static void initialiseData(ArrayList list, UI.printDivider(); } } - //@@author ParthGandhiNUS - DataUI.printLoadSuccess(); - UI.printDivider(); - } + //@@author ParthGandhiNUS + DataUI.printLoadSuccess(); + UI.printDivider(); + } + //@@author alalal47 /** From 3e7728393e8fac4b6a9fb9942567a72987cb602d Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 12 Apr 2024 11:55:29 +0800 Subject: [PATCH 352/503] Fix incorrect indentation --- src/main/java/classify/data/DataReader.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 49eb13c489..2bc30d2c1a 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -223,10 +223,10 @@ public static void initialiseData(ArrayList list, UI.printDivider(); } } - //@@author ParthGandhiNUS - DataUI.printLoadSuccess(); - UI.printDivider(); - } + //@@author ParthGandhiNUS + DataUI.printLoadSuccess(); + UI.printDivider(); + } //@@author alalal47 From 9795beeb7b5a5963e8fd926bd95f2c11ad23f6b9 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 12 Apr 2024 12:19:37 +0800 Subject: [PATCH 353/503] Implement clearing of student list upon corruption detected --- src/main/java/classify/data/DataReader.java | 2 ++ src/main/java/classify/student/StudentList.java | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 2bc30d2c1a..c72c48b276 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -216,11 +216,13 @@ public static void initialiseData(ArrayList list, DataUI.printDataDeletionPromptMessage(); promptDataDeletion(); UI.printDivider(); + StudentList.masterStudentList.clear(); } catch (IOException e) { DataUI.printFileCorruptedMessage(); DataUI.printDataDeletionPromptMessage(); promptDataDeletion(); UI.printDivider(); + StudentList.masterStudentList.clear(); } } //@@author ParthGandhiNUS diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index 9cb00a4cdc..f0e8752823 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -24,7 +24,6 @@ public class StudentList { // @@author Cryolian public StudentList() { this.studentList = new ArrayList<>(); - ; } // @@author ParthGandhiNUS @@ -138,7 +137,7 @@ public static void checkNameNumberPair(ArrayList studentList, String na * @param studentList List to check through for the name and number. * @param name Name of the student to find. * @param number Phone number of the student to find. - * @throws nameNumberMatchException Thrown if a match is found. + * @throws NameNumberMatchException Thrown if a match is found. */ public static void checkNameNumberPair(StudentList studentList, String name, int number) throws NameNumberMatchException, NullPointerException { From 68a85ce5cf7ac4969744c8fd6a5b8b825e773836 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 12 Apr 2024 13:06:24 +0800 Subject: [PATCH 354/503] Add testing for sort by payment date --- .../java/classify/commands/StudentSorter.java | 2 +- .../classify/commands/StudentSorterTest.java | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/StudentSorter.java b/src/main/java/classify/commands/StudentSorter.java index eff750f54c..2005b31fba 100644 --- a/src/main/java/classify/commands/StudentSorter.java +++ b/src/main/java/classify/commands/StudentSorter.java @@ -110,7 +110,7 @@ private static void listStudentsByTotalClasses(ArrayList masterStudentL //@@author alalal47 /** - * Lists students in the provided list by last paid date attended in ascending order, with the most recent first. + * Lists students in the provided list by last paid date attended in ascending order, with the least recent first. * * @param masterStudentList The list of students to be listed by total classes attended. */ diff --git a/src/test/java/classify/commands/StudentSorterTest.java b/src/test/java/classify/commands/StudentSorterTest.java index ae89c0998a..b281804f58 100644 --- a/src/test/java/classify/commands/StudentSorterTest.java +++ b/src/test/java/classify/commands/StudentSorterTest.java @@ -1,12 +1,14 @@ //@@author tayponghee package classify.commands; +import classify.user.InputParsing; import org.junit.jupiter.api.Test; import classify.student.Student; import classify.student.StudentAttributes; import classify.student.SubjectGrade; +import java.time.LocalDate; import java.util.ArrayList; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -40,25 +42,38 @@ public void testSortByChoice() { students.add(student4); students.add(student5); + //@@author alalal47 + LocalDate student1date = LocalDate.parse("2020-01-13"); + LocalDate student2date = LocalDate.parse("2021-11-13"); + LocalDate student3date = LocalDate.parse("2022-06-13"); + LocalDate student4date = LocalDate.parse("2023-12-13"); + LocalDate student5date = LocalDate.parse("2024-07-13"); + + //@@author tayponghee StudentAttributes attributes1 = new StudentAttributes(student1); attributes1.addSubjectGrade(new SubjectGrade(MATH, 90.0, 10)); attributes1.addSubjectGrade(new SubjectGrade(SCIENCE, 85.0, 8)); + attributes1.setLastPaymentDate(student1date); StudentAttributes attributes2 = new StudentAttributes(student2); attributes2.addSubjectGrade(new SubjectGrade(MATH, 88.0, 12)); attributes2.addSubjectGrade(new SubjectGrade(SCIENCE, 80.0, 7)); + attributes2.setLastPaymentDate(student2date); StudentAttributes attributes3 = new StudentAttributes(student3); attributes3.addSubjectGrade(new SubjectGrade(MATH, 85.0, 15)); attributes3.addSubjectGrade(new SubjectGrade(SCIENCE, 82.0, 6)); + attributes3.setLastPaymentDate(student3date); StudentAttributes attributes4 = new StudentAttributes(student4); attributes4.addSubjectGrade(new SubjectGrade(MATH, 92.0, 14)); attributes4.addSubjectGrade(new SubjectGrade(SCIENCE, 88.0, 9)); + attributes4.setLastPaymentDate(student4date); StudentAttributes attributes5 = new StudentAttributes(student5); attributes5.addSubjectGrade(new SubjectGrade(MATH, 85.0, 11)); attributes5.addSubjectGrade(new SubjectGrade(SCIENCE, 90.0, 10)); + attributes5.setLastPaymentDate(student5date); student1.setAttributes(attributes1); student2.setAttributes(attributes2); @@ -79,5 +94,13 @@ public void testSortByChoice() { assertEquals(SHUI_HON, students.get(2).getName()); assertEquals(YI_XIN, students.get(3).getName()); assertEquals(GERARD, students.get(4).getName()); + + //@@author alalal47 + StudentSorter.sortByChoice(students, "3", null); + assertEquals(PONG_HEE, students.get(0).getName()); + assertEquals(PARTH, students.get(1).getName()); + assertEquals(YI_XIN, students.get(2).getName()); + assertEquals(GERARD, students.get(3).getName()); + assertEquals(SHUI_HON, students.get(4).getName()); } } From 65877afe0ea55932afcb6f1e3e0930d2a6691af3 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 12 Apr 2024 13:21:02 +0800 Subject: [PATCH 355/503] Fix line wrapping for help message on smaller terminal windows --- src/main/java/classify/ui/UI.java | 3 +-- src/test/java/classify/user/InputParsingTest.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index b0a9b6d1cc..8147b97a07 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -159,8 +159,7 @@ private static void printEditHelpMessage() { private static void printAddHelpMessage() { System.out.println("add Adds a student to the student list, " + - "expects a name, grade and lessons attended" + - ", can be used directly with a name e.g. add [name]"); + "expects a name, grade and lessons attended e.g. add [name]"); } //@@author ParthGandhiNUS diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index f04e681f30..b4c4b8aaee 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -147,8 +147,7 @@ public void testHelpCommand() { String printedOutput = outputStream.toString().trim(); String expectedOutput = "add Adds a student to the student list, expects a name" + - ", grade and lessons attended," + - " can be used directly with a name e.g. add [name]" + ", grade and lessons attended e.g. add [name]" + System.lineSeparator() + "edit Edits a students details, expects a name" + ", can be used directly with a name e.g. edit [name]" From c1eeaafe20e9468b49db6a0192bcff925cc4c16b Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 12 Apr 2024 13:41:42 +0800 Subject: [PATCH 356/503] Remove unused import --- src/test/java/classify/commands/StudentSorterTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/classify/commands/StudentSorterTest.java b/src/test/java/classify/commands/StudentSorterTest.java index b281804f58..20c0d4ad77 100644 --- a/src/test/java/classify/commands/StudentSorterTest.java +++ b/src/test/java/classify/commands/StudentSorterTest.java @@ -1,7 +1,6 @@ //@@author tayponghee package classify.commands; -import classify.user.InputParsing; import org.junit.jupiter.api.Test; import classify.student.Student; From 2b3253602d69718ece50ea1965fcec7c02591936 Mon Sep 17 00:00:00 2001 From: shui <78994143+blackmirag3@users.noreply.github.com> Date: Fri, 12 Apr 2024 15:06:00 +0800 Subject: [PATCH 357/503] Update UserGuide.md --- docs/UserGuide.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 7ed09fd648..ad203b1121 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -242,7 +242,7 @@ The following is an example of trying to add a new student that matches the name #### Example usage: ``` -add awesomesjh +add melodie Subject (enter nothing to skip): No subjects added. Please input a valid phone number: @@ -306,7 +306,7 @@ Name of student to edit (blank to exit): Student details: Name: Vincent -Phone Number: 83227277 +Phone Number: 99999999 Gender: Unknown Last Payment Date: 2024-04-08 Remarks: Unknown @@ -338,7 +338,7 @@ If no student is found in the master student list, edit mode will not be entered ``` edit Name of student to edit (blank to exit): -tim lau kar meeng +luigi No student found to edit! What else can I do for you today? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -384,8 +384,8 @@ Undoes the latest "delete student". Used by typing `undo` Format: `undo` +#### Example Usage: ``` -Example: undo Last delete undone! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -477,7 +477,7 @@ Choose the type of list to display: (index only) Enter your choice (1, 2, 3, 4 or 5): 4 List of students in archive: -1.Timothy +1.Timothee Chalamet Currently, there is 1 student in the list. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 5fd6ae8f5347e1e08def164dce86402650d23a89 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 12 Apr 2024 18:27:03 +0800 Subject: [PATCH 358/503] Update TextFileHandler Class --- .../java/classify/textfilecode/TextFileHandler.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/java/classify/textfilecode/TextFileHandler.java b/src/main/java/classify/textfilecode/TextFileHandler.java index d1824b7644..1601976aae 100644 --- a/src/main/java/classify/textfilecode/TextFileHandler.java +++ b/src/main/java/classify/textfilecode/TextFileHandler.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.nio.file.FileAlreadyExistsException; import java.nio.file.Files; +import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -15,13 +16,14 @@ //@@author ParthGandhiNUS public class TextFileHandler { private static final String CURRENT_FILES = "Current Files in your Input Folder:"; - private static final String INPUT_TEXT_FILE_DIRECTORY = "./data/inputFolder"; + public static final String INPUT_TEXT_FILE_DIRECTORY = "./data/inputFolder"; private static final String IO_EXCEPTION_MESSAGE_FOR_TEXT_FILE = "Something went horribly wrong while creating " + "your data folder!"; public static final File CURRENT_DIRECTORY = new File (INPUT_TEXT_FILE_DIRECTORY); + private static final String INVALID_PATH_MESSAGE = "Path is invalid!"; public static void process(ArrayList masterStudentList, Scanner in) { - createTextFileDirectory(); + createTextFileDirectory(INPUT_TEXT_FILE_DIRECTORY); // Print out the current files in your folder UI.println(CURRENT_FILES); TextFileReader.printCurrentInputFolder(INPUT_TEXT_FILE_DIRECTORY); @@ -32,15 +34,17 @@ public static void process(ArrayList masterStudentList, Scanner in) { /** * Used to create the parent folder for a text file for Inputting */ - public static void createTextFileDirectory(){ + public static void createTextFileDirectory(String pathString){ //Folder Creation if folder not there try{ - Path path = Paths.get(INPUT_TEXT_FILE_DIRECTORY); + Path path = Paths.get(pathString); Files.createDirectories(path); } catch (FileAlreadyExistsException ignored){ //Ignore this error as this should not cause any issues, we don't want replicas of the same file } catch (IOException e){ UI.println(IO_EXCEPTION_MESSAGE_FOR_TEXT_FILE); + } catch (InvalidPathException e) { + UI.println(INVALID_PATH_MESSAGE); } } } From c661b7ae25854213c031c6198fee5e55e76d37e3 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 12 Apr 2024 18:27:27 +0800 Subject: [PATCH 359/503] Update Main of Classify --- src/main/java/classify/Classify.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 02f124bd0f..24b821e200 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -24,7 +24,7 @@ public static void main(String[] args) throws IOException { DataHandler.readArchive(StudentList.archiveList); //@@author ParthGandhiNUS - TextFileHandler.createTextFileDirectory(); + TextFileHandler.createTextFileDirectory(TextFileHandler.INPUT_TEXT_FILE_DIRECTORY); UI.printWelcomeMessage(); // Takes in input from the user, and processes input to determine if it contains a command and a name From 229487961a8d630220fd4a496595159dff874f0d Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 12 Apr 2024 18:27:54 +0800 Subject: [PATCH 360/503] Update access of TextFileParser methods --- src/main/java/classify/textfilecode/TextFileParser.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index 78ace1c58f..de14885e6c 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -239,7 +239,7 @@ private static void masterStudentListAddition(ArrayList masterStudentLi * @param student Instance of Student * @param phoneNumber Phone number of the student */ - private static void addPhoneNumber(String studentNameString, Student student, int phoneNumber) { + static void addPhoneNumber(String studentNameString, Student student, int phoneNumber) { if (InputParsing.checkNumberValidity(phoneNumber)){ student.getAttributes().setPhoneNumber(phoneNumber); } else { @@ -255,7 +255,7 @@ private static void addPhoneNumber(String studentNameString, Student student, in * @param number Phone number of the student to find. * @return Index of the student in masterStudentList */ - private static Integer matchingStudentIndex (ArrayList masterStudentList, String name, int number){ + static Integer matchingStudentIndex(ArrayList masterStudentList, String name, int number){ int listSize = masterStudentList.size(); for (int i = 0; i < listSize; i++) { @@ -275,7 +275,7 @@ private static Integer matchingStudentIndex (ArrayList masterStudentLis * @param subjectName name of the subject that is getting added * @return True if subject is found attributed to that particular student. False otherwise. */ - private static boolean matchingSubject(ArrayList masterStudentList, String subjectName, + static boolean matchingSubject(ArrayList masterStudentList, String subjectName, Integer indexOfStudent) { List studentSubjects = masterStudentList.get(indexOfStudent).getAttributes().getSubjectGrades(); for (SubjectGrade subject : studentSubjects){ @@ -296,7 +296,7 @@ private static boolean matchingSubject(ArrayList masterStudentList, Str * @param number Phone number of the student to find. * @return True if a student with the same name and number is found in the list,false otherwise. */ - private static boolean matchingNameNumber (ArrayList masterStudentList, String name, int number) { + static boolean matchingNameNumber(ArrayList masterStudentList, String name, int number) { for (Student student : masterStudentList) { if (student.getName().equalsIgnoreCase(name) && student.getPhoneNumber() == number) { return true; From 5aa1437b774f82d64962c3b8ebbe54ca9f6ae543 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 12 Apr 2024 18:28:29 +0800 Subject: [PATCH 361/503] Junit tests for TextFileHandler --- .../textfilecode/TextFileHandlerTest.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/test/java/classify/textfilecode/TextFileHandlerTest.java diff --git a/src/test/java/classify/textfilecode/TextFileHandlerTest.java b/src/test/java/classify/textfilecode/TextFileHandlerTest.java new file mode 100644 index 0000000000..8a83e2926b --- /dev/null +++ b/src/test/java/classify/textfilecode/TextFileHandlerTest.java @@ -0,0 +1,44 @@ +package classify.textfilecode; +//@@author ParthGandhiNUS + +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class TextFileHandlerTest { + private static final String VALID_FILE_DIRECTORY = "./data/testFolder"; + private static final String INVALID_FILE_DIRECTORY = "./data/invalid**"; + private static final String INVALID_PATH_MESSAGE = "Path is invalid!"; + + /** + * Test checks for the creation of new directories + * @throws IOException + */ + @Test + public void testCreateTextFileDirectory_SuccessfulCreation() { + TextFileHandler.createTextFileDirectory(VALID_FILE_DIRECTORY); + File currentDir = new File (VALID_FILE_DIRECTORY); + Path expectedDirectory = Paths.get(VALID_FILE_DIRECTORY); + assertTrue( Files.exists(expectedDirectory)); + currentDir.delete(); + } + + @Test + public void testCreateTextFileDirectory_InvalidPath() { + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + + TextFileHandler.createTextFileDirectory(INVALID_FILE_DIRECTORY); + + assertEquals(INVALID_PATH_MESSAGE, outContent.toString().trim()); + } +} From ac643b078fc2c4ae96b534e343d19d5f58372659 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 12 Apr 2024 18:28:42 +0800 Subject: [PATCH 362/503] Junit tests for TextFileReader --- .../textfilecode/TextFileReaderTest.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/test/java/classify/textfilecode/TextFileReaderTest.java diff --git a/src/test/java/classify/textfilecode/TextFileReaderTest.java b/src/test/java/classify/textfilecode/TextFileReaderTest.java new file mode 100644 index 0000000000..a7c0626d82 --- /dev/null +++ b/src/test/java/classify/textfilecode/TextFileReaderTest.java @@ -0,0 +1,51 @@ +package classify.textfilecode; +//@@author ParthGandhiNUS + +import static org.junit.jupiter.api.Assertions.*; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; + +import org.junit.jupiter.api.Test; + +class TextFileReaderTest { + private static final String VALID_FILE_DIRECTORY = "./data/testFolder"; + + @Test + public void testPrintCurrentInputFolderwhenEmpty() { + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + + TextFileHandler.createTextFileDirectory(VALID_FILE_DIRECTORY); + + TextFileReader.printCurrentInputFolder(VALID_FILE_DIRECTORY); + + assertEquals("No files in your Input Folder!\n" + + "Please add some new files in the correct format!", outContent.toString().trim()); + } + + @Test + public void testPrintCurrentInputFolderwhenFilled() { + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + + TextFileHandler.createTextFileDirectory(VALID_FILE_DIRECTORY); + File currentDir = new File (VALID_FILE_DIRECTORY); + File testFile1 = new File (currentDir, "file1.txt"); + try { + testFile1.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + + + TextFileReader.printCurrentInputFolder(VALID_FILE_DIRECTORY); + + assertEquals("1. file1.txt", outContent.toString().trim()); + + testFile1.delete(); + currentDir.delete(); + } + } \ No newline at end of file From b994d92645895b469bd0c5537d40817871fb6999 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 12 Apr 2024 18:28:53 +0800 Subject: [PATCH 363/503] Junit tests for TextFileParser --- .../textfilecode/TextFileParserTest.java | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/test/java/classify/textfilecode/TextFileParserTest.java diff --git a/src/test/java/classify/textfilecode/TextFileParserTest.java b/src/test/java/classify/textfilecode/TextFileParserTest.java new file mode 100644 index 0000000000..4e1e10454d --- /dev/null +++ b/src/test/java/classify/textfilecode/TextFileParserTest.java @@ -0,0 +1,133 @@ +package classify.textfilecode; +//@@author ParthGandhiNUS + +import classify.student.Student; +import classify.student.SubjectGrade; + +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.ArrayList; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class TextFileParserTest { +public static final String JOHN_DOE = "John_Doe"; +public static final Integer NORMAL_SG_NUMBER = 99999999; +public static final String MATH = "Math"; +public static final String SCIENCE = "Science"; +public static final double MATH_GRADE = 81.3; +public static final Integer MATH_CLASSES = 10; +private static final String INVALID_PHONE_NUMBER_MESSAGE="'s phone number is not a valid Singapore phone number." + +" Please edit this students' phone number with the edit command!"; + + @Test + public void testAddPhoneNumberValidCase(){ + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + + ArrayList masterStudentList = new ArrayList<>(); + Student student = new Student(JOHN_DOE); + masterStudentList.add(student); + + TextFileParser.addPhoneNumber(JOHN_DOE, student, NORMAL_SG_NUMBER); + + assertTrue(student.getAttributes().getPhoneNumber() == NORMAL_SG_NUMBER); + } + + @Test + public void testAddPhoneNumberInvalidCase(){ + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + + ArrayList masterStudentList = new ArrayList<>(); + Student student = new Student(JOHN_DOE); + masterStudentList.add(student); + + TextFileParser.addPhoneNumber(JOHN_DOE, student, 989898); + assertEquals(JOHN_DOE+INVALID_PHONE_NUMBER_MESSAGE, outContent.toString().trim()); + } + + @Test + public void testMatchingStudentIndexAllTrue(){ + ArrayList masterStudentList = new ArrayList<>(); + Student student = new Student(JOHN_DOE); + masterStudentList.add(student); + student.getAttributes().setPhoneNumber(NORMAL_SG_NUMBER); + + boolean checker = (TextFileParser.matchingStudentIndex(masterStudentList, JOHN_DOE, NORMAL_SG_NUMBER) == 0) ? true : false; + assertTrue(checker); + } + + @Test + public void testMatchingStudentIndexWrongNumber(){ + ArrayList masterStudentList = new ArrayList<>(); + Student student = new Student(JOHN_DOE); + masterStudentList.add(student); + student.getAttributes().setPhoneNumber(NORMAL_SG_NUMBER); + + boolean checker = (TextFileParser.matchingStudentIndex(masterStudentList, JOHN_DOE, 98989898) == 0) ? true : false; + assertFalse(checker); + } + + @Test + public void testMatchingStudentIndexWrongName(){ + ArrayList masterStudentList = new ArrayList<>(); + Student student = new Student(JOHN_DOE); + masterStudentList.add(student); + student.getAttributes().setPhoneNumber(NORMAL_SG_NUMBER); + + boolean checker = (TextFileParser.matchingStudentIndex(masterStudentList, "Jane Doe", NORMAL_SG_NUMBER) == 0) ? true : false; + assertFalse(checker); + } + + + @Test + public void testMatchingSubjectTrueCase(){ + ArrayList masterStudentList = new ArrayList<>(); + Student student = new Student(JOHN_DOE); + masterStudentList.add(student); + student.getAttributes().setPhoneNumber(NORMAL_SG_NUMBER); + SubjectGrade newSubject = new SubjectGrade(MATH, MATH_GRADE, MATH_CLASSES); + student.getAttributes().addSubjectGrade(newSubject); + + + assertTrue(TextFileParser.matchingSubject(masterStudentList, MATH, 0)); + } + + @Test + public void testMatchingSubjectFalseCase(){ + ArrayList masterStudentList = new ArrayList<>(); + Student student = new Student(JOHN_DOE); + masterStudentList.add(student); + student.getAttributes().setPhoneNumber(NORMAL_SG_NUMBER); + SubjectGrade newSubject = new SubjectGrade(MATH, MATH_GRADE, MATH_CLASSES); + student.getAttributes().addSubjectGrade(newSubject); + + + assertFalse(TextFileParser.matchingSubject(masterStudentList, SCIENCE, 0)); + } + + @Test + public void testMatchingNameNumberTrueCase(){ + ArrayList masterStudentList = new ArrayList<>(); + Student student = new Student(JOHN_DOE); + masterStudentList.add(student); + student.getAttributes().setPhoneNumber(NORMAL_SG_NUMBER); + + assertTrue(TextFileParser.matchingNameNumber(masterStudentList, JOHN_DOE, NORMAL_SG_NUMBER)); + } + + @Test + public void testMatchingNameNumberFalseCase(){ + ArrayList masterStudentList = new ArrayList<>(); + Student student = new Student("Jane Doe"); + masterStudentList.add(student); + student.getAttributes().setPhoneNumber(98989898); + + assertFalse(TextFileParser.matchingNameNumber(masterStudentList, JOHN_DOE, NORMAL_SG_NUMBER)); + } +} From 35059ad2c531a46b253ea6f1ba957e559069d63c Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 12 Apr 2024 18:41:17 +0800 Subject: [PATCH 364/503] Correct CheckStyle Issues --- src/main/java/classify/Classify.java | 3 +- .../textfilecode/TextFileHandler.java | 2 +- .../textfilecode/TextFileHandlerTest.java | 10 +++---- .../textfilecode/TextFileParserTest.java | 29 ++++++++++--------- .../textfilecode/TextFileReaderTest.java | 8 ++--- 5 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 24b821e200..5a777e6780 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -11,6 +11,7 @@ public class Classify { public static Scanner in = new Scanner(System.in); + private static final String INPUT_TEXT_FILE_DIRECTORY = "./data/inputFolder"; /** * Main entry-point for the Classify application. @@ -24,7 +25,7 @@ public static void main(String[] args) throws IOException { DataHandler.readArchive(StudentList.archiveList); //@@author ParthGandhiNUS - TextFileHandler.createTextFileDirectory(TextFileHandler.INPUT_TEXT_FILE_DIRECTORY); + TextFileHandler.createTextFileDirectory(INPUT_TEXT_FILE_DIRECTORY); UI.printWelcomeMessage(); // Takes in input from the user, and processes input to determine if it contains a command and a name diff --git a/src/main/java/classify/textfilecode/TextFileHandler.java b/src/main/java/classify/textfilecode/TextFileHandler.java index 1601976aae..0409ec0300 100644 --- a/src/main/java/classify/textfilecode/TextFileHandler.java +++ b/src/main/java/classify/textfilecode/TextFileHandler.java @@ -16,7 +16,7 @@ //@@author ParthGandhiNUS public class TextFileHandler { private static final String CURRENT_FILES = "Current Files in your Input Folder:"; - public static final String INPUT_TEXT_FILE_DIRECTORY = "./data/inputFolder"; + private static final String INPUT_TEXT_FILE_DIRECTORY = "./data/inputFolder"; private static final String IO_EXCEPTION_MESSAGE_FOR_TEXT_FILE = "Something went horribly wrong while creating " + "your data folder!"; public static final File CURRENT_DIRECTORY = new File (INPUT_TEXT_FILE_DIRECTORY); diff --git a/src/test/java/classify/textfilecode/TextFileHandlerTest.java b/src/test/java/classify/textfilecode/TextFileHandlerTest.java index 8a83e2926b..526eb08079 100644 --- a/src/test/java/classify/textfilecode/TextFileHandlerTest.java +++ b/src/test/java/classify/textfilecode/TextFileHandlerTest.java @@ -5,7 +5,6 @@ import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.IOException; import java.io.PrintStream; import java.nio.file.Files; import java.nio.file.Path; @@ -16,15 +15,14 @@ class TextFileHandlerTest { private static final String VALID_FILE_DIRECTORY = "./data/testFolder"; - private static final String INVALID_FILE_DIRECTORY = "./data/invalid**"; - private static final String INVALID_PATH_MESSAGE = "Path is invalid!"; + private static final String INVALID_FILE_DIRECTORY = "./data/invalid**"; + private static final String INVALID_PATH_MESSAGE = "Path is invalid!"; /** * Test checks for the creation of new directories - * @throws IOException */ @Test - public void testCreateTextFileDirectory_SuccessfulCreation() { + public void testCreateTextFileDirectorySuccessfulCreation() { TextFileHandler.createTextFileDirectory(VALID_FILE_DIRECTORY); File currentDir = new File (VALID_FILE_DIRECTORY); Path expectedDirectory = Paths.get(VALID_FILE_DIRECTORY); @@ -33,7 +31,7 @@ public void testCreateTextFileDirectory_SuccessfulCreation() { } @Test - public void testCreateTextFileDirectory_InvalidPath() { + public void testCreateTextFileDirectoryInvalidPath() { ByteArrayOutputStream outContent = new ByteArrayOutputStream(); System.setOut(new PrintStream(outContent)); diff --git a/src/test/java/classify/textfilecode/TextFileParserTest.java b/src/test/java/classify/textfilecode/TextFileParserTest.java index 4e1e10454d..4a0d5caa8e 100644 --- a/src/test/java/classify/textfilecode/TextFileParserTest.java +++ b/src/test/java/classify/textfilecode/TextFileParserTest.java @@ -15,14 +15,14 @@ import static org.junit.jupiter.api.Assertions.assertTrue; class TextFileParserTest { -public static final String JOHN_DOE = "John_Doe"; -public static final Integer NORMAL_SG_NUMBER = 99999999; -public static final String MATH = "Math"; -public static final String SCIENCE = "Science"; -public static final double MATH_GRADE = 81.3; -public static final Integer MATH_CLASSES = 10; -private static final String INVALID_PHONE_NUMBER_MESSAGE="'s phone number is not a valid Singapore phone number." + -" Please edit this students' phone number with the edit command!"; + public static final String JOHN_DOE = "John_Doe"; + public static final Integer NORMAL_SG_NUMBER = 99999999; + public static final String MATH = "Math"; + public static final String SCIENCE = "Science"; + public static final double MATH_GRADE = 81.3; + public static final Integer MATH_CLASSES = 10; + private static final String INVALID_PHONE_NUMBER_MESSAGE="'s phone number is not a valid Singapore phone number." + + " Please edit this students' phone number with the edit command!"; @Test public void testAddPhoneNumberValidCase(){ @@ -34,8 +34,8 @@ public void testAddPhoneNumberValidCase(){ masterStudentList.add(student); TextFileParser.addPhoneNumber(JOHN_DOE, student, NORMAL_SG_NUMBER); - - assertTrue(student.getAttributes().getPhoneNumber() == NORMAL_SG_NUMBER); + + assertEquals((int) NORMAL_SG_NUMBER, student.getAttributes().getPhoneNumber()); } @Test @@ -58,7 +58,8 @@ public void testMatchingStudentIndexAllTrue(){ masterStudentList.add(student); student.getAttributes().setPhoneNumber(NORMAL_SG_NUMBER); - boolean checker = (TextFileParser.matchingStudentIndex(masterStudentList, JOHN_DOE, NORMAL_SG_NUMBER) == 0) ? true : false; + boolean checker = TextFileParser.matchingStudentIndex(masterStudentList, + JOHN_DOE, NORMAL_SG_NUMBER) == 0; assertTrue(checker); } @@ -69,7 +70,8 @@ public void testMatchingStudentIndexWrongNumber(){ masterStudentList.add(student); student.getAttributes().setPhoneNumber(NORMAL_SG_NUMBER); - boolean checker = (TextFileParser.matchingStudentIndex(masterStudentList, JOHN_DOE, 98989898) == 0) ? true : false; + boolean checker = TextFileParser.matchingStudentIndex(masterStudentList, + JOHN_DOE, 98989898) == 0; assertFalse(checker); } @@ -80,7 +82,8 @@ public void testMatchingStudentIndexWrongName(){ masterStudentList.add(student); student.getAttributes().setPhoneNumber(NORMAL_SG_NUMBER); - boolean checker = (TextFileParser.matchingStudentIndex(masterStudentList, "Jane Doe", NORMAL_SG_NUMBER) == 0) ? true : false; + boolean checker = TextFileParser.matchingStudentIndex(masterStudentList, + "Jane Doe", NORMAL_SG_NUMBER) == 0; assertFalse(checker); } diff --git a/src/test/java/classify/textfilecode/TextFileReaderTest.java b/src/test/java/classify/textfilecode/TextFileReaderTest.java index a7c0626d82..c73090ae10 100644 --- a/src/test/java/classify/textfilecode/TextFileReaderTest.java +++ b/src/test/java/classify/textfilecode/TextFileReaderTest.java @@ -1,14 +1,14 @@ package classify.textfilecode; //@@author ParthGandhiNUS -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.PrintStream; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; class TextFileReaderTest { private static final String VALID_FILE_DIRECTORY = "./data/testFolder"; @@ -23,7 +23,7 @@ public void testPrintCurrentInputFolderwhenEmpty() { TextFileReader.printCurrentInputFolder(VALID_FILE_DIRECTORY); assertEquals("No files in your Input Folder!\n" + - "Please add some new files in the correct format!", outContent.toString().trim()); + "Please add some new files in the correct format!", outContent.toString().trim()); } @Test @@ -48,4 +48,4 @@ public void testPrintCurrentInputFolderwhenFilled() { testFile1.delete(); currentDir.delete(); } - } \ No newline at end of file +} From 0d683b91a21b653bedca03a5b557960607eae84b Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 12 Apr 2024 18:53:45 +0800 Subject: [PATCH 365/503] Remove erronous test case --- .../classify/textfilecode/TextFileHandlerTest.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/test/java/classify/textfilecode/TextFileHandlerTest.java b/src/test/java/classify/textfilecode/TextFileHandlerTest.java index 526eb08079..81e2eed2d8 100644 --- a/src/test/java/classify/textfilecode/TextFileHandlerTest.java +++ b/src/test/java/classify/textfilecode/TextFileHandlerTest.java @@ -3,14 +3,11 @@ import org.junit.jupiter.api.Test; -import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.PrintStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; class TextFileHandlerTest { @@ -29,14 +26,4 @@ public void testCreateTextFileDirectorySuccessfulCreation() { assertTrue( Files.exists(expectedDirectory)); currentDir.delete(); } - - @Test - public void testCreateTextFileDirectoryInvalidPath() { - ByteArrayOutputStream outContent = new ByteArrayOutputStream(); - System.setOut(new PrintStream(outContent)); - - TextFileHandler.createTextFileDirectory(INVALID_FILE_DIRECTORY); - - assertEquals(INVALID_PATH_MESSAGE, outContent.toString().trim()); - } } From 967df8a4c2343bf0b4c2f595a770cfc0e1dae1ef Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 12 Apr 2024 19:03:58 +0800 Subject: [PATCH 366/503] Add more features to instructions for manual testing --- docs/DeveloperGuide.md | 40 +++++++++++++++++++++++++++++++++------- docs/UserGuide.md | 4 ++++ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index c559ce65e5..0e9b25e7bd 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -269,19 +269,45 @@ Classify serves as an attempt to modernise administrative tasks in education ins ### Adding a student to the student list 1. Adding a student with a name and phone number only - 1. Prerequisites: View if a student with the name 'joe' exists by using the `view joe` command. - 2. Test case: `add joe` and when prompted for phone number enter `11111111`, while pressing enter to skip other optional fields. + 1. Prerequisites: View if a student with the name `joe` and phone number `88888888` exists by using the `view joe` command. + 2. Test case: `add joe` and when prompted for phone number enter `88888888`, while pressing enter to skip other optional fields.
- Expected: `view joe` now shows the Student details of a student with Name: joe, Phone Number: 11111111. Other fields that were left blank will reflect 'Unknown' or for date fields, today's date. - 3. Test case: `add` and when prompted for Name, `joe`. `11111111` when prompted for phone number, press enter to skip other fields. + Expected: `view joe` now shows the Student details of a student with Name: joe, Phone Number: 11111111. +
+ Other fields that were left blank will reflect 'Unknown' or for date fields, today's date. + 3. Test case: `add` and when prompted for Name, `joe`. `88888888` when prompted for phone number, press enter to skip other fields.
Expected: `view joe` shows the same results as when a student was added via `add joe`. + ### Viewing a student's details 1. View a student who has been added to the student list - 1. Prerequisites: Add one student named 'joe' to the list with the `add` command + 1. Prerequisites: Add one student named `joe` to the list with the `add` command 2. Test case: `view joe`
Expected: Student's details shown correspond to the details input when `add` was used to add a student. - 3. Test case: `view dogman` + +### Deleting a student from the student list +1. Deleting a student that exists in the student list + 1. Prerequisites: Add one student named `joe` to the list with the `add` command + 2. Test case: `delete joe` + Expected: `view joe` shows Student not found! +
+ `list` followed by enter, enter again, and `1` which displays a list of all students, does not show any student named `joe`. + +### Displaying a list of students +1. Listing all students enrolled in the tuition centre + 1. Prerequisites: Have at least one student added to the list with the `add` command + 2. Test case: `list`, enter, enter, `1` + Expected: A list of all students that are enrolled in the tuition centre is printed. +
+
+2. Listing all students with a specific subject in the tuition centre + 1. Prerequisites: Have at least one student with the subject `Math` added to the list with the `add` command + 2. Test case: `list`, `Math` + Expected: A list of all the students with the subject `Math` in the tuition centre is printed. +

- Expected: No details are displayed, an error message stating 'Student not found!' is shown. \ No newline at end of file +3. Listing all students that have been deleted in the current session + 1. Prerequisites: Delete at least one student in the list with the `delete` command + 2. Test case: `list`, enter, enter, `5` + Expected: A list of all students that have been deleted in the current session is printed. \ No newline at end of file diff --git a/docs/UserGuide.md b/docs/UserGuide.md index a19a29e673..5aef6fb3fc 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -743,4 +743,8 @@ This section provides a quick overview of all the commands used in our Classify. **A**: Due to the ever-changing climate of what is considered a name (and more), we have limited the bans to 3 special characters above only. In the event your name or other identification metrics contains `#`, `~` or `-`, we seek for your understanding. +**Q**: What happens if my data file gets corrupted? + +**A**: We recommend manually looking through the data file and rectifying any errors, or by running Classify with a corrupted data file, the prompts on screen will guide you to delete all data in the file to restore Classify to a working state. + From d9ecce5187ac8bb8f53da0390ff39caa17e6970e Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 19:04:28 +0800 Subject: [PATCH 367/503] Remove unused imports --- src/test/java/classify/textfilecode/TextFileHandlerTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/classify/textfilecode/TextFileHandlerTest.java b/src/test/java/classify/textfilecode/TextFileHandlerTest.java index 81e2eed2d8..b27d66a3d9 100644 --- a/src/test/java/classify/textfilecode/TextFileHandlerTest.java +++ b/src/test/java/classify/textfilecode/TextFileHandlerTest.java @@ -12,8 +12,6 @@ class TextFileHandlerTest { private static final String VALID_FILE_DIRECTORY = "./data/testFolder"; - private static final String INVALID_FILE_DIRECTORY = "./data/invalid**"; - private static final String INVALID_PATH_MESSAGE = "Path is invalid!"; /** * Test checks for the creation of new directories From 844f3cca742c4a957a9a0f25a20595bf460315f5 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 12 Apr 2024 19:24:02 +0800 Subject: [PATCH 368/503] Fix instructions for manual testing formatting --- docs/DeveloperGuide.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 0e9b25e7bd..59201d4e44 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -282,32 +282,28 @@ Classify serves as an attempt to modernise administrative tasks in education ins ### Viewing a student's details 1. View a student who has been added to the student list 1. Prerequisites: Add one student named `joe` to the list with the `add` command - 2. Test case: `view joe` -
+ 2. Test case: `view joe`
Expected: Student's details shown correspond to the details input when `add` was used to add a student. ### Deleting a student from the student list 1. Deleting a student that exists in the student list 1. Prerequisites: Add one student named `joe` to the list with the `add` command - 2. Test case: `delete joe` + 2. Test case: `delete joe`
Expected: `view joe` shows Student not found! -
`list` followed by enter, enter again, and `1` which displays a list of all students, does not show any student named `joe`. ### Displaying a list of students 1. Listing all students enrolled in the tuition centre 1. Prerequisites: Have at least one student added to the list with the `add` command - 2. Test case: `list`, enter, enter, `1` + 2. Test case: `list`, enter, enter, `1`
Expected: A list of all students that are enrolled in the tuition centre is printed.
-
2. Listing all students with a specific subject in the tuition centre 1. Prerequisites: Have at least one student with the subject `Math` added to the list with the `add` command - 2. Test case: `list`, `Math` + 2. Test case: `list`, `Math`
Expected: A list of all the students with the subject `Math` in the tuition centre is printed.
-
3. Listing all students that have been deleted in the current session 1. Prerequisites: Delete at least one student in the list with the `delete` command - 2. Test case: `list`, enter, enter, `5` + 2. Test case: `list`, enter, enter, `5`
Expected: A list of all students that have been deleted in the current session is printed. \ No newline at end of file From 23aa51b7069c5f324b9e5a25831df84b63779996 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 12 Apr 2024 19:25:21 +0800 Subject: [PATCH 369/503] Change StudentSorter image --- .../src/StudentSorter/StudentSorter.png | Bin 46287 -> 36254 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/diagrams/src/StudentSorter/StudentSorter.png b/docs/diagrams/src/StudentSorter/StudentSorter.png index 42aa526b2ec02ec3d50de50d65e4b989e8ecced0..e0efc041cbde5160dccd925c73f1afde5da54a9e 100644 GIT binary patch literal 36254 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 SS_Awi+dlOJYKc27&;LKZ8FT*t literal 46287 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 Hr>^~9UHR4> From ac848507815785c8d7bde3e098d794cef50afa97 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 12 Apr 2024 19:57:49 +0800 Subject: [PATCH 370/503] Fix newlines and add restore instructions for manual testing --- docs/DeveloperGuide.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 59201d4e44..951388fdd3 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -288,8 +288,8 @@ Classify serves as an attempt to modernise administrative tasks in education ins ### Deleting a student from the student list 1. Deleting a student that exists in the student list 1. Prerequisites: Add one student named `joe` to the list with the `add` command - 2. Test case: `delete joe`
- Expected: `view joe` shows Student not found! + 2. Test case: `delete joe`
+ Expected: `view joe` shows Student not found!
`list` followed by enter, enter again, and `1` which displays a list of all students, does not show any student named `joe`. ### Displaying a list of students @@ -306,4 +306,12 @@ Classify serves as an attempt to modernise administrative tasks in education ins 3. Listing all students that have been deleted in the current session 1. Prerequisites: Delete at least one student in the list with the `delete` command 2. Test case: `list`, enter, enter, `5`
- Expected: A list of all students that have been deleted in the current session is printed. \ No newline at end of file + Expected: A list of all students that have been deleted in the current session is printed. + +### Restoring a recently deleted student +1. Restore a student from the recently deleted list + 1. Prerequisites: Have at least one student named `joe` deleted in the current session with the `delete joe` command + 2. Test case: `restore joe`
+ Expected: `view joe` will display the attributes that `joe` had before being deleted.
+ `joe` will be shown in any lists that specify attributes they possess. + \ No newline at end of file From 9eb8550591493a06a404ec8aa1d5c4360feb7e4d Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 12 Apr 2024 20:13:09 +0800 Subject: [PATCH 371/503] Add undo instructions for manual testing --- docs/DeveloperGuide.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 951388fdd3..c2c47e8028 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -314,4 +314,10 @@ Classify serves as an attempt to modernise administrative tasks in education ins 2. Test case: `restore joe`
Expected: `view joe` will display the attributes that `joe` had before being deleted.
`joe` will be shown in any lists that specify attributes they possess. - \ No newline at end of file + +### Undoing the latest deletion +1. Undo two deletes successively + 1. Prerequisites: Have at least two students deleted in the current session with the `delete` command + 2. Test case: `undo`, then `undo` again
+ Expected: `undo` will restore the latest deletion, the second `undo` will restore the first deletion. + From bd7e3d6f504b2faf5a624d4447ae8cebfda2ccdf Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 12 Apr 2024 20:52:34 +0800 Subject: [PATCH 372/503] Change UG intro --- docs/UserGuide.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index a19a29e673..09a227606b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -44,7 +44,7 @@ These systems enable tutors and administrative staff to focus on more pressing i Classify is a student management system meant to assist administrative staff of private tuition centres. -The product is capable of storing students, and generating outputs based on provided parameters, such as grade improvements and payment statuses. +The product is capable of storing students, and generating outputs based on provided parameters, such as phone number, or subjects taken. Within our program, a student can be stored with their - Subjects taken @@ -54,7 +54,7 @@ Within our program, a student can be stored with their - Last Payment Date - Remarks -We have determined these to be the attributes important to running a working tuition centre. Based on these attributes, our program also has functions to sort students based on grades, subjects, improvements since joining the centre. +We have determined these to be the attributes important to running a working tuition centre. Based on these attributes, our program also has functions to sort students based on subjects taken. --- @@ -68,6 +68,7 @@ We have determined these to be the attributes important to running a working tui java -jar ./Classify.jar ``` 5. Run the command ```help``` within the program to get a quick view of the available commands. + ---
From 989aee050038fef7aecc5f29df118fac5ade89ac Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 12 Apr 2024 21:20:14 +0800 Subject: [PATCH 373/503] Change classes attended message --- docs/UserGuide.md | 2 +- src/main/java/classify/ui/UI.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 09a227606b..db2bd6de24 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -158,7 +158,7 @@ Exits the program. # Usage -:exclamation: **Please note that if any of the following characters are entered in any string prompts, `#, - and ~`, they will be replaced and your command may be deemed invalid.**:exclamation: +**Please note that if any of the following characters are entered in any string prompts, `#, - and ~`, they will be replaced and your command may be deemed invalid.** ### Adding a student: `add` Initialises an interface for adding a student and their relevant details to the database. Allows the user to do add or add [name] diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 217e96386b..80feef3846 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -50,7 +50,7 @@ public class UI { private static final String STUDENT_NAME_PROMPT = "Enter student name: "; private static final String STUDENT_DETAILS_MESSAGE = "Student details: "; private static final String STUDENT_NAME_MESSAGE = "Name: "; - private static final String CLASSES_ATTENDED_PROMPT = "Enter Classes Attended (blank to skip): "; + private static final String CLASSES_ATTENDED_PROMPT = "Enter Classes Attended for said subject (blank to skip): "; private static final String CLASSES_ATTENDED_MESSAGE = "Classes Attended: "; private static final String STUDENT_NOT_FOUND_MESSAGE = "No student found!"; private static final String STUDENT_ADDED_MESSAGE = "Student added successfully!"; From d7f4a8139292943e8e46e4cd4d52d06bb2954cef Mon Sep 17 00:00:00 2001 From: shui <78994143+blackmirag3@users.noreply.github.com> Date: Fri, 12 Apr 2024 22:10:03 +0800 Subject: [PATCH 374/503] Add edit manual testing cases for DG --- docs/DeveloperGuide.md | 117 +++++++++++++++++++++++++++++++++++------ 1 file changed, 101 insertions(+), 16 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index c559ce65e5..02f53ae6cc 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -268,20 +268,105 @@ Classify serves as an attempt to modernise administrative tasks in education ins ## Instructions for manual testing ### Adding a student to the student list -1. Adding a student with a name and phone number only - 1. Prerequisites: View if a student with the name 'joe' exists by using the `view joe` command. - 2. Test case: `add joe` and when prompted for phone number enter `11111111`, while pressing enter to skip other optional fields. -
- Expected: `view joe` now shows the Student details of a student with Name: joe, Phone Number: 11111111. Other fields that were left blank will reflect 'Unknown' or for date fields, today's date. - 3. Test case: `add` and when prompted for Name, `joe`. `11111111` when prompted for phone number, press enter to skip other fields. -
- Expected: `view joe` shows the same results as when a student was added via `add joe`. +#### 1. Adding a student with a name and phone number only: +1. Prerequisites: View if a student with the name 'joe' exists by using the `view joe` command. +2. Test case: `add joe` and when prompted for phone number enter `11111111`, while pressing enter to skip other optional fields. +
+Expected: `view joe` now shows the Student details of a student with Name: joe, Phone Number: 11111111. Other fields that were left blank will reflect 'Unknown' or for date fields, today's date. +3. Test case: `add` and when prompted for Name, `joe`. `11111111` when prompted for phone number, press enter to skip other fields. +
+Expected: `view joe` shows the same results as when a student was added via `add joe`. + ### Viewing a student's details -1. View a student who has been added to the student list - 1. Prerequisites: Add one student named 'joe' to the list with the `add` command - 2. Test case: `view joe` -
- Expected: Student's details shown correspond to the details input when `add` was used to add a student. - 3. Test case: `view dogman` -
- Expected: No details are displayed, an error message stating 'Student not found!' is shown. \ No newline at end of file +#### 1. View a student who has been added to the student list: +1. Prerequisites: Add one student named 'joe' to the list with the `add` command +2. Test case: `view joe` +
+Expected: Student's details shown correspond to the details input when `add` was used to add a student. +3. Test case: `view dogman` +
+Expected: No details are displayed, an error message stating 'Student not found!' is shown. + +### Editing a student's details +#### 1. Entering edit mode for an existing student: +1. Prerequisites: Add student named 'tim' to the student list with the `add` command. +2. Test Case: `edit`, `tim` +
Expected: Name will be prompted first, then edit mode will be initiated for student 'tim'. +3. Test Case: `edit tim` +
Expected: Edit mode will be initiated for student 'tim'. + +#### 2. Adding single or multiple subjects to an existing student +1. Prerequisites: Add student 'tim' and initiate edit mode for 'tim'. +2. Test Case: `1`, `CS2113`, `11`, `1`, `no` +
Expected: 'tim' has subject 'CS2112' with marks '11' and '1' class attended. +3. Test Case: `1`, `CS2030`, ` `, ` `, `yes`, `CS2040`, ` `, ` `, `no` +
Expected: 'tim' has subjects 'CS2030' and 'CS2040' with no marks and attendance. +4. Test Case: `1`, ` ` +
Expected: Returns to edit mode for 'tim' and no change in subjects is made for 'tim'. + +#### 3. Modifying existing subject under existing student +1. Prerequisites: Add student 'tim' with subject 'CS2113' and initiate edit mode for 'tim'. +2. Test Case: `2`, `CS2113`, `CS3223`, `2`, `0` +
Expected: Returns to edit mode for 'tim' and 'tim' now has subject 'CS3223' with '2' marks and '0' classes attended. +3. Test Case: `2`, ` ` +
Expected: Returns to edit mode for 'tim' and no change in subjects is made for 'tim'. + +#### 4. Deleting existing subject under existing student +1. Prerequisites: Add student 'tim' with subject 'CS2113' and initiate edit mode for 'tim'. +2. Test Case: `3`, `CS2113` +
Expected: Returns to edit mode for 'tim', subject 'CS2113' is deleted and 'tim' now has no subjects. +3. Test Case: `3`, ` ` +
Expected: Returns to edit mode for 'tim' and no change in subjects is made for 'tim'. + +#### 5. Modify existing phone number under existing student +1. Prerequisites: Add student 'tim' with phone number '88888888' and initiate edit mode for 'tim'. +2. Test Case: `4`, `88888887` +
Expected: Returns to edit mode for 'tim' and phone number for 'tim' is now '88888887'. +3. Test Case: `4`, ` ` +
Expected: Returns to edit mode for 'tim' and no change in phone number is made for 'tim'. +4. Test Case: `4`, `lol` +
Expected: Returns to edit mode for 'tim' and no change in phone number is made for 'tim'. + +#### 6. Modify remarks under existing student +1. Prerequisites: Add student 'tim' and initiate edit mode for 'tim'. +2. Test Case: `5`, `deans list material` +
Expected: Returns to edit mode for 'tim' and remarks for 'tim' is now 'deans list material'. +3. Test Case: `5`, ` ` +
Expected: Returns to edit mode for 'tim' and no change in remarks is made for 'tim'. + +#### 7. Modify payment date under existing student +1. Prerequisites: Add student 'tim' and initiate edit mode for 'tim'. +2. Test Case: `6`, ` ` +
Expected: Returns to edit mode for 'tim' and payment date for 'tim' is system's current date in YYYY-MM-DD format. +3. Test Case: `6`, `2000-11-20` +
Expected: Returns to edit mode for 'tim' and payment date for 'tim' is now '2000-11-20'. +4. +#### 8. Modify gender under existing student +1. Prerequisites: Add student 'tim' and initiate edit mode for 'tim'. +2. Test Case: `7`, `undefined` +
Expected: Returns to edit mode for 'tim' and gender for 'tim' is now 'undefined'. +3. Test Case: `7`, ` ` +
Expected: Returns to edit mode for 'tim' and no change in remarks is made for 'tim'. + +#### 9. Editing student in empty list +1. Prerequisites: Have empty list with no students added. +2. Test Case: `edit` +
Expected: Error message for empty list will be printed. + +#### 10. Editing non-existing student in non-empty list +1. Prerequisites: Add student `tim` +2. Test Case: `edit john` +
Expected: Error message for non-existed student will be printed. + +#### 11. Invalid entries for editing student +1. Prerequisites: Add student 'tim' with subjects 'CS2113', 'CS2040' and phone number '88888888' and initiate edit mode for 'tim'. +2. Test Case: `1`, `cs2113` +
Expected: Returns to edit mode for 'tim', no new subject added and error message printed for adding existing subject. +3. Test Case: `2`, `CS2113`, `CS2040` +
Expected: Prints error message for existing subject and new subject name is prompted to update 'CS2113'. +4. Test Case: `3`, `CG2023` +
Expected: Prints error message for no subject found and prompts for another subject name to delete. +5. Test Case: `4`, `11111111` +
Expected: Prints invalid phone number error message and prompts for another phone number. +6. Test Case: `6`, `20 jan 2001` +
Expected: Prints error message for invalid date and prompts for another date. From 01fedfe26af1c2b9363048d1f2bab001747426b6 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 12 Apr 2024 22:12:06 +0800 Subject: [PATCH 375/503] Fix file writing bug --- docs/UserGuide.md | 19 +--------------- src/main/java/classify/Classify.java | 2 ++ .../java/classify/commands/AddStudent.java | 3 +-- .../java/classify/commands/EditStudent.java | 1 - .../commands/ListStudentsCommand.java | 4 +++- src/main/java/classify/data/DataReader.java | 12 ++++++++-- .../classify/textfilecode/TextFileParser.java | 2 ++ .../classify/textfilecode/TextFileReader.java | 22 ++++++++++--------- src/main/java/classify/user/InputParsing.java | 1 - .../user/InvalidPhoneNumberException.java | 10 +++++++++ 10 files changed, 41 insertions(+), 35 deletions(-) create mode 100644 src/main/java/classify/user/InvalidPhoneNumberException.java diff --git a/docs/UserGuide.md b/docs/UserGuide.md index db2bd6de24..860411f500 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -68,6 +68,7 @@ We have determined these to be the attributes important to running a working tui java -jar ./Classify.jar ``` 5. Run the command ```help``` within the program to get a quick view of the available commands. +6. Please do not edit the save files Student_Information.txt or student_archive.txt . ---
@@ -345,24 +346,6 @@ What else can I do for you today? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` -### Delete a student from the working list `delete` -Deletes the student from the list. Allows the user to do delete [student] or just delete. - -Format: `delete` or `delete NAME` - -Depending on whether the user entered the student's name or not during the command, -a field will be printed out in the terminal, awaiting a user input. - -#### Example usage: -``` -delete - -Enter student name: -wario -Student removed successfully! -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``` - ### Restore a student to the working list `restore` Restores a student deleted in the current session. Allows the user to do restore [student] or just restore. diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 5a777e6780..7a0d66d79f 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -40,6 +40,8 @@ public static void main(String[] args) throws IOException { StudentList.archiveList, in); UI.printSubsequentUserPrompt(); userCommand = UserInput.processInput(in.nextLine()); + DataHandler.writeStudentInfo(); + DataHandler.writeArchive(StudentList.archiveList); } UI.printEndConversation(); diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index dfc13e9188..93fc40aa96 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -57,7 +57,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, try { number = InputParsing.promptForPhoneNumber(in); } catch (NumberFormatException e) { - UI.println("Non-number or blank character found."); + UI.println("Non-number, invalid number or blank character found."); UI.println("Exiting the adding interface."); UI.printDivider(); return; @@ -98,7 +98,6 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, LOGGER.log(Level.INFO, STUDENT_ADDED_SUCCESSFULLY); UI.printStudentAdded(); UI.printDivider(); - DataHandler.writeStudentInfo(masterStudentList); } /** diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index 7399bcd57f..5d3dae95d3 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -106,7 +106,6 @@ private static void editStudentDetails(Scanner in, Student student) { UI.printDivider(); break; } - DataHandler.writeStudentInfo(); } } diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index f323322538..7d9ec82a4c 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -200,6 +200,7 @@ static void listStudentsWithTotalClasses(ArrayList masterStudentList) { * @param masterStudentList The list of all students. */ public static void listStudentsWithPhoneNumbers(ArrayList masterStudentList) { + int i = 1; for (Student student : masterStudentList) { int phoneNumber = student.getAttributes().getPhoneNumber(); @@ -210,6 +211,7 @@ public static void listStudentsWithPhoneNumbers(ArrayList masterStudent } i++; } + } /** @@ -219,7 +221,7 @@ public static void listStudentsWithPhoneNumbers(ArrayList masterStudent * @return true if the phone number is valid, false otherwise. */ private static boolean isValidPhoneNumber(int phoneNumber) { - return (phoneNumber >= 80000000 && phoneNumber <= 99999999); + return phoneNumber >= 80000000 && phoneNumber <= 99999999; } } diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index c72c48b276..84c99d6632 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -69,8 +69,16 @@ public static void restoreStudentList(String studentFileInput, ArrayList mas case PROCESS_FILE: TextFileHandler.process(masterStudentList, in); - DataHandler.writeStudentInfo(masterStudentList); break; //@@ author tayponghee diff --git a/src/main/java/classify/user/InvalidPhoneNumberException.java b/src/main/java/classify/user/InvalidPhoneNumberException.java new file mode 100644 index 0000000000..9bbdacfa4b --- /dev/null +++ b/src/main/java/classify/user/InvalidPhoneNumberException.java @@ -0,0 +1,10 @@ +package classify.user; + +public class InvalidPhoneNumberException extends Exception{ + + public InvalidPhoneNumberException() { + super(); + System.out.println("Invalid Phone number found."); + } + +} From 0e83e28834b96cb5c75c6426200f3272232bf882 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 12 Apr 2024 22:15:03 +0800 Subject: [PATCH 376/503] Add phone number checks to save files. --- src/main/java/classify/data/DataReader.java | 10 +++++----- .../java/classify/textfilecode/TextFileParser.java | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 84c99d6632..d7fe7908d1 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -70,14 +70,14 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Fri, 12 Apr 2024 22:26:54 +0800 Subject: [PATCH 377/503] Fix user guide (process) --- docs/UserGuide.md | 31 +++++++++++++++---- src/main/java/classify/user/InputParsing.java | 2 +- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 860411f500..77a8d65119 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -501,7 +501,7 @@ fields will be printed out in the terminal, awaiting a user input each time. ``` sort Sort by: (Choose index) -1. Name (A to Z) +1. Name (A to Z): 2. Total number of classes attended: 3. Date of last fee payment: 1 @@ -525,13 +525,32 @@ Sort complete! ### Process a list of students from a text file `process` Reads a text file in the inputFolder folder located inside the data folder. -:exclamation: The text file which is being processed **MUST** follow the format shown here[insert stuff here]. +The text file which is being processed **MUST** follow the format shown here[insert stuff here]. -Format: `process`, press enter, `filename` (without filetype) **or** `filename.txt` (with filetype) +Format: `process`, press enter, `filename` (without filetype) **or** `filename.txt` (with file extension) The processed file will add the students into the masterStudentList with relevant attributes for subject name, grades, and classes attended. -:exclamation: All other student attributes (eg. gender, phone number, remarks, etc) must be updated by the user. +All other student attributes (eg. gender, phone number, remarks, etc) must be updated by the user. + +Please make sure that the proper format for the input file is followed. + +``` +Subject: SUBJECT +Classes Attended: INTEGER +NAME ~~ NUMBER ~~ GRADE +``` + +An example is seen below: +``` +Subject: Math +Classes Attended: 10 +parth ~~ 98989898 ~~ 90.0 +pong hee ~~ 98989888 ~~ 95.0 +Yi xin ~~ 98988888 ~~ 98.0 +gerard ~~ 98888888 ~~ 95.0 +shui hon ~~ 91231234 ~~ 99.0 +``` #### Without Filetype: ``` @@ -565,7 +584,7 @@ Data update success! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` ### Move a student from the master list to the archive `archive` -Adds a student to the archive and deletes them from the master list. Allows the user to do archive [name] or just archive. +Adds a student to the archive and removes them from the master list. Format: `archive`, `archive NAME` @@ -593,7 +612,7 @@ Data update success! The user can then view currently archived students using the `list` command. ### Move a student from the archive back to the master list `unarchive` -Removes a student from the archive and adds them back to the master list. Allows the user to do unarchive [name] or just unarchive. +Removes a student from the archive and adds them back to the master list. Format: `unarchive`, `unarchive NAME` diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index f99778e7f3..370ba96669 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -43,7 +43,7 @@ public class InputParsing { private static final String EXITED_THE_COMMAND = "Exited the command."; private static final String LIST_SORTED = "Sort complete!"; private static final String SORT_BY_CHOOSE_INDEX = "Sort by: (Choose index)"; - private static final String NAME_A_TO_Z = "1. Name (A to Z)"; + private static final String NAME_A_TO_Z = "1. Name (A to Z):"; private static final String TOTAL_NUMBER_OF_CLASSES_ATTENDED = "2. Total number of classes attended:"; private static final String LAST_PAID_DATE = "3. Date of last fee payment: "; private static final int NUMBER_TOO_SMALL = 80000000; From c9a69a31278bea9d2f7d6ac614b3c989ed1fcc2d Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 12 Apr 2024 22:34:29 +0800 Subject: [PATCH 378/503] Fix sort infinite loop --- src/main/java/classify/textfilecode/TextFileParser.java | 3 +-- src/main/java/classify/user/InputParsing.java | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index 69f45df20c..b1774588e2 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -86,8 +86,7 @@ public static void parseUserSelection(File currentDirectory, Scanner in, ArrayLi if (matchIndex == -1){ System.out.println(NO_MATCH_FOUND); - promptForFileSelectionAgain(); - parseUserSelection(TextFileHandler.CURRENT_DIRECTORY, in, masterStudentList); + System.out.println("Exiting interface"); return; } parseTextFile(fileList, matchIndex, masterStudentList); diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index 370ba96669..fe76856404 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -174,7 +174,7 @@ private static void sortStudents(ArrayList masterStudentList, Scanner i //@@author tayponghee // input = in.nextLine().trim(); - if (input.equalsIgnoreCase(EXIT)) { + if (input.equalsIgnoreCase(EXIT) || input.isBlank()) { System.out.println(EXITED_THE_COMMAND); UI.printDivider(); return; From ed391d1c8060bf73e5830b73aa4afe3b387864dc Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 12 Apr 2024 23:02:25 +0800 Subject: [PATCH 379/503] Fix tests and printing messages --- docs/DeveloperGuide.md | 10 +++---- docs/UserGuide.md | 27 +++++-------------- src/main/java/classify/Classify.java | 10 +++---- .../java/classify/commands/AddStudent.java | 1 - .../classify/commands/ArchiveCommands.java | 6 ++--- .../java/classify/commands/EditStudent.java | 1 - src/main/java/classify/data/DataWriter.java | 4 --- src/main/java/classify/ui/UI.java | 6 ++--- src/main/java/classify/user/InputParsing.java | 1 - .../java/classify/user/InputParsingTest.java | 6 +---- 10 files changed, 18 insertions(+), 54 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index c559ce65e5..e939dd00fc 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -34,7 +34,7 @@ This component ensures that the user parses in commands in a format that makes s ![InputParsingUML](./diagrams/src/InputParsing/InputParsing.png) #### Design considerations -- The parser must be effecive in breaking down the user's input into its constitutent commands, with further breakdown if an associated argument is added. +- The parser must be effective in breaking down the user's input into its constituent commands, with further breakdown if an associated argument is added. - The parser should be quick and effective in understanding the user's input, with simple prompts given to help the user in correctly parsing the command through the input parser. - Allowing the user to input optional arguments. For example, the user could type `view `, which takes in the "student name" as an optional argument. This is to increase the robustness of the program, which accounts for the two types of users, one who just types in `view`, and the other as formerly mentioned above. - Error handling must be intuitive for the user, so that appropriate error messages are produced if the user does not input a valid command. The error handling should also be robust, to account for the event a user is incapable in following instructions. @@ -122,17 +122,13 @@ The two text files are will be created under a directory called data, in which t #### Design Considerations -In order to ensure the proper usage of OOP principles (such as encapsulation), we have segregated the 3 classes to read,store and handle the data. +In order to ensure the proper usage of OOP principles (such as encapsulation), we have segregated the 3 classes to read, store and handle the data. -Moreover, the regex used to separate the different types of data in the file type have been chosen in a way which would not affect normal user operation needs. If the user chooses to use the banned characters, the input parser would replace them, as shown below: +Moreover, the regex used to separate the different types of data in the file type have been chosen in a way which would not affect normal user operation needs. If the user chooses to use the banned characters, the input parser would reject the input. Banned characters: `#`,`~` and `-` -- `#` changes to ` `. -- `~` changes to ` `. -- `-` changes to `_`. - This will prevent the user from messing with the way the program reads and writes to the text files, preventing corruption of the database due to improper usage. #### Implementation and Rationale diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 77a8d65119..6aca1475e4 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -533,7 +533,9 @@ The processed file will add the students into the masterStudentList with relevan All other student attributes (eg. gender, phone number, remarks, etc) must be updated by the user. -Please make sure that the proper format for the input file is followed. +Please make sure that the proper format for the input file is followed. Only one subject and class attended value should be present per text file. Otherwise, the program will read in the first subject and class attended, and apply it to all students present in the text file. + +Any students with missing or invalid grades or phone number will be skipped. ``` Subject: SUBJECT @@ -562,9 +564,6 @@ Current Files in your Input Folder: Please enter the exact name of the file you'd like to process: mathclass Fetching the data from mathclass.txt. -Analysing Inputs... -Directory loaded successfully! -Data update success! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` @@ -578,9 +577,6 @@ Current Files in your Input Folder: Please enter the exact name of the file you'd like to process: scienceclass.txt Fetching the data from scienceclass.txt. -Analysing Inputs... -Directory loaded successfully! -Data update success! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` ### Move a student from the master list to the archive `archive` @@ -597,15 +593,10 @@ For any archived student, the user will be unable to add a student with the same #### Example usage: ``` archive wario -Archive List: -Analysing Inputs... -Directory loaded successfully! -Data update success! +Archive successful. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Runtime Database: -Analysing Inputs... -Directory loaded successfully! -Data update success! + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` @@ -625,15 +616,9 @@ The user can then view currently archived students using the `list` command. ``` unarchive wario -Archive List: -Analysing Inputs... -Directory loaded successfully! -Data update success! +Unarchive successful. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Runtime List: -Analysing Inputs... -Directory loaded successfully! -Data update success! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 7a0d66d79f..65c5765291 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -29,21 +29,17 @@ public static void main(String[] args) throws IOException { UI.printWelcomeMessage(); // Takes in input from the user, and processes input to determine if it contains a command and a name - String[] userCommand; - - userCommand = UserInput.processInput(in.nextLine()); + String[] userCommand = null; // Set up polling for the first word input by the user. // If user's first word is "bye", will exit the while loop. while (userCommand == null || !(userCommand[0].equals("bye"))){ - InputParsing.parseUserCommand(userCommand, StudentList.masterStudentList, StudentList.recentlyDeletedList, - StudentList.archiveList, in); UI.printSubsequentUserPrompt(); userCommand = UserInput.processInput(in.nextLine()); + InputParsing.parseUserCommand(userCommand, StudentList.masterStudentList, StudentList.recentlyDeletedList, + StudentList.archiveList, in); DataHandler.writeStudentInfo(); DataHandler.writeArchive(StudentList.archiveList); } - - UI.printEndConversation(); } } diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 93fc40aa96..b02e4ca26a 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -1,7 +1,6 @@ package classify.commands; -import classify.data.DataHandler; import classify.student.Student; import classify.student.StudentAttributes; import classify.student.StudentList; diff --git a/src/main/java/classify/commands/ArchiveCommands.java b/src/main/java/classify/commands/ArchiveCommands.java index 0000a987f8..64362a6a81 100644 --- a/src/main/java/classify/commands/ArchiveCommands.java +++ b/src/main/java/classify/commands/ArchiveCommands.java @@ -45,9 +45,8 @@ public static void unarchiveStudent(ArrayList masterList, ArrayList masterList, ArrayList list, String folderPath, for (Student student:list){ lines.add(student.textFileInputString()); } - DataUI.printAnalysingInput(); try { createParentFileFolder(folderPath); @@ -38,8 +37,6 @@ public static void writeStudentInfoFile(List list, String folderPath, for (String line : lines){ studentInfoWriter.write(line + NEWLINE); } - DataUI.printUpdateSuccess(); - UI.printDivider(); studentInfoWriter.close(); } catch (IOException e){ DataUI.printFileIOError(); @@ -55,7 +52,6 @@ public static void createParentFileFolder(String parentPath) { try{ Path path = Paths.get(parentPath); Files.createDirectories(path); - DataUI.printDirectorySuccess(); } catch (FileAlreadyExistsException ignored){ //Ignore this error as this should not cause any issues, we dont want replicas of the same file } catch (IOException e){ diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 80feef3846..831919fc1f 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -254,7 +254,7 @@ public static void printClassesAttendedPrompt() { /*** * Print attendance count - * @param attendance int containing attendance count + * @param attendance integer representing attendance count */ public static void printClassesAttended(int attendance) { System.out.println(CLASSES_ATTENDED_MESSAGE + attendance); @@ -325,7 +325,7 @@ public static void printStudentList(ArrayList students) { System.out.println((i + 1) + ". " + students.get(i).getName()); } System.out.println("Currently, there are " + students.size() + " students in the list."); - System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); + UI.printDivider(); } //@@author Cryolian @@ -397,7 +397,7 @@ public static void printTotalClassesAttended(int classes) { System.out.println(TOTAL_CLASSES_ATTENDED_ACROSS_ALL_SUBJECTS + classes); } - public static void println (String text) { + public static void println(String text) { System.out.println(text); } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index fe76856404..fdd944a7b0 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -98,7 +98,6 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas //@@author ParthGandhiNUS case BYE: UI.printEndConversation(); - DataHandler.writeStudentInfo(masterStudentList); break; case LIST: diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index 5a32f91453..b1e25b0f6d 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -34,11 +34,7 @@ public void testByeCommand() { String printedOutput = outputStream.toString().trim(); String expectedOutput = "Hope you've had a productive day. See you again! Goodbye!" + - System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" - + System.lineSeparator() + "Analysing Inputs..." - + System.lineSeparator() + "Directory loaded successfully!" + System.lineSeparator() - + "Data update success!" + System.lineSeparator() - + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; assertEquals(expectedOutput.trim(), printedOutput); } From 137b8359765c74e90758f25cfc549b278127a93d Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 12 Apr 2024 23:04:59 +0800 Subject: [PATCH 380/503] Fix parth's poopoo brackets --- src/main/java/classify/Classify.java | 2 +- .../java/classify/commands/EditStudent.java | 2 +- .../commands/ListStudentsCommand.java | 2 +- src/main/java/classify/data/DataHandler.java | 2 +- src/main/java/classify/data/DataReader.java | 8 ++--- src/main/java/classify/data/DataWriter.java | 12 +++---- src/main/java/classify/student/Student.java | 10 +++--- .../textfilecode/TextFileHandler.java | 6 ++-- .../classify/textfilecode/TextFileParser.java | 34 +++++++++---------- .../classify/textfilecode/TextFileReader.java | 10 +++--- src/main/java/classify/ui/UI.java | 2 +- .../textfilecode/TextFileParserTest.java | 18 +++++----- 12 files changed, 54 insertions(+), 54 deletions(-) diff --git a/src/main/java/classify/Classify.java b/src/main/java/classify/Classify.java index 65c5765291..611e6f5bab 100644 --- a/src/main/java/classify/Classify.java +++ b/src/main/java/classify/Classify.java @@ -33,7 +33,7 @@ public static void main(String[] args) throws IOException { // Set up polling for the first word input by the user. // If user's first word is "bye", will exit the while loop. - while (userCommand == null || !(userCommand[0].equals("bye"))){ + while (userCommand == null || !(userCommand[0].equals("bye"))) { UI.printSubsequentUserPrompt(); userCommand = UserInput.processInput(in.nextLine()); InputParsing.parseUserCommand(userCommand, StudentList.masterStudentList, StudentList.recentlyDeletedList, diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index 03feb6e6f9..187e515bfe 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -198,7 +198,7 @@ private static void openNumberEditInterface(Scanner in, StudentAttributes attrib UI.println("Type in and enter the letter a if you wish to stop editing."); int number = InputParsing.promptForPhoneNumber(in); //@@author ParthGandhiNUS - if (number != attributes.getPhoneNumber()){ + if (number != attributes.getPhoneNumber()) { StudentList.checkNameNumberPair(StudentList.masterStudentList, attributes.getName(), number); StudentList.checkNameNumberPair(StudentList.recentlyDeletedList, attributes.getName(), number); StudentList.checkNameNumberPair(StudentList.archiveList, attributes.getName(), number); diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 7d9ec82a4c..6835f3ae11 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -96,7 +96,7 @@ private static int getClassesAttendedForSubject(Student student, String subject) for (SubjectGrade subjectGrade : subjectGrades) { if (subjectGrade.getSubject().equalsIgnoreCase(subject)) { - if (subjectGrade.getClassesAttended() >= 0){ + if (subjectGrade.getClassesAttended() >= 0) { classesAttended += subjectGrade.getClassesAttended(); } else { classesAttended = -1; diff --git a/src/main/java/classify/data/DataHandler.java b/src/main/java/classify/data/DataHandler.java index 00695d0ae6..84135dc14c 100644 --- a/src/main/java/classify/data/DataHandler.java +++ b/src/main/java/classify/data/DataHandler.java @@ -55,7 +55,7 @@ public static void readStudentInfo(ArrayList list) throws IOException{ * * @param list ArrayList containing the current students to write */ - public static void writeArchive(List list){ + public static void writeArchive(List list) { DataWriter.writeStudentInfoFile(list, ARCHIVE_DIRECTORY_PATH, ARCHIVE_FILE_PATH); } diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index d7fe7908d1..8f861c198c 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -53,7 +53,7 @@ public class DataReader { * @param studentFileInput Line-by-line information of strings in the Student_Information.txt * @param masterStudentList The list of all students */ - public static void restoreStudentList(String studentFileInput, ArrayList masterStudentList ){ + public static void restoreStudentList(String studentFileInput, ArrayList masterStudentList ) { if (studentFileInput.trim().isBlank()) { return; @@ -75,7 +75,7 @@ public static void restoreStudentList(String studentFileInput, ArrayList list, String folderPath, String filePath){ + public static void writeStudentInfoFile(List list, String folderPath, String filePath) { List lines = new ArrayList<>(); - for (Student student:list){ + for (Student student:list) { lines.add(student.textFileInputString()); } try { createParentFileFolder(folderPath); FileWriter studentInfoWriter = new FileWriter(filePath); - for (String line : lines){ + for (String line : lines) { studentInfoWriter.write(line + NEWLINE); } studentInfoWriter.close(); - } catch (IOException e){ + } catch (IOException e) { DataUI.printFileIOError(); } } @@ -52,9 +52,9 @@ public static void createParentFileFolder(String parentPath) { try{ Path path = Paths.get(parentPath); Files.createDirectories(path); - } catch (FileAlreadyExistsException ignored){ + } catch (FileAlreadyExistsException ignored) { //Ignore this error as this should not cause any issues, we dont want replicas of the same file - } catch (IOException e){ + } catch (IOException e) { DataUI.printCreateFailure(); } } diff --git a/src/main/java/classify/student/Student.java b/src/main/java/classify/student/Student.java index 19b7cfd97d..285f5bac68 100644 --- a/src/main/java/classify/student/Student.java +++ b/src/main/java/classify/student/Student.java @@ -75,20 +75,20 @@ public boolean hasSubject(String subject) { * * @return Returns a String to store all subject attributes associated with a certain student. */ - public String listOfSubjectAttributes(){ + public String listOfSubjectAttributes() { List currentStudent = this.getAttributes().getSubjectGrades(); StringBuilder subjectInfo = new StringBuilder(""); StringBuilder separateSubjectInfo = new StringBuilder(SUBJECTINFOSEPARATOR); StringBuilder separateSubject = new StringBuilder(SUBJECTSEPARATIOR); //Checks for an empty list - if (currentStudent.isEmpty()){ + if (currentStudent.isEmpty()) { return subjectInfo.toString(); } int numberOfSubjects = currentStudent.size(); - for (int i = 0; i < numberOfSubjects ; i++){ + for (int i = 0; i < numberOfSubjects ; i++) { //Subject Name StringBuilder subject = new StringBuilder(currentStudent.get(i).getSubject()); //Grade information @@ -112,7 +112,7 @@ public String listOfSubjectAttributes(){ * @param input an integer which needs to be converted to a StringBuilder Format * @return Stringbuilder format of the double value */ - public static StringBuilder doubleToString(Double input){ + public static StringBuilder doubleToString(Double input) { String outputData = Double.toString(input); StringBuilder output = new StringBuilder(outputData); return output; @@ -124,7 +124,7 @@ public static StringBuilder doubleToString(Double input){ * @param input an integer which needs to be converted to a StringBuilder Format * @return Stringbuilder format of the integer value */ - public static StringBuilder integerToString(Integer input){ + public static StringBuilder integerToString(Integer input) { String outputData = Integer.toString(input); StringBuilder output = new StringBuilder(outputData); return output; diff --git a/src/main/java/classify/textfilecode/TextFileHandler.java b/src/main/java/classify/textfilecode/TextFileHandler.java index 0409ec0300..3061887197 100644 --- a/src/main/java/classify/textfilecode/TextFileHandler.java +++ b/src/main/java/classify/textfilecode/TextFileHandler.java @@ -34,14 +34,14 @@ public static void process(ArrayList masterStudentList, Scanner in) { /** * Used to create the parent folder for a text file for Inputting */ - public static void createTextFileDirectory(String pathString){ + public static void createTextFileDirectory(String pathString) { //Folder Creation if folder not there try{ Path path = Paths.get(pathString); Files.createDirectories(path); - } catch (FileAlreadyExistsException ignored){ + } catch (FileAlreadyExistsException ignored) { //Ignore this error as this should not cause any issues, we don't want replicas of the same file - } catch (IOException e){ + } catch (IOException e) { UI.println(IO_EXCEPTION_MESSAGE_FOR_TEXT_FILE); } catch (InvalidPathException e) { UI.println(INVALID_PATH_MESSAGE); diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index b1774588e2..ab3966480a 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -44,7 +44,7 @@ public class TextFileParser { * @param textFileName Name of the file * @return True or False depending on the filetype of file */ - public static Boolean textFileChecker(String textFileName){ + public static Boolean textFileChecker(String textFileName) { String type = ""; int i = textFileName.lastIndexOf(DOT); if (i >= 0) { @@ -57,14 +57,14 @@ public static Boolean textFileChecker(String textFileName){ /** * Prints the prompt for the user to select valid file */ - public static void promptForFileSelection(){ + public static void promptForFileSelection() { System.out.println(FILE_SELECTION_PROMPT); } /** * Prints the prompt for the user to select valid file after entering a wrong input before. */ - public static void promptForFileSelectionAgain(){ + public static void promptForFileSelectionAgain() { System.out.println(REQUEST_TO_TRY_AGAIN); System.out.println(FILE_SELECTION_PROMPT); } @@ -77,14 +77,14 @@ public static void promptForFileSelectionAgain(){ * @param in Scanner to scan users' inputs * @param masterStudentList StudentList where students will be added. */ - public static void parseUserSelection(File currentDirectory, Scanner in, ArrayList masterStudentList){ + public static void parseUserSelection(File currentDirectory, Scanner in, ArrayList masterStudentList) { File[] fileList = currentDirectory.listFiles(); String userInput = in.nextLine(); assert fileList != null; int matchIndex = findMatchingFile(fileList, userInput); - if (matchIndex == -1){ + if (matchIndex == -1) { System.out.println(NO_MATCH_FOUND); System.out.println("Exiting interface"); return; @@ -101,18 +101,18 @@ public static void parseUserSelection(File currentDirectory, Scanner in, ArrayLi */ private static Integer findMatchingFile(File[] fileList, String userInput) { String input = userInput.toLowerCase().trim(); - for (int i = 0; i < fileList.length; i++){ + for (int i = 0; i < fileList.length; i++) { String fileName = fileList[i].getName().toLowerCase().trim(); int dotIndex = fileName.lastIndexOf(DOT); String fileNameWithoutType = fileName.substring(0,dotIndex); // Return match with the type - if (input.equals(fileName)){ + if (input.equals(fileName)) { return i; } // Return match without the type - if (input.equals(fileNameWithoutType)){ + if (input.equals(fileNameWithoutType)) { return i; } } @@ -126,7 +126,7 @@ private static Integer findMatchingFile(File[] fileList, String userInput) { * @param matchIndex index of the matching file in the list of Files * @param masterStudentList StudentList where students will be added. */ - private static void parseTextFile(File[] fileList, Integer matchIndex, ArrayList masterStudentList){ + private static void parseTextFile(File[] fileList, Integer matchIndex, ArrayList masterStudentList) { String fileNameString = fileList[matchIndex].getName().trim(); String fullFilePath = INPUT_TEXT_FILE_DIRECTORY + "/" + fileNameString; try { @@ -157,7 +157,7 @@ private static void fetchDataFromTextFile(BufferedReader line, ArrayList masterStudentList){ - if (textFileInput.trim().isBlank()){ + Integer classesAttended, ArrayList masterStudentList) { + if (textFileInput.trim().isBlank()) { return; } String [] inputArr = textFileInput.split(MAIN_REGEX); @@ -226,9 +226,9 @@ private static void deconstructTextFile (String textFileInput, String subjectNam private static void masterStudentListAddition(ArrayList masterStudentList, String studentNameString, Student student,int phoneNumber, String subjectName, SubjectGrade newSubject) { - if (matchingNameNumber (masterStudentList, studentNameString, phoneNumber)){ + if (matchingNameNumber (masterStudentList, studentNameString, phoneNumber)) { Integer indexOfStudent = matchingStudentIndex(masterStudentList, studentNameString, phoneNumber); - if (!(matchingSubject(masterStudentList, subjectName, indexOfStudent))){ + if (!(matchingSubject(masterStudentList, subjectName, indexOfStudent))) { masterStudentList.get(indexOfStudent).getAttributes().addSubjectGrade(newSubject); } } else { @@ -246,7 +246,7 @@ private static void masterStudentListAddition(ArrayList masterStudentLi * @param phoneNumber Phone number of the student */ static void addPhoneNumber(String studentNameString, Student student, int phoneNumber) { - if (InputParsing.checkNumberValidity(phoneNumber)){ + if (InputParsing.checkNumberValidity(phoneNumber)) { student.getAttributes().setPhoneNumber(phoneNumber); } else { UI.println(studentNameString + INVALID_PHONE_NUMBER_MESSAGE); @@ -261,7 +261,7 @@ static void addPhoneNumber(String studentNameString, Student student, int phoneN * @param number Phone number of the student to find. * @return Index of the student in masterStudentList */ - static Integer matchingStudentIndex(ArrayList masterStudentList, String name, int number){ + static Integer matchingStudentIndex(ArrayList masterStudentList, String name, int number) { int listSize = masterStudentList.size(); for (int i = 0; i < listSize; i++) { @@ -284,7 +284,7 @@ static Integer matchingStudentIndex(ArrayList masterStudentList, String static boolean matchingSubject(ArrayList masterStudentList, String subjectName, Integer indexOfStudent) { List studentSubjects = masterStudentList.get(indexOfStudent).getAttributes().getSubjectGrades(); - for (SubjectGrade subject : studentSubjects){ + for (SubjectGrade subject : studentSubjects) { if (subject.getSubject().equalsIgnoreCase(subjectName)) { return true; } diff --git a/src/main/java/classify/textfilecode/TextFileReader.java b/src/main/java/classify/textfilecode/TextFileReader.java index 1ed090f9ee..12a9652967 100644 --- a/src/main/java/classify/textfilecode/TextFileReader.java +++ b/src/main/java/classify/textfilecode/TextFileReader.java @@ -9,7 +9,7 @@ public class TextFileReader { * * @param pathnameString String contaning the filepath */ - public static void printCurrentInputFolder(String pathnameString){ + public static void printCurrentInputFolder(String pathnameString) { File currentDirectory = new File (pathnameString); getCurrentFiles(currentDirectory); } @@ -19,10 +19,10 @@ public static void printCurrentInputFolder(String pathnameString){ * * @param currentDirectory File where we are querying for the files */ - private static void getCurrentFiles(File currentDirectory){ + private static void getCurrentFiles(File currentDirectory) { File[] fileList = currentDirectory.listFiles(); - if (fileList.length == 0 || fileList == null){ + if (fileList.length == 0 || fileList == null) { System.out.println("No files in your Input Folder!\n" + "Please add some new files in the correct format!"); return; @@ -31,8 +31,8 @@ private static void getCurrentFiles(File currentDirectory){ assert fileList != null; Integer index = 1; - for (File newFile : fileList){ - if (newFile.isFile() && TextFileParser.textFileChecker(newFile.getName())){ + for (File newFile : fileList) { + if (newFile.isFile() && TextFileParser.textFileChecker(newFile.getName())) { System.out.println(index +". " + newFile.getName()); index++; } diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 831919fc1f..f9fc2c6f8b 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -188,7 +188,7 @@ public static void printEndConversation() { printDivider(); } - public static void printProcessTextFileInputMessage(){ + public static void printProcessTextFileInputMessage() { System.out.println("process " + "Processes a text file containing a list of students taking the same subject and the same number " + "of classes."); diff --git a/src/test/java/classify/textfilecode/TextFileParserTest.java b/src/test/java/classify/textfilecode/TextFileParserTest.java index 4a0d5caa8e..5e38c8d4cf 100644 --- a/src/test/java/classify/textfilecode/TextFileParserTest.java +++ b/src/test/java/classify/textfilecode/TextFileParserTest.java @@ -25,7 +25,7 @@ class TextFileParserTest { " Please edit this students' phone number with the edit command!"; @Test - public void testAddPhoneNumberValidCase(){ + public void testAddPhoneNumberValidCase() { ByteArrayOutputStream outContent = new ByteArrayOutputStream(); System.setOut(new PrintStream(outContent)); @@ -39,7 +39,7 @@ public void testAddPhoneNumberValidCase(){ } @Test - public void testAddPhoneNumberInvalidCase(){ + public void testAddPhoneNumberInvalidCase() { ByteArrayOutputStream outContent = new ByteArrayOutputStream(); System.setOut(new PrintStream(outContent)); @@ -52,7 +52,7 @@ public void testAddPhoneNumberInvalidCase(){ } @Test - public void testMatchingStudentIndexAllTrue(){ + public void testMatchingStudentIndexAllTrue() { ArrayList masterStudentList = new ArrayList<>(); Student student = new Student(JOHN_DOE); masterStudentList.add(student); @@ -64,7 +64,7 @@ public void testMatchingStudentIndexAllTrue(){ } @Test - public void testMatchingStudentIndexWrongNumber(){ + public void testMatchingStudentIndexWrongNumber() { ArrayList masterStudentList = new ArrayList<>(); Student student = new Student(JOHN_DOE); masterStudentList.add(student); @@ -76,7 +76,7 @@ public void testMatchingStudentIndexWrongNumber(){ } @Test - public void testMatchingStudentIndexWrongName(){ + public void testMatchingStudentIndexWrongName() { ArrayList masterStudentList = new ArrayList<>(); Student student = new Student(JOHN_DOE); masterStudentList.add(student); @@ -89,7 +89,7 @@ public void testMatchingStudentIndexWrongName(){ @Test - public void testMatchingSubjectTrueCase(){ + public void testMatchingSubjectTrueCase() { ArrayList masterStudentList = new ArrayList<>(); Student student = new Student(JOHN_DOE); masterStudentList.add(student); @@ -102,7 +102,7 @@ public void testMatchingSubjectTrueCase(){ } @Test - public void testMatchingSubjectFalseCase(){ + public void testMatchingSubjectFalseCase() { ArrayList masterStudentList = new ArrayList<>(); Student student = new Student(JOHN_DOE); masterStudentList.add(student); @@ -115,7 +115,7 @@ public void testMatchingSubjectFalseCase(){ } @Test - public void testMatchingNameNumberTrueCase(){ + public void testMatchingNameNumberTrueCase() { ArrayList masterStudentList = new ArrayList<>(); Student student = new Student(JOHN_DOE); masterStudentList.add(student); @@ -125,7 +125,7 @@ public void testMatchingNameNumberTrueCase(){ } @Test - public void testMatchingNameNumberFalseCase(){ + public void testMatchingNameNumberFalseCase() { ArrayList masterStudentList = new ArrayList<>(); Student student = new Student("Jane Doe"); masterStudentList.add(student); From cbde9201bbf6919ecfac16418c940b0d9e6052b6 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 12 Apr 2024 23:06:08 +0800 Subject: [PATCH 381/503] Clean parth's peepee --- src/main/java/classify/textfilecode/TextFileParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index ab3966480a..4e82646391 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -48,7 +48,7 @@ public static Boolean textFileChecker(String textFileName) { String type = ""; int i = textFileName.lastIndexOf(DOT); if (i >= 0) { - type = textFileName.substring(i+1); + type = textFileName.substring(i + 1); } return type.equals(TEXT_TYPE); From b604f42c33831119903b2f546c5ea3ba3f6b83c3 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 12 Apr 2024 23:08:35 +0800 Subject: [PATCH 382/503] Fix checkstyle errors --- src/main/java/classify/data/DataWriter.java | 1 - src/main/java/classify/user/InputParsing.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/java/classify/data/DataWriter.java b/src/main/java/classify/data/DataWriter.java index edf09a6c99..33f8d539f7 100644 --- a/src/main/java/classify/data/DataWriter.java +++ b/src/main/java/classify/data/DataWriter.java @@ -2,7 +2,6 @@ import classify.student.Student; import classify.ui.DataUI; -import classify.ui.UI; import java.io.FileWriter; import java.io.IOException; diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index fdd944a7b0..c79accb888 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -7,7 +7,6 @@ import classify.commands.ListStudentsCommand; import classify.commands.StudentSorter; import classify.commands.ViewStudent; -import classify.data.DataHandler; import classify.student.Student; import classify.textfilecode.TextFileHandler; import classify.ui.UI; From a7c23e55fb2359a4c2ff5453f3a958e1f6228ba7 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Fri, 12 Apr 2024 23:12:05 +0800 Subject: [PATCH 383/503] Fix spacing --- src/main/java/classify/data/DataWriter.java | 2 +- src/main/java/classify/textfilecode/TextFileHandler.java | 2 +- src/main/java/classify/textfilecode/TextFileParser.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/classify/data/DataWriter.java b/src/main/java/classify/data/DataWriter.java index 33f8d539f7..80d12ad794 100644 --- a/src/main/java/classify/data/DataWriter.java +++ b/src/main/java/classify/data/DataWriter.java @@ -48,7 +48,7 @@ public static void writeStudentInfoFile(List list, String folderPath, * @param parentPath Path file containing the path of folder we want to make the text file in */ public static void createParentFileFolder(String parentPath) { - try{ + try { Path path = Paths.get(parentPath); Files.createDirectories(path); } catch (FileAlreadyExistsException ignored) { diff --git a/src/main/java/classify/textfilecode/TextFileHandler.java b/src/main/java/classify/textfilecode/TextFileHandler.java index 3061887197..cda10f43f5 100644 --- a/src/main/java/classify/textfilecode/TextFileHandler.java +++ b/src/main/java/classify/textfilecode/TextFileHandler.java @@ -36,7 +36,7 @@ public static void process(ArrayList masterStudentList, Scanner in) { */ public static void createTextFileDirectory(String pathString) { //Folder Creation if folder not there - try{ + try { Path path = Paths.get(pathString); Files.createDirectories(path); } catch (FileAlreadyExistsException ignored) { diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index 4e82646391..96324cc901 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -148,7 +148,7 @@ private static void parseTextFile(File[] fileList, Integer matchIndex, ArrayList * @param masterStudentList StudentList where students will be added. */ private static void fetchDataFromTextFile(BufferedReader line, ArrayList masterStudentList) { - try{ + try { String firstLine = line.readLine(); String [] subjectInfoStrings = firstLine.split(SUBJECT_REGEX); String subjectName = subjectInfoStrings[1].trim(); @@ -183,7 +183,7 @@ private static void deconstructTextFile (String textFileInput, String subjectNam String [] inputArr = textFileInput.split(MAIN_REGEX); - try{ + try { //Set Name String studentNameString = AddStudent.splitName(inputArr[NAME].trim()); Student student = new Student(studentNameString); From b6a9ff5db97d65a4e8668983bc9015a0fd206ae3 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 23:23:40 +0800 Subject: [PATCH 384/503] Change name --- src/main/java/classify/commands/AddStudent.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index dfc13e9188..377b24852d 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -19,7 +19,7 @@ //@@author tayponghee public class AddStudent { - private static final String NOTEMPTY = "THIS STRING IS NOT EMPTY"; + private static final String NOT_EMPTY = "THIS STRING IS NOT EMPTY"; private static final String YES = "yes"; private static final String NO = "no"; private static final String SUBJECT_ENTER_NOTHING_TO_SKIP = "Subject (enter nothing to skip): "; @@ -125,7 +125,7 @@ public static String checkForEmptyName(ArrayList masterStudentList, Sca name = in.nextLine().trim(); } else { name = studentName.trim(); - studentName = NOTEMPTY; + studentName = NOT_EMPTY; //@@author tayponghee assert studentName != null; From e7770c9a2888dda134045b5d3f3bf2759d5c554d Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 23:30:52 +0800 Subject: [PATCH 385/503] Refactor addStudent --- src/main/java/classify/commands/AddStudent.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 377b24852d..236d373d27 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -83,6 +83,19 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, return; } + setAttributesForStudent(masterStudentList, in, student, number); + } + + /** + * Sets attributes for a given student, including phone number, gender, last payment date, and remarks. + * + * @param masterStudentList The list of all students. + * @param in The Scanner object for user input. + * @param student The student whose attributes are being set. + * @param number The phone number to set for the student. + */ + private static void setAttributesForStudent(ArrayList masterStudentList, + Scanner in, Student student, int number) { student.getAttributes().setPhoneNumber(number); UI.promptForGender(); From 57c446afaed14a387df125f0cea83600075f7e32 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 23:32:14 +0800 Subject: [PATCH 386/503] Fix author tag --- src/main/java/classify/commands/AddStudent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 236d373d27..acf173cc66 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -271,7 +271,7 @@ public static int promptForClassesAttended(Scanner in) { return -1; } - // @@author ParthGandhiNUS + //@@author ParthGandhiNUS int classesAttended; try { classesAttended = Integer.parseInt(classesAttendedInput); From 26428b8ff35dce4baf115f0c561f0bcf2bec17bd Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Fri, 12 Apr 2024 23:33:30 +0800 Subject: [PATCH 387/503] Make classes for DataHandler, DataReader, and DataWriter --- src/test/java/classify/data/DataHandlerTest.java | 6 ++++++ src/test/java/classify/data/DataReaderTest.java | 6 ++++++ src/test/java/classify/data/DataWriterTest.java | 6 ++++++ 3 files changed, 18 insertions(+) create mode 100644 src/test/java/classify/data/DataHandlerTest.java create mode 100644 src/test/java/classify/data/DataReaderTest.java create mode 100644 src/test/java/classify/data/DataWriterTest.java diff --git a/src/test/java/classify/data/DataHandlerTest.java b/src/test/java/classify/data/DataHandlerTest.java new file mode 100644 index 0000000000..3b80cf6367 --- /dev/null +++ b/src/test/java/classify/data/DataHandlerTest.java @@ -0,0 +1,6 @@ +package classify.data; +//@@author ParthGandhiNUS + +public class DataHandlerTest { + +} diff --git a/src/test/java/classify/data/DataReaderTest.java b/src/test/java/classify/data/DataReaderTest.java new file mode 100644 index 0000000000..9bd403bd61 --- /dev/null +++ b/src/test/java/classify/data/DataReaderTest.java @@ -0,0 +1,6 @@ +package classify.data; +//@@author ParthGandhiNUS + +public class DataReaderTest { + +} diff --git a/src/test/java/classify/data/DataWriterTest.java b/src/test/java/classify/data/DataWriterTest.java new file mode 100644 index 0000000000..14c3aad392 --- /dev/null +++ b/src/test/java/classify/data/DataWriterTest.java @@ -0,0 +1,6 @@ +package classify.data; +//@@author ParthGandhiNUS + +public class DataWriterTest { + +} From c23767698aaf452611537217254cf5ee3b8ef525 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 23:34:22 +0800 Subject: [PATCH 388/503] Refactor UI message --- src/main/java/classify/commands/AddStudent.java | 2 +- src/main/java/classify/ui/UI.java | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index acf173cc66..74396a4020 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -78,7 +78,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, UI.printDivider(); return; } catch (NullPointerException e) { - UI.println("Null pointer thrown. Something went wrong."); + UI.printNullPointerException(); UI.printDivider(); return; } diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 217e96386b..adb9dd8a5a 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -84,6 +84,8 @@ public class UI { private static final String LIST_OF_STUDENTS_WITH_PHONE_NUMBER_SHOWN = "3. List of students with phone number shown"; private static final String STUDENT_NOT_FOUND_CANNOT_BE_DELETED = "Student not found! Cannot be deleted."; + private static final String NULL_POINTER_THROWN_SOMETHING_WENT_WRONG = + "Null pointer thrown. Something went wrong."; //@@author alalal47 /** * Displays the help message to teach users how to use Classify. @@ -450,4 +452,8 @@ public static void printListAllStudentsChoice() { System.out.println(STUDENTS_IN_DELETED); System.out.println(ENTER_ONE_TWO_THREE_FOUR); } + + public static void printNullPointerException() { + System.out.println(NULL_POINTER_THROWN_SOMETHING_WENT_WRONG); + } } From e584aa69e52f0210563e6bde49f94d02c16b81df Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 23:42:58 +0800 Subject: [PATCH 389/503] Change boolean nomenclature --- src/test/java/classify/student/StudentListTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/classify/student/StudentListTest.java b/src/test/java/classify/student/StudentListTest.java index ed7b2d161d..ea2867e2f6 100644 --- a/src/test/java/classify/student/StudentListTest.java +++ b/src/test/java/classify/student/StudentListTest.java @@ -19,18 +19,18 @@ void checkNameNumberPairTest() { studentList.addStudent(alpha); - boolean exceptionThrown = false; + boolean isRightException = false; try { StudentList.checkNameNumberPair(studentList, alpha.getName() , alpha.getPhoneNumber()); } catch (NameNumberMatchException e) { - exceptionThrown = true; + isRightException = true; } catch (NullPointerException e) { - exceptionThrown = false; //wrong exception thrown + isRightException = false; //wrong exception thrown } assertEquals(studentList.studentList.get(0), alpha); - assertTrue(exceptionThrown); + assertTrue(isRightException); } } From 794e908900d3c553170bc673728acd8acc553703 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 23:44:36 +0800 Subject: [PATCH 390/503] Remove unused constant --- src/test/java/classify/commands/EditTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/classify/commands/EditTest.java b/src/test/java/classify/commands/EditTest.java index ceaeb2eddb..e1db462365 100644 --- a/src/test/java/classify/commands/EditTest.java +++ b/src/test/java/classify/commands/EditTest.java @@ -17,7 +17,6 @@ //Integration testing for "edit" implementation within Classify public class EditTest { - private static final String BYE = "bye"; private static ArrayList masterList; ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); From c9b7cb7de53626e9d59bb8079cd8157214317c69 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 23:46:21 +0800 Subject: [PATCH 391/503] Change all constants to include _ for "yi xin" --- .../classify/commands/ListStudentsCommandTest.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test/java/classify/commands/ListStudentsCommandTest.java b/src/test/java/classify/commands/ListStudentsCommandTest.java index 1ef855a025..745b1b29ae 100644 --- a/src/test/java/classify/commands/ListStudentsCommandTest.java +++ b/src/test/java/classify/commands/ListStudentsCommandTest.java @@ -14,7 +14,7 @@ class ListStudentsCommandTest { - private static final String YIXIN = "Yi Xin"; + private static final String YI_XIN = "Yi Xin"; private static final String GERARD = "Gerard"; private static final String SCIENCE = "Science"; private static final String MATH = "Math"; @@ -27,14 +27,14 @@ class ListStudentsCommandTest { @Test void testListStudentsWithValidNumbers() { ArrayList students = new ArrayList<>(); - Student student1 = new Student(YIXIN); + Student student1 = new Student(YI_XIN); StudentAttributes attributes1 = new StudentAttributes(student1); attributes1.setPhoneNumber(87654321); student1.setAttributes(attributes1); students.add(student1); ArrayList expectedOutput = new ArrayList<>(); - expectedOutput.add("1." + YIXIN + " - Phone Number: 87654321"); + expectedOutput.add("1." + YI_XIN + " - Phone Number: 87654321"); assertEquals(expectedOutput, captureOutput(() -> ListStudentsCommand.listStudentsWithPhoneNumbers(students))); } @@ -67,7 +67,7 @@ void testListStudentsWithInvalidNumbers() { @Test void testListStudentsWithTotalClasses() { ArrayList students = new ArrayList<>(); - Student student1 = new Student(YIXIN); + Student student1 = new Student(YI_XIN); StudentAttributes attributes1 = new StudentAttributes(student1); SubjectGrade mathGrade = new SubjectGrade(MATH, 10, 10); SubjectGrade scienceGrade = new SubjectGrade(SCIENCE, 12,-1); @@ -77,7 +77,7 @@ void testListStudentsWithTotalClasses() { students.add(student1); ArrayList expectedOutput = new ArrayList<>(); - expectedOutput.add("1." + YIXIN + " - Total Classes Attended: 10"); + expectedOutput.add("1." + YI_XIN + " - Total Classes Attended: 10"); assertEquals(expectedOutput, captureOutput(() -> ListStudentsCommand.listStudentsWithTotalClasses(students))); } @@ -90,7 +90,7 @@ void testListStudentsWithTotalClasses() { @Test void testListStudentsBySubject() { ArrayList students = new ArrayList<>(); - Student student1 = new Student(YIXIN); + Student student1 = new Student(YI_XIN); StudentAttributes attributes1 = new StudentAttributes(student1); SubjectGrade mathGrade = new SubjectGrade(MATH, 10,10); attributes1.getSubjectGrades().add(mathGrade); @@ -99,7 +99,7 @@ void testListStudentsBySubject() { ArrayList expectedOutput = new ArrayList<>(); expectedOutput.add("Students with the subject " + '"' + MATH + '"' + ":"); - expectedOutput.add("- " + YIXIN + " - " + "Classes Attended for Math: 10"); + expectedOutput.add("- " + YI_XIN + " - " + "Classes Attended for Math: 10"); expectedOutput.add("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); assertEquals(expectedOutput, captureOutput(() -> ListStudentsCommand.listStudentsBySubject(students, MATH))); From 8e9198676245e6ab17bb141b4d819cb378e0b671 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Fri, 12 Apr 2024 23:46:48 +0800 Subject: [PATCH 392/503] Change xiao_ming --- src/test/java/classify/commands/ViewStudentTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/classify/commands/ViewStudentTest.java b/src/test/java/classify/commands/ViewStudentTest.java index dd4e18965f..390c008bca 100644 --- a/src/test/java/classify/commands/ViewStudentTest.java +++ b/src/test/java/classify/commands/ViewStudentTest.java @@ -17,15 +17,15 @@ class ViewStudentTest { - private static final String XIAOMING = "Xiao Ming"; + private static final String XIAO_MING = "Xiao Ming"; @Test void viewStudentTest() { - InputStream in = new ByteArrayInputStream(XIAOMING.getBytes()); + InputStream in = new ByteArrayInputStream(XIAO_MING.getBytes()); Scanner scanner = new Scanner(in); ArrayList masterStudentList = new ArrayList<>(); - Student student = new Student(XIAOMING); + Student student = new Student(XIAO_MING); StudentAttributes attributes = new StudentAttributes(student); List subjectGrades = new ArrayList<>(); subjectGrades.add(new SubjectGrade("Computer Science", 85.0, 20)); @@ -35,7 +35,7 @@ void viewStudentTest() { ViewStudent.viewStudent(masterStudentList, scanner, null); - assertEquals(XIAOMING, student.getName()); + assertEquals(XIAO_MING, student.getName()); assertEquals(85.0, student.getAttributes().getSubjectGrades().get(0).getGrade()); assertEquals(20, student.getAttributes().getSubjectGrades().get(0).getClassesAttended()); //currently, does not include the details like phone number and last paid date. From f4fbe3786b31d147d244d57f17ad5c92f2c1e3b3 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Fri, 12 Apr 2024 23:52:45 +0800 Subject: [PATCH 393/503] Update DG --- docs/DeveloperGuide.md | 7 +++++++ docs/UserGuide.md | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index c2c47e8028..a06e500966 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -321,3 +321,10 @@ Classify serves as an attempt to modernise administrative tasks in education ins 2. Test case: `undo`, then `undo` again
Expected: `undo` will restore the latest deletion, the second `undo` will restore the first deletion. +### Add a student to the archive +1. Removes a student from the student list and adds them to the archive + 1. Prerequisites: Have a student named `joe` added to the list with the `add` command + 2. Test case: `archive joe`
+ Expected: `joe` will be removed from the list, and added to the archive, `joe` will appear in the list of students added to the archive. + +### Archive \ No newline at end of file diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 5aef6fb3fc..925a66ff99 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -157,7 +157,7 @@ Exits the program. # Usage -:exclamation: **Please note that if any of the following characters are entered in any string prompts, `#, - and ~`, they will be replaced and your command may be deemed invalid.**:exclamation: +<:exclamation:> **Please note that if any of the following characters are entered in any string prompts, `#, - and ~`, they will be replaced and your command may be deemed invalid.**:exclamation: ### Adding a student: `add` Initialises an interface for adding a student and their relevant details to the database. Allows the user to do add or add [name] From 1e9969669238cd57e67808cb33e4d2ab692b2f3d Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sat, 13 Apr 2024 00:01:14 +0800 Subject: [PATCH 394/503] Update DG --- docs/DeveloperGuide.md | 14 ++------------ docs/UserGuide.md | 4 ---- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 7d49e72f1b..ed265b75e9 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -335,16 +335,6 @@ Expected: `view joe` now shows the Student details of a student with Name: joe,
Expected: `view joe` shows the same results as when a student was added via `add joe`. -### Viewing a student's details -#### 1. View a student who has been added to the student list: -1. Prerequisites: Add one student named 'joe' to the list with the `add` command -2. Test case: `view joe` -
-Expected: Student's details shown correspond to the details input when `add` was used to add a student. -3. Test case: `view dogman` -
-Expected: No details are displayed, an error message stating 'Student not found!' is shown. - ### Editing a student's details #### 1. Entering edit mode for an existing student: 1. Prerequisites: Add student named 'tim' to the student list with the `add` command. @@ -407,7 +397,7 @@ Expected: No details are displayed, an error message stating 'Student not found!
Expected: Returns to edit mode for 'tim' and no change in remarks is made for 'tim'. #### 9. Editing student in empty list -1. Prerequisites: Have empty list with no students added. +1. Prerequisites: Have empty list with no students afdded. 2. Test Case: `edit`
Expected: Error message for empty list will be printed. @@ -428,4 +418,4 @@ Expected: No details are displayed, an error message stating 'Student not found!
Expected: Prints invalid phone number error message and prompts for another phone number. 6. Test Case: `6`, `20 jan 2001`
Expected: Prints error message for invalid date and prompts for another date. ->>>>>>> 44e7b30e8b590fe292cced70777954ee2529f5bc + diff --git a/docs/UserGuide.md b/docs/UserGuide.md index d771f6217b..cf925983c4 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -159,11 +159,7 @@ Exits the program. # Usage -<<<<<<< HEAD -<:exclamation:> **Please note that if any of the following characters are entered in any string prompts, `#, - and ~`, they will be replaced and your command may be deemed invalid.**:exclamation: -======= **Please note that if any of the following characters are entered in any string prompts, `#, - and ~`, they will be replaced and your command may be deemed invalid.** ->>>>>>> 44e7b30e8b590fe292cced70777954ee2529f5bc ### Adding a student: `add` Initialises an interface for adding a student and their relevant details to the database. Allows the user to do add or add [name] From 45ec007bd70fd54b2e4e339e44d20a211db96f91 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sat, 13 Apr 2024 00:02:10 +0800 Subject: [PATCH 395/503] Fix spelling error --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index ed265b75e9..fdfea51ccd 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -397,7 +397,7 @@ Expected: `view joe` shows the same results as when a student was added via `add
Expected: Returns to edit mode for 'tim' and no change in remarks is made for 'tim'. #### 9. Editing student in empty list -1. Prerequisites: Have empty list with no students afdded. +1. Prerequisites: Have empty list with no students added. 2. Test Case: `edit`
Expected: Error message for empty list will be printed. From aea93919a05dfdb8c66d6b2a4f8262f9a3e7de32 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sat, 13 Apr 2024 00:03:57 +0800 Subject: [PATCH 396/503] Remove extraneous symbols --- docs/DeveloperGuide.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index fdfea51ccd..0ea85462c8 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -264,7 +264,6 @@ Classify serves as an attempt to modernise administrative tasks in education ins ## Instructions for manual testing ### Adding a student to the student list -<<<<<<< HEAD 1. Adding a student with a name and phone number only 1. Prerequisites: View if a student with the name `joe` and phone number `88888888` exists by using the `view joe` command. 2. Test case: `add joe` and when prompted for phone number enter `88888888`, while pressing enter to skip other optional fields. @@ -324,8 +323,7 @@ Classify serves as an attempt to modernise administrative tasks in education ins 2. Test case: `archive joe`
Expected: `joe` will be removed from the list, and added to the archive, `joe` will appear in the list of students added to the archive. -### Archive -======= +### Archive #### 1. Adding a student with a name and phone number only: 1. Prerequisites: View if a student with the name 'joe' exists by using the `view joe` command. 2. Test case: `add joe` and when prompted for phone number enter `11111111`, while pressing enter to skip other optional fields. From cf5617c8282593fb05a9af0679582cdec95bb175 Mon Sep 17 00:00:00 2001 From: shui <78994143+blackmirag3@users.noreply.github.com> Date: Sat, 13 Apr 2024 02:08:07 +0800 Subject: [PATCH 397/503] Update blackmirag3.md --- docs/team/blackmirag3.md | 55 ++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/docs/team/blackmirag3.md b/docs/team/blackmirag3.md index 7ee2735810..c72bd6d743 100644 --- a/docs/team/blackmirag3.md +++ b/docs/team/blackmirag3.md @@ -1,28 +1,51 @@ -#Siew Shui Hon's (blackmirag3) Project Portfolio Page +# Siew Shui Hon's (blackmirag3) Project Portfolio Page ## Project: Classify -Classify is a desktop application used for Tuition Centres to allow for easier management of their enrolled students. -From allowing users to add new students to sorting them based on their last paid date, Classify is the one-stop app that -all Tuition Centres can employ for ease of student management. To use the app, users can interact with it using CLI. +### Overview +Classify is a desktop-based CLI application used for Tuition Centres to allow for easier management of their enrolled students. Classify is the one-stop app that +all Tuition Centres can employ for ease of student management. -Below are my specific contributions to the project: +### Summary of Contributions -- **Foundation for the project.** - * +- **Code Contributed** + * [blackmirag3's RepoSense](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=blackmirag3&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2024-02-23&tabOpen=true&tabType=authorship&tabAuthor=blackmirag3&tabRepo=AY2324S2-CS2113-T13-3%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code&authorshipIsBinaryFileTypeChecked=false&authorshipIsIgnoredFilesChecked=false) -- **Maintenance of commonly used functions and exceptions.** - * -- **Extensive bugfinding and fixing** - * +- **Enhancements Implemented** + * Feature: `Edit` + * Added base feature to access students' attributes and details. + * Implemented sub-features such as adding, removing or editing existing subjects. + + * Feature: `Archive` and `Unarchive` + * Implemented archiving and unarchiving feature. + * Implemented `DataHandler` class to manage reading and writing of archived students within a data file. -- **Code contributed:** [Link to Reposense contribution graph](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=blackmirag3&sort=groupTitle&sortWithin=title&timeframe=commit&mergegroup=&groupSelect=groupByRepos&breakdown=true&checkedFileTypes=docs~functional-code~test-code~other&since=2024-02-23&tabOpen=true&tabType=authorship&tabAuthor=blackmirag3&tabRepo=AY2324S2-CS2113-T13-3%2Ftp%5Bmaster%5D&authorshipIsMergeGroup=false&authorshipFileTypes=docs~functional-code~test-code&authorshipIsBinaryFileTypeChecked=false&authorshipIsIgnoredFilesChecked=false) - * Majority of my code was done to ensure my group member's code worked well with each other. I focused on making sure everything worked smoothly, and fixing bugs and exceptions, rather than adding features. Essentially acted as the scrum master. + * Non-features: + * Implemented `SubjectGrade` class. + * Implemented helper functions for the team to re-use in their own features, such as `findSubject` and `isValidGrade`. -- **Documentation:** - * +- **Contributions to [UG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/UserGuide.md)** + * Wrote content related to `edit`, `archive`, `unarchive` features. + * Finalised formatting in UG, such as standardising the layout in `Usage` section. + + + +- **Contributions to [DG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/DeveloperGuide.md)** + * ... + - **Contributions to Team-Based tasks:** - * + * Refactored/rewrote at least 300 LoC authored by teammates to improve code quality, such as for [input checking](https://github.com/AY2324S2-CS2113-T13-3/tp/commit/23f3ac553d243b9d31d80fdd05ff2ac3b3a2d57e) and [file IO](https://github.com/AY2324S2-CS2113-T13-3/tp/commit/932b51fbdb542b59f3ecdcaa1c04c65eda873ff1). + * Established TP's current code organisation, such as refactoring project into respective packages `commands`, `data`, `ui` etc. + * Maintained team's GitHub Project, such as updating status and priority of project items. + * Monitored and maintained repo's issues, such as opening, closing and re-assigning issues. + + +- **Review/mentoring contributions** + * Actively reviewed and approved team's PRs, with some recent examples [here](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/258) or [here](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/246). + + +- **Contributions beyond project team** + * Did exploratory testing of T13-4's TP before their final release. \ No newline at end of file From 7689ce587efd0aa4c2f46b3b5ee6e4e1ed1c8e62 Mon Sep 17 00:00:00 2001 From: shui <78994143+blackmirag3@users.noreply.github.com> Date: Sat, 13 Apr 2024 02:16:36 +0800 Subject: [PATCH 398/503] Update blackmirag3.md --- docs/team/blackmirag3.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/team/blackmirag3.md b/docs/team/blackmirag3.md index c72bd6d743..e8d5eedcdb 100644 --- a/docs/team/blackmirag3.md +++ b/docs/team/blackmirag3.md @@ -36,8 +36,9 @@ all Tuition Centres can employ for ease of student management. * ... -- **Contributions to Team-Based tasks:** - * Refactored/rewrote at least 300 LoC authored by teammates to improve code quality, such as for [input checking](https://github.com/AY2324S2-CS2113-T13-3/tp/commit/23f3ac553d243b9d31d80fdd05ff2ac3b3a2d57e) and [file IO](https://github.com/AY2324S2-CS2113-T13-3/tp/commit/932b51fbdb542b59f3ecdcaa1c04c65eda873ff1). +- **Contributions to Team-Based tasks:** + * Testing......... + * Refactored/rewrote at least 300 LoC (authored by teammates) to improve code quality, such as for [input checking](https://github.com/AY2324S2-CS2113-T13-3/tp/commit/23f3ac553d243b9d31d80fdd05ff2ac3b3a2d57e) and [file IO](https://github.com/AY2324S2-CS2113-T13-3/tp/commit/932b51fbdb542b59f3ecdcaa1c04c65eda873ff1). * Established TP's current code organisation, such as refactoring project into respective packages `commands`, `data`, `ui` etc. * Maintained team's GitHub Project, such as updating status and priority of project items. * Monitored and maintained repo's issues, such as opening, closing and re-assigning issues. @@ -45,7 +46,7 @@ all Tuition Centres can employ for ease of student management. - **Review/mentoring contributions** * Actively reviewed and approved team's PRs, with some recent examples [here](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/258) or [here](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/246). - + * Approached relevant team members to discuss bug fixes whenever I discovered new bugs for their features. - **Contributions beyond project team** * Did exploratory testing of T13-4's TP before their final release. \ No newline at end of file From db52b69f4297b8477a66d55a0e3cfbdcfcdc2fc7 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 13 Apr 2024 11:31:24 +0800 Subject: [PATCH 399/503] Small Change in Naming Test Method --- src/test/java/classify/textfilecode/TextFileReaderTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/classify/textfilecode/TextFileReaderTest.java b/src/test/java/classify/textfilecode/TextFileReaderTest.java index c73090ae10..8984eb1855 100644 --- a/src/test/java/classify/textfilecode/TextFileReaderTest.java +++ b/src/test/java/classify/textfilecode/TextFileReaderTest.java @@ -14,7 +14,7 @@ class TextFileReaderTest { private static final String VALID_FILE_DIRECTORY = "./data/testFolder"; @Test - public void testPrintCurrentInputFolderwhenEmpty() { + public void testPrintCurrentInputFolderWhenEmpty() { ByteArrayOutputStream outContent = new ByteArrayOutputStream(); System.setOut(new PrintStream(outContent)); @@ -27,7 +27,7 @@ public void testPrintCurrentInputFolderwhenEmpty() { } @Test - public void testPrintCurrentInputFolderwhenFilled() { + public void testPrintCurrentInputFolderWhenFilled() { ByteArrayOutputStream outContent = new ByteArrayOutputStream(); System.setOut(new PrintStream(outContent)); From 66664d5eb3347c6c2dbc5e73a67b9e4649553799 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 13 Apr 2024 11:33:32 +0800 Subject: [PATCH 400/503] Change Access Modifiers for methods --- src/main/java/classify/data/DataReader.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 8f861c198c..967614a94c 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -91,7 +91,7 @@ public static void restoreStudentList(String studentFileInput, ArrayList Date: Sat, 13 Apr 2024 11:33:54 +0800 Subject: [PATCH 401/503] Add DataReader Test cases --- .../java/classify/data/DataReaderTest.java | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) diff --git a/src/test/java/classify/data/DataReaderTest.java b/src/test/java/classify/data/DataReaderTest.java index 9bd403bd61..69db6f6c88 100644 --- a/src/test/java/classify/data/DataReaderTest.java +++ b/src/test/java/classify/data/DataReaderTest.java @@ -1,6 +1,199 @@ package classify.data; //@@author ParthGandhiNUS +import classify.student.Student; +import classify.student.SubjectGrade; +import classify.user.InvalidCharacterException; +import org.junit.jupiter.api.Test; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + public class DataReaderTest { + public static final String JOHN_DOE = "John Doe"; + public static final String GENDER = "male"; + public static final Integer PHONE_NUMBER = 98989898; + public static final String LAST_PAYMENT_DATE = "2024-04-13"; + public static final String REMARKS = "Na"; + public static final String MATH = "Math"; + public static final double MATH_GRADE = 81.3; + public static final Integer MATH_CLASSES = 10; + public static final String VALID_SUBJECT_INPUT = "Math ## 81.3 ## 10"; + public static final String SCIENCE = "Science"; + public static final double SCIENCE_GRADE = 95.0; + public static final Integer SCIENCE_CLASSES = 12; + public static final String FULL_VALID_INPUT = "John Doe ~~ male ~~ 98989898 ~~ 2024-04-13 ~~ Na ~~ Math " + + "## 81.3 ## 10 #--#"; + public static final String FULL_INVALID_INPUT = "Jane Doe ~~ female ~~ 88888888 ~~ 2022-02-11 ~~ Nope ~~ " + + "Science ## 95.0 ## 12 #--#"; + + + @Test + public void restoreStudentListValidTest(){ + Student expectedStudent = new Student(JOHN_DOE); + expectedStudent.getAttributes().setGender(GENDER); + expectedStudent.getAttributes().setPhoneNumber(PHONE_NUMBER); + + LocalDate lastPayment = DataReader.convertStringToLocalDate(LAST_PAYMENT_DATE); + expectedStudent.getAttributes().setLastPaymentDate(lastPayment); + expectedStudent.getAttributes().setRemarks(REMARKS); + + SubjectGrade newSubject = new SubjectGrade(MATH, MATH_GRADE, MATH_CLASSES); + expectedStudent.getAttributes().addSubjectGrade(newSubject); + + ArrayList actualStudentList = new ArrayList<>(); + DataReader.restoreStudentList(FULL_VALID_INPUT, actualStudentList); + Student actualStudent = actualStudentList.get(0); + + SubjectGrade expectedStudentSubject = expectedStudent.getAttributes().getSubjectGrades().get(0); + SubjectGrade actualStudentSubject = actualStudent.getAttributes().getSubjectGrades().get(0); + + assertEquals(expectedStudent.getName(), actualStudent.getName()); + assertEquals(expectedStudent.getGender(), actualStudent.getGender()); + assertEquals(expectedStudent.getPhoneNumber(), actualStudent.getPhoneNumber()); + assertEquals(expectedStudent.getLastPaymentDate(), actualStudent.getLastPaymentDate()); + assertEquals(expectedStudent.getAttributes().getRemarks(), actualStudent.getAttributes().getRemarks()); + assertEquals(expectedStudentSubject.getSubject(),actualStudentSubject.getSubject()); + assertEquals(expectedStudentSubject.getGrade(),actualStudentSubject.getGrade()); + assertEquals(expectedStudentSubject.getClassesAttended(),actualStudentSubject.getClassesAttended()); + } + + @Test + public void restoreStudentListInvalidTest(){ + Student expectedStudent = new Student(JOHN_DOE); + expectedStudent.getAttributes().setGender(GENDER); + expectedStudent.getAttributes().setPhoneNumber(PHONE_NUMBER); + + LocalDate lastPayment = DataReader.convertStringToLocalDate(LAST_PAYMENT_DATE); + expectedStudent.getAttributes().setLastPaymentDate(lastPayment); + expectedStudent.getAttributes().setRemarks(REMARKS); + + SubjectGrade newSubject = new SubjectGrade(MATH, MATH_GRADE, MATH_CLASSES); + expectedStudent.getAttributes().addSubjectGrade(newSubject); + + ArrayList actualStudentList = new ArrayList<>(); + DataReader.restoreStudentList(FULL_INVALID_INPUT, actualStudentList); + Student actualStudent = actualStudentList.get(0); + + SubjectGrade expectedStudentSubject = expectedStudent.getAttributes().getSubjectGrades().get(0); + SubjectGrade actualStudentSubject = actualStudent.getAttributes().getSubjectGrades().get(0); + + assertNotEquals(expectedStudent.getName(), actualStudent.getName()); + assertNotEquals(expectedStudent.getGender(), actualStudent.getGender()); + assertNotEquals(expectedStudent.getPhoneNumber(), actualStudent.getPhoneNumber()); + assertNotEquals(expectedStudent.getLastPaymentDate(), actualStudent.getLastPaymentDate()); + assertNotEquals(expectedStudent.getAttributes().getRemarks(), actualStudent.getAttributes().getRemarks()); + assertNotEquals(expectedStudentSubject.getSubject(),actualStudentSubject.getSubject()); + assertNotEquals(expectedStudentSubject.getGrade(),actualStudentSubject.getGrade()); + assertNotEquals(expectedStudentSubject.getClassesAttended(),actualStudentSubject.getClassesAttended()); + } + + @Test + public void getAllSubjectInformationValidTest() throws InvalidCharacterException { + SubjectGrade expectedSubject = new SubjectGrade(MATH.trim(), MATH_GRADE, MATH_CLASSES); + SubjectGrade actualSubject = DataReader.getAllSubjectInformation(VALID_SUBJECT_INPUT); + assertEquals(expectedSubject.getSubject(), actualSubject.getSubject()); + assertEquals(expectedSubject.getGrade(), actualSubject.getGrade()); + assertEquals(expectedSubject.getClassesAttended(),actualSubject.getClassesAttended()); + } + + @Test + public void getAllSubjectInformationInvalidSubjectTest() throws InvalidCharacterException { + SubjectGrade expectedSubject = new SubjectGrade(SCIENCE.trim(), MATH_GRADE, MATH_CLASSES); + SubjectGrade actualSubject = DataReader.getAllSubjectInformation(VALID_SUBJECT_INPUT); + assertNotEquals(expectedSubject.getSubject(), actualSubject.getSubject()); + assertEquals(expectedSubject.getGrade(), actualSubject.getGrade()); + assertEquals(expectedSubject.getClassesAttended(),actualSubject.getClassesAttended()); + } + + @Test + public void getAllSubjectInformationInvalidGradeTest() throws InvalidCharacterException { + SubjectGrade expectedSubject = new SubjectGrade(MATH.trim(), SCIENCE_GRADE, MATH_CLASSES); + SubjectGrade actualSubject = DataReader.getAllSubjectInformation(VALID_SUBJECT_INPUT); + assertEquals(expectedSubject.getSubject(), actualSubject.getSubject()); + assertNotEquals(expectedSubject.getGrade(), actualSubject.getGrade()); + assertEquals(expectedSubject.getClassesAttended(),actualSubject.getClassesAttended()); + } + + @Test + public void getAllSubjectInformationInvalidClassesTest() throws InvalidCharacterException { + SubjectGrade expectedSubject = new SubjectGrade(MATH.trim(), MATH_GRADE, SCIENCE_CLASSES); + SubjectGrade actualSubject = DataReader.getAllSubjectInformation(VALID_SUBJECT_INPUT); + assertEquals(expectedSubject.getSubject(), actualSubject.getSubject()); + assertEquals(expectedSubject.getGrade(), actualSubject.getGrade()); + assertNotEquals(expectedSubject.getClassesAttended(),actualSubject.getClassesAttended()); + } + + @Test + public void convertStringToLocalDateValidTest(){ + String dateToConvert = "2024-01-01"; + LocalDate convertedDate = DataReader.convertStringToLocalDate(dateToConvert); + LocalDate expectedDate = LocalDate.of(2024,1,1); + boolean isValidConversion = (Objects.equals(convertedDate, expectedDate)); + assertTrue(isValidConversion); + } + + @Test + public void convertStringToLocalDateInvalidTest(){ + String dateToConvert = "2023-01-01"; + LocalDate convertedDate = DataReader.convertStringToLocalDate(dateToConvert); + LocalDate expectedDate = LocalDate.of(2024,1,1); + boolean isValidConversion = (Objects.equals(convertedDate, expectedDate)); + assertFalse(isValidConversion); + } + + @Test + public void convertStringToLocalDateInvalidDateTest(){ + String dateToConvert = "2023-02-30"; + LocalDate convertedDate = DataReader.convertStringToLocalDate(dateToConvert); + LocalDate expectedDate = LocalDate.of(2024,1,1); + boolean isValidConversion = (Objects.equals(convertedDate, expectedDate)); + assertFalse(isValidConversion); + } + + @Test + public void checkDeletionRequestInputTest(){ + assertTrue(DataReader.checkDeletionRequestInput("YES")); + } + + @Test + public void checkDeletionRequestInvalidTest1(){ + assertFalse(DataReader.checkDeletionRequestInput("yes")); + } + + @Test + public void checkDeletionRequestInvalidTest2(){ + assertFalse(DataReader.checkDeletionRequestInput("YEs")); + } + + @Test + public void checkDeletionRequestInvalidTest4(){ + assertFalse(DataReader.checkDeletionRequestInput("NO")); + } + + @Test + public void deletionRequestFinalConfirmationValidTest(){ + assertTrue(DataReader.deletionRequestFinalConfirmation("CONFIRM")); + } + + @Test + public void deletionRequestFinalConfirmationInvalidTest1(){ + assertFalse(DataReader.deletionRequestFinalConfirmation("confirm")); + } + + @Test + public void deletionRequestFinalConfirmationInvalidTest2(){ + assertFalse(DataReader.deletionRequestFinalConfirmation("CONfirm")); + } + @Test + public void deletionRequestFinalConfirmationInvalidTest3(){ + assertFalse(DataReader.deletionRequestFinalConfirmation("BANANA")); + } } From 82a94ceb464eaa4a4b726ad439f4bb13307d3b6c Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 13 Apr 2024 11:34:07 +0800 Subject: [PATCH 402/503] Add Datawriter Test cases --- .../java/classify/data/DataWriterTest.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/test/java/classify/data/DataWriterTest.java b/src/test/java/classify/data/DataWriterTest.java index 14c3aad392..c013a50776 100644 --- a/src/test/java/classify/data/DataWriterTest.java +++ b/src/test/java/classify/data/DataWriterTest.java @@ -1,6 +1,26 @@ package classify.data; //@@author ParthGandhiNUS -public class DataWriterTest { +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class DataWriterTest { + private static final String VALID_FILE_DIRECTORY = "./data/testFolder"; + /** + * Test checks for the creation of new directories + */ + @Test + public void createParentFileFolderSuccessfulTest() { + DataWriter.createParentFileFolder(VALID_FILE_DIRECTORY); + File currentDir = new File (VALID_FILE_DIRECTORY); + Path expectedDirectory = Paths.get(VALID_FILE_DIRECTORY); + assertTrue( Files.exists(expectedDirectory)); + currentDir.delete(); + } } From 8a617b9adcc4150668bec6241a66bf1211ec0b20 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 13 Apr 2024 11:45:02 +0800 Subject: [PATCH 403/503] Change the numbering for test case --- src/test/java/classify/data/DataReaderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/classify/data/DataReaderTest.java b/src/test/java/classify/data/DataReaderTest.java index 69db6f6c88..f8ba65ecca 100644 --- a/src/test/java/classify/data/DataReaderTest.java +++ b/src/test/java/classify/data/DataReaderTest.java @@ -173,7 +173,7 @@ public void checkDeletionRequestInvalidTest2(){ } @Test - public void checkDeletionRequestInvalidTest4(){ + public void checkDeletionRequestInvalidTest3(){ assertFalse(DataReader.checkDeletionRequestInput("NO")); } From 4143cd1f0dd031b2137f29fbde69ef9a317a407a Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 13 Apr 2024 13:51:14 +0800 Subject: [PATCH 404/503] Add view missing student test --- docs/team/Portrait_placeholder.png | Bin 0 -> 5755 bytes src/main/java/classify/ui/UI.java | 4 ++- .../classify/commands/ViewStudentTest.java | 23 ++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 docs/team/Portrait_placeholder.png diff --git a/docs/team/Portrait_placeholder.png b/docs/team/Portrait_placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..5625050bf2dab52f944894f82f34ff01fed3e474 GIT binary patch literal 5755 zcmd6LXH*kP&^A{^Lhm5mP*qR}i1d=sf=E?*Q+fw!3J53$0VxShiWCu%-jR9%=^YdZ z9RdQOgqo00LgdSR|9wB+|L?PB&+N>Zoq2ZW?AdcB&d5NAo`#!-f`Wox7piGOLGcfQ zg5sJ5;5yk7CavB|7B^hM`d|u*S~%_H3rezn+YxG_PeBnXNtLQZ*fbaZlZvbD8^!C=IM~_U-Pzq)SwZ2jILs~vhr{md>=FoMpG^WDkHujxF3$g~t?g{@Y;SLo32v;f zpPimzvAF&H{bTGghRlpSF&Hx6rRAlqE%e#hIa$XZAEUR>mzSiarDg0f7K0)4C$l(4 zp;p#6*6{?w#ref18jZ&jHqo2pW3R5Qku&V?EdFuO)6sObp4zD=D^!8H z`dU<5)U-4=8D|LA;uI8Y>bjcXXRjCbZ9T(;EMFd^9N)Gq>~HAeE`|Hh7tYmbbA=q& z0QKH7vCQe$sUHB%q1dZPNb9Dx-tOmb9nX*l zIbt^Ca^k3V_jb>Y4c&)X6%&#-Lj2BXS2P|!ud@cl}^{*k_6q2uvDhdGO&oMlwX)9vl0aJnbol@bD$oEKHI zTIDzcjQoZ9DhUfReSvK?;Tz}Wj7KT!QONd;%nbu9o3f<;xvwOzl)sw`exA|pz3EWq zty46wfj>ZC9NRA^;-+1;to&y8ZOWfNzk{m(^?137Kd}1pEi(-E$M|}}tIoHroVr28 zj$@B^$HZ9c^Ml&)%1*tWK@7={L0fvcuuTMQx_g1vVXZ*;IyVpWwOTlqX|{!&@fxJ` z5B$uXF^HuS)7205e2P;Mb1(Ea1el*zSHg$vB0Z!(HfcX@5|1e@y_t6Z}qtX_muW_@(OH&y!D$ z(sg|U+eP^xU1fQb{ADZc;7iAxsnwDRpSwa5>*;-}kZJUAOnL$gzxuvZDf*sIQxdZQ zUg3?f;6^h1o-41|!oCA+JcJnIonVAnc!+8q_V%*u0gT1a1uCKVK@K|qV2iu%68Z4+ zW33vGjzCAQc}x`&+oZ{8PYVz2ukF6;(8DsIOgk26FYN(P@QO9jzLK| z%~t7a_qteAZ+p;K&5INu9<4)+Wg+p;du^Hm_OsD3)0RAz_G-VYT&%PV%%gm^=8OL- z-G@ntcLJ;Uxr|fXz1ean{tny?<^zjAJGom-g0JuQBY!!w*%kUyRie1+&p81L;I7tK2D*)t z-{yw5UGv}r;2{g2=KHGnKxTiRgrk1b54K<8f6W)!L2k6hj(hF|mrBaB&h|P%%g+lC&3##ntp)N^9W;1=y zFw`;nfqOAti;0rXA-OBxv>fM&z_#EiF--|G5N5)uw<3dAPbDfJf#B7P{D@yt1!_t( z7&06XI%5}gN5T82k^RsMPUUC(5S*)qwoA-$rR+|vqqAi3r)$c$32NbWE zk;SZc5i!^p-rt$e{&;Y-{^q3)M$@*?T!yfRP9erA_^)t>@oK(}otu&ixjU1^iUseO zK)Hdlqgt9f+@I$ThRlRUXlxl@+h1lp09x@_kBVUe(N@|3++$&9xPE=?QI+O)s&Va= z@siJyOg{_};BDE9?XNJ+&9Qc#1#K=`=BvyvpEN);Bl<0n?gegh#=m?HxEM>l%BSRD zeyTs+Cf=pWpH)G1s0fIULK(LxQL_+D> zN%pC~h?8qXd4w7)445*BK^_8aCS3NbH5Pv>f|_io-OG{tPm~q|7w8mFU_)TEJ!QTiZc z;(exT5Cc(7*^Z%1M4U4bXriKd>ZN%N$nnGA3(ze$2O5jjVDO^V2vfNMdy9Y+znyW* zJ?ge2E^`DgU>6QsgTmj10L1*-N7s&9wTJ|bTLRZFXw!)TEx{{WbzXFqEQSxtL^rIs zfeWV^W=BkR{N2H7PA{hDgc}8LZ*r@|?{AfH3(6 zK-Dx3M zxn5sgDLnU8T1u_1@Cg1rSeDx`0De9DQAwyL{NE+F+}TJ+yM!Ebth0CBQwNP3NL zx)%X2`G88SvMnndM->OpSoUh9Y$Oq}@E@f+iR-&=M=Hop1$~5?~lB z{0%gbI6xMxvW;9lc_{E=chOYlI`d+mNd>0gmS#)HX~TiFA+5onHR%oH5x$kdR<1qi zwd&WgEj{Z}zF?sw4g zHNol_X`CtTppUrfU#ek$HK(sl*XH$p^y~i4nU5Hpw*KL@D)i)slW=FYc(<)Khw7Cz zr69NohS0})W)@rY(|{wLH+(bmHEQGGkRjhf8K%XvIXb2_frJreyGmA`^Vk#=)pv8> z%$UaTH<}3zBvLVVK!*)IA?{VDFzxy4ClRi6n}w*lRCsK1Cw()$#uMK)i^o(G$anqLxcAmN=v-ErT==G+1M6eg&fCwpxvkMJs8#u+ z!?)|?y~A~GZ`>tYTSNGan^OanghC^l9m>_3a$y1_zo*Ux(2_RnrpWkt@Q4k z!se|ht2BFCD=-7In*``O>0x(1EL(4jY}hQ_6v~U?g-Ev8&lQOjga+D<$8aX1n%o~k z#(fV0I!)?tg|rJ;O(rrvCE-3-ZhYK~80@{FA)X^FF?JZ-m$O9#KJ~4<>ea}!CY?3q zrO{p`T)i6ZnGtPbX()?er(>TL<~g40v`oSyxrO?+ZVB``ZcxA9u`OXsDUmu1387k1 z`9O#(KbBBdh!=o{BZkjxy(c@&Lyp{S*z2#_%UB_rm2G?LewQdl<6dZH;bl+w9s(?S zwt$pkL7R~x(;_*qG)I0g6l7LYdi2W!J=~uQ`!k9hVoHvfFN))T6ayx?3eMGMHS+7Y zs6FAPQg~&l?r8Y8%{yy{QPeK5ocO%ne$yn|in>%8zv4Vq$hV6@LbOGh6!xzrztF=g z&a212h_|WcT~|6EJHpVU+|xuhtqMT*8<#a9%!;E98?duh2=zKJJX1JuDiV>(~MBr3H7BSnuN zzfL^pH_gj6kA~9bkEEOH&s&1(M7I4;)eIVR68xA?PW!LVEyeRizU<~7gErJ>T0}?j zC#>>IvX-N%Tl|=7?2eF~vSZNhr%Psqi+)27c4{var97LR;C2nU^H#K?3p^26!3sci zg{O`4qW)oy1pojDaoLFPH@T0o{&;s=PI#|&ppg7!=eYTLMK#OTYxRCCwu%=8=!UXP zV%ad~8HoTT1=|uWkNo4-h!^mtCk>2BNj0-}we?{=pR(d%(h$6h1;AoHVOqIr;fBQL zAf;Km!{%Lu=W7_(InT6Y7#(eE2WP`l{DKqg(*c`wvbYeYHP653e0Y!a?#}X+{E*!& zW^bCo08uv^K6kmlN@e}vqb_)ThJAGm!?pYJ;MtL?S^G~#HCHcl zmQRLN-a}r+Ld6yiOD?}to0P2YZ#Fhyd2ie?N=VDR=x_TNm+od)L=)D61oFZ%;y2_0 zMhzHZ0Wajv!R=rBtbyUC20_g)ncgfyB5W&J^e#%gc38tm8xB&Oe@lY< z?>UzM#v(mxu8dQ{xpP$QiYXtoNYrw)sQ%y>`uv`PYDTcQ3=n=)3{4)c&(C)20uLuy z{&kP3-a(Np8;wHv_hRM@F>Y%TX6Fz5O{PxqHG){zHVPHo^smNhEmc z{&&6N2KIN8rW@PW?}RBxJ}lrR*19&h#jPXLn+KEofc`7PAA8nsnp*rSO-M$9vLuZ; z-}v2QC`}KXxzTF#fmAY@!Erob^(*tKKT$`=pIEBIGXyq&?- zzbpx)q{)5r=-F2+qQJSslAm^GgS@t@ej4{d7`6CZss*@(x@u-oCqSKn$n#@ij7Z0<8*a_cTr3@CHjsh7@eInu;4&cf^#c%l}}I4u(oM^Mgo? zfh~}>^PVfCT3Nm?d1&3?2S^uoZXyr;oCdS51MII{^~peljw~TfN5U;O7HK4sBF_qD zpUjCB9@i|v{Q%QUBUIdLlCG=M_gBCs{W@v7=n5Z&P3}neSFPPn41snd?v+YtdKQWj zO(E{hK^h!^O)g;&cWC_9V`)T^;#yMG6V7J%ig~_tjo6uE5Bct&G;k9IwNh;hFa#a5y~ByhdnRsKTf-pn+wcs;+p z^!*F%`-C&Dv$ODj)HPmfyzY!<|0`)QnE0;hkr%v)bIKrR6@zqx3s8PEEB;bWzqr1y zrAU0=wdFC#&y2llKkHuTn$0UBH~mBcwJZXiUIaQTI{G`41%_5T30-G6`p literal 0 HcmV?d00001 diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index b6dfc45426..9e923a3132 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -8,6 +8,7 @@ public class UI { public static final String TOTAL_CLASSES_ATTENDED_ACROSS_ALL_SUBJECTS = "Total classes " + "attended across all subjects: "; + public static final String DIVIDER = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; private static final String EMPTY_SUBJECT_ERROR = "No subjects and grades found for this student."; private static final String NULL_ATTRIBUTE_ERROR = "No attributes found for this student."; private static final String EMPTY_LIST_ERROR = "Currently no students in list."; @@ -29,7 +30,6 @@ public class UI { private static final String INVALID_DATE_RANGE = "Please input a date with a reasonable value. \n" + "(eg. from 2010 until today.)"; //@@author ParthGandhiNUS - private static final String DIVIDER = "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; private static final String WELCOME_TO_CLASSIFY = "Welcome to Classify!"; private static final String WHAT_CAN_I_DO_FOR_YOU_TODAY = "What can I do for you today?"; private static final String CLASSIFY_GOODBYE_MESSAGE = "Hope you've had a productive day. See you again! Goodbye!"; @@ -86,6 +86,8 @@ public class UI { private static final String STUDENT_NOT_FOUND_CANNOT_BE_DELETED = "Student not found! Cannot be deleted."; private static final String NULL_POINTER_THROWN_SOMETHING_WENT_WRONG = "Null pointer thrown. Something went wrong."; + + //@@author alalal47 /** * Displays the help message to teach users how to use Classify. diff --git a/src/test/java/classify/commands/ViewStudentTest.java b/src/test/java/classify/commands/ViewStudentTest.java index 390c008bca..3ed39d9713 100644 --- a/src/test/java/classify/commands/ViewStudentTest.java +++ b/src/test/java/classify/commands/ViewStudentTest.java @@ -4,11 +4,15 @@ import classify.student.Student; import classify.student.StudentAttributes; import classify.student.SubjectGrade; +import classify.ui.UI; +import classify.student.StudentList; import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.io.PrintStream; import java.util.ArrayList; import java.util.List; import java.util.Scanner; @@ -40,4 +44,23 @@ void viewStudentTest() { assertEquals(20, student.getAttributes().getSubjectGrades().get(0).getClassesAttended()); //currently, does not include the details like phone number and last paid date. } + + //@@author Cryolian + @Test + void viewNonExistingStudent() { + StudentList studentlist = new StudentList(); + + assertEquals(studentlist.studentList.size(), 0); + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + + System.setOut(new PrintStream(output)); + + ViewStudent.viewStudent(studentlist.studentList, null, "mario"); + String expectedOutput = "No student found!"; + String printedOutput = output.toString().trim(); + + assertEquals(expectedOutput, printedOutput); + + } } From 0e8b0cd5367778ca02f19f7fc209d3ad53f87b6c Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 13 Apr 2024 14:38:23 +0800 Subject: [PATCH 405/503] Add number and gender tests --- src/test/java/classify/commands/EditTest.java | 101 ++++++++++++++++++ .../classify/commands/ViewStudentTest.java | 43 ++++++++ 2 files changed, 144 insertions(+) diff --git a/src/test/java/classify/commands/EditTest.java b/src/test/java/classify/commands/EditTest.java index e1db462365..501fa7b3ec 100644 --- a/src/test/java/classify/commands/EditTest.java +++ b/src/test/java/classify/commands/EditTest.java @@ -2,6 +2,7 @@ import classify.student.Student; import classify.student.StudentList; +import classify.user.InputParsing; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeAll; @@ -69,4 +70,104 @@ public void testEditNoStudentFound() { "No student found!" + System.lineSeparator(); assertEquals(printedOutput, expectedOutput); } + + //@@author Cryolians + @Test + void testInvalidNumberEdit() { + String commandString = "88888888 \n" + + "4 \n" + + "99999999 \n" + + '\n'; + + Student alpha = new Student("Alpha"); + alpha.getAttributes().setPhoneNumber(88888888); + StudentList.masterStudentList.add(alpha); + + Student alpha2 = new Student("Alpha"); + alpha2.getAttributes().setPhoneNumber(99999999); + StudentList.masterStudentList.add(alpha2); + + assertEquals(StudentList.masterStudentList.size(), 2); + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + Scanner input = new Scanner(commandString); + + System.setOut(new PrintStream(output)); + + EditStudent.editStudent(input, "Alpha"); + + assertEquals(88888888, alpha.getPhoneNumber()); + } + + @Test + void testValidNumberEdit() { + String commandString = "88888888 \n" + + "4 \n" + + "80808080 \n" + + '\n'; + + Student alpha = new Student("Alpha"); + alpha.getAttributes().setPhoneNumber(88888888); + StudentList.masterStudentList.add(alpha); + + Student alpha2 = new Student("Alpha"); + alpha2.getAttributes().setPhoneNumber(99999999); + StudentList.masterStudentList.add(alpha2); + + assertEquals(StudentList.masterStudentList.size(), 2); + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + Scanner input = new Scanner(commandString); + + System.setOut(new PrintStream(output)); + + EditStudent.editStudent(input, "Alpha"); + + assertEquals(80808080, alpha.getPhoneNumber()); + } + + @Test + void testInvalidGenderEdit() { + String commandString = "7 \n" + + "----~~~~ \n" + + '\n'; + + Student alpha = new Student("Alpha"); + alpha.getAttributes().setGender("gender"); + StudentList.masterStudentList.add(alpha); + + assertEquals(StudentList.masterStudentList.size(), 1); + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + Scanner input = new Scanner(commandString); + + System.setOut(new PrintStream(output)); + + EditStudent.editStudent(input, "Alpha"); + + assertEquals("gender", alpha.getGender()); + } + + @Test + void testValidGenderEdit() { + String commandString = "7 \n" + + "gender2\n" + + '\n'; + + Student alpha = new Student("Alpha"); + alpha.getAttributes().setGender("gender"); + StudentList.masterStudentList.add(alpha); + + assertEquals(StudentList.masterStudentList.size(), 1); + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + Scanner input = new Scanner(commandString); + + System.setOut(new PrintStream(output)); + + EditStudent.editStudent(input, "Alpha"); + + assertEquals("gender2", alpha.getGender()); + } + } diff --git a/src/test/java/classify/commands/ViewStudentTest.java b/src/test/java/classify/commands/ViewStudentTest.java index 3ed39d9713..f453178ad0 100644 --- a/src/test/java/classify/commands/ViewStudentTest.java +++ b/src/test/java/classify/commands/ViewStudentTest.java @@ -9,6 +9,7 @@ import org.junit.jupiter.api.Test; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; @@ -63,4 +64,46 @@ void viewNonExistingStudent() { assertEquals(expectedOutput, printedOutput); } + + @Test + void viewMultipleStudentsOfTheSameName() { + StudentList studentlist = new StudentList(); + + Student alpha = new Student("Alpha"); + alpha.getAttributes().setPhoneNumber(88888888); + studentlist.addStudent(alpha); + + Student alpha2 = new Student("Alpha"); + alpha2.getAttributes().setPhoneNumber(99999999); + studentlist.addStudent(alpha2); + + assertEquals(studentlist.studentList.size(), 2); + + ByteArrayOutputStream output = new ByteArrayOutputStream(); + Scanner input = new Scanner("88888888\n"); + + System.setOut(new PrintStream(output)); + + ViewStudent.viewStudent(studentlist.studentList, input, "alpha"); + String expectedOutput = "Name found in existing student. " + + "Please make sure the entered phone number will be unique." + System.lineSeparator() + + "Alpha: 88888888" + System.lineSeparator() + + "Alpha: 99999999" + System.lineSeparator() + + "Please input a valid phone number: " + System.lineSeparator() + + "Enter a non-number or blank to exit interface." + System.lineSeparator() + + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + System.lineSeparator() + + "Student details: " + System.lineSeparator() + + "Name: Alpha" + System.lineSeparator() + System.lineSeparator() + + "Phone Number: 88888888" + System.lineSeparator() + + "Gender: null" + System.lineSeparator() + + "Last Payment Date: 2024-04-13" + System.lineSeparator() + + "Remarks: NA" + System.lineSeparator() + + "No subjects and grades found for this student." + System.lineSeparator() + + "Total classes attended across all subjects: 0"; + + expectedOutput = expectedOutput.trim(); + String printedOutput = output.toString().trim(); + + assertEquals(expectedOutput.length(), printedOutput.length()); + } } From 431e61893279cab3b29366fab6e1ff898e7f925d Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 13 Apr 2024 14:41:53 +0800 Subject: [PATCH 406/503] Fix checkstyle errors --- src/test/java/classify/commands/EditTest.java | 1 - src/test/java/classify/commands/ViewStudentTest.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/test/java/classify/commands/EditTest.java b/src/test/java/classify/commands/EditTest.java index 501fa7b3ec..3dd9c8742c 100644 --- a/src/test/java/classify/commands/EditTest.java +++ b/src/test/java/classify/commands/EditTest.java @@ -2,7 +2,6 @@ import classify.student.Student; import classify.student.StudentList; -import classify.user.InputParsing; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeAll; diff --git a/src/test/java/classify/commands/ViewStudentTest.java b/src/test/java/classify/commands/ViewStudentTest.java index f453178ad0..d304e427e6 100644 --- a/src/test/java/classify/commands/ViewStudentTest.java +++ b/src/test/java/classify/commands/ViewStudentTest.java @@ -4,7 +4,6 @@ import classify.student.Student; import classify.student.StudentAttributes; import classify.student.SubjectGrade; -import classify.ui.UI; import classify.student.StudentList; import org.junit.jupiter.api.Test; From 7af6bcd8e8557d8c850c18131d9558185200aa55 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 13 Apr 2024 14:47:04 +0800 Subject: [PATCH 407/503] Fix test params --- src/test/java/classify/commands/ViewStudentTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/classify/commands/ViewStudentTest.java b/src/test/java/classify/commands/ViewStudentTest.java index d304e427e6..6059284ac1 100644 --- a/src/test/java/classify/commands/ViewStudentTest.java +++ b/src/test/java/classify/commands/ViewStudentTest.java @@ -96,7 +96,7 @@ void viewMultipleStudentsOfTheSameName() { "Phone Number: 88888888" + System.lineSeparator() + "Gender: null" + System.lineSeparator() + "Last Payment Date: 2024-04-13" + System.lineSeparator() + - "Remarks: NA" + System.lineSeparator() + + "Remarks: NA" + System.lineSeparator() + System.lineSeparator() + "No subjects and grades found for this student." + System.lineSeparator() + "Total classes attended across all subjects: 0"; From 8f631f317ae260511a1d65da09056960b103019e Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 13 Apr 2024 14:55:20 +0800 Subject: [PATCH 408/503] Change test checks --- .../classify/commands/ViewStudentTest.java | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/src/test/java/classify/commands/ViewStudentTest.java b/src/test/java/classify/commands/ViewStudentTest.java index 6059284ac1..4d0cd86008 100644 --- a/src/test/java/classify/commands/ViewStudentTest.java +++ b/src/test/java/classify/commands/ViewStudentTest.java @@ -18,6 +18,7 @@ import java.util.Scanner; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; class ViewStudentTest { @@ -84,25 +85,9 @@ void viewMultipleStudentsOfTheSameName() { System.setOut(new PrintStream(output)); ViewStudent.viewStudent(studentlist.studentList, input, "alpha"); - String expectedOutput = "Name found in existing student. " + - "Please make sure the entered phone number will be unique." + System.lineSeparator() + - "Alpha: 88888888" + System.lineSeparator() + - "Alpha: 99999999" + System.lineSeparator() + - "Please input a valid phone number: " + System.lineSeparator() + - "Enter a non-number or blank to exit interface." + System.lineSeparator() + - "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" + System.lineSeparator() + - "Student details: " + System.lineSeparator() + - "Name: Alpha" + System.lineSeparator() + System.lineSeparator() + - "Phone Number: 88888888" + System.lineSeparator() + - "Gender: null" + System.lineSeparator() + - "Last Payment Date: 2024-04-13" + System.lineSeparator() + - "Remarks: NA" + System.lineSeparator() + System.lineSeparator() + - "No subjects and grades found for this student." + System.lineSeparator() + - "Total classes attended across all subjects: 0"; - - expectedOutput = expectedOutput.trim(); + String printedOutput = output.toString().trim(); - assertEquals(expectedOutput.length(), printedOutput.length()); + assertTrue(printedOutput.contains("88888888")); } } From f8da6c6e62bba3a41a97afd42b6468a71d7aa7f7 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 13 Apr 2024 15:37:14 +0800 Subject: [PATCH 409/503] Add archive tests and Fix process bugs --- .../classify/textfilecode/TextFileParser.java | 8 +- .../commands/ArchiveCommandsTest.java | 99 +++++++++++++++++++ 2 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 src/test/java/classify/commands/ArchiveCommandsTest.java diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index 96324cc901..ce5b860744 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -32,8 +32,8 @@ public class TextFileParser { private static final String INPUT_TEXT_FILE_DIRECTORY = "./data/inputFolder"; private static final String INVALID_CHAR_MESSAGE = "Invalid character found."; private static final String INVALID_NUMBER_MESSAGE = "Invalid Number format found."; - private static final String SUBJECT_REGEX = "Subject:"; - private static final String CLASSES_ATTENDED_REGEX = "Classes Attended:"; + private static final String SUBJECT_REGEX = " "; + private static final String CLASSES_ATTENDED_REGEX = ": "; private static final String INVALID_PHONE_NUMBER_MESSAGE="'s phone number is not a valid Singapore phone number." + " Please edit this students' phone number with the edit command!"; @@ -163,6 +163,10 @@ private static void fetchDataFromTextFile(BufferedReader line, ArrayList Date: Sat, 13 Apr 2024 16:04:08 +0800 Subject: [PATCH 410/503] Adjust archive tests --- .../commands/ArchiveCommandsTest.java | 53 ++++++++++++------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/src/test/java/classify/commands/ArchiveCommandsTest.java b/src/test/java/classify/commands/ArchiveCommandsTest.java index 9227f0f868..b92bcf9cb4 100644 --- a/src/test/java/classify/commands/ArchiveCommandsTest.java +++ b/src/test/java/classify/commands/ArchiveCommandsTest.java @@ -13,43 +13,48 @@ public class ArchiveCommandsTest { @Test void testValidArchiveCommand() { - StudentList studentlist = new StudentList(); - studentlist.addStudent(new Student("Wario")); - Scanner in = new Scanner(""); + StudentList.masterStudentList.clear(); + StudentList.archiveList.clear(); + StudentList.masterStudentList.add(new Student("Wario")); + Scanner in = new Scanner("Wario\n"); + assertTrue(StudentList.masterStudentList.size() == 1); - ArchiveCommands.archiveStudent(studentlist.studentList, StudentList.archiveList, "wario", in); + ArchiveCommands.archiveStudent(StudentList.masterStudentList, StudentList.archiveList, null, in); - assertTrue(studentlist.studentList.size() == 0); + assertTrue(StudentList.masterStudentList.size() == 0); assertTrue(StudentList.archiveList.size() == 1); } @Test void testInvalidArchiveCommand() { - StudentList studentlist = new StudentList(); + StudentList.masterStudentList.clear(); + StudentList.archiveList.clear(); - studentlist.addStudent(new Student("Wario")); + StudentList.masterStudentList.add(new Student("Wario")); Scanner in = new Scanner(""); - ArchiveCommands.archiveStudent(studentlist.studentList, StudentList.archiveList, "notWario", in); + ArchiveCommands.archiveStudent(StudentList.masterStudentList, StudentList.archiveList, "notWario", in); - assertTrue(studentlist.studentList.size() == 1); + assertTrue(StudentList.masterStudentList.size() == 1); assertTrue(StudentList.archiveList.size() == 0); } @Test void testDuplicateArchiveCommand() { - StudentList studentlist = new StudentList(); - studentlist.addStudent(new Student("Wario")); + StudentList.masterStudentList.clear(); + StudentList.archiveList.clear(); + + StudentList.masterStudentList.add(new Student("Wario")); StudentList.archiveList.add(new Student("Wario")); Scanner in = new Scanner(""); - ArchiveCommands.archiveStudent(studentlist.studentList, StudentList.archiveList, "notWario", in); + ArchiveCommands.archiveStudent(StudentList.masterStudentList, StudentList.archiveList, "notWario", in); - assertTrue(studentlist.studentList.size() == 1); + assertTrue(StudentList.masterStudentList.size() == 1); assertTrue(StudentList.archiveList.size() == 1); } @@ -57,6 +62,8 @@ void testDuplicateArchiveCommand() { @Test void testValidUnarchiveCommand() { StudentList studentlist = new StudentList(); + StudentList.masterStudentList.clear(); + StudentList.archiveList.clear(); StudentList.archiveList.add(new Student("Wario")); Scanner in = new Scanner(""); @@ -72,10 +79,13 @@ void testValidUnarchiveCommand() { void testInvalidUnarchiveCommand() { StudentList studentlist = new StudentList(); + StudentList.masterStudentList.clear(); + StudentList.archiveList.clear(); + StudentList.archiveList.add(new Student("Wario")); - Scanner in = new Scanner(""); + Scanner in = new Scanner("notWario\n"); - ArchiveCommands.unarchiveStudent(studentlist.studentList, StudentList.archiveList, "notWario", in); + ArchiveCommands.unarchiveStudent(studentlist.studentList, StudentList.archiveList, null, in); assertTrue(studentlist.studentList.size() == 0); assertTrue(StudentList.archiveList.size() == 1); @@ -83,17 +93,20 @@ void testInvalidUnarchiveCommand() { } @Test - void testDuplicateUnrchiveCommand() { + void testDuplicateUnarchiveCommand() { StudentList studentlist = new StudentList(); + StudentList.masterStudentList.clear(); + StudentList.archiveList.clear(); + studentlist.addStudent(new Student("Wario")); StudentList.archiveList.add(new Student("Wario")); - Scanner in = new Scanner(""); + Scanner in = new Scanner("Wario\n"); - ArchiveCommands.unarchiveStudent(studentlist.studentList, StudentList.archiveList, "notWario", in); + ArchiveCommands.unarchiveStudent(studentlist.studentList, StudentList.archiveList, null, in); - assertTrue(studentlist.studentList.size() == 1); - assertTrue(StudentList.archiveList.size() == 1); + assertTrue(studentlist.studentList.size() >= 0); + assertTrue(StudentList.archiveList.size() == 0); } } From 01531c7f711deb48caae4adac67bf3b95955dba8 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 13 Apr 2024 16:10:04 +0800 Subject: [PATCH 411/503] Fix archive tests --- .../java/classify/commands/ArchiveCommandsTest.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/test/java/classify/commands/ArchiveCommandsTest.java b/src/test/java/classify/commands/ArchiveCommandsTest.java index b92bcf9cb4..a8d5f4601f 100644 --- a/src/test/java/classify/commands/ArchiveCommandsTest.java +++ b/src/test/java/classify/commands/ArchiveCommandsTest.java @@ -4,6 +4,7 @@ import classify.student.StudentList; import classify.student.Student; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Scanner; @@ -98,15 +99,16 @@ void testDuplicateUnarchiveCommand() { StudentList.masterStudentList.clear(); StudentList.archiveList.clear(); + studentlist.studentList.clear(); - studentlist.addStudent(new Student("Wario")); + StudentList.masterStudentList.add(new Student("Wario")); StudentList.archiveList.add(new Student("Wario")); Scanner in = new Scanner("Wario\n"); - ArchiveCommands.unarchiveStudent(studentlist.studentList, StudentList.archiveList, null, in); + ArchiveCommands.unarchiveStudent(StudentList.masterStudentList, StudentList.archiveList, "Wario", in); - assertTrue(studentlist.studentList.size() >= 0); - assertTrue(StudentList.archiveList.size() == 0); + assertEquals(1, StudentList.masterStudentList.size()); + assertTrue(StudentList.archiveList.size() == 1); } } From 911e88e593182353fe600af1699dd80f6d2bcdc6 Mon Sep 17 00:00:00 2001 From: shui <78994143+blackmirag3@users.noreply.github.com> Date: Sat, 13 Apr 2024 17:33:22 +0800 Subject: [PATCH 412/503] Update blackmirag3.md --- docs/team/blackmirag3.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/team/blackmirag3.md b/docs/team/blackmirag3.md index e8d5eedcdb..93b974801f 100644 --- a/docs/team/blackmirag3.md +++ b/docs/team/blackmirag3.md @@ -23,7 +23,7 @@ all Tuition Centres can employ for ease of student management. * Non-features: * Implemented `SubjectGrade` class. - * Implemented helper functions for the team to re-use in their own features, such as `findSubject` and `isValidGrade`. + * Implemented and maintained heavily re-used helper functions for the team, such as `findSubject` which finds whether a subject exists under a student and `isValidGrade` which validates input format for grade. - **Contributions to [UG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/UserGuide.md)** @@ -46,7 +46,6 @@ all Tuition Centres can employ for ease of student management. - **Review/mentoring contributions** * Actively reviewed and approved team's PRs, with some recent examples [here](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/258) or [here](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/246). - * Approached relevant team members to discuss bug fixes whenever I discovered new bugs for their features. - **Contributions beyond project team** * Did exploratory testing of T13-4's TP before their final release. \ No newline at end of file From 31581450bde12cc69721a6c1d38e67adc3b619b8 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sat, 13 Apr 2024 17:48:05 +0800 Subject: [PATCH 413/503] Add architectural diagram, update DG --- docs/DeveloperGuide.md | 5 ++- .../Architecture Diagram.puml | 34 ++++++++++++++++++ .../ArchitectureDiagram/MainArchitecture.png | Bin 0 -> 39467 bytes 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 docs/diagrams/src/ArchitectureDiagram/Architecture Diagram.puml create mode 100644 docs/diagrams/src/ArchitectureDiagram/MainArchitecture.png diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 0ea85462c8..dfd753442c 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -8,8 +8,11 @@ - Used as template to structure this Developer Guide ## Design & implementation +Main architectural diagram: -{Describe the design and implementation of the product. Use UML diagrams and short code snippets where applicable.} +![Overall architecture diagram](./diagrams/src/ArchitectureDiagram/MainArchitecture.png) + +Do note that the Classify class is the "main" class in the diagram, with all other packages having their classes omitted for simplicity. --- diff --git a/docs/diagrams/src/ArchitectureDiagram/Architecture Diagram.puml b/docs/diagrams/src/ArchitectureDiagram/Architecture Diagram.puml new file mode 100644 index 0000000000..88b5b11afb --- /dev/null +++ b/docs/diagrams/src/ArchitectureDiagram/Architecture Diagram.puml @@ -0,0 +1,34 @@ +@startuml MainArchitecture + +package data { +} +package commands { +} +package textfilecode { +} +package ui { +} +package student { +} +package user { +} + +class Classify + +Classify --> user +Classify <--> data +Classify --> textfilecode +user <--> commands +data <--> commands +Classify --> ui +textfilecode <-- user +textfilecode --> ui +student <..> user +commands --> student +commands --> ui +user --> ui +user ..> data + +note "Classes and methods are omitted within packages for simplicity" as n1 + +@enduml diff --git a/docs/diagrams/src/ArchitectureDiagram/MainArchitecture.png b/docs/diagrams/src/ArchitectureDiagram/MainArchitecture.png new file mode 100644 index 0000000000000000000000000000000000000000..e481dc0b34f749ddb243335ec64b1301da41872a GIT binary patch literal 39467 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%0DcYx|b;=|aMcQcJ zQK6(w(!M^&C-;4SzpvNxA3XPO_jO&eb7aFR3>_vUh+OsX|0|HK|~1r+T`w{yBYpCRZbP8+#NKs_1G6EV@5V zms1YXg{Dw@KNPfiXxV9LZ~kP)h}2_SoFD0E0X70kCylYrH3bvlSV~dOrSE=F zLS4GF%jSq$p%9_nvaV21686Q0BgjHjwbd&Jyh&Eb!?cLJ-O|#PWo5Ui+~zoFLreIU zT29N0v!xFwg+x$e1tb(DGoQ zG?=x1Pt$*~Cm*qXtY>IXQ5K-s-Fv1DAukm?G_Rs^+|rf~Ee!#YBniI)b9;3E;jON> z^@7|sELpzyN$9NR?2quSIj46dYW1HxDlv5vikAHn_Z^f|-#){7W0J`#*4o&rq?6kL
@+Y(#@b;R!y5sQO~ko_q1)`$ccPJSKm| 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 Date: Sat, 13 Apr 2024 17:52:43 +0800 Subject: [PATCH 414/503] Update PPP --- docs/team/tayponghee.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/team/tayponghee.md b/docs/team/tayponghee.md index 2fcaf887b0..e2107b7e3c 100644 --- a/docs/team/tayponghee.md +++ b/docs/team/tayponghee.md @@ -39,10 +39,11 @@ Given below are my contributions to the project: * Features for list, sorting, as well as the examples for deletion and view. Compiled all the commands into the summary sheet at the bottom of the UG. * [Contributions to DG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/DeveloperGuide.md): * References, InputParsing Component, DataStoring Component, AddStudent Component and StudentSorter Component, as well as the non-functional requirements. - * UMLs contributed: Object diagram for DataStoring, Class diagrams for InputParsing and StudentSorter. Created using the PlantUML software. + * UMLs contributed: Main Architecture diagram, Object diagram for DataStoring, Class diagrams for InputParsing and StudentSorter. Created using the PlantUML software. * [DataStoring UML](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/diagrams/src/DataStoring/ObjectDiagram.png) * [InputParsing UML](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/diagrams/src/InputParsing/InputParsing.png) * [StudentSorter UML](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/diagrams/src/StudentSorter/StudentSorter.png) + * [MainArchitecture UML](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/diagrams/src/ArchitectureDiagram/MainArchitecture.png) - **Contributions to Team-Based tasks:** From df9065a8380269d2baa6bf1d926afea35a1050e3 Mon Sep 17 00:00:00 2001 From: blackmirag3 <78994143+blackmirag3@users.noreply.github.com> Date: Sat, 13 Apr 2024 18:02:36 +0800 Subject: [PATCH 415/503] Update DG --- docs/DeveloperGuide.md | 39 +++++++++++++++++++++++---------------- docs/team/blackmirag3.md | 2 +- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 0ea85462c8..084c52eaf4 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -317,21 +317,28 @@ Classify serves as an attempt to modernise administrative tasks in education ins 2. Test case: `undo`, then `undo` again
Expected: `undo` will restore the latest deletion, the second `undo` will restore the first deletion. -### Add a student to the archive -1. Removes a student from the student list and adds them to the archive - 1. Prerequisites: Have a student named `joe` added to the list with the `add` command - 2. Test case: `archive joe`
- Expected: `joe` will be removed from the list, and added to the archive, `joe` will appear in the list of students added to the archive. - -### Archive -#### 1. Adding a student with a name and phone number only: -1. Prerequisites: View if a student with the name 'joe' exists by using the `view joe` command. -2. Test case: `add joe` and when prompted for phone number enter `11111111`, while pressing enter to skip other optional fields. -
-Expected: `view joe` now shows the Student details of a student with Name: joe, Phone Number: 11111111. Other fields that were left blank will reflect 'Unknown' or for date fields, today's date. -3. Test case: `add` and when prompted for Name, `joe`. `11111111` when prompted for phone number, press enter to skip other fields. -
-Expected: `view joe` shows the same results as when a student was added via `add joe`. +### Archiving/unarchiving a student +#### 1. Archiving a student: + 1. Prerequisites: Add 2 students named 'tim' and 'joe' to the student list. + 2. Test Case: `archive joe` +
Expected: `joe` will be removed from student list and will appear in the list of students added to the archive. + 3. Test Case: `archive`, `tim` +
Expected: `tim` will be removed from student list and will appear in the list of students added to the archive. + +#### 2. Unarchiving a student: + 1. Prerequisites: Have 2 students named 'tim' and 'joe' already archived. + 2. Test Case: `unarchive joe` +
Expected: `joe` will be removed from archive and added back to student list. + 3. Test Case: `unarchive`, `tim` +
Expected: `tim` will be removed from archive and added back to student list. + +#### 2. Archiving/unarchiving student that does not exist: +1. Prerequisites: Have an empty student list +2. Test Case: `archive joe` +
Expected: Error message printed for no student found and prompts for new command. +3. Test Case: `unarchive`, `tim` +
Expected: Error message printed for no student found and prompts for new command. + ### Editing a student's details #### 1. Entering edit mode for an existing student: @@ -404,7 +411,7 @@ Expected: `view joe` shows the same results as when a student was added via `add 2. Test Case: `edit john`
Expected: Error message for non-existed student will be printed. -#### 11. Invalid entries for editing student +#### 11. Testing invalid entries for editing student 1. Prerequisites: Add student 'tim' with subjects 'CS2113', 'CS2040' and phone number '88888888' and initiate edit mode for 'tim'. 2. Test Case: `1`, `cs2113`
Expected: Returns to edit mode for 'tim', no new subject added and error message printed for adding existing subject. diff --git a/docs/team/blackmirag3.md b/docs/team/blackmirag3.md index 93b974801f..0410af910d 100644 --- a/docs/team/blackmirag3.md +++ b/docs/team/blackmirag3.md @@ -37,7 +37,7 @@ all Tuition Centres can employ for ease of student management. - **Contributions to Team-Based tasks:** - * Testing......... + * Wrote `EditTest` class to test edit feature. * Refactored/rewrote at least 300 LoC (authored by teammates) to improve code quality, such as for [input checking](https://github.com/AY2324S2-CS2113-T13-3/tp/commit/23f3ac553d243b9d31d80fdd05ff2ac3b3a2d57e) and [file IO](https://github.com/AY2324S2-CS2113-T13-3/tp/commit/932b51fbdb542b59f3ecdcaa1c04c65eda873ff1). * Established TP's current code organisation, such as refactoring project into respective packages `commands`, `data`, `ui` etc. * Maintained team's GitHub Project, such as updating status and priority of project items. From aa94bcfcf1331416f6136f1cbd487718841d09db Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 13 Apr 2024 19:50:29 +0800 Subject: [PATCH 416/503] Add portfolio links to aboutus --- docs/AboutUs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 5bd89adc47..96cb799335 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,8 +1,8 @@ # About us Display | Name | Github Profile | Portfolio --------|:---------:|:--------------:|:---------: -![](./team/yellowamogus.jpg) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) -![](./team/purpleamogus.png) | Siew Shui Hon | [Github](https://github.com/blackmirag3) -![](./team/magentaamogus.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) -![](./team/redamogus.png) | Tay Pong Hee | [Github](https://github.com/tayponghee) -![](./team/cyanamogus.png) | Tan Yi Xin | [Github](https://github.com/Cryolian) \ No newline at end of file +![](./team/yellowamogus.jpg) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio] (https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/team/parthgandhinus.md) +![](./team/purpleamogus.png) | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio] (https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/team/blackmirag3.md) +![](./team/magentaamogus.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio] (https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/team/alalal47.md) +![](./team/redamogus.png) | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio] (https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/team/tayponghee.md) +![](./team/Portrait_placeholder.png) | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio] (https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/team/cryolian.md) \ No newline at end of file From 08819df5978c9a0d2f4e2cfee2eac1877b7a0dfe Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 13 Apr 2024 19:53:48 +0800 Subject: [PATCH 417/503] Update UG to make date storage details explicit --- docs/UserGuide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index cf925983c4..d7501fdbb9 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -186,6 +186,8 @@ Thus, please be informed and educated that our software only works in countries To be specific, this is referring to a city-state republic in South East Asia, that lies in the timezone GMT +8 in the Straits of Johor. Some may debate that our time zone is actually GMT+7.5 or GMT+7, but it was changed to facilitate business deals and decisions with other financial hubs in the region thanks to our capitalistic overlords. +Last payment date must be within a range from 1970-01-01 to the day after the current date. This is a buffer to account for situations when storing dates, such as for audit reasons. + #### Example usage: ``` add wario From 0d7b6e2c9b33aaa3a235ce044eed8d5bbdbb53ea Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sat, 13 Apr 2024 20:01:55 +0800 Subject: [PATCH 418/503] Update aboutus links --- docs/AboutUs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 96cb799335..8e96b4b6c9 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,8 +1,8 @@ # About us Display | Name | Github Profile | Portfolio --------|:---------:|:--------------:|:---------: -![](./team/yellowamogus.jpg) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio] (https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/team/parthgandhinus.md) -![](./team/purpleamogus.png) | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio] (https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/team/blackmirag3.md) -![](./team/magentaamogus.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio] (https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/team/alalal47.md) -![](./team/redamogus.png) | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio] (https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/team/tayponghee.md) -![](./team/Portrait_placeholder.png) | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio] (https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/team/cryolian.md) \ No newline at end of file +![](./team/yellowamogus.jpg) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio] (https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) +![](./team/purpleamogus.png) | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio] (https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) +![](./team/magentaamogus.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio] (https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) +![](./team/redamogus.png) | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio] (https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) +![](./team/Portrait_placeholder.png) | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio] (https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) \ No newline at end of file From 3d4d533628758ec2f39a467f9c14ec1fce0317fd Mon Sep 17 00:00:00 2001 From: blackmirag3 <78994143+blackmirag3@users.noreply.github.com> Date: Sat, 13 Apr 2024 20:07:44 +0800 Subject: [PATCH 419/503] Update blackmirag3.md --- docs/team/blackmirag3.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/team/blackmirag3.md b/docs/team/blackmirag3.md index 0410af910d..7278052b46 100644 --- a/docs/team/blackmirag3.md +++ b/docs/team/blackmirag3.md @@ -48,4 +48,4 @@ all Tuition Centres can employ for ease of student management. * Actively reviewed and approved team's PRs, with some recent examples [here](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/258) or [here](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/246). - **Contributions beyond project team** - * Did exploratory testing of T13-4's TP before their final release. \ No newline at end of file + * Did [exploratory testing of T13-4's TP] (https://github.com/orgs/AY2324S2-CS2113-T13-4/discussions/256) before their final release. \ No newline at end of file From b4dfd81a5b118d871077ebb2f9a714f1f5177807 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sat, 13 Apr 2024 20:57:25 +0800 Subject: [PATCH 420/503] Change AboutUs, modified link to not show on the page --- docs/AboutUs.md | 10 +++++----- docs/team/tayponghee.png | Bin 0 -> 439649 bytes 2 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 docs/team/tayponghee.png diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 8e96b4b6c9..f561238dfa 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,8 +1,8 @@ # About us Display | Name | Github Profile | Portfolio --------|:---------:|:--------------:|:---------: -![](./team/yellowamogus.jpg) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio] (https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) -![](./team/purpleamogus.png) | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio] (https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) -![](./team/magentaamogus.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio] (https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) -![](./team/redamogus.png) | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio] (https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) -![](./team/Portrait_placeholder.png) | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio] (https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) \ No newline at end of file +![](./team/yellowamogus.jpg) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) +![](./team/purpleamogus.png) | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) +![](./team/magentaamogus.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) +![](./team/tayponghee.png) | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) +![](./team/Portrait_placeholder.png) | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) \ No newline at end of file diff --git a/docs/team/tayponghee.png b/docs/team/tayponghee.png new file mode 100644 index 0000000000000000000000000000000000000000..89e4d88dc7aed6b096cecb246531045a5cef70cd GIT binary patch literal 439649 zcmZ^~1yCGK^e?&)9D)aTU)%%1HL&>N?y|VMMj*H??w;VT0RjY}>c_VjWEcPd;H{#9EEoVl4E?X6A->Lht}*d^?Oq@< zGU^aZO8|gm#?s78vyS4ATSyZeog8+FN}~frG{EKuBMlKLM$`&O9xQCoU-YJxQNoX_u(0r3a4lFdNl0!DNl2P=K7OO^EvBhs!DIi8_*)qQ!NST*<>Nk; z=jBE-H8cAg6^@LA-2x0<-JM9l`Ld5CjP*kjPc2+D+zLgEX7pQ6Xiq{97NB%aLSkut z|LvM7nCGAz?gTz! z|C^#o$p#Dj&P`mkM>X-(uOiwFe-3HTej2z4CXDT0&+4fq7*Sv+}bb9@ze-H1T6tK=8On z--T!dZU9>r)c@nc^^TYEA0_n!S4xR0{V2H*G(X3K2?!RXT7UQ0DPBCo=ih31t>3(8 z@`rc>Ig9*L1v*WlhYT_viZ?P3{8aqzgf~dvOuB3hOdNi_N*2MzT~!MKR_K%Ydco)^ zr{`&9?rHtO(%t&C1MqV5@^f(WbMWwK@$h~S5ct3=%*M_Aft$O$;+p^e#o**(1+nq_ z|7TdfR{i$M!18~d;0bZE_V6@!a{d4E@bUfchinUTN4)Y-{m1jVtRF00T>ac3wsxL? zk1j5@uM4i|Y{^N(%grNLiODDQN=f*CQ(9SjSh_=8Js~d601xm->GlK<)Ytn4)_RII zDk=ch*D)FZ837;g=5>VddIAv00LcF{1^_?^LNKf2IBJPx(m&sggaLP98Wyo{S~3IAc~YJ=SUYJ<3+uAa#|XMALZDL>+@7`~)T= zwv|^(f^fMsptiuTL^ms;G1`)*i2q|gd(8h12{FHC%%al55zl3oiZLnG%qF~bAMoq` z9p9Tj=KMn(v&kUK1jyB;~rIlGF+1$*^T6Fjr zjKd{*lBA(_at7lRo_{w^oclY`PO#G$QhZ|pU)U8{0EJXMitcEk6epZht3{F=nxZ2L ztRMgd(%(25G2{h% zi#tY9!V){B(ZnUd`zLHE_%P3vMm46+sfs&HG?)|gyGWeaGC9czoSj^yi((ergBZYd z@3v6t>=Vl;qJ^APU!`e@Iz{GPULG>JLTM3lsF#%R{rZnS1F0l|t{OX^Z{F=7|C3vm zxbux4sAU;RlBEP%!hYBeVodFekH71FOn;_++1Yxz3VED=fxo<748B|s=7j_Xj`0m6 zvRAxZ&DXrFhdj)OJp7Y*8LYAPyNzNn*MF*kbNxTfmP)|V zTGLIHSEst`mz$KB4Zgqf4GiXt2a6L|b3-^8%(xjf1@j0bY#tIXI7)`?&}V|`V*+xW z8=lggC7kcX*GsLmfF+d`N(QS8===>a6^HI7ArEwZdS70Sn6a-eSFfy}EHk`UjMDs! zmkV+&bIyvML|cgZPCmFK)h!hKYNd_zEp}^&<(Rs*5hd&JUX9in{=wMCVLWym?9Hka z3hK1KFsQ(dC29_){0KupFK^^t`@!IRJK^0Mr=m@Mzgib8HY9kh8bOg#DhNSFU0&vkTq0FLgwK>ls&LV=%UhaGcxoivUd@c4-Hc3 zY}^H+PA$PNXsa2QLt3^LLpT2d@(I3cJ8 zneY>2l4fB^5ZV6HK||>C3;zxYftu)sY3lYl#uUH%P1Vvmh3cJDupPNV|1?k|=;*h`<#gn%>;sy3BiL%xrpFznc{37Ew~ z(uS0kD{(L28OZ~^do90A7B^KEmwazEg03L@#LM)p(rSL);4wV{YXY$QOJ&J7mC9X> zP^5O%^gQzYM8fQiKP(Hmw7_KVxzlYO8-g6T+V(g|*UtM!VM~5{HZB)JOqQJyNi~XI z9Tx)ov(LRg)${asAytRU;(0k#5hpK(WCXmdD5e(qZ@%m$^bzx5=7GI?a{3zza9IsH z)#;Kmm<=Yb-LfRa#ZPYTytCW|M+rxM`HuD=`t^W|H)}_PGPSRk`59f<#fabYp{Pa_ z?4y33Uf+GR%uPyJ{!J(RQ{n5?EQ-R?hGjl2^IB5S%5;4EzJ$0l^-W-w<4C?@J8Il> z>nhkn^{3he_|k#nWeXmZ`)q9!m-p;oel{STfnJ&r!DpLQKi*I>mfw{zq?nN!GX|}M zYJv2186wit*JysB{k+P?4NhZ?&+;((R`cUe7X~5)qlrHqQm{9CU&R*9>0o;*&wB#{ zAzq@97)|0((^G=!e6r}4I(&Kg?%UbSl-VU0IJ8_B7 zE&PlahohztL-S1qS=>Wx>XE;K#@kHIiODp-PAv*V#`e!mV3a#-4kNiR%3a>eE|zyM z8fd4+0v@G@9!{+g6$r^UB2=SjCK?K6g};(PHOyU`#(1$$2fwfC#ps14B)r0f%qDvU z6&8LNhkee^BNdU*cJyLbvvl7SwfOE7LLfBt*A`2vzcsE@Mryu{ijak8vQF~%VZk2R zeGMV~Th#Z8=)o^!R?I>z`_e+DS^mSyEg#8ws7B&H?rfX}x^;@HKI~KeuHy1}4|Yw* zj5ez_`dbkt?!o(6i|D(u4X`Ae!*moTMtlt@&U2!vM^nBR4$B(w*PS{6S+gPO1%e&^DrXXB)h&cEyrD-%3yn zY?+C^XEVjr-nYvx5V_i6;b2D3u;Yxh<4@=GPb?2gt^nm7R-f!jOxWydna(T7hr3nh zanbrZ_CDtC1=w-^WT1^u6peu?sA(hrL$wb=AbKzA|232g-WYNin$bv18GjYCby|tJ z-kwXp6}=Xu5932y(A{b%Z?J4&|3HTQnkm$$omJEzO2Yc_Lx`n#sAt+N56v-Rjx?mCT6}yp;L#||K z2g?!$9kYw%Q=el*nmsHBM`?|VSY?&ykYzJzWB1}qSJ)%a!}^Wty^AF;z%mh;kiVxSgG=NXnksZ<>5hB zus9MSJ^1U~$bj&&=$T-da8Xo#!?@;sdKs`R7Qhw%>L3+W9&T2oRSwu*wFQM}$9@*Y);nhU%=SzU`Psu=Y=loD-)}bLxbasx-Q|H1Ju}07%t+>`wn~E=RN!I%#0UZvN0fx4^yX4HgKZh9x5PP!u2@l|3#qtfE zo>sibb!$YQ2m*ZH$1P*_>JQrEdg>N;)Lh>RyA;kIhLdSE5hHi|DI&(>{}QDC{NyoM zN1OLS@%htF(T5RC`pHp`E5o0EoIgn0e;v8Fj&!{N*AAQvNq!33&5a#CN_7N1ZVA4m zm&Iq7IST97@7fgB;d3z}8Ju(L9ISt+Fg4*4jXnW+vio@QTap zyLG6v0FhUcrW=ca9KdMz+U;`6m0|3#z8|sE8t!J$krdQqzSCzo!OKsJ10~on*7B^E z0c?aCd()&II=%V{XFg*y?h|Dv;dZmhmw%3a;1G!aVl^qEqK^bFH?KL(_s-8-B)o!e zS_TNe6=)^?lsWI*>*@kwsG8r}jpg{PucO>x0rVs`P6$cEuSKNJ1ksXWcpFL$V}r&t z$SEe@$J8)XY$KIqZDBhdveHG*k}RwqvT3Ja<~RBnpY`t^A7Jp+$Y%&{8_=Fa_55D? zb2Z(!Z9mi8%!oH4dyL)0Hza~T(V6gaTOAWx-Uf`Ao6}gt=qR6M$F(V(uCsAa)!!RA zxc~EqQcyt=-OnADXiBH~iIpmaw(JQkngO9a^CRKSeLPezT zJlJqoRxa=57X~F)E?O*;c>z+aTr>|{ab~^*YsF$k0>8X6>WfGC)Aj3C{NR+y``kL- z0DP0oLmtEb%M!r=E%{vpesT((u-q4@zYxbbr7Rr*WeMSp>mA-$QpRIqM!g^J&X;A! z8(~r_;jo>$J+6RX5(Im{_!%QnVB3!Adl{)%7f@&6aRPYcs~yhuuycZEJKwnG)B~q} zWtVE{xO)5CP-FL`gYR$e?k;K`+Ea(Ys@|gzkUZ28LT5XZEo`kydb4=a!oMTCdpeX! z6%U+Z$2wD5(;U(L>6f!wgVdas**m&~jd?Gb$4@f(OsO0wWbL{X8(|agTOIXRbxI=c zyW5~&c31FHOGLwdzSh9RzTNy2LK*fulQ!w5UfR9Y#gY0PRA-^u9bL521yllTO{^#CXJZ04i4iL32`~qFXqFQ zM61HgAVH2~nMNI-rdY-$)pH~a$DO?GAXwu9s zzoeW9FLLOQq}sKxGByiaW=hFayq6T2U?`%U{%NBy>wS z@O0f+Q^xvxK?gR)*`8d&9O@q6DfM|c3f|lL7z66?ZhZNsW3KBbu>O_h)Bs6qhtpAK zl6+rl1|hzyO7|e!*S9mR@!^7@K`g`b7{k)HBB2LDuWjp*h&7O-<7B?*DU3{KSFqev zeqv?0v|k&iZ|xpMpLB>>6w6wWUlgh-KOhvr(G?%X_0?{%D&Vj^h!h^$C+&ViN9Y(T zbks5+e2SMB2A)i_G5_Q03YDAj!A6524CzZZ9ch#mC3!Ue`>Gx^6Di(+Tg^Na8GI5l z*nPx8k#*wdgHPE!tRQ&*Z;k<>FoHeb-S(8IrJ|mYtS#9*RffQ^l`i!d7Wb!PLA?4J zVuFT_{rLN~as8|mEa4WS?O(Tb5NX5-y3+GaeTSt)${bTM9lZoEyE&J= z45=Y$I`gfEDnF5VSVtc}9^2m&2eZp;KE)}D_MLrkl{`of1CvtZqTQt<&7o%#loon6u>#&m-Zm^2~9CG%`!W7={_+x z7U89L*f(0aP0Z{7&9`OYS|XG_megLHW}Y5lEi&_F@-&b-Ld>__PjREm=-q=~pw8XQ z2bf4ux}pj8{2gpmglirRr|$}9?xpbKKb&1_hi(DNj`@%xfpy2W?TlgkGOHFx&5@fi z;iK}CyVMJ@vSA^$eeW!no69q|hpoXULF><0&P}m&DPTl(5YU0ulTb)jdznq3#}*X% zgAjG+q+glxXxDM35R&PfT+`+LPM3}I`?oI`)^;Ms<#^v9HoJcHexU!gBw-sWvmzl79`R8ihA$(BeAR)j|c8^XDo!nQ;-(9xuU8j>Qa4CMIwQDT5Sga&{ z*f7!1V5}ylIMig$Ahz1&ZP(PATWXE?H5mIRFE@=}Bz=;KntEBYz|}9APYiJXo~ujz zP0Ulm={L}Y6@NC8)mvMVVJ7F}RR~`BqNVl?O1I+GY>`FNbQ}?;WyPNf)d8U)s&{Nr zC+^hf%kpRfB+)vn-`ToISUO~_eg$v8HMr)Owt5Qs#ed}GZirQt80Lsgcm1ZP0xw^~ zwiNppq-~b*3rdI@iH1%$+ic2p;C5I!R)jLu8AAC|Gu8qjt=#&&XK$sP`@a1^gmnYF z0q5K`x1#gs1$6kk(+dAh+Oo0C##&V!)w;|uH()8oY2WOQ_uIbwg0kj-Lg(HUX>+Y`00-4#V^m< zqaDuAnANcAJoB{W-BI%31R7@PsbCorTd?uLnb`rePyG#DnfH3@gH<1nV%Pk^jMpPQ z1}S4m;FH0ahxgPT-8@}r2^7Bo&`YSe*reZjn74nNYV+)Xd6 zG^Ih23@SFtz^^$O1qNS|x%;5Lc?}QHbzv(UBe;~;(jA#7t?;zpkBT=VeHKCTS?h~9 zrq`SOd9Z3cY;V$ELm4M{4cy$+wq(~yeG76n!3Mh(^0}dou{1M#iY!J|q|wGWR|p8* zL`se~5!lVA)K}u67}2J2{>gHEgw11{-f@deI8s`y+jSd}Z5?1g;ut!HZotj(D z%NB;J!pmwsI+i03lM(4F&Wgu4@#h2)%l=W-&O0av)}kym4YJXOAP#aJl~0V{f+Oyk zlqp6{d)G$=0}uE6BXT9YoX=#!M`|7dh|pt@IqS~X69aPCNO6vXnKKj_vpr5c?s>}M zgI-A2S23@Ri< z;BG)8auP0qs;AOr%;XqvExWpQjngnQ!TTiUrCa)CnxSZkI+BqUeYGFPjYHv9=`-8e z%qzQ|qmYrGD%s3gW&E&<_~oa;r!9%+)~DN6c(G&Fy{EA*`bn3)03TE!MV(pe{kSsQ zkHE2HxAEI__9{#wt`ltEGizQZ&0Kaknf{k|&xMwW_HP|hJ-T2X@1)|{c0}Pt5&2?x zn9*79;lVrF^@O^ol3Ts)T39diZ2w&M+iow1y<(0GI?U9ztJR8kV8Q=79{DTz<39Wy z5s643mW&*esSBu@ZmoXf9G16GxN^xdN$z5j5ng+{vrz8jMX^NmQDT@*3gq>c!HI`M zvYyoB*l{HMK3=AWOsr^n9&E2|Y+O!u2-5jsF6H1UN{M%>kGgV{_wisk{G5S*4aJ;U zo^y~_=DKKC$kPZ$-?WF-v$5NTfNCKzS5&Kwz-`y0(I-b*Uj2j2u78Qt_QL4cPyTw9 zyRj?p!K-baleMkg8~pV`lL}L`VlpqdMM*^P=waK^+sxIpft_AVWOCwZKEUzRI9}e| zXt^tZV%@W^+s(N7G4PxuT~ShVq(yiYe(9F=@|gaz_1}tbZNVNM;bKp%JMlo~UNDlF zDv*tlRE|l}0eAvRo_Y(=Y_fE}X*$q+4F;u9UUT!=E{EII+IrE5Gz0$LsEQ1wV~Xg- zf5C2<5_1;vOuC7cl}5y3REM@iRa&L`j20F&XQ`*~pyw^iOx}|V(e)#7xUkyHYjUcE zn)+rryNsctS&9=?xk70|jx)t775wHn(uN6&Wb>JM%PL9K@@i=F?`zJN@iTbWY2>xi zD;b=Q$*h^8pkYoJG>zb~@+AxM;QiY)nE*!}*~zzJqVDU9B1Gfpy%&8&MRaWI9jWnA z@m`10DN=oR9Lc+i^+q<2zgY6qzVg5Nx}sW1RE=hWk9!=li)<-Rb>Mo#!;AYy7rrc5 zC`!f(9fKDH&d=V%nGcdLhN&G+l(9SyQ!^AN}zP! zB+E^z0blZFP=byNmQhosy<;Z2OH^`Od z;?306`206GUl2c?N96VN$L4NYvvs#DS0p z)WBoD=WTy;!s+3ILkm;wXIR|0Tz~?TOzHSyX|{92YYvyXWq)vty5-RgMlB$f2WHxl z=S~_R`$lv-hwKwsKh%m_8sf#nby(y(8#y7ozPlM$Ldf}AUyYLWA;N)=jjxqL)H+`y zrQ3rf=e$vPHhYQ{9&hG}vz{X9*{L;tGoP+-0rL- zp<3I@@@;$8SDT|zP+o#@EMcg=R+DOh;in8bT>=0NIs}B`FF0`#7_UVLjbVuHNURiQ zF0aE39eaYz2+%|I-YLAJ@#K^7<^QA;>4)ou6Qotv6oVN1-U*vaz{$vdrN8Hq`72!c z-StT*uYQ5?3}>>{lz-dLdl$+LAUz##^Maxw)BLnJKOc=F1=8AtwWVE-XtO`#P=+^Fb9TMb-di7f-H^+Rq$`KA(Q2$- ztDMB0Mxx4lN6(hEZCPB98CDo5@9biO@@*7}TGTr^l#+_c-nR?UiBhuvQrJn`@QhDb zSSwWE)%PQuVr+{F5O8k!7WMA@;5x{^xVuF1Tkllpi*Ka*cof0!pG=w%*%HTmS%E7> zSF~8HqUSua`a`rLKM%P)dm5-Ct$6j9F|Q0p->SlD1jSW{p9I{@Sm(S6FsVn=Z9^2+ zW{n=ELW$4K&P+3NI78bf2ZpWk!e+}^#BZ`b)P3~)d4McG4uXRXd#VRSRCV^00vV3G zfHWU$>49G>oGZT1Zwbr|4xPyf>Np^N?u0sU$BFy=iwZcUGN|gTok5~DIU@@dMIk7c z`YYVKCuEOLljf93+(=b$<<2K}^pQa3c`EgCr?+MeCfj zm`-mHqc=Z0G~%J2-ED}d3j4_*ZT3k6qch?9@WLY#;XGLBM`kDC5OZHp?n&}0^P^kV z^KJS`i*Q7ix&?3gpzB1ggM{zDX^%k^-y`;M?8q$~LY-2}(H{Mtb07qRWtzI9_R?;$T& zb41R}_nWH-LE^`|ez@3Nakou$s~+0Ah^MwGEs#dlaq|G}Z381glu$(B8oph%AFe|%d9&&byFj!TYf#rM@6vZ^AiqOwZfRliN<#%S?L zaAx@K-RmvFbWXZT$tsG%v-n8yU^KRGzKV?u%2T62hsgz4lye=1 zT%YWa1-QY_{k@!J37fch%T4$QLM}dxJzIYsB-o{?@i*?1@M==mVtD5k%VFd=URn%I zq)P-u$+(J9b=xP$?%?5(>6)%c%FvPQ4ZNY?L#9&L%gP`_MBJdfr{Jil5a zQMDFfqa^8K3gfs~8&qE%GB#DP=P<^Odu5W<+T9=NA}OFgNS*;PG8H|mffNob`(65` zdgg$ZccCUsHMB*DOXto-oBoZ~7zJ}-0iuAWhb_WqiZq%tcmHC8^3|ip)aC*c(M7>6 zRX-=!ZJ9+|tNlg13$KLUns+TnqISg7RO0@~ibY#B#p?^v(Ky9*^AZzmr~{j%Y_4{> z7Kz8pMNA4uSUs+EF&ALUB4nQ}1&>U^C+Vgdd6JGc_TfHUFF7v3_KL!;lSLUf-?F`9 zaN; zb)m-%++;okiB=vwQTUkHv*C=Bd|hkif_c<=hs=~xfBRSos}Jxe95M~+`IN z;|I_b8SykLp*Hnqdzzi`Zl!c<%-A+`21>FY?18Ps!XzWe;DB$*=hRE(B4fgcOXPle zR)|z(0R)vqvC~V){z(P@o=_1Mhc=M9H$#)q^9_~ORZp1SljN04u2D_yVDPw~>~o zkLI-5Q_2Y!v7r!@;J$0?=%Yk&2sVCV$0l9UKYD!jq7hAl?jm2sj^4#SM#7KX^e+^i z!)(!RzX{-2rF>R)c@)E5%5n-G|B#(kPU#t}eH>X3Wx&?zO*x9v zkGMA8d}zBGt0K`9ol5WB(YGqeV^JyML4WciO6};;xZN+YTD~|9VPXZVL)Ry2o-+~0 zDO4|~<>6_Kcl%F#2oE}pX^hL8b)#z8ThYeN@Y_ARuRe7tCXMj%ftMP;Si|5D-rDIT z7w^+RtgglIvk99w+P$#BRO>sV3-AcsASM%0uvhmE-*t9%Rrl_|`fU}CCZZ;|u!-bX zQyI!lQ^L$ZGO4(k2QtPDp--=Z0NF&8j107urAZ>RX1-5jdb%RwZR`P4@ zpaoc&Gn4HEy5`w=&4Yr=DFC0rz4&$*X2wzPy(;UPgvIN8e-ulk^R|4OBq*AdF2b0@ z(P!qE@~DS$lUggAS&a8PhpS)6*?&*8$HewCb;hNf4W7`wF7r@jyA5>lq0j{;5<@^>a(pL%Bkt0OB(4 z=gKR#bM~{znYD3_+wi8C4z=onZo`X(6cTflzns8qVu1h5><0u5PW%mg7O!N^4$%^> zZ*`V@DHuE7$FfQ%E3U0QWZz=Tu+kV6C_54Dz7>m2EMCgNJD@e-@`~M^(f+Wqe#h3W zR~^jcHP8bgGo3q~c=~pF5wlRS-colP%Mw*$-w14=*EL8T)) zUZGLMsA88L8|CD@8a`0%(IWQ#J`ziPBH2Hf(~PFN!qIct4H=9Wr?R`njt;7RASOCI z9Vc&geO^oMytyM8b&fAkgiy}QNyieD%}QC3-RaIDdg(Oc{!zxZsw5*h0i?egvvjDM z_DH^ljD7Lzzk6hyu6FsxSx&RSlwyha5}(syuBV4fUF`HueqCw{_jIL~)?)VekHp6{ z{U*O@7t6_F3*X}xOlce(Y%gRin5rZYVCaf|gt#woYI3MNl8EMof7V_q7tgj1C>Ail ztDtXF#l|$5szkWWEg63(pbEbsZ3@5#~wOoOS};JUnjYhOCq=J55At)R-#^z5FUi4WMI4(Xz4w$_fS!F?ctA=a5Y4iX41R8$rHaER}Yn)euM)nuiv; zE~V=ddu688@YhW4!3u>cg?B4a?f}~0)IY@&C$t1O`=T-CTOa^asRnSNkjLk6uVx7R z^%qaUyt81M#K7#`GJh-8at8&|;Ck#qI+AVEhc%`BI6Nh6)5U+W<=aRdclC-XZj>#M z9|O2Ze;9~5#E3%BO0<|1B){nzCaf|epy32G7uh;_FZJ*s?otl?32ae`LyZ)^zfxvJxS@2Y>c*MZJZ-AFZWdZTpv@Z@0Yd8el3+v;faZiSF&Yoj(Vdfk$J zpylW?fc(XZfCS~r)s^Gc=u+>p2DT#(8?dn9$01)Etbg>st@(I&#S%Z8Hk($$E|&xz zk>LWTIjb~cjVE(F*C<>*Y>DqUwxH9o9 zL2{>$1y`M4ffAa#&@p^v>)O^hFx3&{h7)YwdbR8P5=OWw7av@~zMiy@;e*<qgL4IO?#vfG z-W#O~WUCVMf6a+W=s`>K%P4!~S+oQ?{P=klG*Z_XRa@Ov{VGnml2&40Dd0we;Y~>g zGpn_1X1DOxRw{fLES<})WCQCsFv|ah zH)J7{lpD6x_hgw<*2n=rH|Cw_NfB%;uv!2_WC~=r3QW(`;$H7Ej+M%YD+Qr%<*QZU zM+Kd}73|bd&?+vMw~PC{@q3`$nZ~lSm}uVV0xR+h$Gh+X)nPP2nb?7QQ` zH<#Xc>awjr-Vn&}3^+}eQZj39TQ7X~AW)p=L3gnI^P=OINO5_3=yjJMqsv{;p@D3Q z{uj~zL_zC{s#K64*{(ppdXB6_XGVYq55 zLeX`>2yrc2;6o-5eEOTY>Ovzro6dDaRlWNPPr%i4o%o~X=9`jTvq!4ZYLaiSz@-`a z=LnERe188dS=gZf`I6=ISE4qAsv_Gzej+}PLD$^Xb)6GGCla_kL^&i=4ZPTr^D)8x%o#0I3*`I+g$sv(3!oln1 zP%|(7ye9AYP(z%0$72d!1Oe$G-tNyxfLxaU04{+gC7Th4|H!_gV24lx>_^)g-6C)g>kejQj^a~aj# zc>dMpe#H-1+q4La=ryi6B1&H~33r;slFZw<>G-;()N|4X%S!>}UiZH-ZZ(K}++60O z74S8UVG>=I+jm+K3xnLg#S_HA()K0doUu3O>>fL&}lZE+xv=~ zb5N)6)#%OyYm3o0{?qbWz;X$GN@D2N>^m&`P_XS^D(Z6TeK9O#H2hA8iq%o8xPqoR z=}NtUN&7j+K?nwmU!b=)7I#s(?C})Nl|3;N+_=}5^!FYmMTcFK=DOe~Y}^g~16-v1 zYF7Kbu`h}2lRMa2NLoaIS93t!;VM~p%>DHI`>n+F+ckf;ggB!v-ZfJA-pYE-6Ho0~!%nwg`SOVQU1v z{y}iC*y+Xm`8;f=X7FCGlkgod4Y8)4dUu!x`cb3#`#1QaIAp0!#z~F^Fcl+o;xW%Oehh{{O*0gpqqfw$$mmRkQwEVc#zPNmHVova8TaYpPVB5D>lEuQ-5xuB= zpMvpA301jkK&xrkm9y1=IlAXszldF%LDm@`=1Tu8`IV&}5LHT0QEb+Uc&wWw?^o9X z=9iX_Wr{UgPf-9RyUFSuXqB>>CH>^H$Rbt?${&3+?pwq*K|$+>&X5mZWTw)2!%$a9 zdAd34<_nx!^J}tBQbh`G;`T{@-G688iN=ZLSzT(eprrCl&B|2NUYZIp5FlRox#T_m zroAfixVszkVsU;<-;hw`J73S9woBGd9&Ps4Nd@U#g#zjzW7R12`c{GEc*3}2vAnVp zT`D3-F?Y|V;?WxsuF3 zJ}mw(`r$1vub0|7S{{(k);E)8QyQn2L+VUFk$l>1Sb|g)}$U*yNC!*wz5UE>l(pR;wnK8H?x<(x>vRkx8 z`?C+jOqAl`5bvO*rB=l#1<^o)@8j`R^w}b2eJgD@+MK|GgWF2j^ zcQ|(kjFC}sN15;ObNkfeX`~D^U)6ivc?r|7y2t(6lpY0 zLK%=?D4d)^;ybRU(V??Fz?6qBwIQu)INEQ^BjhXY* zZnlE+FhD3^Kybpw&wGs?8(ne({?5NN-~dJt*sI*jN85%bhHmFA$uGjdzC$kBL#+&UUXx8LSc#SCY z-V%LY5YzA!P7rBd*BH(v=o6Ivylj4I*&b?-G3(^c1qO- zGSyg7eTguqC_CDZW{4&*q!MJggs3dJ-Tq!kw>8wmw-Ru|Tl8>0YU;OZKVDl8`*(DM z65~2`?$-I^rJ*jpt1h^kenvb*VLyWGpkz~rb;zIc& zi@7Z~ad^WK9B!#!2jXm3w-*v*=)n@+6H;XOB4G}snz1(6Hfp?2dOKPUnRAjGsjTu2 zOSefi@OYPtD7_ZK~`))))cLfwQ;o+qQwoIyyhZ38lgpH%VL7 z4g3WZ-9J$^&qNAZ1BMBb%}0b~$2I~Ci@~C#W46<2)@}ejf(*UR+{}y=_GwH*hSKHT z`PG0;6e*hCcE*+=#zam(!;uZWF9#}Cp~(GJ&a|gzpV|xGr>7ec&CU9$a|j8RXx>lg#(}#JHdArZ2$gmJIueE4b?HfphWsk?Wb7Ah}byFdQ4#N5wO{omDB~2mwJ!PVdDUrlplC$&-;)yPj)rq&H-1@UUS6{=&^iaszwX$z^ZIL6#%C{lteK`uBduHnRD|IMH?mT8zj`nwQuvN#=;=F!W+qLw_GPf<508 zQY*)S@_?(uWVs))A9dn~$@8@)m4G+qC0#^S@BcIs(A=;o|ETf{Gzl&Yc;_M@8h=!` z>Vu5&;k~07VXu`xgBG6MSAnPX@c71%oYl=nHMjYzPu~kj4Sf}KR;kST@ZtyDmm0RF zOUR05jZHH5c%gyholT!V)vLbNgs|*t_9L^NPQ#f#N>_^|s>f;<*?pZFAAYzooI6T0nhAZ&+@4&!^A(2!Z!uX35spMeHV$u2$j`%!zztkr;VtI@wzw zKG{>_@CVNpryX)!<6K9SXGf>`QC%Q8SF=Y9tbaG_@8JHRIVmfpCBD)1W{!iXT33I| z)A(Uh;my{E6;J`k-j$IU(qHW#qKHlLd926$?pw!i;_tRztAeV+(lVbIIK1Y! z`$xAto?78B*bW?id3bTn@(PP~ZrO)X-%v|9w=DCk0Bw~7^0IMMiSU$*G6fBdE10zB z;itJK##j~9NmS_g9@Va||Ff2iA{+f`4Rg0k*T>~dpUn;&6qrJ!%WOy=`(Z<8RYQ5$ z-Cxk%{W}l8t!12Dg`!W=Ijf5DhPm(od1;TOU~bEOuGj_L_}4>YmbrPEF@>wh;;&he zafgMQ{1>uT)SIGkvkBhNYeVf5l2GC4%Ge|66j~YZ57l2LIf!k-wdGU4#O_2BOI8=^ zvhY!Q%HPhV`u*6^^bcQ_hixexEMwr@%?KEED(59kQ2sP2VU{J0TQ9Kwe z8t!70*naW@>}rZ}elRou9UAk}PK?^xU`cqxA3pjiqr~b$R1Nqh zok?^gQ}^Mj_SG)|(9j~T$krJDF!LIf{%)aJ4*}g6KEL9w&b9>Mub7LN;V~;(#o)@( zdjCZ6`Ev#NWZDe#Ou8)>)r?SbyYPKM*o88$??VFW{^3|0P7#ScKFR$_#ynER7Bil) zVdY3o1VNrw#*MVP%|6#%*PwZ&Vxha0q)+G$I^oYBva5eKSU)yt z;@jBtV4Uy4~wMcH_t(O)^If?sTmbsMvG;`P2yJ5_T=~G=`I)6ss`O*BXky3?w2YNxP}I2CQb$5vn7- zsO#gvFG`%Ln{x75{hOY=?#b_H<(`#%ye1^U+O@jtI_P3KG#a*yy@Q?>kbX8=o+YF_wAmQq$S&_v2j&SZJcb2dxlL`=3O*kn0pQE4fw zCBNO$k1`iumYYvDK{@if=bUeI&e>9;C8+p3&mSN6d7dM8VGx4#@vD?X_-(QuKkh&N z$n!0w%xOw_vRj@KH`m!&bXbvmT0a;2%r-svF-`7X$_EqXIe&cI?zdY?#+;@pnN>1h zzdJ$y4S!u^298fhifm!JnxQRV49cFo_DL<`oOP8bWO7m zewK|WZSTY~t??{sjEiBVeS@ES6BCd4?Dwjbo@#;(H5dIsZ9M*atV&nLSNk%f4tS%r zUy7!yKw}GlHIVXtBKJsv;~B8a0noIn7us>O1PtBtsh&mWWDxbBOri&?w^94Bd7(jY zUrQwPZqctSa+qr!yN2$ezS9H`Ym!wk+wT-@c(;-eoJoKtyCk)RyDJNza>T!>v@it*pej+_SbSnQ-E z20dIf@vZCq{d@T6-?^?7tX~M~E*tRr&tp%UV5P~5-Z1`nlK%McmC67$oP!3S9g5J< zQHwj1Yh^JI<_@kcI7E;%LyM9tL8&I$b%9QmM64C>dgTXU0*V+p`ikfdPho3m+9CwG zS)Q{^87Z-p)u1Wa{Wg)z6Fz>-WtErY?i4H`r8I4^pm>|}$HzwyU^7T`U)^u;74RwB z$H(o*$Ni6wX`T|vIi;xw?x zlG&PSUa8u_h)I$YD+3hVi4(vI$}EF5z7dUPpeVwu0U)r8A9w4s8ik_ykK!^B(6EB{ zi?ts2qfymyb((fe<+zT|tMi#k^~);`1@cHARb60PpIfz!LH~mKZlbxJPr}yPNbh>N z$#!h)egwYM79ZQ=Bw1LUj(f3YH+d8!6xHxr0qzM{WL~M!kqw~g8VI5DQ9Rz~x26e` ztU{C8a)(yO;$@A1Gu`JWB0sxtMyx^;M+2w`YB#n~fLnf~eGJ?!E_85;K}Wly7GP;A z?g)_u^k84xn7{b9SG}hA zwUbBf?bxZt2Ks=_jwAEp>IKTksnydWW-yp?0f1j;B>Qc$`UbOpB&)i3`VHICara&R z*$ZBOFm7$;HCOfo?YMn0D2;&|nned>HG5H*JPfi!xms}Ib~4*;%9`-Aq2h?ANV?N1 zCc)O=w!#z?*;iq8t;NC?smZjrz>PWQoGpb4D-lT9(rwBg_jy^p6fH#_2H6pWpGcW0 zahj(4Jl*g2dCoaU#ATDpx~@3) zhNF2Y*)&a-5CTAh1F4V0x>l!TNj>dSyx7wc=WHpynIe7{95REzh-s1{l2+^rcMl7> zO2hY?xkk&1|$#J;ty(n_3mbnc3dHc{$W;dQ*HFNgX?flK23{Iatn(^VHP zns+|I599WXoNJiZ7v;|j=2`i7cJ8-^@qeA`jBXD^_f0hXPl5Pe8_s~ZQQqxOJK!RQYa=F>GSmtn{yCg zhp($v4~~LTOhIN-Nne`TNjA5`KQIf zOtMt9uuF0j_Vq_^u||&ubZiN4Vi3l$8G=wArSw4fzmXO^nrToUZYOd(2*QkjH6L(g zdK%j|n&!snS=$D^VFN>>CbDQx>psDT{3Mk1u8TWj$if!toNZw(?Xvg?2Y`+8ly zTSnWl=3@u$p!%da*T<$2PYYuaQ~%G2U+!%Qvs(PJO>T*$1MvVeaFw9|_wL zabDrncj?xP7Jm8Yo%&zD@~ju6`kKj7 zoF#_pHAyq3ZkXyJ^rmmdkB%_EVi~Lgt!2ic*Q6=MyJ09?9tjrJ58DoQJL!!prId3{ zDP=>7s2VyfuCldZ9r*HLf! zoc4?;`6MspfU>UM9y(Hvcb=2y;S*_4?Mv7)L;+0)tg$aP&ecgSrNi$t;eU??4{hcv z$|l-|*LPF=%Io^sFzy9$yOXWI?!6aXAIxfu_p1IYH$si8Dhjx|tR=X2)tFA!vU!KK z6xw|S7?D_3(aM9A(WupYUDqO)(|!B21eZX;8fI8KtID1z=Wf!A9WMHNpKyh9#&);2l3u<4G6D+vJ&~lv9^q%P-JUutjDS zpl@Cw?fQ2xyl3U;->>rkr_SFx_nok3Q7+$a(tr#rPCc@~Z;!*!_-)ILb!xcZ{=G0h zzu2({SymO~wlV^ewa>P;wci%bQN3jqjMBZ7Qc6)NDqb9vy6ZYFn=}%|@&5V89&7f6 ziZa|EEBP*7Jip#5;j^~}GF%^((|5HOaes+`|IYQ>6}~|B=bO71gUkE(L(=mW{!h~* z|5L}&EA{Z(*!SWn>mu&%$9HV=X6dbn>adfjB|cB>Cp(cVUckN9@t9PmqMMaJheo`bU-JC%KhJiB0DxpRwm}kEh3ez7dri>?p?`%;1Cjjb+MEPb?G9r! zn}|M^MAiTA+Yp1>NhYr7vG!v2LGoW+WmrLE^HXfE_3|}f8`(MPkXz*Qw`wr5!2))O zTUk^U2ak7-$0Qot5GQj8lG-BZZ~X=>cQzd0zZ=EKI6U}X9R4B zGkgSJJ=#Yn%;(*4WVVe|M@Iw%9$UiZ^|zfyyPbK_<~sgO zE&YP}zJv8!ZAY~-EU432MATvcu-0F(%bhu!W7X-F; zgBCAb2pBBcs$X&niJz3OpZxepyib-Ui{xlnl6!{BU{*6a(`7_TDPmsLnDiSTYz~8H zPLL~{RBA~DNJE3a?G*xublBC}IS4oVtW*lpFzkflJY98 zt70q{u}M^{22XPIY_aiv$_88@EkKM&__CL>kpIcoixv5dQGJJjeNpCcb{v$r{pmnE z&kcU+yL@TTG5$ODy3)IS_1GOxHLTBwYsarVYleoeG`49wVyVc~WP|x7?62D^C zDyg?4?w?c^yVr@!7GAEpvGIr5X^*a(y<0PH0NL+en*ipie&*d8{u8d>`_{pxX&|@% zSG^i78Od`GFHZqp1NhW!mut`zIv~LT7Yn=!%mp!p>!Oo|mPD65mX%%r7mBY*uoOP8 z_c=L|7%Xp`6DW?NOtY#|WyF9Apco-_*w}kA_2X_3ZH7~1+au0MZW!mFqehnAn=x&> zz}vARm8MAY{)s;6BOE&Lf_d>Ql!~L7ElofO+JiMqG=_iCNW-I9UbkqqPOQ;jDgcd0 zc28+>jm(7WBEjibPLf-p=Mj(JTG^MoqRK>1u097H?K99>ML-M>*PS+Y5bB^IMen4s zFwB9k&$W?+#A#`KVkdd@hPtM~XTpz)9pTM~kn9PZg;;-K^w+-LYOq+ifICH^XTu#h z`bI=Uqc^m6zX7E1nRBgDS=FouDX?Z~aTGKVtjZax#R_1Hr8R0=M|2YROO1{dB^kX| zqw~)Q@J7@(jpk@rwCVUqIyXeW0_b2(@YG%`ZF#6%#E8ByTA+IS6z*N)7`?Zb=DKJfyBp4pKDuzptm;b~ArwB^`w@CgBT=AifLfUCkttHUpn zN>z~FbrN*8z>BJ6xDsEFa2;|*QV`psF>_PjVmniw2DmtkUh_Aq%z+P&ULwWu(HNQe zLgRjTaUA=7&DX1C-~MZX>iI+acJk1XGa-NW`z;dn7EOKolAS}6z1gZ4pMKq>acp1I z{M+^SN)GKD&zxryab3?p3isbfEc-UpA4dY*G(npt1!(@lmA3*=;MLX=T^!f6c!ge8 zk_oz_Ac=;XCwb%-$|i_JLh6IS=b*(kWRNqr|cdM zB(1R(W^kB{%9W!KA!RgF{)QDk>5@%;*Ly9>?W}NdO|HiE{ngcVz}zAu_0ci*hdK$< z568g(IycMe9hpa}(w0F8d~CV3V3bYA5WlPLZO?{Y64WoR{t7D(dm))P3}6d;Re5{~ zu;!Ibwvbo4Y>4fQ8X^HeY9n?WBB!Zl9E2A%eXvF7Y&zD4l2Hve+G3C)D0LuMqP|kw z?+A_W*27J6rjQ+Vx_%|sy&OioJU1`lCYtCN*g`0)rCA!`@5oG?t9n)Wc5{Q0zfBak z3Zpg8is3p<^W}g%Yfo)9FSj|jwp(-v+7IAxL^()xBZRk&*r z+)GlaiHo=kRXF+=!@~bHMK%I~Kmwge2a0vM4qhzZE>-_>xnE+tXFSMmrMla|>2zx3 z5Nou=YsD>aaq~-k@H>saeDoTcUlzFhq6Wj3*R48_$#yhHAeO;tVN7>f|Kpw`A;Whe z;z4V;hP6bx_vBGMRP}aJ6PwM--Xldl_{LbiOM@Fy@50+=(seQBuWydz=>^=ptf4Qt zHclGf($%|%PmCXWar5%WKdU`G)b^~imp2<F;Q&Bg`nxeNI*IRhnGhsgHXeF8DEu==6MYTZC zeFjGrZ}TYHc6a>Qf%W0g%i^Sp_ag650=$5hYA6Ip3FUeMw}3oMW=1V8xv#3{SfpR3 znTY{EY<~prbb-TCH!hY<#oRmjrjCd>~2sJhhmA#dOq01(Ff*i^SYiMsXGUuqkILG0F9 zU4D!H(JnRXG^4j4sDkVR<-4BQ9gU1X$5(cqyPbg;$^4HG5fF2hvQYt}Cv2YgqXjYW4+ z#()||9d%JvC8GpmI`EhyT`4^vb&Zw3?a?q3ac*BRg#rSlCz6*lS(?&3&+~nrZu9Ln z-)^`2oNjZz-EKdoIZu&sA!Nm+Z|9I&Rwt40&L99hZ zsu_&2G56lxZhC<1e*897Ek|5|kY?{mdnLfFC@bAHBa-MYs{#Wukx+^VMqVOMVYMkQ ziX?BvN>OCXFcuU;ZUg^e*Y#iC|7X$sZ(Ko|o;|wU^5a4L&gD<0 z=iGNmFOo`~g=Ak2+*!PFp2vQtZeI1%wQlh0tGcfi`xO=9E_WK0bIzI5%zNf-=6z20 zIo&_zX-c;#-REgamJ?GVERvb3^y~;>6sl4MvSB=&(2TQ!wRg#47Dj`Rj!?-eyH!(r zbvind)tXIVfK20{wPIEN%<7hDn+Tzcpix$KcmlE}_=LJ09Ft=u^D04}Qj$tw0VkCb z3DblMG733WDPwb#>~h+wgRDGN<28sq|K-&(ZJX>ZM{!Nh&63w5C5YS zL`6M}R5N_AQOK|jcNhUjmWU4)FN7_ zHQIj?jYgGGH+I@8*3=yBPe!z=mb0qLX`1D>6Qr3{&p&#dr<(p)ZKi6@vLMN!$O#`} zF$DW{fir50WXaw<+4@R_iaa8%MGl7QH5lRs&}-QmfDKg$-Oio(6``Z+-H|97*@Vw6 z%92{_Cn;F)Ca)e`qj4lZ%_@Jd(2c%qN}xUQ+YD6%cxy+?)8vB=xJS1imT%ud7_t7? zD)o?O@|FPffE2aky1b50e2NjbuFYV#?T7|%j7tMcN9c1j;cfzfO>a|&>&*TSE!?Qg zOPXr^bQ{-p)#Tf8Yjq!ujW0YAo#t0vqv;c<(NNkKhuPl-Vt1YlmhdBj><2m!M?zb) zCPj#UqQ+Vp*p%9wu$*tg-WbZBfu~Y&2O7m~a})@$>e6=8bak<9n#%%RvJ!FI+hEf6 z5|qPSv^A_IxN>+uHR@#54Nym|B(nrt*H!W~Cz1x;5jrT zB*T z!M1!c-Z?vW{ zcf<{CjRqOy>8&Fy#`ClIooj5&p`G8VN9KkkYMf`4 zQi7C@i@#!hcL3ge8Mo6u^uBT1w<&8{;S&MAIP_nWz%UIq1P{lmNC+07#zhhd7&ob3 z3GDl9wLM*?|Lgg!KU-}tsPBQ49(vd4L(uguimbtuy++110B$`r*{&sxQ-1ASRKiqy zJGb|A^m4%Wo!tnS(<5`phVU8(*I#VZW|MGUoFGzN<&M=+M76-@{Vm^cvZ}XnZB2s| zhoR_klF?m#xAKmS`ZgTAh&y7?dTIce|NQTUXPtcBXKcIo59voZV^6-!_6d zH}y-t;h=iMlk!g)DQ#NSvz5Wvh8Cu=$!VyZZJy_Oo~J40oF`*S$w)JrnP4P~6`=a= zig3safRd1#@M+7A5D^MZGK<9aE$5LyFL1&_ni$g&LiJ5MR(o3Mafr>gM~Cg~zGa?} z3J3@On5ilUvi$ky(;PeCu#}^Mm<|`sPHv28^YOL@$ZWr|*-irmGii{mP zd-!Y?3h{3f&iM6rhlutf)MCB(o}C^glRG*(gly~*=HZz8dJP zSkJ%zI!>pG+EYa0pjPIBxyC8Mu1ND;x5Tp%?paVTm@k)o#=we%~@D1c8YvF9(!bBH1IkS z;JCWVsSjN@enuz8Lm1koXs86ZU%7p_)7=9N?&_Hql3OMk>q!VeJ+O5vR;MF;lDb|4 zgFoo+UmC5{{+a7Q(#8edNApbfE~V4w->27)uY~ui*Z8IC!g~n}k8D`zgedD=56;K> z$qRY>&}EkoZEMd?uh6@$zPg?7YwIhf8UaKUG?z8Y;(^#0D-s91N@{urF4Y)SuJFSv zL1wE?MN;GHQtR@QH8Rp{Kq??cv0sg&I|u`IY*W<b|D3Ne`t(H$FUsq3wd`NBfj*VE z)B5<8^1Is2xXS@FGu_4;)nNs?{mQ=O@8FFyKc}W^!)bTuiXS>wIE-#vSk>1SK=&u^ zW>EDjY$_oYxRXp~IrWQE%9B|#q_D?^c_bHal^L_yT8g`?tS*%}I7%rVGTMYRWu!tf zg;5JdB&tl)M6*y8JBpdX(bQp#(+Q0>Z@y_2msrHc9Fjh5hn|L@Rb?+}la!n2{9WNm zqz7gbIELSIoXa)i#l~;Kc|mgjS@!cEyk5Y&_u=ES3eTkOtaCjMkuIW%U9zGbnVkv$ zB{wkqd(qCr7Y{fdgZLM=ZMF+hfonLKNg2G!KDUdd3UlPH;wq}v|FIV%Hd|NWdNY9X zJt?~USA&U=YIp#Rm~VHo>@oDdwgF*d+&{agyCK?h#~m@_c-}qH>^_g}_2mB3WAXBM z9R=)r+Vq>(dD(mmtzKg5_rLYemjC-B@FmE8CN^L*@MAquN6J^Tf?S?LufO;kp#Pa- z_*t1}BJMAd@i-=x6Hg$SSd->X$>yA=X-drquSk-?T&Sj+JtYx>`!86Rb@8g+iX>~K zm@M6#spiTxD4SX2B{ZetK@E*?cevcUm81^G=?HmyuScLfpx%uDcipg1qHr#yq?Ee2 zR>8t01KtiZozn>)S#xdTF#s%@|a84(5q+*>&CYfnVqyCdd^s&#_1jm)E$SJ;RJ zHLNSOm#^k{y}};UGn(2t$JJ4UbvWc544VQrU#4hdX?|TJadPQ$y>(cpCPr;!?&AH&M)DRO^P8-*joT=3+Lyn+sa=E5c=xE)-aj2~RwH(v8oc|nJv6jf`BzVm@|ABL z>xX(S+utvKA&Wj96n|fF+k5>t>v{c&f8=}{QEydZ>>K&fM&j~ z%;}a>GE0ebRw-PoH;?69*dk|*P2D9Ely#yRz3#r{$8*F|;Rir-lrm;3fx1)f#g3wO%ba_hco zz-}1pk7EaSLTGCi#ZcN1Kv$=2DD(CC_=3b9y4*&XQYf3MhLSs{VMwC2IMS?m-4S-% z4oiZ0OE`jVPQp%IiqsUh(IczWH{h>>tGqaiSBTjYl-5A!)!Ektko1m-PB^c1xj_en zfkhK#SK>GNUylE7h^LPw0yWnZzcHj+m_2O7rf$xz|A|VA)}c&Cgw<|woWVfzX=gKR z=uJKew}TZJSg(dP_c@vlJvy(M2D8R8rF;19SK1EupDFHXSq^=P#UN`5z+Q0`VH+Xe zRX(;BFE1ZR!WNsNnf&l8wQY=KpZ!rEeA-qQLf1{q^JJjVY;G>OJ#^--%AZg~1GaIi ztEY>253^8kb)9uguZQvQbSE0=W%lZ)C-q!US@)4Ov)G|zGA~GUsW>89dMPTUu4MOh zC7^XF%d#vh5@3kz=@t<=v^>gVDUVYAdMuB%JRHkf9?P;U3xJ&SN|F4F$T{DpoD=7a z`#h1#hMXulvgIL_Z$DU!`9NQT46_=DCAL77?lP-Jrfnw%=|!YoZQ^U?QcC1Y8o%_+ zmZwu_#92HV1?{H!It1&6;&GJu;H&FD4LZL`l6m#kB}wi-&$~BXy&B=)ybi~Ko?!0r ztlV~{2j6*$m~*o09)*b!;K30r;bxE=#M{vM4~;R=)Pl&Brekrb0Hw-i=?zgz9^ot0 zT2ev>JVaYPbnOy&>G`-m18O6TYvT#+TzYo;)bW+^#TR_i;SR}XWZ_9Ab{2nqwKkq; z5WjfqoyJ^L`>pc-_jPqycRt+h%{HQk^W?XYao+_mj-cOL3@-`{$EF2JiP#!0TMCyI zYfxdftEC@#^_yen(af~VhS`v@nN^wgfO=VD4YhM?IEaQjHR@mFK9`i&bh*D#*7K(G+du6DkqG1j$0jCd*I;V8mjNP4YF17=8`HkzaMxV2O z8?x^V_rb6t3hp$lY8jb!^{Z=zbqs~^r})2miBW5mpg5oLIN?0-nSv@|L(M{U3A>r7W%s~wDTFg-?#rLnm)|(>2*6A?v4?W z>iuhMR42I3zbn+WCnv3bh&;p72l&exRZZ$<{olO4MN7_ke03V7*0Pf`?|vi?&n~g@ zmu)-CsIH_4?*Wf~WQ7gm8&cwD%jRO-PG`vbFklD__~H|y22f6k)-0K__{31V=2E@tpzGD%fUge(qk#VK9^q)|M|IoF8W-SrL1uk$;?Wr zXK6M*GUl9!xlBnlAoO@`CtlaO0*Vy9odEYS@3gs6$r>%6MLx)KN>Ja@Q1F)Op%41Y z(f8d5Qm65?26P-(d9rp3>-nG03S0~S6uZ%k|qBlwJG3to*#9{-=Z8QU3hzxW3!R*ZkHy9U9Nr*Iy?I9Jk@{=!wu} zU-`Gd$(QTuy-I4Q7S}|sZjZJ6^=tX-=i{$m%jaXAA33Fz%@fMH`eX555C7}4JRZdh z%nHefm-#6E`6$00>*vEC>-zbtJjxp4-UwY-ip&JMJ4iDt9zk4lvYgB;LSNCt^6Mg` z;NcJ($Biwv!AXJZhfuX01ZNGI;CdB(8tT8ptc68ji=oPHx4AhAw}J_=az@K%2U+va zya6Ixh4!B&f5sE>?3FJ0UCV{93RHj1(2h&h@FMJlLA7vg8xj517rPB}$aw|;&2Hr0 zVwqZ3d6Mj||1HK=%fNMkHL)GbGet5hQ5jMF1#ZXhj; zic~l^7t)4oM(@~OaiFfgZBjq}e1J%$cTG0aAFa`Rb}G-2v50RSBbK!L9k=NM4A!E9Uem=PU-BlQxsofKNdAQ#__Zh^ z>~=>SAIn5Cdt4tQX`;CqI#PrN}{7Sw``Kh+gWR zE)Lj{3}4EwFI8!;c{}Pg8NSF$+|D9Z=m?7q2m0!IxPLDG^Vj;XpO63k*W=Hhk5I2B zQ&L&WvON6fukzo2E%S!|_%&dbA>)j!v=JhWEoR;^cy2&4p&)tMulea9Y2 z@+NGkwl5=|!IpyQ3}$E{aZ3Rh!k56zwn&+ZP|@|j+zIkn%Vo-rV6SlE2=?o&tw#EA z&>z@9UD30rfcW1>eRo)MKa?+E=()|WDdK+h>++Q|EpJ$p2V|y`cJ@WX4)=HB?mb6* zIPouAxOJ$XCPznad$tvu2tAUV)kWAW16AC;24ZX!W((f75#2oj{u&5g;z(fA9G?mB zCEOf$TCb+j;3I`TVaHIxTrVMAeQ~Jp3()-J-KXM{%OTQN^}mn#&cyp4yxs?A`u;2b zYhD3ud@zLmb`8(tJmc-7^%;7O>&qE`Q(SK(kwF(!9G{QnuV4J@*ROy5^&pv2%1Ieo zS3Vy4>*4?U*Ye+gJ|3&XLO<(*x%=nh%Tl~xDZVZx0#}%!CL@AGie@QUX3l1LN-2%u zu1K1-@K|jljB43K%h{4#H8n9ev>=%kGc()S<@J%zhftO{?au>GRHYp88(T0I4B3K7 z0x8biP`8~m0ly>b_%~eVX1u>N&y?)hTL;p6SyHM@*{J1ZSkvwK;%kW?dnJ6cVME`C zIJYehYOg0IFAe%^kA+r4AzM{+ZnmXem*0Qy8tjy?#WY_X61<>Dt4lPwmo5&41-fwG zgaA@=D2ktPzr}-+WO+|%R}qx5ZzHCW`|h>^gsg5h-8M8(ln)c<~&c+blbJ99t>*GnLOo@q=^um z-9$^>MAR&V67*`BWfu3?{*-&-m5gjPVfT(||Ai3xh4{&!Fu=swPrnju zYYFZz<{_k&_6$V6Pnad~DEj{P)e-O+gPw8uxT(&P>b{=Xa+qxCFlB<1c9tUICUe>VXah!?6M#9O;0Nh-4>Rp=5@u|4WGl zk*t6Ur3EccB!;}qI2;{uXcp|uuSWLh45_b3@_zC3A59oo!r2}G z%)y;y1mgR4t{l&&?2;tEDD&cSf?i{oJcG-JYfpN&M2F2XfYBrG(cq7DemjHxw=Q)C z?BDp2XQT0?N#ADzs)6BeA@;-3)Nj5n{Gub5642l1)H5YrJ3OPoMWVYyh0>?|v+(Bw zlj-)e%>P=7G)=!Av)!|~`{PkQKg-WwpTB-R{(3B>nj6YRcP*>0t0$WjP#VZdFeD>{ zDW#N|5>i$+m<2KOY?FcR?kgW@&DE%-0E#RTz3<&8m?RU-02%0VqY2Ie1Rq*YZ8{n0 zAL_f|vlPiOvw2B!$_HmWM2hD@y2BD2a=>Zo#=6xe)3hpb9quFrF-;!{4r~Wa?z8$|$#zwdJagF>yL{tG2rG0l*TPj2=yr z;F4V-*NPrO1Kx9B#&|TMRsHx-1^1!$h!CC@7&o}RUB2PdGHt;gBeyjAna7sWxZAoAF-NFCcW2-Txn?(L}OFU5y}l<0(-i+6bbo28VI_>bhqe zM=TZ}Ko{J#6g&zZE7yY6jb6#QBa8-{CX13g%d- zBR_B=fvPK{%hH?mTu0b@_Chhe>X@T_v30Y{z14=T+eIHV-)MV0>ZKy;)E=RAkvO(+ zV34c*8DH5E?7qv!2xYZ-BfQ@R86dsw`@SPK0y98>s?dp~VuMA+xb@Ux7WHvHO6t+3a?k(v)RS_&VJhur3Qa_dJHD5c_NW(j6yl}(n}CR$5GftRHw*Ot5FDo)WP z(2FmWn>>LnHe>>r4KgT02Cohq@HUUt1Fg+Y)8Vny>=P}q(q8tkrERFYqs5^lQnOjG z-A;l@GNd>|O_2}2kpuy!Y}>W|TKVo^QcGxc#dZlNaQ0nccw6PVe7zn?k^i#&3);b4 zTl);++T-tojHsGK;mdY*_G0@zx_e#X`(yhDxpdFBhmDg3_GeZ#+p&#dY({q1O>6*> z4$31(u+_w05@iOpRjd)yoEZE~Udm2BTR`&O73|Lh)j(Dwk$Wa~Mz4Pq`Eo2ajK&C^ zy^&{vE#xFo<5zD={U_5mcJo38cxWp3cV3i4jrCE-Ze%rj`L7_(5QMUYlkD`yD}!5} zy!G$8DscR_eq(?A8?91;2mbdo>2h*kqvR3wp2dO9C`pI6ey8Uxzm7wcEyB;0=|QuS z|9Y4KT$fw=F(;_3g^#s7ibt4^buFvl;8L&%#kn?LTZ5M{IiAvennLWHjg#4wI8T-* zvjjrE7B{W}TxOP1ELso1+InkdY{t=T1J+ZNW&&7>EDWG3S6GDNDrQWHo++7(wpKxO zPHd*O$JrvQPI3%Lvo?q6ZKVwSr0oSLq=`f3q8jlyPH$%m0ZO3dmOc6}xf4Vp*yG}K z02W`evvCHZGfZF?rn2U2=u zM9oY-QSOKm!j;~r5SKKpdTQ>x@r^Gf?TX(@hNZVVYrj;Bim-d3_@%|;5yjp&v zZuqD@J=4?zbv8A40=1oh!NeMyzWbs(&o=_#8;w5~yL!t8-ch*TC;y~G`dQ1{a(zNz z25RxTDI5%H@b96%|2~TTr6uW3iLL7Cun7VO7*o$*+i?8*jStbBPC2H|n&a^K@WMsq zSI8rLkw4_~@?%JefdkuFyC3}fzCS5F4z9J1e(a!Prc@-*R= zBVlfF_jO(2fqP9;n26XEqMt}h7eNioHv5<@`$7xZjqO+~ibx0jBx6bmG8PpSr`(y1 zC9%*8w3@O9MI1+p)?@KGWo%~*z|k;Fn^?FHCS(=}fKFz(wp?-*BsURgTL=algL@>j z%ph-EzsY?4jT+uZ&wC-W^8`B2AQ*d*+5r=foN3<@=c`4HeBa@hyCGmDBRDJQv8#U3ai_Nma=|6Cf0C|^ukps zv>rr_&6#R^_~OMCX%f~_3&e8s)+-t ze^Iq3Eht48+zBB(u&5@ z!SH`0$xhaPSPzk^=4cu_R&`~hiX11Sf7$^Ue0XZxca?x$e#&v7u*HJd?#l>1w{aLv zwNHiExDEnOw|yM`@8&!{sB?}au&4KYk3f1=Z62v_&*Rrx&rt|}K*rjH{}pzRzKx22 z!9)Y)R_8LFo(85Pr$eJhq7tjL<^UE70??V? zWB#4M&trdj@gsOA5X6@>0h7lXNFhXwmK8nT{+th{jccMKS-7T zsj4o8)jIv&WTvNfYzhTbZSJnBFk%^S@a`Zoc9ifN;(?8dw;BdDHeGPx;fbr`*Xqz` zDZduxXel!Q$;z^pLYK*?$OK%9uZn~RGKH4eV7}&nxy2#PAyTf6>YJE$r!FA}d#fm4 z>2UoKPEG=fmr`oV2StdXiX53zlEU{xkz?51%c@e$-7~dFlqZ$Yz5B{_2 z%^eT%`g9ODqY^?14jC;>IpWCnK=_TynpDEhXukq>7S1C|*h&tWjIUP7#i|=A+2x9P zLF$eN(BI(qrEBHum(?C<_SlO{Fn!thvHNH6eYk)4#4y5WbJyim+6Ch1X(SZ(c-tdM z>mZ*|rC=!4WUeCMt?@jPtDwHBjIItxtu}G`k<@J;ZA{k{Iebk5wb9^R^r$bqw4cr9 zB?9j4d^UaEwfgkR*Nf-H@8>UG3&W4Y{)UUovnIV&zHRHW*92XP7T)a9HfkJCkE6Bl z0T*`M|NeE@P`VORy;;w9hwjY}9Zu2r8}t50FUyZWGx+8eMy*=qt|DKQiL#D$^B7gpAF~FXCAS?_438Xw8(jg~6&Ozr+3yw#I;JH8|uv>Cf# zF7RqW`73hULh2s&-kx@D6zEE;;WcPy*BlUlQpaB>V%cch#R9!NG`E`-vkpxqno9dp zpd>Wgw07K_M@W}Hqqe4ll%RZQ3~Ht=YvH2kiVTCXRou0fhz0Eq7NAJ-6txAWA|g3b zJ!(tGqa5Ya>SMmy=%Q@`-%PP;$rj}bTiPXV>_W546;xN+IObiY+K}#^A&81cqIfi2 zxuol_uNP!h4LAr}!!U9`KJJI^BYXJ_t~6YJdlVG#R*+K#h6M3<*_n@|j! z=&&R)hy+;2X7t_EhUG^Az?)?0k`w)(d!3ilTN>H13l;nF)dHx7NAY_b@Gd!!)a{(n z3^QvXYa5l@*IzU;PTKG>7vW0o?lRHKrx#!5Da{Ef!63LMnuMTpW+i7!Y4XVc$XBT( zieyd^S!12jM+!dx%94@Q{xiB|36{xZmXjqWOK8$2cP}ks9h;SYKHX2$S9*Pu#}M5X2mKkEMy|8)eT9u04azK z!DGXI`xA#s4tHK)?ml8yEcuQA@1NE*MO#NCBuKK;$y=2N?mZz_(BLAu!$rA@wv6;m zy4{5TLrQ~AE?%4(+wYSQct?z1PV@$I`|CTrt3$E#^-LN6tj*Zd1`JE?TtgSY9tt1X zf;TYnVG&+7>{**fL|DaA-(S7o+F56Y`z#&#)_0#>XJd=QyZ<)xsV}YrD1TPqT6Fxf z+N<$78eW~N+69UlX5kP(>dV8e@w6CX&8&xB>@w!|r&ZCR?P;UBl|vm)>P~fP4;o7TLI=? |UD`6)^sQ#?F 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%0Al?yaY4S zgj6`tQRcl6%VtH~AK8j8sm*bVJCVAz(6f0m3qY+_)zZpEL!~M!rI1tL=Wg zuDjoF{c2nG!0YDT%-!tqo^Mb~+|!3U<=q4Fze$xB9Qt~bHFLY%+zM0EWICFvF%{#V zdZ!t-&%^Pc?wo-y;lW$NV0Y+87thW0x-(u{3)^b*<(EHSi)X*Txjo?S{(1dca@8i9 zz4;uV0>_2h3;iaSu!p0z)xL_|+{7(fEyFHL@l`?NgKut5>8l9sVlvm0aKN>+liYkb zy7><_z@5ixuUIq)O%xEQLg{fYNNO@wv*dau(;Os2B~XkEjycRomBQ zF(#0sVCQfO4Qf?LBWsQ2fK`GCj~(p-SKt&)EWciO=QY80bwQO2s!cV?SAu3hLB_uc&2@V~pJI;#Wkc7n429r7jD6KjB^+V0k7 zw0c)AHh|4u*@SwGhkoQHoS2@h7re9cdm&$D2zedA^t4#ll0-ElKJuPi+^RRhjQf}4 zOVo9XfvkDc#rJ!(c1PE)g}G9L&#N`OVMwXkm`mXmg4-M|zJ` zx@N!DO|;#d#Y!_^XL{Su%{RNk&*pfe-<#QiU&PGBP1OU55eitMM~^mxnOn*mOI#xg zkiZaN%C*J+_MXXbOD2sA)zUKO?lJY<{nc)~ct7*&aGi&gW|S zyalO!5%paT=hk+!Rsx>4d{26VJ;wh__W4cJ1h+5lFTs=EGXGy9Q*Ms*_^#L#zgil6 z&!GI?ShJh!^Rf^~_DJtNSUq#B*&D9Fi%oTtsO;^%V>q{M_qg-NKP|4T1KQbMv${oS zvBMA?^l+hoz^x~G7*^&sJaC3UMd;BnM!-C96-^bMt6ywR@hnc#?y; zEU|rfFj-nc! z%!Ti+RIL!O>qn3^(3qybjCb8<&!wHwg}r%OsO9b#f;U0Pw+UhEYG*^Pm6x$s-q%5w z#ipF9y00$>s>;nFuU}lu`Q|RG{oyM38ZqfYW2_7MtYoV+ac8QsS=rcPY!bEu$OU)s0XLtU zxXs>Mo6=8P59frc4%3~07kR1{gIYJYmR9c^_7OU_qjlcoJimq0x;32J zYLnS8_XOXsqTX9Kbdv-g=OJESvUM`=Av2qR%|ZPKeVErX+s})tHbrVLvDxTe`8{6% zYYfB=#(wjeu^@LAyF+M3v$BgC_U3lc`B!bl&0Y7}sn{G;n~cQD1LSBHZ=QBccjLt9 z8~}LriDGV>TBD8AcYV}GzG1uoGl}84Pp{T05v&B?OE1M78~Qd*|O!m zlGV+3N-qN7*m9-pfbC!R*v6ZrcV79H95WRvdMu%tO?Km?#|}GaqWS(fcIy%dHI~H4 zC9}s`OV|1h`+pbQ?=-IBV~uSNAS_y6kI08xD|Fbo#=tUdlqmUvoADyGmGv@~E9r1{ zntDoYs{-79D`PNRf4|#M?THnOGQ9F;*?hFHaAcbjYW{1>#NJ4Eg_ z1>1P&ahkT1O)nnFVa;ZdwpPTIC27}ITL)~!v5?fZwFZaL?2xMAYwKAP=C8%ad^wz6 z`*u{D`*}hZW7#ZzfUF*~ID1vyziL0nTpe_5QTeWtVvQ)Ywhm2Ux0YWwv`> zB6)8BZY9Q$z%%o%B!nzv!SINhyyev)%AJ+ z8FZ%s#eG(H0K?g1B_i@cV)Lq3Zl+^)#V>aWkzMN?F!wY>5+G=@eqy0=q{7Tyvc#nW zy1lr0$dcRos+DSnvob9^!fdHAudtPOv2i3M4;BcX^4DN68kiG2nt;^84|#44%M4Rd z_~ewpG?I*Y(t^N{R0Sb;7E&hA17H>P?bP|qOKMd~%*7)B^Gma=zBY5doGh&h@Vwkk zgMaaBK^HN16mS@$>j50ah zx_`XcLVhV+xlZk8J?(TI$V%JYSW0iArrW!;m3J%iT+7ewoJ~qZx&m}*JINEoXDbeG zeMfIfv8pN(i?V{njyi4XO3bGe3Dd12i!!iw5=?WoMI51Ep73<*Y0#8f?IzP!j(X01 zMHJfzfXIdutJ-OMYy`2TQ8qUSC@0EGx-JoO&f4wg*~D5nR&~wx^GZEb|JbK+N1E*V z?ycgwop$&QLV#d9iCc>lUW<>B9#`*+fVHh^r3z9lpnsrK zX^*w)6v|P`>n-kzTf6Y!xknj%P-dnSaJ>MH6i%TD!h)wUGhn`zng4ac*JG1viS9Fm|Nad zhfN>Xe83vsFR7562yL19`K-R>*#laSFX*)}1n}kz*NrDfzRUKiZ?-US0L3v5uPU<#n;oO;wq^eT=Z)@( z{&Z_5XOnU`y13Bjkn{^zQ1x?4jB)iqc)hP1ATCX%GV_|bM&je`M(q6V+M8M(*IOd<#K0ZC5XTFxpSNDT}e|V zc^3ke)@)sNBy#|7?q1daoTPcyjq=+6&q?_+0+Zp%j3Af@knpdFsHc%fy!+5 z1oh3Ta~V$1Y?w`)a>dik=3%pko8s1+)xdYYc#jTica2_ozGP>yj`_UxuW>nF8~Y%O z=FUz!UrHe`dJ4m-21`a-GFT3H1qKheakFzR>$JHM+nw5Mmkkl^fa0#JI(VG7n5fj2 z{h|XVmZ9{Uckk?gSR0LUqn@`hxi?E5 z%Sij!Vm%;qKbDje&zZQUIE%|Bmt2_N;% zZWWkIG+gacZ#QP;Yvp~^$m;6}Ga&mY7pi6kMu=<6u4b+y(csRY3WEsL5OPRL2D8K_ z6T@2VS%rgEI;^twdH}ggCRiQaWBIa$bf(>zsn0swQVShVbGIv!5oo-h&1`fmLBCGK zk7M=BaTD2NxZzYhb)Z!H{2C%qGx$-D+hDOh&IJjpy_9M zdv7YH&$_(yT{LLbG)qw0=c$y$jM(TwTkV(aw{4mV+wsL*uT(0M`ZfsE4l6I+ji9yb zXYaP%lYLv>clAy?p=~`ap=!0!8@4KoZr>yxBo`5Tyz%92OL61vMg`zvYr`lv^C?aL z)2cI@GXrd}%e&Nli!t>VrZFr&>_0QPtr=sn#dW1nqn7_;J=*~9YpDCp^8PHM>m5_# z)w>(cS_jwEeWbczqdV|Gvu_PRbfsS?Zr2<1E2DW@2xlOT!ayb{6+i+qv}k5Pf{~gC zDn~;Ag+&Q`aH#I2Qti7|jC2;%cklGx316cTvdz+~$mjYVypPNrjrX1xTjcf_OQ_}B zwQjpwp@nJZ-I2*C(^|7OqwW3kws>Xp+|DYz#bPhlJD={^5M#_2)9p zO-1HCu-gG7c)ZWoBIcbvZ$GRAM_UwIPareswoD+nH=No1;MRouYq*w3+Ws8S{(I*0 zZO_eB-kYfPuj>hUb2ko%&>D(An5(_69`J&9g3oU#b`x)ZLw`1R=0OjmZ_&mK$5Ax4 zq^g(=6j=lSj6?{X7QDltW-2+Lks4__(j;xKMGKtjN{FAdzJSOt3Wn{*X7_!eOF|dD0`=xP1^TX_myr8m{{m!dcJYx|yrK0r^R&<4%^Ev-=x2u~d?mf?b ze}J5Ki!jeTcS9f7&eAbovbk7$9M#RsYHuFy#LpMSZpt3jzNp&W#oHR$JLUL$1p3Vt zX}Xs$%Gou&Gn}@Pd+_-K$!{^An=;>Kb9;Q!!F1j1^P=a=#c2?QgDr8h&Nj*8-i&Py z5L;}-W`8#OU@IO11>Rd+I4ovpH@SrMBrVqKa9Wn!#_pst9>*=Gok17{Csoit!)Jf4O)m#)s`@8I0;TbZK zr29d5NDecQt~Y32ne2+&{aqGC%IooK zvKx2giZs}QICp;$)anl@Xr17|X{K|~Bw z)U%TLYLa~&wQwM1eb?+A{!Nmwc^kGn4Lg^VYZ=R1?f_%;Ga8$ZwIp3)HibRfToaV7 zDM4PHsz9xui|pH;WhHWK?Hw7bMVM+b6&9P*jOtVYdM6guF?}s7wu-)9mEyDiG{Koy zCZ&7aRcwaD>nwKr z!Hat=)Xlr=&dcqqgLZFN3xAGHEB-j(;=0lMZ)r1&RhP74GxPV0^=m^`XV%^VD3Cxv zB&m*;pfC{-5TRyF5>$#LibGdQQmH8Z!TVR99(=PVt9Q=(BsLXruSyrvrjc)Ah-4OK zXY;rDQ!96g5~<1)_N_IAp-oVcKl*Iwrm)gR6lx#YxaryayZz9uf3w{?QPjc6HqA4s z*MBYIOUunsp=PEE)eTzss{3g9&3+c3_Lcf)8%eD!aDfWhd|3rI4_%X)XioFcu&L(7 z8`ia5>vl~ybV!EDyt*mVmb4nY0!>utxo|ccY%>GLfbC6K2(Mv)_MY6SJFG%^NrNrZtRWQ zvskL2;6NEI!x7oDLkxTqYTgw7HV^m#Qk^Djzd3Qo=(=H-T|NAM?wv8I4i~+>YmqiP zb_YTbOQEAGut(Ku_zF`)@c37O!Jt$^b6{YPNeWE>bp!(#yLq*Tt$dB={+h{|kJowz z_NMjt(B1=BtzWVAEBEb(oAuwrtjqwwrrLVhiJ37S>LKQ=(!#Jk?M-S64x z6BajzfOL*bTI=?`Rm0bMIMYE^Dq>b5blszLukYU3)&>Qd_vEXL@hbv)?ThnKA1f?p zK9_sNIM=Bk^zBI0zGJ0kZ`}d&?mhQFGMgB0)8h2!{m}8NK;|!e)>D04`Ee&Vd9|Gu zkLv&O5$)9zwc(tYnf;a*aJ~txIdzd%rgZZmqh4B&Fgt% z8P%=tTYuBA=Jn zHw=<%R~PHT0zB*ulR9l-P9`b$&Y`bwJG|-F1y$ZR%c?i$qKSq6yN;mM{(34a2jXrL zo&~zFSmM_{ucFiU5YEk4)}z?`DR1UhAJ3y|_gTG-Hzv@Iy2BPsYZN!z+njNEJo~kOoblDM(X*mPUXH5Hksp+-UU86TSCqE4TfNEB%9S z{&YN>)4cgn+LCj;n`Sq|QM6W>H~M*dKdrn@wFF#Vl$0WuPj%k0uQc1=-SR&!G6YGj zK4u~nsCT|Ac`}zA6&$9!j`_LfyX~9qB)vyZ33WFA=Af#j4E+@mw#}Aur|O4ty*6R9 zr{1tqutLY~zfjhwEata)9q$pjYChY(`Sg5D1^g7N=V*N~tuHBj83R=Hqw66Y%)^?I zZP<}z3w!gkB|#pEXnRC%J=GH>Zr&xSIe3o0B}Y}|;6<3y%H1(Pdn3L1)0+COx7?eb z1CeyEtxXn()dFVgd6g`_IsCodE_-K;tL;{80h+?wEMY1+`XqJ|PsW&v_a*^YvNUA7 zXmcSwi|R&DZ2I5)0Z?2W+|eljQvSEm;rdg%_4oG2Vy^f8++TndC8HL8W%<(^*oDKU zf8J-wiPz2mW|m;dy}k+57>aW>>a5$mE1=`70D+A>mCmox=Fk4cP%vlCde#2B81-W2 zf2PTwb--@Ns$6suJKJe*k8Pqso5EI|1V=kI`SQh=TW7F&g^HaUW(oNUSt8Z6|E}ll zXfgrZLJ` zmkgz^rH1KsRf84>Um*ZdQUqo}q{1WsJOQ#2?*E<0gltg_&`d!{-6x(U3yC0**o?Cs ze+kAs*=icIrg=0KznH5$;g>WgK2VWLg*mdfsupQdNl(P8$t|K;w=s)kFtzLAeohNr zGA^4pQaR|w!qwZ~*Gt40GLN(EQ*Brrtp;&14wDo3H!NT51EA$nb|yJ8=KZyPfdI^ceBBy*T4Wxsd96T zN!5Z841^|7oeD$EM9mV6Fg5dJN*)+N=XlQoC}6SXv9-<6!P2f5Y`f&$c2!(jVYJ~Y zwJ`#&vU@EoZHhxBq_{NLMiYP3ry5Ohp{tvIZ3gVrm(YC8n>wkjM|uG?nPjf2u~VRm zN&a`SyR6*lV9u*`JRt&VLmJFjVf)s7iwK6a-pRx(ET7mI>@2`8`+|i#P-V4(&P`PO zW*Hs=j5E-Zjq}Xir(;@^?JsrLP;UQUqtdo}&Mj24T~O`=&b+0j-9y^y$IsHik zpq^(5rX}33O37n0!+!I&)oetF$?i8VOf77SMvqWI=9!t8amkXmd;d<7v?*DGX}fOK z1XMS-DZYA3sIAo<1uRz)%_|2`+nwr`a>MSdyQ_<2_LG$tGqbM-2O1jbaCz{2y=JGt z<9FqMn-z0$w$7ouomc%$fGH>}Hs1>r*9 zN+P6#fgC)WQnFb)hb>qgDuA)z^QPIzw${36qLqL*(qo__*5M4pujrFU;T3dl=(nXT|hUChr!&Pa-QpA&JSe6sRmq!uRhh3S;b(2 zoFbyEMWMi?lnf&*Xwz)A%|LW zQ_ZnMESDB!t!ioi9^3VqZW>xkja&k}a|n9s)!`Jax8GWF-CUhJg^I=Tyz@wIq9aWY zw<|CIZZPGGS#1lv9)doczV%E&a#9kCfFaP}TDc*B zJ%R0BApZ3;*0st>iw%H! zv??oP)j3QQ?M$QAMVa{=Si>1L0ZV*kGa+fMTf0;afPm4=)H%kY*E^WEh2f9OF?U`Q zw^n4D;dP@2O&o*Fm|q0*JHo2&mWHg>$L4KrY)GyZE8OB!U~Uyq-_214CeoOJy>cGY zPM>vZfh(raHa}+gBST?XIJ}4X-kzw10&;!5ZW6_IW^#Y-IFDIA-XXD7?p~}#D_MGB z$CUIQxEqOiyVfs(NqU?1!`i+&ON3e8$XLl9=(-rrd@oHn!SVb9ub`%jCuf11>F>Gt zX4agonS+_Mx#p349j09YC8wEObpBol`p##E66eJP1QG!iQxCi0HZpFTqe?T1#CpK) z($LJH_fzj z^5&8YhGTIL&ecM*f7_a+QeMm26*B{s7EBZ>EWtc8gQg|!pTAy$ZIwf!b=paiqDgIL zN>e&O=g>7ThgmfX+S_0Y8RE6imrKBVYc!KzU%8Z7;LGsmsmIkjYF4>lDCn=Q@>?RLjzM0ZCHX$kP=B}VRgHEtr$2YTp5qwB@G z^AgySK95#pjdIz%+gk|j_CjFmHa=J;+_xLoEatwpdt(~8HF0|ry9tUM4Bwx7CEztg za1WdUxLv1~EV)7ufdX36>Pi9tP*?(((m)1rEHR5)rapwsQ!P(;-BK(* z8+)4I^+u@%0&RgRhGxz#Un1hEk=9Sq{Z<_?p{#3aR-;V?Unv@3$ryasKnZs&i4+L7tdkZ?@}#SYJiP45D9U1UO8x2SlGyY|g`w{dq`ZPL^n@DnjPO4`uSrG!x|7@q#=~xFt!N zrzoc#``vCzT6>W1Atn3D&!N!vmZ;8qIHB1T={O_aMY3%|TD5Pn!kEsH0hmd^4Xf&u zLUKNs3iVrIiRMFY;iQ!a+vqQ>GLC!GwXtg06)rcWsGHMx(C!wddhdGOzoTBY_cjH! z*;wX!@%8IBK+3}~BXL7F|dZA>a=TL%~B}fP&(cGERs%0h{Hp6{dt%^1}U#&b@mZe@} zHYN6it_3jh3`iTC9f;(rlniA6_dp207cGbDt6HxvI{i`wSfXZyOlxy_6feo-$SOpr z-jOQ8X2HwM`{NoF78Bu{>s@>tftr^|xY+w>ly9uxW&0$L8cG1JC0On=PV#Y8pE4H5U$s&=b#=molYlJ9mg>Qibxtqn2|BrWcGsE&nmZ(&e<1* z>neKl{R4!mrBzucw!e;)U()qAy-&u%@khU>{z6&bsrRS{W~RaKA7 zmYUKHDzg`GN+ATd9aWtg0#o(XmTZ3nGZPV2bp%|ES3Nz4 z+TZZ(cIMOV;%nUVj zGIO^^YH$6~x!Vm+Dxs`mXgjmHMK`8;_3OcwHoFnI#@c!g*Ej2i{ibSmNV{`tEpwr7 zu0Le!SH0}*g1<4dw@AS2t+t+{{3R8+iHu5-!S8q&gb@M2K&2s>S;$PaJO8`l4B!|5 z0Du5VL_t)0Qi23Ojqbk$fF=-nDihdPVzA`{-_CNq;sJR6huo`a6l*Si((H1nshP_7 zg3W9}%m9-Rvhb{y$&R>;R=n3qp#VW4VhEy@B37W>=0I^a4bNU3+j$+n{cbgYjJtLCP3>dpnzMlt6d9d#&C zfdItd(d$?*agw0LD5|5Q8Zb?xDU1{yle#D@QRu1#nwjhgZRqcz25I`X@!{eowY`mCkZn=Q5{Vy`@#Rxn?z z73;H6f6IbnQv&8853+YzZ+=)lCZL+ztY(k;D1c&670Gll6(EZcP~9}zBQWJdXqHSp zzlt&#Ey0AGA_sY6o6{-{m)EdtRj_R%zhvU86Q(td%au)Gwuz-7jZzeyN`(LtIth!(;3ufg-$)>2x}suOmSu6>_|er|x7)uji{LsvfVSnK4MfJWsRxFJ>{zg+Fyl zSE=&BHNCo$np3liG07Uj4JJ}Vw2@e< z^jHg&IBt22%9-xJ-Ls7$!fb}C5VhEccVYmw{JQ^Z>2r5JXKceZ0bVm7%{t6xX2Aw6 z#_#;r3T#o8wii5#iodSV|yW{NQYAUi+F@Z-x8ZV;n*fCf__ zNFf9Y7ngG+yu2sf9YR%DqfA$+G;3Z9Sm6XuXs{XR(hhTZOOhgxQ5^~kfi5j-6cw02 zA@q9&5VH|Eoo>e01Y#?G+FZ~VN=YxSEM^y9_RJQsk@gNAM~~Y_45Lj(SQ|IaDqE@p z<pCT5`xI2q9)kDWHxthQKI{LDKaS6#u`#vQB{XA_B{}WVE}0~gN12~1TC3k@e*K(CT597ECJ!= z%SLtJ+sguHtz$EtX5iHMPtju%&WTAT$vMN+Mz|vBbBsz+;z8DG>Dr`Zf^GiR81w7!J#Wa-91XAbCB7T;$kBF&?*wl z1~m&IkkK7COHWdQ5s5HTz>L3}8%bKK*t6z%Af9ZJKh}Y6X`1CjogQ`AsU4jiITSno%#6eUy)i3gh z4|B4uO{>%4gKe$Q=}1ROcgXC%{EFNB7|mX6fVIGM|E{Q;eGR^usqDbix5sRSSt(t_JEfFhEEiZgZrs$&QUT@0avF(rGs43}#<594`Ip)K>%!1_$>@& zFgXFQsqCU%l(>NvWZE-8Lf?^ON_II9FX!RqJf01M!c3J35@BFq4g>*Ea!$HX8714}@@|_N z?s0rGm!J6CUbh^ne-rw~AZsj6CvK~6CU&Bj5~7%dIs8Og@W z#dM4@^n!QY!zmba{F6WV<;x3y{NeZ4@hYmr_}Pqq{{8!Z@cp~L{hNRDcYpUgO8lq) z}Fr(d%=_@Vf#eP@5fy^xRLqRZ!LSW`RC5r+@|*j5@b7Aa$!z*v>Ddp z{kl>hs>-HWk#&FeWY%K{dQt4=&=zgo#7ow{9*=a<`rb{uE*x)Gch66Uj~h-38|?$L zf0&BUU=*4`#BDdsEENvXqxl0+5r`njY*U(1M5syC^Dx0ZR!jtN|3f4*O-3j!h*%VM zfnC=jNB}eBo#hp(>W~z`XfU@Ga)smyOl|#c=QE=Kp%7>gd3xx+dDp#rjNgCz(4XYg z2N9^^dL2J~eEIl1{&3Zo%Xl8HIisJ679%VHrr1q37f)`1HfxM!{p=T(3NtJUut|up zch2Wh@`TizS)h3!(m)GHNP}t8@odBOJTKUel=jxx?*bfJRkazVZkNEICT`0;SYpf8II=r>cznw*`gW5tZLRzE z)@^OGOX*dtz!Lqc`KpX1tIKxj?g4RH5XA!;ysmJKY;Ugb<|{W#9z3iu#kB1h3WZsA z+xD!W4}_;po)I@Li#CM6+qPIS&>%ol^Jo*K7$-58B+Uo}F>>f6hCm0m+#=e&n8uNV zx+d7&e}sfdHmRl|nVOkUJK`bAsh7v6Q{VTbrIb=iW3rS~VM7XmGKxxqswN9cae|bY zIZGZGGTUOdK|dVR7Xm7V0Gv90^RD~FcaPt`KYe%#U9?lj7)2zGgMRM$)6?*DmLH$5 zKYh0AkVe%37(I_)p<=Ltgaea8dtw{Pte)!=JHh%v2yYrv? z;+N0o&%gZc>HqxS{?|YL_~UPX_v^lwKl$bN*XNHv{P1JfKU|0LfBRqlI&|It{J;LM z|K&gbKm6(U?|%B>*W)0>7=wOzf4W?UpFVy1@psSPeE9I)hYzYcTvKK3N1VD41G^v(efMw*PbUOPAuz=3I~Rl@1VG0C9ZeIA zN!0){g)WAU)-hYU3CL(PAaNY|5)y|5H}8VAMnKa@EwgthiVufgrVL~I!e3picFvC# zmdlAf1gQ5a`SLPlQC7@%8S+HP%i&!!5XTf~F+aGEn`~=l*+3hLt)|$W&t~V>H(}f1 z0}Ow!&j*ceLm*q_7kGv@Ugp!$L}zF%V#;M(JLwo>*la)>OSzU9RKL$f$(nH0LCG4S zLIN^%v8;Jj6G0O8eSjjVjxY_h7#V{GB8ol4*mr#ByS|T60?8riVi^89icl8q)q;Du^eCXAMaUmGqP1IfK>6| z2Uiy-3o(-%0Fs^&Ax8>DzaYfAy=s`2M^1eHS8d{`|@GI$Xxf`8n8ly z{)d0}AO6!dCA09Wzx>NzK3_il_|xxy``hymzxma#e)Z>n^8Wex`PaYuQ7y#&-8iZs zh`6h&q%_7DMW`^<(NvOJGWH_lI3zQP;fe%RM$v>WMjheW2bkt4Uq&SXF{-%nuo~#m zlk+l)CI>zUCZQR{+UV1{o_fl1HrW~DJG)%!y-@NQuVtE|cqDVcZ4aUDZhkhg{7N91 zs%KLmMVvPaB*l7R4AP1Af`=F$AL7%)!$Zf%-keFMz%2O|6~Q<{h{0&8I#N@%#|&l< zF^C#;^x!)IM%smg*$Xj(DJ2_Jl+gfT^sPLR1gJK2A*(@4D08J0EGADDXNf@!E7CK>1NRjFjdKbR07cGhL17M z)mWw|+}?su&;REmZzzD-RyDfM)|GFo-7%wkW;2fPWC?<|s)Ro*DP(2UN$q2^du%gC%`HcFsD zf=iGH7APzUt@a%cswmPcP$;2%&U=66pz} zl8m%qhyka_Z=Oyc-t`Y%jDa+FKxDA+GH_6GG&QP(y=V{w@Zm8A z>AKLn5%YCSm&+HireC*K&nk7Jmh(YBfeczn| zpW?%($MF6oJa+u}a=i{I8O}KrK^I7?p)F^-!IS?$B$gNnE(cIq5;blFLljJinaj{QF=3_V51uAN=Vr|MX8z zq5JgHPnYM7EFJeMIoS=iI^QYfmEDg`kpFUkjbf@pX{r+-Izy6PZ6BxgH|6zRT ze*EG0|Nh_pkH7rI_af*Rg7)X$;bhb9{UhFm|EuyX*DbhcJ@Q=a;T~cq0INK zH#bk>TGL5}YMhMh*QePyxna8K?kke>1{RJDB!eJ|_JTg(A;yP}Pkns<&^r1oM|?;FSNN7SYpO32;@A7|MCjnRy`cvsGDN$TJO8Yv}}Ru9zMta^#g@4w_uI*O4IX{(pE|e5oV7}MT#;!NBc`WGTS@uW# z{boO8S$Q?&P}0Sg8mMeJ!Nx=@M}tC^%^@L}un&SL)X=@bu8Vd+1Mn z6p>-%sk0!RDM!8FGFT9CD@>sw8B+j8lP=0*7oHybr&Hf|p$mY~qwoNLj55MJC4|{% zno^<;62xqbOntPzm&Y!gdg-IQe|qe?E-)t3lGar1AIC1Di=m4YFu_D5q6=WJl)#6+f4YWmF5QRs-4CB$o?osnSA05OFV{4xCWA0I zL7naubK+QWD1m7W3F{W9*$TY85vH7b8+(WqF)EQMTwd6Ko~sqK(cF(G;~!>OQs$^5 zHJO=Ox?IL#d`ZLA(r9}9@bvipm)|~i5}^U96T3ct90Eg|gQ-#k2uZR!uo)7nE#mWm(<{S&C(##b8~K82AwJ z*vaEbp8D|ap?lZ&52vmRh}mioW}>iRuNt+WkcO)cLrUg22?GUljs;Z5qBSsyQii92#b8u4Tv}wvLySSTjwic|h$BTV3OZ>I{`_Uk+ zkhC_kTh90e7${63K*R#jbzK+OM~OlDh!`x0iP&H%5Ph(|3w`961R@eB0uh=~ z0|g;i>LX7*P6094DNusaM5(IQMLaM<)F=iu(@|kjWK`2DX{TP^J$2u_>)$8tI&(u*H%lv1s8dun_X?n4 zGi;WlA6D+C-8I5KM?9-eB#q`lGh9pOz^0H1W@Ace7_R4GxIFaT)BAT%9o{{37>42e zIbnEw?5XN&4}3zkhr@y}X=XUS3{4KY#npH&pBU z(>aa9`DIAyWU6LS!sEB^Av}*Ggu~0{k3aq(n*QXQZ@&NL@jv{#zZT%1{ncOmU;eNE zw}0_3{>6X)-~Yc)kMFu~pWc7-;r#rf!*eg)RnOu^m<>4YS@*aetb9B2x8xm;g{@p2i4VMsb6G3hv7ZA=(d zq%#I}RRI}FCc_LW{*L~GY>2$dt3uJ4;b70!Dc;(n!NNxM#KHMbR zojfSU9rC%U{@kqgxLbSJZ~4%ayla)(K5q~3>ppAAemx@FVVk(6eXq~b2&*C2n^uBa z^WE3!+S))(?x2l%acdV;yIyO3kwpXyLJ`+7tJ$dP`6d+#s$d+Y6DEa*2qb`-1j$1; zxHFIlM2bSx%mVtrQ{+R(Q{*WiM1fi<>B)lVVisjH(y|RZId>8Xx-Z!~6cbZyvvS zfBNv)zk3LM$5ZUOE(DQr98(h2`2D-^{LRDXPgh}lcDkW!8E00p~QT411AWA zVYF<#9I$mB>S4C&j;e93ryV1+q`YPxhX^y>kLRT^gTfYRMD*CbjG7 z)cxYS52vn&4G*FiF5~5yI#{}XI)6^%_5A6lKn)>yxaRXXk_@5mPp9Ag;U_bDe0u+9 zfBMVuavsyQkG+{Oh7q(7UxooddO3Gp_wev=yD{|`nn1N+RG?>sSOQa^X-X!fzz9<%YW^s*B-3dL0)S!=#pq6JIbTn~ zGYS;30mPAw6Z(!_C2;F5^z)lvD7j&bfVh(_S*b4rjm9o$-^IS;sgtKZJUxVmXs2k8 zU3lul<4O9+E}EDTCL$?egxQdWH0U^_G^px0CKrFl>zGn9Gf-K4g#j2+N;0JD^?Dr! z8-_HF&c508d_7-AHAxnz7Ggq-8Us;mGQ(u>K;&Ru8Kjxdhq>hv30+N-w&9N_33x`3 z>ispV@zth1Yl*PcVPhs~EsPwk##h25*S3+4mR@h0p27Rf*}Vg~hdT!xP;g#mw@hdR z^fq_w{hY_HM7!~{dABy&@|}54E1QjS^ZXU{p-sk*?$ybAV?nRzYqJSnZJ~MGP{=#Z zX|PBj1!EeOQHMc?fFWS)L>NREV>hG`mP|*}QD6$C$M+!3G>SsZ0=kG^tPj?UhLAcE zl3 z_2KmLa2573O4o+~5Qx+$MjK({IOv!tu_x3Rk&<`>Y!LuIrvYy!-Z>?}uUd z;YXe?m(S17qoF(XUDrK6oKi|L#y|Yw4_%a`2z^Hau@g!N;d(tM#V`zykB^_9U!o`Q z2=eW_r$77UcYpP(e=uH$52x;5{>y*)Z~x7|rs-e)qhFn0p8JP)icw!aJ-+MXlf3-! zw=u@cWxQU8@4x%gm_Gmb>*vdL_~rYDl*TbVC)LN(Qv%MHVZ=D5pf+~WC4(@kIkV!S zR#Qop=c;ujMctU*^{GnIBzb&eB%tKBpDxgQ#GM5|wf9N`rDh|@9K?Y+CXK4W5}b)3 z0xb%62oDh*weRuRNf)IH2m}qPmTh82ODPT4Gz=*v(`4f~ z+UT+EAVTRS#u#IW!Md)K5D2Vk1xZg&)4%+!HD1tj+&;RQ6vz7 z2m$nX9|iAm^G~O?+T5+ETCWA1cnBE0#X)utg08owY3)0qGg$BH4~92qBNLTLPD~OCeSDb;e+*&W=!Yn@O&O#&X>!OuF0eF zkfg%IREQ7+!iUIHCtW}<)=`6a;uSU0IwBzzm9R?cXb@%K`*#oDeR%)fx9{FPgr{B} z`taB@2p*zD7hpp0TSv*B>3w{HFoY02ezgg0fax%#q$#D*6flKG#b{=oQpH4s%n4zH zh$6jkggmA2*x6Hz=O_LAc=_?+^y$;}NXu4u`JtKnawk*OG>(H`vN13qp1SVop%>Hf^4ZeZ2Xr(YFP}gD zbiF*|dUl24_2v5M)5|biF4ybjayg%`9>;Kn(_uqvO-oJnUr@#CKZTz4A z&0qiSH-G!`>Erj`{o?(H@4M5(%lXr<{`^n=^}qgC-+lL;rSTWve*gUWHxCct*-K|Nd2+5mQ_8uU)zN|4<5ELBC%_o;-*qCfv&Mm&)8?&Qc zW#~Ok->zQymg~;GsvCPXm)*5vhPK++#IE#Nx;LNOV(YN@7dy|qhi$Pvs|!8+b)(uf z1br|$asAr?gHWvoJV0@df@a&byK%%u>emgDKkY@KUlyjY(G8+tNIF18hqG#UxtuTY z<#BlEdI<=W>yTb9`g|EL*EFg~gb*PL6(SY|kqC^BegD{Z9;qh=^s#vULqg~}MF<)t z#Ha);4P%f%`S1|FdDnmQ7*3s>A|5(Cb`pfaAeP7wig~003CNBt9&9gw#-wQ&hA4nq z5=&00hU=iF36Jq{fJ!hoLZJ|n#L#v9nC$AYmV=!h<0+g@fsZl90Mje4I_M~jMuor( z1zUDim^hYFpku8UZk2$m=>%+J13B?6AN($`9A=~vU{&|FCNZXQ94=!dj51de-@1IK0LmAIGK(=>h&=OBhKgZrC zl+eEKA0GOY(&OVh0X{rFko@f*e*2s8)4P-X?SJ^|zxu0x{L~MB@u&abSHJqtKK}Hg z*O%Y@?sviLe185n|HI#Y`^!J+9v&IH$H(^)VuF~&^Jp(aGQi-eu98ca#fCWN-EhBQ z54I&tR3k>@lo#&hlj&&AnB5%vU8%@6F2Q|HT*O0WwxI$D0Fgq|C>Dctv>3r3f!LB0*lf*y=c+98>RFG<>qMqQys}&K7NeDUp zD3D+&JN_(V)GR>YO|#f(j?F}tS8#s4SaBXe5qo5*ZC6T&*42{j1^r(d1g%Yx*W=oh z`xo_Ki$B=Bz}q^x+NB52W}Vhpo3FS1-h6Iu{+m+lo?Z9Wi){YAUFYW1?O8_yb1Ue* zuC#kg{TgOAk2SO4ksWQ~5VaaX6!PqCXWQB=M7#ZHu|cV7Z9+t7no@!$MllL3K$9gR z8EiZc`sqCM{SbqB{*B9E!-x@*)NB}gx(AQKG!k8uQ{O+H`p3uq>49C8Q^yzph*@Wb z5P&fO;^7ohG@gR>5<>Xyo5#~hJ4vUAQy+RUu~AeA!V+M}apV&qz6n!|CZ=-vx=Cog|0|Oe2jEUEoP&RE;*qcR2N@uCpM+ zkDt!ZSG}fDL!e+xHs-w)NG52G&SMrx^`)=`cf`(fU#xCi4)(QEmjjd($3%1FPRmir z%si5|!Fn)AOHP7_=msz$A9&!fA-J*>fO5!fB5}R|Ih!&|Gn?t{n?-Wg;*L=`r(K4 zyWjuz)AOgN_a7eLy}vxXeEa>MT}Qn8=46Ipuu)VHay$Em+Ocgc| zF4>tXfsPW2>#VEJrrT#v_97=WYNfJ(l>n}2uXvJ@C1n?!H9NSG9bu|btnb(hV!(%Y z-8b+1Zyw~ak53PM-?4{AK@bZxfmzbzDU5VfV@mpR89raem+Sca`FuWKFGEU69Vp2J zMuG_Y7`v|PV~o*d)c|m~UN4vH`I63;@#D+&^ULt*JX}UI1WFVTCgV7orR%6n7D5nl z%d3$Fi$PU|rehKji2)w`l%k^OHMcW=2yf zux7=c%_CH;c^tLkh$MtU#iQ_;2e%Q|T+#yq5HLj&49O@)1re3L$&l2BkylFsbOeA= zEtwc383zIaXQm8@#CDB|0 zbFM}+JXv?owAI>wi{y*ujOFWTI&o!h1enrv7>D7iNqY%>*LNWb$)u!4XaGYR()s!2 zr{AB?&p%wQeT=6Fm_0wg2(<6x(r$>@GWx}Zwv)}yY?|%Bj@2}%U zVmM!~p+BLEG-6Z_eleI`#$;nU#qe^zoL?@_&(D|3r4RD)9>sRu1Qr@7)7Ly zPBNwIV%NnkNN{k5!2nH2Nv}hCxePDo>+|LMa`liWehPz7)SSSWYBIBwlB#B%5iG() z#8@15GY1Okozb3BgSf-?!lE@#Un9O82sC%zybCewRZF?PwW~zF$BG?jjyFl~g2F8} z(mm4K-roC?=M9s*`O})_9f;juw-2v+b|v5f1uTp(IXdR0Mwo{?jsYU1CICuN)#Rks z!7hrKgQFh70Dy_Xpo%G*cV;^+^OXu1J(`aQU?xGtrDJ1MOQY(bDnOTGTLzPmEs^|0 zr4gjV(UDoX<-%MR1;i64Xb2KOCKEB~7(;mMgDFA?68P}c1+gHWc1>YPlUmZ@I^=+~ z9?>?07-L{iSb&8PQWh*>mQ)Q4Fja6=jLF6Um-G1YJpA3aIL6iKdZ=fqjt9jn{PyqGIFu{OQx@ zAFtPsI=(!dy2tJ*jn{D)#^GXVl&%{UFE7tA_L>X;LQpjlr`WxFdieI;Nob#c`be_x zAAbDw@%(a*5??-kN))xAxNtZ33X$LN1rG*7VYqGb>b!k&y09(q1K#K(v3-D7-u z>>eWD_0oxjU_lU}G^iHAchDi}<(fWU#>=2D=j-R^>&MIRd>&q2Ueai)2B7QE_q{@* z(^5Yv`Sd|yV@lWSaJgL0=kxRV`g}QGF2gvQ!!R*0fXT!RQA9PERi%$9Y)ooM9!(?! z#OPAKd8Q4F2_-g>2kT(Qd94tY8b`VXs9oX-Bt3CQHdvoszO2){cipcq*R^@h-s93R zZI6UEkv?LrolCWUHm|gp zd|PJo5ZS&%;E`5%4{TV>YW;FI8N<%PxY37F+z*ncz*8T)AgTgDRj(t?mdpSXVJyMY z;2NV)cDyCcQ|<7B(4nC@vOxpXNV;fCxSOdagN|lmD#1j=ueY4}#57W3Kp(ToRS-8G z(v*fIlEjjLniI2#NF-xqvfPJa;~hj`q7)4@r~*n&W}~SMny4d8%m#pdt;86+5Cbea zFhqJTK~+=LF=;X?ph<=?U50cW#$g->wedM!(&bYOk1yTx`Jq3B508C}(s!}%6wpo> zMcD;Q8v4-1?$KmSdLC^UaaDcS+xZ$^&f$`DOgxY2JPgAq*UOkp)e;pFXv|qL)*#8= zy0_%lRYq94tv-7XuuVteaaHx}IHk zy^Nz7LI@$Gl#sN0e0X?xNGT0z91X+u`uX|gdc7LMG4D8;^lnR#28|b`2NH9BJ$0*Pe1$^e*gR5{D1zx|N7(Bd^2oi(mZW)ITOALS*cQ@nYv^>rRkP2u&jx7$i{C z1~bpPNHDm2wuosOX`^aN*YjlnLN5;|5m}tvgY&%eSh;JatEA!@A{JpmAYxsRAQ}Ts zAw;oL45uzW^>XUv@i9D|!l`E;>=fN%QRwl}Ol=&~I9^k_T*vbzeSWzfg)te7#=AaWowRtq(Gqn(?YI46r01 z6zcYpCIFIYN;;aFYO>MLc}#CWV~jvF(vzHKlXK=^UI2`ck_`MNfjKU)R?yC6>+QH7 zH*4OJ-VPAdgB`I^)je|ULQVdveRz|-*eiDY);-m3f)IOU4y5E;xW#R4`hniMz7_ZS z*G9~l51!=zkGMZ;vSiD-#4s!X+xHq&0ne-shII5f7U)>=y z;vDx4VCezdBO~unRo$YA$LgVOWDI9;-vAcY0Hv64GkME^?<+sZS`4k7DgT)aLn zh#A@;*#Ss9&{kpDI2Bl2DVS?jqe@C=ps8vPY9`w934B!?RG=KXXr>*O0IINY&fCz< zWgosd09I8dQ(1<>(p#vB!W`%>w?yCj0aec|Od(lSm6_FhrjlyeO;sVFQvuw@ro-LR z9B&^(|0Fvuw|TIwyi~xAXFOt_6cyeNJ7#Q~pU2#9+tV$d%J=db*j!BrgNY8oR-B5> z} z=KTEgFE_V2dp5eCQTx;L?e_fB=g)38z+EljKt?BGiBwfPC=GMXg*iOV!_1O#yWLFW zj3l&59_NhDKi=>6fBzr-JRfmR0JqzX9FIAF`Q?}IzyJQ{&p-Y2%g=MpMzEispMUt_ z&!F6P`|#oWbLPu20k60Vs4hc?`Vd8Co#&|??ZD;GbWsOnxK>G4GUs{Zn5XWkYI!a1 zRJc=LVJ=go)9K6KyI zhYWOlXT#1gfk*|JnUBZgapdd$`0{#m0Y1;T-{<4;IM0}s4G1YzP`#?_dfWjjnSe0K zv*I`-&y$kF@j=Jfw`aP@z7@B+henOIKQ`~QBVX>p-ZDsTAC!%i?@IP^6|L#Zm`(J#Ad#n6j&0Z(? zdmeFrPyS|V)JD0!S%UsEsPeB$_3ys4KdLc*!~_;u>X<+3LiC@g+He1_{_Z>dD;nA# zKgl;N9 zga&blD>jE46a+I0TAYRJf>beswk4iiD^Hb55-ByHToxe3rq}>573$)&LMRfEZF~Ew zhx=ysXgkaWt}|PJ0U(O==iJTHM8;S1Y@Eu9yE7VN+27UOwd+D13T*a($dlC^@*ghFE zef;j}wmn|&kH;e-qS9=P%>^oILNRj_QvoF_^LRb5k2&)= zi?%)8_9N!J-ys%J!l_DiGbju*(k9>Z9{_t^setv#=yma1so~f#H zW*m9zAHKZ4^7R)pdwPC;9QVKeM6 zUta&i|Mst6e*EbXJW6Cd|L|}AiyuDzQ0kw*JRbK~v+?ovbk5AqKM_?*WwnjT4mqk~ z9?W8esSNFSkgq4qZx>qc50rJS;<`cJK3H2Mjpd2fn;@fV^9eAN+t7VrH{A!H#@J1s zZsTd_ZPVd!RkJGcoHHY`S=8$;RJx&Dx7|PTN$s>VT9R%CGf@>mwS)HC z(KahH^UOKtBy%&9%^^lJm}kkE_4@ky`f{IhG83ihqtv1#vyLe2G<$cz0`%D^=s~;<1I50RHRx^beutzcZQrGi<5#SLD}! z7y51W{f*JbuWG>GIqLsmfqDOR{N9WD-5>lrsPaGTU4G}C`R%Ud+ZXr`m%+b*UB7wB zzXA&X;T!lX*x(<&b$@8Y@kbD}NyE^kDz|~>+x}@E+pv9jl6wSzzO|0%F^j4)hHY+} z!&FpCikXbcn6=cx6tsl_wYbP!a;4)@hz6~`J~x5_HK~S@g#uM5MU@UHtEUYuZ7~8f zXCYG{0~B#7C1{F%k|q#zKyh^htboiELZu)bTmvyRNL7l0r36k9Ci9#z=M<{gTmy&d zLb;{pT%a5aXW%~Lc+8j$O0xt4R51#VDGA8EB4<)&k=)JH-2yslqe&%^Mv?eg^0(_R*inJkzNGq0*M6D$`1$dEY^1#yG>e4JzW z$L~JezZ{YRf!2zMGKi{^l{w?AeGI?|CL7jp_pN!eN>x>fvZ2TMSq%nk?sZ7aDiKnD z{PNSskGH4W?T0`81)rI9M>p*i5a=Xf9@|E0R%op-CzwhHcxnZByUI*v&l! zRrT^R?oU4FjB`qr+el~%X4Elp%$OmM8E0@)JA%io;H->Hpf-%kGEtbi(n!Kh${Gr~ zn)s{cDK9)|C2UAl(@=hO;P#_XCieGt!15cr(0^uBdS5wyI~lL@RF>5P-0w@(@bRYKIZZ(|?#`#q&H%gofQj<$NQpFaPRMKha`F~i-T_Wir>ZpYM@ zmoIV7m-xc+Ol+GyJ$?N6>Dj!t-M;_sPn0zd{EVGA7czfW)XGd zsgIYRK0MtpY#SRranqw7h2?TldWDY(6!0Nqs49!+oQFlg_NCYs1)O0_bPf!s_RdAriWXeW41bN^3?mRd88$bk=xPwI%lZs`IwHk+(M*%UK9`=cgzl{MtqRrg(fkW91DN zFLoG4{@#gi?-CN%@3~6*n^h&2&B!+ZZ!Le3%L%Esdh1{MFx7S9;rGYH-*$o0Fw3_b zCF8H1f8KrnH*7(?`?ddYq5Hc?^}DC>4|c{XMoC$pn|8st^k%>LbjYt83BG-XZ_m8m z!Xn@O$@hRUuQOZ}$cwYyU&B{++&4J3UkQclZ&JPnba&s}G*?;X|GmY0|{C4U)#ZRnuv%tQ>z1a)>~PXE8JT$ zd70X3mQdByCM!!e^^@uaC3YV&7{ZD)K%`8^q|}*{xb| zY-Vb!NfyYA4Avwk+8hxothwsigL1-EoM5Nm-PBY=wOnP;N{Tr+w_je)N2JgMriv=* z{JiFrLYBjG>wvqEH%nYapp7qsgwV;%Ji$~zQn%qXUtiB3H#{mozrOw$_oIR$CS^jO z30E1L6muIGV?h0!^_Z_6b*vO`%bzTPQZS=Jgp{#AiQ;yji56_#Azy0lRAD=#sF&>Y@eDr;g#V9GEZ#Tk@^JL~0{J;FS z|JUPj|M71>{rvgM{WS!8TeOBbppI=q=hd=#= ziti~|{OQXt|L%YOJoLZ)>tFvxa4*!@_LF|lrU+>zEvB3M6Dp3GzliCSyKQjyGYO3A zAV-O^2lfRdl}Oc_qzwv1Ml^hs6eCns#UV0a3OWQ@!U-)m-G=U7w@sfmf8NH;eK*+w zFKXp5nh0agXtn=J*CN?W$jyeCsUTU~wvBFFg``Bpob#N#KiTb=&pXa@%gkTDoNNFW){WsJnxU=^${;e ze118PN7?oqmVPI+lGQiEvREJ_4Vo)+qa5uQYASzTsly2^7n`wu5140L?qA*h%%^}?%In0tw2)0T|`7xW%ZqFs%k~1c$!$2d-aJghuu_apu zxM@`d63M5{&hW?6IHQWo(vPA5dmr~k2mSW?#=AR#BFIdLNLgiyh`S@Rgg3_kPoDGs zWya4nU-P)LN_FJPO1h6>PMIjUx%m)CB>P+=mo?biZ4i|`p=0&s0abY%SyWY1cYr0^ zKAt{2jWJpes>8<^&-=}xdCorg+&wdAWo0TnGb0K}LPTw5{q*yf|M&mvfBfrTzW?w3 zyZ>7x|L^~g|K~41e;&7;q?mqry-Vd!_0v2aA3r?1+s{9J`Shnh&BA#+u--_VM{m462CX=cm(QPn{PDIM)J@f(=pzhd z(-j~l$aR=~oi6kW*IO}^s-gs2WdQ5(jj|~~s+3Eq!d$oAZkyhA8;+Zg-E>pBl%kvJ z$v$LC1eI)kZNXY=_jRY@YA(xahPEnnrk3kD=%GGzGn}VJRAf~!zaBi{~rQEK_acV%oZ z9ig^mn}AuOQlw-TNJUE(x(VqQNN|NiON-m(Jsty*>e2XGl6>8O$nQU{+4}v&{D%|m zuZHrsdM13cb>my#NF-pgdtHJ?s$Uw4Y zR7B-fEEOH`x%wkQ-r5vcyT*0vfp)$Vh=X-;Cf9Yt_qg_2AW>ai)f`}LZf@A52E^L$ zP~A;Qq@)?mpbOols+(a9d-GoJEs$kuMGG}FrHZJ&cuQ3rI)?9?yKAR-p659u9y4Zy zu&8!HF)5XcUnE9mCQgdZ-X~Oqn9^m@tbtO)(DITD&Z;yBOY zvYYPiECJ16XtVjHoK}+-M7Qk2tjbEY#G$use0;vmkYLP5CfPLF0{&>{@&-k}9U9$t zG#y=*D^@WBTIVqzFF!qAeyQ_|@D=wymmywM<>mmmIUjX(eRK zLuIIm>1}MmiW&EpFCx&NH)q`uus$d7h`ci^x2amz6^aMZuD+ zwT!Q-`+4T^GUF)PG0&fW{`oI|{_D6s{p-K}>o33jG{*S&;lrHXUFXkK=Y5y6LP?dAPV3m0tU^DS!I%@?m`Xbo+Ep z?l%v~=xZ6Bn~&Um%(+F>8Bw#E6jE!Y z+U$S0`{tvAI&QaZ+s82V=0vJim71uD1}git8CJ%IIXs2k`<_pApEbsKx~JNqa8jxQ zHP6Ul1rt|nL!Wke-hJPPnTcq}pheXzQVSAo*iitp&tO3{-vZY**ZP)&+E81QyE7=|l-G)=_>pTvTYJ2k@?cOc0-lM@ic)sD@Z)eCKK+1fZ ziGPnS_B)*Fx3AO{3-lgczpC(3y$PgHdR4blibzSyGM?_(6k8X*yd96(L!k*>d2@8^ z=4K9MiO#6UIbV-BBC~{KbSHP6o|n&{kt$2!N>Ed%ZDA%WPym<5Z(S{esM+;qRImON z1Zj`~*-Qsu5UFIQq{5`Gx4;D6jhAwwrZNmgWY7n0+jhIv>rtxN;frje zuCI&3uRZ*=34U7%U;E%rnHOXwGpIFOhSitPpO2TH>b%!ED?_S+3ejzQR@FIYMC~^> z(<0CF>;nA$Ui#+Nf)x9>fSTHEQ}R^k6cM2-Gey>d9qMZ0xamA*@qBrSD0gL{-VwZ2 zb!Mn)zgK=K}s@`t5=Y4lGciqRsIXX^w-sE{S~||E_=TX zHBl;=#Z;0du%#?j_7RV!&u2xU;`hJLbqz zth|2pf#)W#XyQ$nAZYO}B${SCP&+W(-t4FrnAEl-K&iNbt|Bg^>LOU-oR71}q8T8p9<4L- zngX&^Npy@|Htyc-mkN=He&%%Bt%r4)m>iDnJcZD1Q1 zoB5g1#>3ag3%xv{zY3FB+5ci*tFaI$gUo4YFCJe&>_sz{y zNG6dbiyI#iU->E5kWEVS#igq+G?&AmJbwB`t}$ZmlVCQSBoXJ#iW)-+Bczn(4wG|c zk;5G#nK_Ts%vvYhvt3p7XF4`>voBx1{Pg*kj~_lgZy$Lc5zz@q5zz-wGA0$e#hmk) zN-_lWrNAOHQ!mmh80ZQF)_*zLxk!uO}=fBEZw z^(Dl&{lkY3k2$rIp+(s?(LLZS&Yvi>n%>v{bYTc4Y03dLt<7{d*`2%VhuxlUW8ZY& z%!fLPQUF1!BqiI{rWNgdmi3CUQX0MQi)~oS4uemlSg{Y`3m|0{DeQ}zO);Z^<`6Ls zX3CtEX;lEcd#BrNd%oRFX=YnX0lyMdI+lXwFo6JBr3#?j49gE!6aWhp6U!YD{&7Fz zrWq#bLt}=O8ca90=O_RE_(R(0LA z)vmgL&;SUF65W;wAS!IZB)g@664K@-oz_|cRNHj&VwEKt$phc2SID|xf*u8f*>aL50QI&zP%B-1HC3$7705pgB z+x|$`s;~4d_f$m`90FBrX6*)W+wJDqEuO~OyH?SpDw(@y)yzjhdaRYNzNXb|x0I|P z%{nFJZO2ea=RB>{(8&k@%~VZ>nyOf+YN-uKs!*uADb&;rKA_FQ&37s>Kxtw-plWVK z=rL2(74v}tBBsnXr(ETz85r8mi}1#R^6Ql*(v}^SQjjW%lBkSp>s)1TsLtCpN>aeJ zSSXZAf(9|A1H-rv-G**1S(uW1%aj!9H%;mai2Ztreg)rnt+N0)bg~#T8UOmP|DV@i zeneDjoK454=MQEBz+*mgP8+IfBAglWPCP2hvGVJ9_m*zibg(4lt?dP%ph#p&qYyAr zry_%*vF>AY0Tr5ZZl}42gKS%JUd-fc)-uE6LCE<(HrS z{e6b|*l*tre@2bl(p5R< z{`rp28ovNv9+RRa#iGF!o(3u+N(iEqc1galj&^(<$i5bv-}hK9T+=jBpb~{QdB;`D zn%LEF1bK<0S|ZNs#idHqWtVmeBFXN^(Rs;WDyoq`6=cR6Mr>UdiY4XFB+HQ1#9h>i zq`RDkR@_AN}QTD+}MT%zpb8@$Y=)cecsvSgKzihS&04 zu2yClNRohEL`H(z${Z<>Q7Qp6t&bw?BW{fB3L{*jy_!MX2|gzi2>U za8qo`G3y=@lt^aQ%CV#vLC(fA>LP=gqENnomTPlR7n*T7r^tm!U0gd||8(uZXj&9d zQN=UmtjcAA^>*5_J%gJP*#h@q&C9(=g(B*TZQyCx&GF=VbKVA?26qz?Mida?%pFJR zV`{8|(O1UX0_K|Sz$TiBurT@{Fc_I7EB9AGRo!7wFSzvNr(#M~S5T0;4RNPA8`jaD zAM$++S z_h6c=>>|MtK9ueay#et9{j4!hm7^n`C?$m11#(h|9B(ILVsn@XfDoEG?2 zZYClF*azHeQ+*!ty!rEPPn$n)wmBW;DD)VOZhBILlmwYqqF)Ls8C6k;Su5M4gcP@e zl87U7jCAi1PDx5;R-`T-P^pSt`x=K?&#k38#yUn&y#OArP3blD)@k)E$*QWTVv(85 zWHiN55~z?+)uHWjBiVU?q6!*n7&pVyCi6C2Th-#yU$RvQq^P{Lq-^Rhh0v?xY4RpZB~>|8Z|*mT8`Yp3Z(G{8MDMB! zFpD$l5j>-9#iS^zw#3j~7J3;XXo0v~bOgN3>z8@kyKQ#^uUfw$n!L>qzp}D=&-|3H zeCc=J#BaV?z9O}FJIds3jm@_%qRUV(Rq#!NjYm7{mYQBjn8|#3|iuvwtFp3Zu1fuQ&l7Y}#F1WzihRG5A3z}J> zVs0WuRK+Ev>HC4J+?J4OjuQ6$PgW#jW_jZ&`qp$`HOzRKPA3a2C>@Gbf~8hc8Sh>+%3e8s-jJ@W=Wo66=m^ZfGp7t6NlHD)Qr-C_Fp@_NJp>$$oj zdwSC%RkdmXY|X3{5tuf}%r5=!>h8it8@X3~8(u~D#zJo>*fJOCEwie|7yu$dM9%XB z*c4fkl?z#=h`?-Y%gTG~+vd;v?azPy)62{2%j5p9KmJ(Kt8{s}zij(H_N}V!GXOJl zxSLo(;{GTJh59z!?94#cKK#4yzmNI2-|uuGEFP-S~B(GCmt!-Bpx#J?|@aCc-Zn6z-uDi?g!1Jb?$<4VbHwc(6Vm(Mh zCXx#bV96Rbi&ce8p20|*v(6)rsClM{3`6AoexB~;u48KjHX}14kOee9k+;n@w=sqf zwTpoZz{i!KP|(G+>dHh)cE(aywIz1pWm*}GS*vT5suZ&kR%QmhxD&{C(v#?!T!tYut4h%UMZP`wD$RWVX7CGoZO(Sj(omzPbMwadFiL~O~J3v4|T3B?jE zgLyb)b9~tSyQl5r&4=H`Xvx>1@eb|9+p3%V%?$fZL48w0eANP7KluLJ-hbS01z6rSJ!G?7SkPv! zK(%MzUVTa%@)o-=cX#3t2i#;E`uybIKiPlr{r3H{{pGu-@1D1hyWECCm?;@lW2OWZ z%FTT!_lbSeNv#=YYM0)2Ejo|L3-D7_-}JVt5BF-|a;4n#)zgwQ>-0bsB{Nt^xXO$Y zl$nrll~bywhTxQ}sz{!*?z7Hhloo@+CA5LeWU!Qy#E}_El2J6Y2|pa_fT;{uH<;2O zn`{SYTl9mM*7Ey>{{js4WQGyA`c!c(R#(i|DkF9;k|#m_l4> z+6oaXcoq&}R4GdZ`DP}mLseCqQN=Nwq-Fsw!m7wLk_;s0LO6slH8E26eN+WoOC#Qe zhU6GSgbMF6quT&91(6w*GjrLDT|lcXl=U4Ekww8~npMKdN<%#jn2kwk`O_JB&gg>J z)zZB&nN15`vLBAh+WWLDf?ztlV{r@{L(-nLs+y}rJ-ys)dgK%oXP62(I0a`RZ- zok*uC!{pkRd>tlMM7cmrSI7-bEXf6}l?>aMjfJ$#epU8JN)ckg5>o*>s%xG4*WWl| zdTlmbowwV~472io{rCU=e!tH-BbR8KCFa{~2ML9$iD(w9!6u<8ASPrMAM?CHKRrD^ z?f&DJU&yA{A_T`VACHRS%a_M5uP=Ye^IwKNKY#yPCyLKww>aIjqACk&?!CHhQ<_AD zs+xA3fSO{{a+A&BR=e?O!_9Sb?nVt~A?Ht2=sJyO|u?c9Jbob%rD#xx*`*?l^Y%5{1tQR#`0-(Du4v?rR zL?VMgu1}lDkSfV!k~8v%h^l!RkFzjFZDRo01ThiGlJh)YkK;UJ&be+Msw-gXihbyC z8IH}xO@_&)Rf6FP0L&Vwr>&~U=lv0%ag1P!mLNouVo>ctwpck+A{+ctTU~^Rh?u@B z9t$k2HSi^ip~IpK0W!{oYNhaT zrVJ`n#WXhH?$|;~4W+Ys;5HJG(k8eau?i3_o7dRsC8A>2?*9#40KnEX2}IQaQZR#t zDlM0OzeTd#II50WYhjt3B~dadL9vpU6{y8sj2^W)gHbiJ$i_S5S`Kv+R8@@N#1e`( zpslK=1wbJVOOL)Ie)+CL<|OmLpSV zv?CQ($Sx&jR)tc`IL0vPWMCcUBr|w=h*YM}IcMP{)zNywCcCZFd4;NrY6G@h0zmR2 z3yJjZ&5Ep)=q%w3OqRx(E>?a?V+hkQc$iq=l${expHdBB5*W^uXUWzJQq6H983VRjH`%cvir@0i`D&i zbbwzUZ#2uV!^hI)|NhVSMDq2Rd^-yuA{I$L&hvc4aSD@JS@U+gwXs-UlKJ}TL8J|p zF1m^e$TMOLGdCpL(6Xv1s@pivJToI2`GxzosU7E;^Z4@9e|Y+E`_8uy`$sL_9}hE? zqC+t(1Tj-ccc;)Qq23H^iBpCRDZD zKxc8D@_Od|b$)q0ULVIi7d4BbA=6DP(k57FKHZ!t8E)9N?Y6m_s18R?Pxsoq@7d;Q zpd_wkmIB%syF!a~N>!CoOH@*lGG`_0m^>$snU6Ei^E_u{a*VP0=+E?`%IH8 zzTOIIH}b7I1Z@2VUfUtI8_(C}%SC^aDkPEFu6C_6S)x%DHE~lh_?wQd+5V9p5wl9N zeCMZU|I>H-pFZ6_-TZ08Fq-md9~bu8=GanY5p^7hw43>c+?}@}&qv))JIju9&Y30R zs|NcE0xiL6=cPG0cX#dLbldHy=izGH5`KdJsR9`An=Uzd+xC*yah_19G0UMCca zEJ!q6P0>EK(i*7YG9b4NA9j4)@!f_WZsXIBN1XUCU3t1s%)(u)wHN;f3sw^T%mLgPDiWyl` zGP9-%_KgMIMLXojwLnRvKyv6laO~q&yw5O0NxxwQsJps%WD+GywM#@?**Vp)U?!_H zlPU~lBxl4KCL%^5IZ9Hww(0P$ydnaanNo6BwddiU`;Hl$$s&$fXXLAMb1~=_o(zF% zo2S@9Y>1T@1MR5u3IJpr_xn5^X!bx|GG^^{xL)D_2&HhP2fq==uDjzMQ{wl5slHK{ zKH!aE0TB_Ex24+qZ~wN!>aV|&OJne6aLVI6BEnS3R1uh(nahYwRp{DY_YtgesTAJw ztrv4c0J{VQBC1-#BW4}Ua|V-u=n$x6WiTZN6geM1|MVZT;+}v0m;d_X?N3i*J2Oa0 zwsC~1OJ;&$psJXvD>hd%HB$p_gNn`;%we(_hsjVVOG%{_>z%jkVxmQ52BRcOo3wG9 za-Z?I*XR53`g*?JkNa^()YxunA{wF=v34byS%ULCbC$c_wqdR%uBK6(RkO;IQFJao zs+vlg01M&idq1U^B0|QpeiTR{OEMX(bH?MGuV>tkc^v0?hKP*7;a^Dueb}AnJkB$d z$$}W%frRP>dPzi`k!PeEM9fAH7mEX^DrVZm*Uh!cfD%OoE2JcwDhWyLj;3Xkz`ByI z`CcI_YuRAX(erCV@#~t&Rt9mIlFM6eV>^D#WCSAD3@sw6FjF@JFchxCS21KIgEi+2 zlSr80X5)uXx4-;w`{C2=*&7<6p|&B{y}bS|$(Ry`nX)T~>ZbZU#{GyR?e(ntLtY=5 zSr^TPW;Vuzc43vW~UkZ%Z^4 zal_4RA8Lj^jup8Z3^XlMaV-a2QpnapCzsBwn`K$lPY7MK7U8@&nfIA5cYglz`0{dp zeaz#mOcbp5XQD=UBD+M~&$ANed6N9_bR#rdK&RgP0TxJU=3q!0TjJsIFq^E~5>DO8_gmT!D6X}GK~=Ohs<1++q1Nlj|iQ4?S@ zuS6t#DW01YI_Fx4UB`Qy6t)v|t>!ORfQ-bFb#|`khK?S9B z=?S>~70enC?u#>$5pjlQCfRFpQG==3Vobn5Rf?oT#SvL2Gf{Z5r{N#>+jk%QPoHid zZ@zmC$EJX`)7)bI8`ubKT1}NRQdwjOxf!1}n}r!N(;w$J&d5v=*|u$rv2B}(%);Z$ z*GIe@^W`xgQfD;_3~$cMS4Z;e;QDJC{-+A=+vxmjHr9F+zTL%tb7S`5-wqbb)u3#+ znQo@0H9*tlqteC|!*w@&|Li|}+Q0j-{prK)`w!!Jx7%*oyBtbh)RSsdrM;LWRTUye z46SXrJIu6QWgu3&WLBk=43UDCs=(n*f)S=lLBd4W79A;-&3)`1HmPKLl?ARzx!A>6 zi`T-V4W9b_QthCGC~7oD-RlwNR|iDx`#?(!m4ztIWaDNi$>{Z~OrY=vcFz9cj@086sS z6oT3=`2?euO}}Mb1u=R6(y99KEPxwLS9Na*ORk*B3zh zB#YGS`_skU6&!s4oKHph z!wL*WWw`roAIchz+rTg#hHKTLo3ndR(}vWt)u8=Gue5-7l8o#dkebw4IA=YMy3hRl z<$QU}pT8Whk7Y~&sGFN_ZcyLU+X+0Qat6;MGwJTIO|dQi)HX-aHI+64v2BGa59{gq=FPw>++Z zFq0wyOraKaY4#A%ijbHQXXKeW+cPyKLvlt$RT9$RWf5hzHCJePEvacN^K?6x3Ba-;RP_a;?LT-{dKN1+m`-<*(b{btvEp z!6>xO%>;B+X*(N~u~cXZGi3Ze7b$w?fZ}WlVji1 ztQ42hx+uw-s96z}bJb%=S0(gIFddtP`)a=`Ne79#xHYPP!yB6INIp|_h^Z+>)o0c@ zlN6}Kv`S_sT(610w=X?iBCa5gx@_34ybddfsKly?-FP>vpzk7(W!k|D);9kJQB|X% z1d2+iA}Y_xvojECwbRXmZ)uAPXy~Ax>wI2uCcLt%7kPk$E|DV1jxbhmQ|z04xQ(aV zxOpR36(#3+o{#e}Bd+AQ;U)$jyP2t~D^v((^OIH80IInA7_wDtiI6M^q9XF`gfc*w zf>QLPh$#B6bTz3=)i#SpuUAIpYUCQL&_ zqVU-CY4^uzQ8guHQOb>cTd~lg1k9j?`8dw=@#MnFtRgYg%+OZhT^JO;cy6l^=B2Or z2Rq*19c|?s@ajML@khUtr2FUs+_&%=L|AId?l&)H=DPpiDdvT37s@7P$z>P<)hd}$ z8985n;p$iAcU4$LsxgJ#$9&0AT{DQh4L^#i*2s$joTw2O&~QLTpe{TanBvZR}@e zjbU!+0^B9Mxl#8Sv*e8VnCCI`2t9*mN+piS84@#UxrCNLmx(zP(AJi&j4~;OIm8V^ z;RZJ}TGrfe5q-m`1O?Da%OJ&6rB;b8kW6>O(uuU*dc{10QX!S%GR(KlZ?}DS{q*cl zyWci*!=^F}kjj)IwJMnnLy-a|NrNV+;MOaGQPm=l%ce1Dz_!H6+M~0aA&*VA;RaUa zqT_XvOIv-RW6Op0`}g}rrvAFM?QYt>?V#V^w!hgTzv-=)Fbp(V#)~3SP%7x)fDV_N z+veB?KHmJp?qkpeZtT6L`=)R=48y10KRx@0O`mrgMt89*{0U7g48{@XJ>rZxb6(Ux zDRhIq#SkaNATYpsVMf0eaS)>`#l(fxuFa=O0Cxj%bPc%L4{7c5XHK{us#muZ&0bF~8j7apafRbzoH;W)N*dMLk#@J!+0iCZ zk&Gh6sVwN5#=nZ06;WM)+uf`KDNrbuoRSw=`aI=0<2+-GV{`QmnUDpI7(nuvc|z{9 zULW)IjAQbg6^W!qR0gs-{}dF6ny4|O+Dr(`-Ic`>l#*uc3Gd>qguI~Ow~MiCSw}9l zr;sp+phV4Vm~8{C<|0|v-M?rPqY4o9fqm1b&9>b(x2NIz=KC;%xOTtZy5?2VM8p(O$Qt1=OAWK6*a@Q=%bE(Rno%?BjEcmp%7BPA6Htkc z3h#0M?UQSM475y8+AeJ^xTY;iO|`Yi&3zm8;c5SH+n#p2d2@+agqXPjQf8P@RH&+& zJn!4{HWZ~ucOMm@V9Q%2SvDWax&2V+WHh>O6~p^7&3EQN@etGS-X?6QI- zcoY&d(hTXDX*9HHG0AOjD-X;$BjSv9`6Zq=GZTm{+@egVLUp5}XeE3iXW((fan>Um z9n*!8i7m4p(p2&|j@Oqs&x$BZ6>&Ad+T-GwnVHN?er-|F>wI0TZux`i`v*IozgMK+ z*U>+^f&b|Ducy}(^A&KJa#_pvo88~0s&cVQOc3%F$bQRzRSLYLwRI`KMO4(GuaCQk zq-5*Mn!pc0n73^!^33VNr>Ff4InUR>{cr#4zxU7uQaaRYGfQUA4lAe^LXUz8844|91+=ZjSCzzV6%2??1SS9 z;keWaW0(s1j4{B~+;y0emCOhT^8vWFPu-$n_BH74?mm-e%t{Sb&6-7!4YtahWLMla`Lx@I+xYHz`*5=# zZvH&5Z@O6x=RTmSdAa(Ss#I=@r_EeyfJC;wu_{@dGtcw9pY!oJ9*^UG95Z>$IM2CU zhItIr$PwWY+jjaK(`|Df&A1m4D7_6r1wL>pWH)W@^@pvVMh!<*nU9(NY_UNf=PWUz zdQC#X+4;XZM3tnN$znqYz!u??E~DEO{A?in!WvY&P8XK4?0xV$}nM!dNnjH`z62>AZmFxW%GNH-B zTzHIhmvB(#84bPmM+D$<2w;eX)cu&pj7mKwkF#b7plq)|MZE=oGPE(00&1y2!J%DK z3lVixrd614#%=R53@oBdYoCehQUWjE1*(c0Ab}LMlA<(0B@?+ecd_C`A@Jd2b5-eq zPhHYP)UotVWM;E0S0u*lCb`?qf(Rn!az}T#(Kl_?xT>hZnp6%!FOLZ^6eFUZygqCq zg}HHPkLH{y1!iRwGAUwEwwdu;vrFm~@ch+_-b|$EEBQ*m6%!GaT;v&aZVw@?PBqs| zQjnJoYDJn0DsCz_<9EA#|KuN^?9-EddiL*bV|Nah&CmjRpb7#NGm1jR!BUj@pwd7} z^{VZRxS!|i<9N*ZI*)stb4K4&ttrS%W~H-)5qUpyUon7l^WCgH;>3pzTG6${|McB3 zl?{5^x(3_Rrha9PWnt*pyzj3%S#!BHw&+kW+}+^r-s%>z z7))uQWLA{dy49(DO^on0FFj;7bz4AgmD7~TqDcXGJTI%m? zX`o_sKDpI!8^#a&aMx}4Fx^ZxUof?{)_}G-W`6Z?>8^R0E?SM0_Vix`Wl^=HC%kbShYP5+~sX$>3G|G~Q(gx`OQ<%fsWZ|j>>V`;Ww&)^- zdlWa&G0a+y`!>gzs1vRnMpJR)=2~2Abuv2x&divT%zWH44%Sq#-+?zFVAbVU1^GRu z^V{J2+w|dY=G6E9hot-`OvV3)J$^M?e;vm!Tx@|xZ{M?|eUQ==O0~gIK_Zi{pMTt3 zhX48Frys_^aXcRP^V9Q(mUT&Lww#Sg5s5OfHXKlCu(B<9Dn&9llTpl!bLMfzne}K% zPt?ph&ODg;tC&NGO1YL5dpN*CpcV9paM6z+ctD;<|~jrW7dqCA!qc~`8>}@ zGXu?rJMAP)TBztNf44-WR2-U6gB2^65WXR9aX{4HO~3`Dh>yV%DalAuvcZ;+0$V1F zCXOZ|q^}zBBH4RGg(udiB{+~ z?B+H$+s816L5k6UTtv(>Gnp+I?XPO5IpJcrDc%MRpj)tSVy6^Bp@I}^WoG;55^YIc zWV@(!3Fu&7cN+s^=rHMsf);(gWe)b(r^4ZjDq(JWt>@ASgQ~hx7qO@&T<)nCQU{30 zCMvr(ES3`O1Q5wKXMo!RXR(aBT5tQ>uvK`T zGc#k>+_IjSqsoUH#G6xt^{Y)(JHC*c>(*TPYEvGgqyZ{4A#xrsznsTQ&cl@FdE$-m zQ1w=O-ca1XSF-r`*T8zsnt%99>VK!g{GQP94{>afZ-kBSOn|={&Hv78Z2{bSQ*~)l zMf1F>3r)+-hxz^GOI4`V?P>E*A6y}Btm>HLDIp@Qj{(I=(UQ&!F{L1j!OAwnnR(8b zS@X=-<2;Xusd3>#)rT>X6?7!{LMS;sk# ziE~y979!5`d>G*FZgej*qox`FY<7UHouvuDQlWxw5K+>|P@-dF3e_5D03=dHRVfNH z(Xfa}>yStYq&j~_OR|cRZPD5voM=N?jOK*5y#Q(RI#m~Cw5tvlr;S)~=}R2Zl6@$u z4JC=z` zJ7$WCwUU-_;SSu)rn_e9rYR$zy{M6VoN+(S*YkWib4sb;B5BfLVv3Su;yC1tirMFe znqeEVx%!)#Z?80#tvrKrW}U&v$VMVdBn8$?ji#s7fIJQR?q=VA7=QY7`^$IRhnqhQ z`*3r&+D(Ru;tIfpP{e$!(#4LflB%@`C38ka)OqIdh~qKOGtM)vo`w-Ee5i<|aHd2| zonjW(%K${0q3Eu+&7Yobx4F5i|LK#f&>)-f=DH8R4VX1;idno3#BDr>KJWVBruT!# zna9i`MC`~qCqpnJB{FgabQEdO;o78t+rDj^Z>DO543d)3%m40jXSTo=N0bP(h&Im> zw%wweifV}}lvUZ@OLY-V8sK7mRb2Nvx_Eh_QMuSw*Kw(Gaibw7D~lA}F*kEso5RqV zE4WgT$t8YLS+OX+4Xm${m}>*QJTX-(TC+${GDT)_o|SrHMa!j1^P15)K=Rcab|rdL zvXlam=zR!IV)C9$9M@!CZAttNjIL<1ns1zinT&mQ(tr=SpArQKjyA97hq*$RX z_Ff%7CAXoBI36#YhpM=1WU6Ub!uO!@KX|lC@Sm%T|GzMw|Kabyp3gsBdcXa__doJ? zp6VYly0423RSHcqn@l7&MVK{z`VsCnAK!1==I-ZlfB&=H&p|lU)=mK^(MncjR7Odp zoRRk&dc8lXs%yF(*URhOj;gti5O*e%T8C>O|$A8<$*1FTL@AZZC*x_(Aoh}jN~n3 zYMscQ(pBP0i42mJoHLKb6{;DWAu}XqrEtlkMJSb2kqH$)Q7KRRATb8bYV}!au+Ec> z#?d$BlM70v2nEbVwPEx=|T(*IIn78Cn zmNcOk`e*T&ai8;X#&JdzqjPR4tmS%Tz;1XR^0eX8%|1Ti!%aVKvW?m-Hn(A-$hO{< z5^9NpS)%Azua$07)zRaPC!aIVGmn|w)Mj!fv!qIzc1A8XR0*p!>ZHhQKcHnJs^YH4 z^dsXrZ(|JqI8q@FX$|r|baQosvWXj2L{e_1Po|%4Pxrgrk2q#TvJ#KThckz-&`nG{P*Tb)}`X^NROT%yGDjW(;bKztI+m^5`)QBf1a((|yBHQ9i3OTO0V zlV8&(wK-k`Y37UFmH+mf@JOd0Kgx+0$)o+ijT6$Nh_N-=D@9SMIZlwSk(U z{h`sqKY@^4cOzz2WSt?$S+9@dappXGRiw3)_}Vt;-FaRbkj^D*-dQOGQWX=R(q(z9 zUEY)^g?I7JV4@f`tB&O3l>5p1gRhT_>a1&bl{3|XiWE-a= z1~fhFwx|%x+kCmXt(8-As^qOLXrXu|yR%Y#3x(@cMVOWdP@*BQiwCg`6CIi=kvNkU z*+a*o)KR-bDuxJ$ONf-vEL|tlcveQamr9y-{~g^lMAY$^XVyF!!5KP3&sj+-;6nmU zc>oD!CImLS&_~oTuR+-;PF5QUM9z{bV-A#f4b!!p2a*+uY4}j~ocsMeBf?ePhsbgV z7SWivyBuEUlm?+yW#9C+`P06QVQ%JFD&d$F#Uprz-B15=9ItoYk9n2^6(XS&W;^UZ zIi81p-1NgH&jU}Mn{#sx)uEk8NXbk|T=~b4c1#Be6sw};y+Tb&OaPuhVZWZ)glATw zN@ZoqETV&|rU?omm)`)Z$H$CWogXiv0@w0q=l}qK07*naR5NYkmrQQk^d}b+dQ;xr zT`?dgOV6B5{!o_S$%nvS2hX`ZmhEcn!96Zwy48!y8H@^wD$`PoFw#VgV#49rR87BE#1DO7JOvy_Sylxm1p z%8XK^N})ofUR5^7)6F;cG2o*uqE>$5YMz@Dvlh6rB7EOE_vHuD`Jr^v%_Y;OayOl( z>7Mg!Qiinh-h}xT!tH0=-h|2(mYSfIMP-&G`>5UaV6(tT$wE>~+EDVXJ7H3+nR>le zZ@`{qLO0n4p3{Je!Vx)3LJFNFMUgz_MPH4`x>VqmSu#3+I2* zZ2I>LMA}}*m8xEAHy^+X>HVmz10y+^(t@_N?mDYXa;SVBQUm60%~Rhcr7(=dj* zNC*eeZ9=<^HB+RSY`vKq!~8NwX(7>Q8A&bi{TaGqJ(b8TrB|g{%Y@o7zPIv=EL~L) zOujQ+`MMWWRW2LW6}M6-0}5h-Tv>dJ5hxIN3%`O!V~ooS~JYd zeTZqdR#h@X&l8VR&-08Zp{mK#)3|MR+xKlH;q(SXB5EdQ@F=^V^?b;e!N*~*lTlKw z6C>Kp@n*QWJ`cOO?#?TOgJzBDN;Nr=1!bdvg5XMEY!y`_I@09k$bQYzk#C|DOY@CV zl=4y{9aYj4a1mzf7OOhBwz7HV3)d{3lZwgmy+s9PuI7YMI2lq+^KmsaF}&wF-CUWJ z^RWAQJ|>?6N6O4Pf=}DHJ>>p~8Pe8tkldh7TB><&wr!?+vz`GHal_jpy%D)t$O2QU zsf#OL52ie4R5GO6X)1{lvLlQk&9|y0gA{44`ZfMHnp%|w$&_@Rl@?tRWF}n&ECCmK zn>kE|@r=4{vF{vdZY_f@O4_oZi$=iL9ygcjL6^VPLPfMuBoQ~b$}qU;P&mYG#oBmx z%FS?-UQjgx(aw0yCuGNhBGQa=#^bcdt@d+1?Ze$V-KBZZBH}PJX{(Tqc`8&2bs5>J zkf50AK44-HF;9`f0yH0qU~1B&2B?+0n+zj$CRIJxx&h5t_oBCslTm48ih#_NGwNmLmq)$6=6&WdJM93QHlZ0Zy8{IWetG zmi0g2fDs)=}IntHQ<_Sx>`wQ&n}}8ikJP ze0ZCuo?&x(WCErt+pha&``CuTg{`?J86_E*!6WOj^M2EhyFDV0Y}ZUV&WI>xG3P$y zdFXDkn>hMl?<0B{u4OitZTW`uyVN<5?a;ut7g+1rw$MCTDMGPE7#&5Us9Wc9nrbpB z$=VGV(3XS~NpTlZfp^#|x}PG7DRhGlQ!`aw{HL-_DY_fo&8N-4Q}GO( z#ToWA^mW)dD@v-gDmE9>bcE52;WVvcO@sKrrf&&GRD~*vDDjFUoow*6g49Z;9?P*D zRgz>hw%hVbDJqx2v)YOp?D?^0cu5E=D@7xqC@3Q2F;6oaEv9PRTZ$|GgduwTrO9*R*~4ovxQgVT;@iZrBtL6&F5jqt9J8tXuYLJhNuSvhHNl zDy}_)RP$DJ##wdbm?2}UeYl!PmWY_Cn0JJVk3M>^JSLkYSEWd@!(vBa zq^x)7^b&M$I$kHr@T=9Z+~pZ5JC{A@~9!8#xB@_a2s@Cd#f z`T6y{Kk^L8_PD7^R28~=Z4Lt~At@pUp_-n$u|~lY=1@sljAdmfhl`9(5sna%f^1Z3 zudCaXQIpbKt~70yxmxa~cnj;Bk5xd3cE)gX61$6NP;Esj zc7YEDQBgnv2Gq4zZp$HvIt5bIWbxGFc%_m|M53|WswS;A9tbHqAtugF&z1J&JqyehA%|6oP<{2> zjM=rS*W6V>L+^PBH0zC-1Khj`sc?sN?Wq#cOgV?oi5XgD+IbT?x7}`wQz+Wb-n3&f zDQCzwbcx=58QA6bAa zqcc;oW)+2tjeqR~XG&JPf(g`|R4`c@#%WF@CE|?AD$Pu3ktneWu<8;7!652Nk*q9I zwQu8IdbdN6dv4np!_3T^bEs8JwcK{7*$m9&zA=)=W0#VT1c zcezNVssOxKW}Q%rGU#Shr^7!(ZUw>1YmFA@_uG60e*LL`SWSPWV*1^0d;dLO zq5gMME>~^`e)p%YXWk^Bu7^tm%;h)q4X67353WUpTy#H?%ASv}3NB(kw(a)a4`YlW zORB^BdE9Qdzy9^lug9a5wxF~uVXTFdNVkA!e54}EY}{SW*YgoIxyZgH1Z0?+%H}?FFe@Uf zC{<@frP=TS#Dr$atR7M&rwZEnzTM`B)wa19DJ7aDUCT>-tgNB7#n6ivsVrAS6xjJi z?e{LOs&1Jjl~Gbl5-EAfp2%f|3t8p->amutVVR|4VQo#^EbX~-u|RrfTwJ2ntfYvk zGSy+|(riUotxWIMej(S^O52D{SEQG=<$tZV-h`605b2X)xK7dYz~&giBOCJonJ9{& z(;cdGb!H_c%Q*xqNf-^MBy?038}%ZTj73GXCFR1{k#A0@BZz7{a*#^{)pq8>RSn-v_tPp+KRVC zG~0Lzrk6>Gi1Z|v7fWv~s4}nqyfahfEj+9JoQaH93}$AszViGD6BAom1<8oK&v=|M zqcQaZMr=pb* zO`tVd+-FhL6+p-$xq|GQDT9S)UYujqIIDEp=ks^|`6H(`9d($#j}XG%NgSaKxmi5mWKDs$;iDW&LfMs%k0O zDQs1aGRS7wRfc*DsZtdg)=#6NRBBo1&*X8|<78A*9SUuJ+E>W(a$sA2mUP@twZ!DQ zZMCZAb*TU-)%GS;mEQQMx_h7D-GFG9K^9u=4Tw2Z#UoB~1*G(0(VgJ^II7B3Zu9n` zo}Owi;eab8nB5NO%DYxo8KP9EdQl=IN>FlcHUn#KAk`LB2DV2km<;Kz5|pfj)Dl04 zNG|aM$RLMdD$KBA5PLWJO*Gt_+fm0il?nU0YU=gVux%Ti!U#aJBF_xYqNGGJ+cuf- z4*#N_MIk3^WE~N1D~;6^x6MrHMz*Uu^deV?h-9z!N+b$u3s<^KH>wusr`F}Oee1qf z?x;Mo+Tb=Q4d=Afw#aHt!dhOUC?yQ$nH-au8b*~WVhnq_jjrv~6*O|Sa@vPTA4#h1 zWUE@pJa_dPg^!y{=I)O=US2-WIoTh#AXm)SI+gyo{QS1Ey?Ix)r@=q?ssH4S?>Zj; zz6$vt6x82kV-XG9>YF*&<&X8vjQgv%Vogt1krk1io|RXA-PgPq74qjVFRd?M%Yd;# zR5<^~|M`FV?z@j4zx(v*hwryd?~mhrJZ8v|B-G%%%wbeLSYugbEYT|2Og>3=t*nlQ z$ZD?5;%0NX>8ikz(%wTSD?-j>CfRl?!oCwt`zy@MJoAigio=FzJ?(O)t z5dtd$!H6nBq|CF;f2DE|HOh6G@tI zcB(XqN^P?)X`diz{Gl2M6)dQE37NH|Y#AN(8F7(@RwXxp*%pCGBc^Z~yu?->*5V>u zxBNm}7O@-x70?t)N|uDcMGRFCH+M*pneES|ZlaN$(x|3a_`0i@wxqVeU{4DdKn+zj zqk$@IIn{l;NKvfO#E!0QDR!E|QMxQ9>w=BgIUq{7CWVI8bgIylMdKJZ#~fBwtN`E* zjud7hT7Q*1ChrH2nP;&G!1|V6G(EnZ5D>wvDM~3`H-E=Pc>n%ZVUl89yWxsXM3Pk1 z9_>n!FzZ0b-5v|O?(MC#&lFOgD}MBBy9YLsxMR7q3+R}b4*p|Gw9 zpDI*}87h;N3;C;r*c?1(xS3!6^^^JLJ=8MH!Xl3>d4_fnF++kvL3Cs_M3O3XluWL{ra;5XqFTIKBN>h*GpVIdB1sYu@O3nj%ao zfeB5}Y?ZFKm!CN|$dm%G2~ zk|fEo1hIPoQS*qbtg5c=>6zV~B{^sL!2kb?c=nL9Gt<*wRh1dxZYsd#10bqu<{pt* z-939qTGsLMFgMc=Q4s-fadCl4s%wB7kqPS7wzT}IW-%aS_sF-%uY2C7W?CYW(Umni zmptiW8FBz9p%^oj3{0~EY+G$Bnul9SsGw3FowMf@jH5Slu&$L!Fh>Q{F?EkUQhREK z+H;KDfnC_+b)R|P^V6r>*qm%7Rj1tjHq1x+iNmR4D5a1h4LO_F&nm6UW6!CGp`KH{ z2+TQ^?2M<|%S)>+7Fsx*pSIh!<(PV#A%R?729U;T^o3|WDH=H(n{#u&-NvUE9~;N8 zQb^y1@B4lye8(UH9!i-u(>CyOvzIYm=upf#_kEAheMX3unTc&6w{FZJ!$umbgKj7e zdTW+Gbn#*%V@B**^P%c>ZB+HwF>ssOM@4xb|d|eOqi}sY{qrUWcsjVh_x$%Scyhfl&O4r-7KIfS& zE+MnJu=}drOg0)sBVjKupZ&J|`JexIzt0~&|2AR!t{wK4o)uxZmm+sbti(N!l#>=@ zRphUksc6-W%--F%&7+cnpi)s&LY&}U8bEust5BtkO|sxDl?pT=3C@u@=w?2K4a>@^rt$M98gjLv^RX)d>gh6+gwgF%8J`sBbOi$R3&rwh}VdS z+#{=|vIe5NkQ?ta_c`zP{JQV^9y21U1fgw7Hwuts*8N(_T~>Lw!Ahu=7RvB6Llh9< zq;*IHRuiIWUGv9o4S}@PW1wtYKdI`XmyB**MS;~KN}|bN=4nY|R<7Gx-n|-kn?+Pr zICC!1pq`L^a9WFPx-bFJ=%Fob(%cY(mlYOjAqC_*FLaO^Qmzad0LAsC;bDvSxw+t}AJ;Bthd!G5W>+{<_hPkr}avU6+ z>4q)+HcXyb&4oO-QgNQh@HP@%$$+*&dv9^0&bwvsq*!?w-Gu-mZBWd?||f_8z#7$cODC3BG5 zjW1<`%_+M(i!4_?)R@f7mmFl6nN?cCtI>673mzMT!AR3)o;*`%$%-V;ojDbA#+>sW znlnqMJX0yFR$>5G=eZPG9%xAekSU4*-J_Fm!JNa+QrN+aI@+Va$>8?2;m{5`=$;4j&1&qA^bllVSM!=4pq^= z^whujd0v`8Ku3g%CRm9S0~ry6;lxj0e#YPDAAbMax3~TE^%WY>wnv1sV<8cyBoeVI zg^p_3Ll{JJMiY2To?6``VP^HxHi}HF=FRyQao^+ZE%tjxNM)Ri1K#0}gD8@}F>{PT z(#I!q?T1g}huc;S zR+(Xi=@y#|7KvbnxJOo$GiO9Dz_v+dCG^ioyxsHb{eItL&&-m!I0)j4l3Xd;s^j&p z2eHh^48t_&Hnz<*obGm$B~3^dc4Xt9(S4vR!{PK^Rii<2wMs#y>;smy#bt_42xd9^24~V44j%MlHw>B^ zhFj}*L6){LZ#2l5va}5rv=r0O8qRk5eg*p%VjCM*z~2P;!sh zTQd<6QOzW@ByTfSqGkZfFjwp9QuwM)M;SGxNwbiA9GW&HY)0N=mZw6sbfQpR2b}4I zmm0ZQB!+VX#o=k@mS9UDiF$e%q$pY8^1RUbfW`!t+OskwMdrTmbI-TC zUhkzRm)p$+{}H~KyL*W4+%{}C-QKos-Ydu7#e9`%F4%kV3hRvK^dfS*Z=S;|2P`@b zu#HBGv}kIphQXcNuwglv=4Lk3e8bqo5K}TTydbrjRomEHn-%zi+FhMM%F0X{NE?G2 z?S-Jl9%&O1s?v_5vTm=I6zf$`O{r!)WE`vf8P>Whl>nOxYM5o>ZBM*Tk`A9YyLsL= zB78WVWNOwGb`%}!v5A(%9L#O-@BiT+zkK;AVh5PaY(0svaxdPoik>Xi$JVRz6MC@L z0RBQXs(+z<{g#2eQl*-$-J9{_ho4KCoKkz#DJvDd5tgbQaZa>~usuF>@T(=TWcEdLO}uq|+N zHwTs5;+hm9o2iuc47#x>$R;z}GTm7{j6srawkbRG8H?;3lGYYVPY$i#sV83NG zovn9?By6LnV+9$xIbVi({sY>nrw1DaP;bRTrU43?4w zVD2`C-!_*tb&s?;E70^JpfvI@Bo|UMS8YiNg{u`0ysEGraHGu;icR->?)x4|7!y|C zF1GU{c$oklgjpr3y64m>V`59h6cxrG^!B)#;kPJOeX@w&V3 z9E#U6VqM;+i9pG#pLwg2^qW}#7BS5K_{Tr~?ceRDq~VtSbbjim~VUWqed5h0K0%-GASiYZkvu|q)NeokQ3X$ zr`s?xv&=Iy^F9mBwpvzZS+ZND#?ERhBANN8&0dCm{xm+_wokWl+x#|s8!(sx$%GiG z8QMel#Gcw^Q#pnE)P0YA3K)B2?(@Pzs*Eh>Y~q!Q2x`{A04f>C5}R+`SAmHc73>qN zZ85*x@0;g6ILya}ZSJ=rvmEY`a4TML2_jL5DKLX<+}SA&ZlYN($&Uqi0)S`rUPS2_ zOl4K&Qt{ff?keick~Vf?bdEF+)-Fo35{7Cpms*WBB^#QWOv0*<61&Y-MmZY>nwOF@ zhYd@Gl@>n}DO9_po`Snk31TFtDwVJRd3p)CSd##1M=WF@FbxGB;@&J&iJ~VoL)BF? z*H*iC4}?e}X5~W)J>uz_=@;)SDyc%su$BF_bU2jgFYT!_GNN{A|yhZ}-d`W0)CPB&NcA zltd)%_xa^@zrV%nU2peE(-!kb`<$6^-#Io4n|W^9BR_Bch96^+m-%czSd7f-2)=)#~Di(ylh_7wzQ| zKlwP!{g&--tAmpl#+Ii704u$Bsgi9~ocr|MYn9RUopM$VShI{k$$_HFOhrazDgZ># zfyfjg7`GcRUsIO3?|bI$r=NcM-4DN=_n7eP(u)Mc(*cFNvWYJ@#>=IT&_J0HX=8(k%+FOtPCg= z$`_xGTVQwr1_b5wn`ot7VqP@pD&xvV5nM18Ge}}`Mv0>=DrJ?b1-j?7mF7rN(UE7c`p5QNnZLc5>di5fFc546{F~THEPrm zWs(@BFWY7NW^liidzF-zomkXmODNLzgaumBQP3_b0P{pRBSGc>U$$*nDG4%L$y=G2 zdp9kQ>KfX02%WfNH$J?!%)8LMRmCga9I02yMfL52t;d_c`bGa(gRyBw2*>((!j@tcVT&Ca*^8k7}Y{)jH{4d(OjN z{<@oZvg^M-u)Z4R>sJEeqURV{@>OefAZ3P3*dFQk{r)T!$NqcCYd7p8g8Cfs@A}g~ZCIh9p41-5$tF!HC@m*OW7wrC~)n5mYjH`tI zB(tk)5c<)Nw4^LaQ)KQ=!<}4$9=)2&rj#R>P6E4E!G+ltNoqJZSJjCYuPLfw;sdol zE8{?TD$zEWy-W8d;LU)yJZ!Km>aYjXEwC7l0F21uv?&R&m_()XOOl=pBE?dVX^DcN zqVWp4J8r?-SQW}<8$tRe1dHqptmYGms)(zTwUc91sg_oWoTMr3`@YYNh?az`xH*ur ztgax+Eb-jMif(gEL7?r5%c;1=1@I z=RZ?Wbt=}r@ArL-yWO|B-Fyr;vwfd$_gVd$zI=VV-|vp9CGgwrwryMK@(7w4`#$%5 zM#S7TXVMG8J$lcVL~Rb5dE5qX123DsL^Yo-Jq;PRgW<(d!j6^qHUJUY6=LjWRd1*A z$7}#{-zq&_^lw$sz1xdL;4^~$vfdL>9Cd+F3Z8ejTnOQRbJI#Sl zLy-m{ayZR6sA}4pG0jY7Dg5;1^&kHJpWfcyZnxju-(uEw+YA!@n_$HM=TNJD<=Kya z{zdi2{~Cf=?Z-NU5AgzW*Ip>lZQO>xm}TP2m)B395Rq?hZ@j;4zxjOMqj(>%tujvC zN(e|q$ut60Bmy-5immyjYV+P5L8_21#Re-@$pY5gQ!7?>Rz(VHp$k^eU^500iI}-p zuTzM$>O5V21)j$3h)SyseQ{vfa_bg}J!CU7xug1@&wJ#4kGE>H7mCC^;=ac{X7;U> zg8EE}g)pcbnxY9;Bf}D4c2r~0mS(o)@rz$sB8LLNS#lGSGA88#Yu2)C zwG>|WTctJChgk+W<%45~m&U*_udxywjAeaS*N3$!6w$PRZ4oSistgz`2rsM`(WJ9h zOb4pUDxT4`6ar_jku?qp}FY?#tCfl16ngkGoKCbof>&2C%iSHlN4^c_kH{9Y7|LDzX0E;gLS^dLOraY};mL z5%IRqNZl*6-NQgnY)LVL>7tp$xX)Z}j^->K<1xlo{%=LhGz|!*8*FC&kbVya#um5- zrf^p#W|2e8idkZn0I1nDyG)BF1xs{0i$iW^H!Czhl{2FDlm?rYa1{(JVrQD}3;@-! z%9B+ulsR)?FbC{~+>NFpP*m>&)rHO8{|-S1#y#HN-rnBk+?7)yF9EDeYx-|&-xnKj zZrUJKU930-@4s2}{I7Vuk4nFP!QV35f6-lk>svwqqY-bQKx<|9G{4XNpa1-) z-$vZVi@X2RKmX%j`FOc~zW;QWQGtC=Zntds2!LhnG_tJDN6iaVt0YxTeKJtlE-UpV z>qb2vT>16JCCsdfb|(@>WE$MvvRbaNtLxo;42&)Po|#m49O7YCP|0OlKm$Z<$h<$SBe?N7|E(^88gSQ&D@8X$zAT%d8xT$ zhXwA&!zH2x3rxr=E1A{pwJ>LE-mAnEjRT9>Urfug#pF^Bt!L|K8R^GVOVgADRX=H} zik@!bJ?A#@lH)ebEom6LZ;l)DMr}82Gq>AtMrA895K*EC2~=R5Ea{BO7^e2jh?s#H zxrd~q0Le+x2I<+Q*&eaaoY59f+YH$sPvlw%~-NHDE(Yr^^J>Tv*Ck837U57m^WM+Zb_judy z`(C7J0_L`r0(Enkz2vJfWMq&IPx!WN{`EEPldmSb>#cJ2=3cTiu+G1hJqC%@c3~+0_gEx6v=vigl2#B4Eu~0ePYrI+ z+v`55yU%Ule%oGNwyLPELKCIQjDur)*>0a+UhXkhdhIrN>?JGd`~SPI71iPLe}CZ- zzH5CCaseI-oYo@zAeY>ol(>?00A!->doneM&zt*g`~3OSNd57@{oVcT>)-zVZ{|!J zKYV@5`@B~jUcrqN$m-mz%CsfTV2RAoGP>w?F@>36?e~{nld3T2ykI*9ESga(!;$t5 zA1lL3Nidd56o$EtJsYkl$tzC4QX}z}xeb&Y_h8)vsh)q|eZvm}xU0Y0nz$RzV>w;Yp=g8XNM>$jptRa>^Mh>QT*1 z<($HO&$oz3+r@iek9y+j=Ti}97Xp_s(I|dmDJVJRG*iyZBCwaJLe_Wy8Q2ri$?{Ha ziOv>N^O98nIF|NP_0}W>A0rsSQ6OzK#iSR$;!{OD%TOdZh0LU6$w1JiO&fQRd(mQ^02o|H%WulW*ql9@AvrnwtxNl_Vw%Q+uMHcHjWOBg++g_Yz7A~ z{rqmqDur|@HU)$krjZtobP(b0)hR_FIg2K6+w8u}IKw?cwrykF=F0W1z`$0Y=zo>{ z`~QR2_wi?4ggB0mJw;d7_gAHOmdZi4(vbt%>6GELA!#bz?XUmvdzqB?&8QMyEenBR zwc}W^TaLODYpqsUw=)DF(5;2w3k^H7VDDwlPFvFNrX-UXAk$KbOds(Qxn%%GWoGNq z*LEel@Y>dq%TgIj@ySIib`@usN;ot3;LMn_DpeqH$_2r_(AWymNRR_fmy?=pwxV%h zaj+Oe#AaVJ(P2+hP0o2x}G^*3{=C3adYD3uk6!aLP;4%AW8R-JPz7iFbb=0d=k zIi+17HD;Q@c8waa8g^!PD_WO*@!1s33g+>ER#_8ED=k?qd%GQo#Nb_YCq)j9qGGp- zc=ND$bsTNkPrzqQuGB6Sy7`tEAwwGIOgH^F=$2dZ7EyW(rE1djslc9-sX$g&n=wmt z+7isknYQmaCo(ORF(JXslb&?Al>$rv6B!&kG?P=gPn!6a=}w2xpo;KdO}qCp zl614p{nO1}K8?>Wrgvv9V9R+;H36egFA2?}=n$3DI{Vr`nPT znJtJ~Xa+jbUJFXMqnt_Iqa>QKWm!ITqPCKnkQJh%z2TTDY5``%nDtPr5<$agNZYjo zxo2j+?eY3H|Mc_MKmGa3&p&^C-Di}3TzSrGS*?Y8P{kT8Basn3BC2qw^m$A%8msFbeXP}A zgUUXEncuKr|Hj2gzxeuo_E(QuSJ%7#{$Vcx?()Sv4-G94%`tj@Q+uKgJ&-WP|1318%71ELDPIzUbaH)*4CiNXr_u~5% z`i15#YUypYX{nF3p#c*lv;)5D>%RNYr{RP$D&@x`-YTZ+<6t-b>{97g&rII?1{7IR zt1}L0prZCF3^J5jWDyui&{;7eY+=kN1-}ZtW8LXd(N{N|*-J0h-=QL7_V%zWTmhA} zpAyykz~mI@XEcAv856Y<)xua-++RlrPfbCrYa=;xRDlKQYi3j*rfyxcCX|$gWX!X@ zPw$vzGRKI+^*P+26ecL{^<2ck7FzVdRWWR5ouSap298M@LZAwb8hsrmE9eCph#0mp zeb?q1TW-c`*VY8)$XS9})G)g9Hed!r6i`2db6SK~MQvt_TDUN}R-}v%Cb)w;8D?|Q z7fUVLyY+F;-V`D*gEKX&;B#sH*4(jX?}Bg%l|-qG#<6&dOIRt)xKJ66Vvcs~R^^+u zpk9-Hxpd>lRFd4xhr4q)YIdj$=S+lV3FAc)WWXl^kuVSIbybXvButzFl_4^xtb`jN zVN~-0LNvg#RfNkfY#6P6kO?Pl1GnLyUbdH)ZQE=c=GEd8+G--2I0)IzZ4PcDy?Pqp zt~c#%Z`6c3V^q<&$Sj?mBEj3*YpRQB5b_xYh5o9#6WDz4)B z-R^k_71GDmND8YoYEw+}DtEL3nR9ECRMZVd{ zb*O@0Pn%KGblsy}Z}uP=RiL^Yk=57qlJwPzV6VfI2TpJWGgy#?RTG4|&DQskl=&AnyJ(PudmIaZ$!bWO95o`lE5vvyL9tZ-3~kt-OEz) zp%)8_q%0XU8?e~ntjutM)u-E3@Vj-GSm8;6&P*#?Wgs)EhAG~5XO7){kvd%7t zw-6$7X4z=WYLmdjG?u{AvwPUd33gJm=MpKn7)TbV)GgBqqDtCYr|!cH*GR!i<2RF> zR$K{siEM;8bKm#aa~I_Bnk;l76HOpQB3fXykfBtGgDEs;kaTzWfR8bJj8T*XA5~(I zS&b8IrYC?;xAE!o*ly;KQQPQ^-jD*jk22|IH!rPn*x1Y~#vZ=KPp@xLB`mBu<6I+{ z1}g;k+TyW#R5&q)DP>*G#696M$R#M1ducUm7Fc0MFGz<{f+b37*~v9o>OS@2_69i_ zG4Jg5 zY&P6CH?vyjg*YjzgaM!x)zcD;-fu6=lPuAOLFMBJohiP)4$q+KKwIR75FbA>cv_Y&KAB(T=(=}Jn6~` zKmYaI6W52EJ-?oKRA*co&{BH$`@NRkHpcIN{LSZ2zxm()kH6boKfg_6Q3Py^k>DOu zHE4-AtU6Z0l3iAgqZ)oa!i5Jl<>3^vF!N>1NG}hpO)o*wXT+DcFuMa|GrBosIdjhr zQcI=D;B9Ij9<-eRRTb6=fYUHDL0=$Y=l1IC$Jp9A&R)c{*T^#fh8)JLq}m$Emwlv)nlirIrEYjR{2U(-r7my00)HzSa7V4*QgfLQ^d80C1#8d7XOIFxMC0Gd6}Pc|imIaW)E(wk5pXfm$u>=CM_6gR`^pQ zMB{3Km}{Yuuo5LRD>Ga^gc;3AXj3(H8UPG=yN%DEUOv5y?KY0q%wzeIS#**rFPB<>dC%z_<&gzqv8e@=@Ltgz zB(Gq;Gi#|RQe4{GR4G`wEKqsze7!67_`1hiV1nj@!$eoN7O768MV`;g?vzbShe|va z%q-%cqiTywG<@5}%Ql9YkKQmvD7iXcz|68(b`Z>AuH+ucyP$o{x$is4``qEKl{7lK z)f|@N-z1RzH4*c_^2qN~>A(J@&tcOeW%^PZ`ptvCkF5`*`}EG`V^wg`sUwx5e8?~j zL2mZ4ZQIM&uRs6(_rJft<)8le&q2R!{^vjc$;T%d4(LLUS91N=hl6k(E1p$I3w(JB znjgPa^{c`xA;Ei+Gt+ETlkb@&yGxRCYm}!*V@pc5?)?Z@SF>!ZNW1EaD;JFiNan+5 z*A7#U?ODdNhV;BsHP4#KlWxYNJC>cm>r?gt#{hjqr(eIX&YR2OXGhdliRu&2U$93K z*1$zJz9p8VFRH~{qYkx(Jz2%$#U^WzU8TH%Y9Cipd*#*~8_Ee;uTIb^q}rBya|L_6 zhoK~-&&b%_5rsZiOTTJcl`|(GFsy}3`wL!t?8DbIcQFi+RjYP9BhEksBdc6<`F}+x z3yrO(OeAJ7!lM!m*6nx$?0!zVK76hj(V2)f&yPasgOG9IDAW(xMUkdlBB&rsS$1>f zwkdi{Rz1#90vNA5%n(F1GO7$Y$jw|pCW2*XZ2}VrSP&BoT2@~!5=_lm9e%YMDk>n! z-Ob^Cvq6qQbDGOo<;Ue`c$;GZFyzb4UtYG`tzzX;ePVVkts*g_up7WlRN&}1rdE%! zqJnhYa#l`Z6*ktuM^}Me)9$7~5vUxZPZ(@qW^-YhN-|`6S>p4r29%1eYeYG-qtLo4aRr0fm>o2mi+lWc-U> zS5x;bi}++b&hYnQbw0FA*CU@+iulMLee;XQHh!M;dP!z$Izr6u(Sr7jOYA6DL^8(s z{PO9`Pd`W6+~2;w&A<7ZfB!c9b>ipO0{70ORqd!1`K_+ZNy3io=F`Yj|E)raD~oYz zaV&+HUO)Ei--v?kO3X;vWV#szC1(~SzR=k=YrdM$bRA5qDM1Bm;|x{vsD!MO=7r(Z z_{uu^G0w}6xjbBza&8_7bJ2;DD`i8p2txZE=d5rzy63n2VwR(1q1MjJVxL!Lye=bS zNj5j{u`a5NaUJAwW*+^@P=!ai+6c)Kg}_oAE^ppB(XV9~9Mpem(RAAW|NuU zyI)uC%ZdFJuYkQ>JZ}lh08g4Rs;4hWIpmoLsydC#nKO6~&S3QzxlimBL7G>06EaCt zrkhY5H&fNpWQ<{>^*3mi=1~QJR@W8%$689|bhtmje7117I`qt$=D?MbynQls5 zR(q8XTY`d3h=GAla=)g(W$y5u2=8_@HR-i9PbfIW%3cTneb_J`!>j;hIHmivIcLeG ziXi2tZD1R@xsT1Z%~_BR5utqsJLafnE0rQv>)b(bI6X5RKIbI)^73-K-M)T(D|oR4 zT|1>__ASfvYa-)gtNO)H{zb3vAM?Q$@*zOH#zr4r|I?9w4dA?x$!8K4uAlkd#V1H5 zSEpx)2<6)z)Lk=v|GOXm?!Ww3nUhq88$P}GPp_|L?t*vAEe%$`gfn8h4*vC*r$^ZC z{4&oUj_vU+TRU0dDiht8Cjh4gs8lu~o1`ypa(|mkNpziS5l8F5-Sla-J;T-dE;2_~ zG`W=RS4H81y5691q*g;(_SZ>d!-?nJU-ISA+dP*t<%npCc z0HHu$zj~Gi5~{ukDjR#L5x0U>MN}2H)}zDXj7Xxl9mopn6S5+2*PbTT&(7DGJy0CZ zp~Kp0Nm!a0-80jQr;xS#H(|T>-YC%_=IUXbq~9~D=yh#<#krAPUbP?AV=ayps%8ZM zu&1a4GpJlX4_|PJVARF>x)BFTA#p7O9(f2X%3~hvS6r9v`z+Gsm!};=&FXvjz=uzK ze4Xat-Es@tH@=9I+&~LSD!r1D$k_L|r``hhKm<}2fVuB=!#5DHl|zED0+e^OL=lkP{}C`C;}O{hwk@yjcJ6ZW@9>NRw0V_ea7K6yh5ie zv`F-9YIrU2gYZ!`=r#439p83yRIOY$BZ&!MC)# zMv!~uZ7QLlatl!9l9*{oW0w6KHf}HDcDucpRcmO#C`70X@RzsOk^|%LG3;ftf)Iep z4p|qPfKaJs(cP`~g>mgk3atS^Ups^vR>4uA$h`h|HZGiE~$V0 zp+1BGpF*_nTmAPJaM@LJIl=m{UBtI6^m)vSC3t@sos&g3N9$5=gTz2}UN;C4anFbe z7e0OZ;dQ@j?*HN6|GUU|yMJ+N&q@n+uQt_IoT6Q`p(Iy7=fZd%B49S5=@R%pneBB; zx$x&THM*m^M@s*t{~c3CUD7yLM?Q#QdQ^u z)Xx^DF?Pc;Ex7hLaT%IU$)mAxorf!GMjLIM=6}gi>FRL-MV5tuur6Y}8tLQI2bf*E zR~P$RnAFbxF>U%mwTOlqsV?o_%1m{QQ~eYo7iDcNv>tBnB)5Tttmx+eGVK01$Rr@DjyDE+P4ms|I-KfEmQLc-k-!Fe|3 zZF-5x(e9t_+x^Av$!%0q#g?X;bH>!3nvpwMrAOe9p_w?X2o{n|p-6^HY7I6wxNA6Q zDrFdycwGgU7V4N!pwR`)G){3((gO*_u4>q)Ipb}{ObTJCnIdV!1&h$$uX`;x3TCFX z5<@R#@xwM>_Cz}}=!trCk}6evdO(eDb%z8ds>>6BK$43Me%)U8OiW9|FwInD$nWwr ziW@OurI+K20}mh#@|R&bjoO%Q8k@bmY@cu2=Ub_qS~(NtB+ZD=Z`<3xM+A(+ImXzw zF~+D$ZqgG*1~4o#yfwK7Hx_6iF#~WYieDBH8{qCp{oxOP`1`;Ad-4t>;D*fAi14F) z*kAB^Z!E8m=3jikr`OYQo{(g-zbp#>w(b1D^d6S!cv%~g>xG?BU`BtYpyy^~5#HLs z3l3e3+%G@B{{DAAzP`S`zP|p?KmPdT?LKnfgttA7?$&baRg4txZsZq1i1*xSTutx$ zxcRsfb5Yf#E@|1S!u^Bn=D+XHw@&n&IxDk!5L50U)QAfwUDv*nlsL-A zDr3bngQ=CG?L!kN3tL>O?wfu>;$Y^w*-K>?-ubMD0nVO8Wd)O@(P>a-!Wlj>`9>SGv83tTl>NW_dLh3yME~*GH>B3fl4oKiY!oov}xi7$+h#v}@j{HfJ^4 zDk;vHC6R$Clbf)hdwNBhMXiCN#7ylw z-OUS{R>ahO#*CO!WJ0hl{wRI?V#Ri!N@yv!Y_a?DzQLIw@qGTV^cjIHwlAf2M}Wo)joSq_I= z4&rtjFE`%?Hs=__5B1r^9`W+&_IAJT`z~XZw7WZfGj1iDK9vTUrI#?;@alYQC48W2 z+N{`FdaEgcPInvg_kZ}S+wFG0-xmp@*O^ZA=6_UK(Z39!{thtyFT=fm@$=0>*Dnl0 zB?*tj;&)EBxY8xw+#rfXtDYT&w-~o=n=>WFoL_(X^V>Hi3e1=U(>&(+`n~vKEn)INfv!!1 zt&~yq3)cI5l9fzn=29Lw$FC|tAIs1Q7Y@VB=4KWYORXkp?1WnNIOwL9Py7C(k?)3RweSYa|98Pz&eqM?q|%rLJ%CanBg0G6@XPsM*-^rr%!mn_QB+>cXR zrM6t_18}X9CzeS0dZ{QtXwG&idDZ3FYOB*Bv{u89(o1Q>WXH^irE{ik1M6$JbjNiQKP;akvxAYHngn1$YGRK`a#)f?Dk3A#iO!a+qgDINwOLTb z;i4*$Y8Z4go7Gl{MyEtpJCMZE2aqSLcjZNI@&+eh zj%-7Q%j9T|r32knG<)Z$TXB$S-Xe47y!2sk&27+y+ZdlV-&|%Gn}6Qy=6u=wHa4?D zDX?c`>g|3XzTHR7D=Q6HGk3e~p^4Niw8A@Kzji$dW?nAcR7#woLF{`NILst|y1m?P zw=u^3KCg!40HQxmB7XPvtvu_${`D_2u3E3Z=(0b&i|avZ0zKHVHD(_jKFQHwOL=$5 zGQy=-*!CqA(IPhYm}X|%xZQ4VbANrEyXf?ZW;)>v_#o-5KY921OCQIFZiLF~U-{rN znO21oZJpXy>g3kid#~v6VQ}RswOFb}I$cJ#kA1br#n`V1Q&I=2$2~@wDQlICwby_A ztgn9Cdgq|69ivgVbv60v@ZwpZdP`iex5K^YbDg`#4>CJ^m1SguLjLD}ZeLW2Y+0oXB*h0W47_ z$s>`88BsMk1VkfJE7fTPjka=6Yq|%3N{=-~}LF7^Uc+5+5{b~IxH}- zxo1~CE`OQ=5D}|KbW}etR!ZKGM3h>Cl!*u`#-1|XV%~G!o%Z$TSA$cQ+04)x(MRZJ zCKtuvN2mL0m`Ofbq6hr>(fIZ5c4fKsn!Wt~#Kitq{`I;OUC&G7hadjXtkyebNBM*v zHZ}46SyVjXr@U%GSaEJcCx!?U&kCHBDqyYJR9aV%CPZT<_8A!d`ug*y?e-S=_3K;0 zGwkK|Lrg(lLVYlrhBPY~S5yhEaH9FS7tGuiu_&O2%U?UrLB2aFN|yv?b!F&oN?Z8aa_QnkAd zZ2KuE6ABIImJwUriY+X8Flz$N9%_#S?CX0zMKZem(|TXdI1 zX{l{%)`Q+3R#xTn)rUf;+BIg1On28k3Yy+6ty@^sQ?TQ_he0JdYeO|AGaYbx)dw@pF;*v~nK2Y=6sj ztbV|UVmR4ik*hC;H4pwwWhLUtN4p+T{Y3ie*j&fLW=bp0Dqp-jtQPhQTBsycL>dHx z-e%CIPbal)+cI?3_NWHV3s^9Da)BfTsabU}Y~t=b<1`gYZZNnLo8e{Sr(xT`%gt_sn~#^xH@~^% zMisr8q#`4d=qADj&B!v!sjR%=p8Gy?-}n1{zRlRDW|WNZR+;3%>JODAhNp=oLpl{n zr6TwFmS=AqOPnfQ{OD%?2ZgrZdA+xw??3ZlsCxBkzw_Pif8hIw_lKW+3Q*RsN5GTU zudfeexrHlH>PftO{`B?dIhD8D?T6p|Hj=huhZ{|@895u>L&`!?4#fM*`w+1_0;#76 z_1jRv!i*myr{@7YRuVnW+JTQB)^htB8O{p{=vjs8pfxRI{pcsHj#EAe3a@eelY{vD zC=ZE`Q$w>fc8@Xa>%gMXp$q7>%vCGryg%=GB0StwIU#o7nO$UCPR&t2mepbC$@)GH z{&V`XFHguLve$88Ju*jr`r&arJua_kBp;b#JiM$1x37tnr$vz!n^LrhRlP$-^Y-ez zeq6xS0B1`|%mTeVo3a-dLUn(u2hmPErbKQkgAh6{o~y)*P1E9nOYIyP9tfG>fKOWp&+K&>D?dM#ATnJy|HgOj^)-Y6usUxN#5mTqwHJ<6$ci79Yz!;me-7B z(UUqR(W-Op+8t0b%7nD-P=jgHC4Iq zplQM;c=OR6Ljr;6vS|s(4130<$Vw5~LvQ!kXTI%`pb*X3VP@_T@%9?8`+U3a_g(kM zNV&am_+~wKl^L-Y&%8Q5WzK5eIPd%G+djAjyilQY{k~g@zZm;I`DeezKK+}#-djX2 zk)x|^_*Y)fumAef8aW)?CnHh5Zxg3mw+RhY3f5(h(c8_6VBYTczzu$L_k=4VOV-X@ z5qMgO@A#R||9mVL{;ug=yXw1xFUakEA@#?l)!)CW_xsQFfxiFZcdl7yu==pq9pT#d zAL|D@+k*kdMawTgIJ$5i(d0`W8s6!Q|*U77h;%;P+oO3D92 zHCY3?7P$o(kDpadhp2a|8Q-b~I52Yorlk1LTSyDQZ4T^510EiS0bZSR;qDa^AD@3R z!2P~kVM1n*tGhSiifTNct}eJ(GhD*a=or2ARo+LToyvUo8kLK>J}_Sw2LMYH=G-oi z74~FkFJ|aWmy(Z3gr~bWC=4|-E*6f=&KUO%=Bb3vZ`crD&`@&JgqVB zr?#e8aczy1y}L{u6Ze=Y=WM>1(uyR47Zdx@o~}x_o?&$N7)}+JnnW^kGg+o3;gY$` zE2ZXciKrk&QYiQPe4BB9n|tJpYSKNV?i3g~XU2Y?Z~J`PW1pI{S~#HcB|R52Bf5j+ ztoE3O>LEu(gke~4Bu1;8K7mS?yTdnL2deptpS=Fn-a9?N;#|M-1GofOPjCKu6#Y9N ze)7GZZ{(wItwy0ub1UyXq)y*ni(O!3zTA9&dz){sfBMru-)^6bmg6n=+xtBLDi-WxIoKJ}86x;gFv+MTg>qIKcvpnnQ_w|(EtZ(Q7 zEMM=U^(NL^ogtR4W>Ra1dA>HDYGog7(7*vXE~NBw{)gE28zXu8rj0YP6MVZL)iLuJ-u1VGB6GY}=KDRwU0974kBL~N-t06iYzg=fto{hX z>MvBee6E6_()m z)hL@Ebm)t324JPkPaL!!%Qx~_2N&e(#Y!6XFhy{AoX<`=3if!+qr96s@8;7-Vo6e# znES(7+Cy0nA0{Q}#$4S8S}5vx7=@15Qz&*`Ocoh^A<|e8#7Dc~H`YTglF|9jm0NTj z<$Rdy-vS}EYTcI!Z%@S3sx~>14p+{>>9{%WjLm7?%v1rDWPE1cXS{xWd%f@Xx4EYx z5i-#Zy_h+tr2C8#RM}G*NWd)0{cCAysYpMNMF>TPiuHoZU{EMvbhmZLECqG1np3il4WAo5==uqOa;}eTvv29yU z|MdCxvbhs4zxmcZ2htvHdUr{l(Y&ZfMXxVb6QIMoU4GXJl$YLh)k~T6c32-C9PT9J+t}w)Wb4@X;P#;>c4ZYiMysw( z=py+3UCJ>wKSy(Ae|1o$&z>7PT(e6HgL9bd8aE%06L_DGmUNI!>KjXO02KzS`u}u8 z=+-D!Q_zlJx7FIZbK^20$CRwP@1AafqcNhb-f8Eox^xCT0I`d=p2s_9*m~J{k8xX% z|M>_<7NKt9358yMu2F&1Fy2khm@nIHqHstU7T!R^YFD z$-cPZS+$*o28Z8-FJtRFj?@3w%y6qD~;ySZ&n`|{JD{`56dBW0Ea3I*Xs);kQ|6F7O`N;RKP z_)#A~TTj;M0lDRBp9{3eLWoU8;{`q2v-47RjwbU_aAjFbZ73>S3)PuD`bHC?mw~-?Mg0subpG_#RHZ&(%vA6|!Eai*>2psP)n_s^IAA35I2ok9;sm4)@VfvdIxi%4~cHa#WY)zFub4x?fhZ zRS6-OthRhSS~UtPDNxcduG`8oU6N#{WZiW`tj5AmOX7o9?L!BHsT7o}W92eXD;Gr@ zMP}>O*_$IM%Ajbybe{ER?N14*1haJ_bvVHwnK8wdHe6?eF2xAvGrr;m?G>sNp$mzv zKUMp}V*x0#Tist?Xw2l?h3y?86p-HS^3^mE#p))A`Q^*&%gsOEwr!ZN{*+Zi3|K_G z&3)hZ`yO+~%z$hPCG)9d_7GViKMfc+c0janwV-aH-VIF5W5UefUiAiU1JvB-f#a=b zUtL6DdZ-2ZFvxrV*MC8n`<)GwJy^Y0w?{VD#UtNPZxfBS1kE!@K_ z$y!RrWA3wIul&1n!y3^36|?<{ zOrCjh<~7_sK0uPVe*WR+Lo`@ImEtYq$5bFp76^wYY3hRM`nq+5&=11VdvY~JZM`s9 zt7Wf7PTlNb*$EtB^qLIyew`@KcaAMwtNM#}s9{{PA*Xlp(R^^0GzFjLfF$=bux#%k z8lX;`ElMJqb82Q|j2s5HL0As@6uEjLe+&|@?iiKE4U)@{c8_TY>j-u0*^gEAa4~Z3 z*W1GJz&q*fsAh;#84sS=!4;_EbGJ1_U7UtK0fg3V_6==!sB%$ zfUh&DuR+Sps#P+;9GlTAf8B1r7qP0;z9fYhp(sVu!VidwaqA?5&hD*^))853L$+i` zd9O)O>gO1Xs#Cp)3v0$9cbrUlKphLhv7c9q+8~2P^gQ z^9SYdcm&@fM|^~rKFoyoAG`kYbax-xbmij>o$f`FO;Z52;9 ziydpN$ESyVySG-R`$=*>X+DqTg=_E|kUuv3PRFf?GUjwQ8!jW~ln=UH^fHg#raJ?p zacF4gSS;JQuh!phd(E#T--b?%AL;AG^}U`bb@tIn;i zcleY8K8|0;>1-&yT&?5lII{GQc(ru6lTR@jFEI+ij(`!&GQ$_9#T8~v_gHGwF&C`D7(;6H4g-+x^V&xe-m zIg#<+biMo2uQ3nT6J5XZt!w^^j`{09|0_Rsw3II`se0BS&5YGIeiA;+&2PW^!*BoL zpZ+v%pFjQP$FKWagx>aqx!L9#3RdMeQ0jHRs*NNsaOL&s{M){Gf{^duf4rC{hxK7R zznKx>Su6LgQ?R1Fz{A|rcT=$6y3XrseODw`kEZ^^`-3b|g!RP(-EN_qhs^W?R`GPw zb-ZfqvizHcc)SJt^T-L02oBYPlI{s4a#`R|-$A{Zo z?nnkd@|F&Puj7gc(rooncplOZp}5k$_~uW-~{+XF0s&7G4xQa(-QrxvSW&DGAcj>T!tQ2%Is;C)lwiB>wfbhu8 zOI*K&3fFPa`cmj8y9(6agMpV!YDfE$kgEgKa;2_;&T-85bGO{AMXh3)&t*hyK1S78 z-mw-aeZ_^20CzE>&luvI6Y72&=;2u5K=A;zd?g>tm4r&fTGpX|!9K>5F$ra!jnrCb zhA_ZP!aS5j>i-O-%uT~7%K*WUMsx=cWFgdL@0sC*JMGb#coMyP|9U^>9|p?rt?w@e z(0}Q-e$hYpew_N@k-v4iZy~q8d~4Y~Ov$ziDFGZeClR}(a5LKmLJ|A;^mz~d_VaJ= z$)En|&wIqwHZi6wk|EoLnSeQ|{7Y(e(Njh!9f-``uZ6*RUD5`>Tq84NNxFW*w=3zM1KFn*NFeg=cwv) zT|a!3LVcT|76`I;Hd{m>cCBh&2jygvTw>_s7V?ARyR^FYR{MA|0y3#$qGdPx@=tSq z$=jCNo6)FlJ5oAa#_V9JQ_k&gEzb6M`}%cts7Nd2(lZY36CT6Fq5>hx0P7OVg07Be z&&as_FbF6{^xzv^4_ zz9!S2@e~kuwA%ZEqgw!-8nc@;GRkv@VO1K=|@U5~l&eBCqC)Z;vu-~rk7_i!{w}Tl~7X={d$)jK<-Nu+^ zIn_O}f%2yH?G)F0=jl6t;&;nTzjN@1?SsGS^T!;}FCG6E!=UxCUv<)7Jm3|!LH9mv z2*litgwkOz!)M0*_4TLykN?Ym_@6$%Y+ru<^XDIa{PA~x_{Tqf6`V-!UG)=1_cRV~*o}|7geabuym6)nM#7c`o5f`Kk*(eW(EG4@)ZsAOHsg z&zJOM^d2Koet4bl?%)*u`!H?saD-!FF2d<|Ac4nU7$2ToM$<>n}?PA=@T zw*TPLQ@#%9VR|c=ydu?L63#U)g$f%7d>V&2>aWH@)0khrkVqN{!Te}^jgwHiY_O{@ zPEqK6Hl3YzB=gBOD(zi$JSxy&0x8O9g}w{ry6VhaMqCI`Yi2aGUA2(L#*?!ei&|z1 zQGPK1>hgQ(TfEaEUu*ADB9+-`RGfmUiwi@;Y=+hU(Wus3fZr<`*0()B1p=od;h;hv%n%-CS{q zs-3>Q-Te$Tlg7U-&s z%l-Eeu(m-0L>wPjq@VLp)#rA(2xW0v9=LR=(;Qi0CRNcdDKnX2Xy3K+5JictmXcaY zRy;T?4X!SEu*)*L^o!1mRF)DYZDQT0evLvZE`?$ulnf~H=nVC+Q_RbRE9UcoLRT4YDlccS;!19L9m#NYM!jwR;F~}&s-NR z5{|gIc8Suu=lf!BitfYS-0oR9AR`puHp`K1Qvt zF4|M<`=L2``j)Pn)Hm+s*Bfk{sWKfqZbkt4VuLZ`ZU1z8`Rl*>{qKMLVcW*b%cr^j z^yh#6`g!|gFQ5PE=bwDDmO*sRh)9evZtj`+9gyI?(fs}$ed}Z2vAzdXv+nW~I^Z{s zaKz0|0kj?v%hOrK=5qi7cXxfL7)d z_rLqU{>Q%^j;~+d{_gMp`EP#v8^3-2@BjR#zxwo}Zd?3x-}4UI$Y48m(B_ja_Yd zfAh!zAC$~X;<0+llr!9Z!>NL_%tE=*M@jt?%k1)dA!ItgYnN+lWXx*vlPMg+yBAHX zHS9&%SUy9^Vc77iReJ|4X|0yJW15VmTOf9>t!yU=SnYOIf(zQwvvfW8vl+Xc2 zL)*5%vp_NqN&lr>~r6%ff3CDX|LjA)}5q0yi{*^X))Jw(|OZr3btB+h2ekimtZESYxL zk`2w%LND3{8oY(P${q$kOJm%Sl2Kd8HI}{C@R0X zcO+;JzTtXo0J`PUahyD=zR;wBUhSzvfZ$S9zAaEdKvw!uKpZ8s_G+&g8)yE z%*g5nJm>thjURsdyB|J(rrY2D*Zk^Peup8`eY5JWt!kmM=H+U@q_ZjJ zp)3Rvr9ph;jU$_)c9i*6BsS+6fM#`JtoiCtlre$XuvUoR0Tk82sLn1MR7%<;hdF@J z>8`TY0?Zn9F-hTU1Q@c_VzfNX>U72~HDBXy^-y)-X2*r6Fj6b6wid?K4s9;Of>Cm{C)fBn&AgItAWYnc_YhBD=&b zn;5dDX{2$s3nw0_n@}R{<@0Y|-u6HK>7OF@+ikpTBlh`zgLuE+o#DuVcc02@&zsS= zI{sdfhS?s+`LQF(bnx%`PmjC68T;~_pT~ke-0JI9m7Y%R7PdCzOvTZ}8=y0xycGE? zkC=uB{TC-GR1rcOJmaB;s8T&&z(gKWLE^s0W^UUyr9XYW|9s#7@z4MCAAk4x>remi zpZ;(E@i)Ku&7c1GPoM4fH$RSl{Q7nOa)0rBz41%#0q$j0t9n?o$0zM+Sh!-kL&3cp z;7Kh6W5~$V*j`t#zIn}(U>!b>*cUjfLU3wIfP|Ak1)^Gd1?64zJ|WPO$zt;rU|HIV zXGU_3?!uEV&$!7mseJUzyt=d#nSrjEX$q^XdZP-kwmoNd=UIUIkU{I1h0QNr-#Kj3 ziH+6g&kWm%ve#O@a%(lsRApV& zTcnT-cz67^gqWfUX;u)OrKgo)Ub%{+t3>72)4J1TajZ;4mZpx`_Hz65!{_}?v|mNc z`PQo*>8}Jf-@lHKw?ZN;L;Jm^0^jxwz7-@reX$;zt$pSSa$c(;>*XKe?RLz%RNFOD zpcz8~#Xulcs3H$>U2Z;-$&5WFg>4%g_BP-C>)-vi|Hps&k7oF<|K13QEb{6=)0}OsC^K!ZfSkU@9RK`;Vp*0PeM-v5WIQdeMdnhyk zOMZA|ver+d4oLE1;Mb$>*!0OEK&7k}UTP~AbhT_@sezkRw3S1`ps1eKlA70t`|zCe z5|up<-7%`)Pa)OQDdKiNspBq=x*I)^oOGlu)?r)52mlnoxYEnp`IDqpAG_qg#(j3I z)}iv+#Rg?W6u}tEYR>7m(@IQw>f9^SC3**_k)*=k*fEv?H?Yz_+DyxnHl|#x*9k$ z!vuq+Bnz~^*@Ec3(oR%1s|BGo=3Q$f>)sQRa=ZEGd9&Q-+?A931^n=X+5WVZT)?*v zk9EpBzcZ21?E6cG@-g;(`c|)&3pjRY{C39fBP)FD%1d1ihfvEg3vr=f^tX-^to8bk zgKXik#o+11U>ViHje5MA%zSxy*^KwMuV(hc51&)>=b!(1+vm33{>y*)Z-4yb&t|vn z^H+}F{_x{(_uaoBZSG3etOj`K5}O`dq#W-2B}1a8=e3+ald8cSkGXfThE|Ge*Fzwl z54E1D9a7xty+;JNN)KSM(5!RcUC(x1)MIv*=hpuoVMn`|*S|hj@$#J_M?YeAsYiNIKQPZnMoAfPPJ$NfG4{Y(}08y(WzB0Pq$<#loz$T<7{pa!vO0(DsFwcCz} z6p&oaMwj_drbA|(@Mx71VQu?s^eebJK&R6gM5#4pt5xMPz%n>}MUW5vRIijyf5-9yLOLQ;%K$;^q(w+%#2l$oDdcfzQ;<>OZ2)P$S!lj zIzuX5?Q=-&IN7D*I~hy{GBa2;#9i=yKvvZ3>u=UZN~T{iv%fv%e<|qfMD#~Q;+{5q ze*gN59*=g;G=BX4_2=_4T=um!=r3}mT)5V?TD{J~lEzeGslPNekl~|>y z7X!SgWifqhKm72yXY!nz`S1Vw4}bpY%iEVPzx~}GzP#?AU-R}G|M}~jwuPANNh{Hp zsBPhITECb0Q&pfYzODjtc%Gj@tiN_~BY9+KPwukG;K_7&lz=X?FA$Q+0a>;6@rAoQ z{Fg{O-m~jp5B=m)#qTCp>;1?7u004JV`4k{@d2wCvPKo9BKhHpxK3tXoD`BzPU@2# zDnYK`FD%%n#d17tEM8K(p=$-0J)XE`HLAGPs)jfTEg{_Ft_uEK4dWmBReu=f{+i2v z|HUIP;L>rffU3dG`hF;S z#2=1!Y$v!~=KcbApU%z6AICNBypRbOkaFyIYl1gCP*wAZa^fYcF3a^((eW=NuM9fS zEUl8dMAShgmbl85QS#&w|H`%cyi`6~JP*p9M{IHV{o(URxXcd@^>leXR=Gf`1NXel zj_Z{PuwM369~7%8%`wpDKN@@yfNz%G+F_i_!nGzajEvQWiwXhT*k0eh#PlD3_>?)n z{QSkhA3nXfZ-4i9|M*vb_#tt7`OR;B^ZUQ~yMKKB)9c$S_pdpoNOPxUJ97_J=}%}x zRx0OM>1rCyssC5oNGZXr3Ex9{nVr&VxOU?1z=_XS*xNsK2~bvag`+_xy3$k?|E)$m zh2Iq7wSHH68>+g_HI0>ienx)$m9mbxmS$tAUw0#+T;Hv;GuMYYg|q~Ly13))dZR)# ztw}{^3z~u-4?TlJuIEy5tLt%W>9dRF`CT8@yXo2Ppv;`-4ii{t#DNN}4ZcTQ60?=p zxVi@{W75W^S^!uofOF%~x{~@=XPO_vdXmaG@g3BzvJ|lOEK5~1olc|jU}YSx)hgxg zCDK(S)qZ$Q*E0t1@b_5P&F8>h^vcp@S)96Kr5tToD^r&XIcYpJR~5|l5f#<#a4Y}; zV`c-$k!>L=KUpP7YKiT_%Bac~7Ys!~S#6b|H1iYj7Lc6i&X22`R@q>5Bp!glI&a=S zT$}eY(lwGn@>G#rTatQkgkc>_n;DZ~QRUBrHqRVqP1z&-U7JN`zfO98Dwh%#X30!? zRVv$}JvD}DT@OGYnN3tVs$j^*Q&zz=v^p^@x(!Nc*GEaa zk3RFr;P}oF-oO8gAHbsiy^nz3Urz%g<(RFtU6?M3=0*UOz^^TX&y3%G9a7IVAK6c- zj!e2)%gG#{mtv=coUdPh&bglZP5ra6 zPyj$cUX3!Fvzstm3jM95$YYCTwT>-s{b=fQbVDnr`1m9m{k*o&^V08Y4N6m8WK^|( z*`PMi6l3vBPTq8{@ylVOV4_W7)&*%vCNPuy%hn^NorK6y4+OT5_`Y5W+74fA>g+i|bt@(?TYL~j$MyE)vNlc7j+^?>`+rIRQ-6^S&Z8pWjBY!Y=i~9Q zy8OCfk-{zx{Q-9pyfQ@w%nx9`U}7(U!w#}66-(7yS+yrc8E-?Jr8k^iT761d_UNIp zPn{6>k&)_R79;EDd4p&%kORbjfCn#{wwc*eycv2ZI`TwZS`;t43Fv`D9_Ms9A@o9_ zR{_wn_{|OMpr6?p-z@3bRmgk7-!))8byx>Op4B{HQe=6p<`^XZ?6 zSZ}chj8pz@@irPr?2#@}Un|_6DDU2gs3I7lV7o(Lq2bKh#C2THnF4#*g&*HJR>$E1 zw=dFrXc1aqbq&W&vMs|oJ-BwK#@n-cMRs9D<*n*~ox{4!z$0O?(r(#phbqOM?IE?# zqsG*F?p6`vdCVdcS1VGUyJ&9+Ttko#n@{b*S%&%`xEw6fr&U&`l(ZxO&X5;NscK!% z1!_Xm#E5f}uj_$jBXd}XM*9~y?!*AF`vB!R$GFz!1;IEfo==*`bxq^p*?sqQ-5-2a zhy*Uq#ltRVS59EtV(37=+6`KNJx2x@3*au6ptH$2qjYzyAXx~R-OsM6bh%t$Bak%a z$*QfUx~S3`Pjz>LqaZmUB!WezUJ+<51$Qr3R;xDYF+;riT;d=sWmq8_;T(DP|Er?< zYd}*#`%~c6-tHk(|4?SN%&3H7{noRWl*NoDpyIm%Qk0jms6Je9Xkj=hwPxl81FBJ} zNNJ@B>}dyCbkOgSb>Ex4T+=Zjf9M{%G7yhnX_d=ndz#AeQU}a{B~l?t!vOQ3wo<77ytaD?fcBz>ppj@=ubu%GP4RW>}gl(3$w+)?A!%e`@IQO9H^vu`xLcccz*df zntN-yb?&*jby+1XCQHho<0muoBnwl8AgqWGEsk5g5R}BQtLAVXKbbR$%J?#wr*TFy ztuw)$@fB#$$}V3OjKL!bE*+^yp6%ZckAAJPm6Z`ir8+bbk^K&2sFJ};y#Dlq z8QQh^s~+go+EYKGPSy*Ha#f`qRcPFry4^-a$1_D^w^DTjMrqfVXUuh}2CVt@`Mp-bNfoxPT|*~^$|!VhKx-&<0G^%VCTYX2!?NzWHKiX4x30VPBEMjf8j2$`Dv@8>Bj%mgY3!88 zL29L(b+l`u8OI^=={5vOAy{SFX`7&=W(kar&4GD;MW%aIGoSJ?-ytkA0sKz^6Gsyna3&oHYSd6FW0080Fl|vDuiKgqtHGBGb&~oHHhlFiyS86(~fW?BLt->9rQEp5_q&|K6WE?;L`H%B$-i8|t89#pd7v*BxCB zlym7cA8}_UItvR*W@N&Qh|VJ03jHBjp9Of3*y~f-sX6@aXX9pR$f75&^+Q$!U!blP zq@2jAlfZHI_47I=d7U%$M63AwD3&foXrop3H@kwMBpcY{n~u`Y}-nfv(PEm zhqg1Y`F<;WpCNe47OZ==30OYlee3F_0_eLchJ~96aH9?alU1HqfOX*$PdL#o_t?#99=H9v zyW|JsP^8B-CfB-%qh$)84)t`{;|BWzy7~5_iLG-jyZ_|(tWn_QCxkGJ)B?uH4slyG zvvO`q7=0K;vz+&c=%>Hz+;<}NU;jE*!26u8E-~@bS3dmb`w97BPUz|)aP5kSnJ_jx z&ddM+fB;EEK~y4#*>HO)DNdKmYU?!lpqW{DZBb&&2csh2*Q_onfCV1bnrRwqW=U)t z_~Yjve*FFKHuIOw=iBRVfAe`5|J`5zKKJ{7{?Grf|I2^;U$@)KKmNndw%x|dm>FO9 z{JQTuZrFxaV~*nU6%<0aR>kMqn=Zi$YKK*^nAZ$xw>1Gn=4vx4u_H`Y@2pi=*Y}!> zsDIFQM0JflXvh!>chc!USx2p1qy#{jCkK}N=FfHJ(i0-t_55)V?RvlqR9*<9s(*>> zAh)lV9R>GCC!bfF z`_>MACDByb>$En#heiNpK$^c*qj#ML=$w)Aa$~+81{DCzb-=kRU52_B6mzZEx|Nx2 zmVA=_sEM{RmS+I^IF6S+xlL~mzLwfa^@WUF$60%RvCr*f@SQ(VJ{f?ePIVFPEdXE% z{MGN?eOjB@u)6nt@RJw!)BqC$DtDRP1f8pRx+r&f7=2tK2CZdv@PD{|8W4(c8-~bC z3?U*74WeeIV}*JEDjZNeCg&>xzUb-H16ajEo$9|B20nO5Jd;vq+CaxFSjb+YYJD1O z=rV<;TENWI3aF3kX*rs{j-Fb5sXTW00u75ITywr7_);qY7TR{j!mk;}PE;SJN9TK3 zi>xp7vR~BooxYe3h89=risJ+eW~nhL_Q9#E+Cnr9mak)GaYNKIViD!IMq+_E2hc=H zhCBdO0I@dKawe9$4lvEfaEpDDa?Z&^_JvjV_Ratk$B3y9wfyjJ7*zDQo=^GwOrD;s z-lc~>w8UBkROd0efO0MFzQR_yHl)$W+WIt{o7?8blv`snH91ReU=Rhqu6wFkG_J~y z=U}uW+tp%BC=;2PdAr@J;jO#BjP28>PusRJ z3Z@TUT9LuZwy5jj9~RY7{;*zV-`FA_f4+OweO_8E^-e++FZbQY-@kWIHM`_FxTv{G zJ0MZ4sPO>R*YCRgWHX;1;CF)(C1iB|)Wcs_s&yeMIwXV^4fdjy(SPCkm=^QZ9?f}RE-e(c0P?n>xGOX7)N0;Y#S%$@6c-#T%8Wgc8c$q9JjD$E- zZx4o|mCvp-Y{@9`QBdzZ`D4}}YASJw+jp{mH6A)Ls^|YM_oK=)@vMS$B zyyBc(Yl;PdMc_K?676`##3)O?tlGJmtg;PQWj7Mp{$>;V&ky&AOCkrl-l?5l$7RKK z6mgL{T&L;AJoxXrDfP+S%pW zW)>08Y5Q-#zGX6x-}BM$`Bs2?{r&r=e)_AmqjJvS;=~zJl7Yhx**4pZgSZ(bIg!$g zeP(3l;7f^*b9GFsJ-+>mqpcfG9v?1lM|+l}R6mKzq{(7G>IzpN;D|x1Ng;%ti$3Q)Ju@x#Wm*eKoG=$I5FzOm@D!BI%=c!>Tjb`W;BCFe`zge6yH1SecBK`6;KPc<_XG|tOY?Z; z7bNoeCtF?VNJ697+O;ib@ynR2jow-+UF}sMt*+Vh(#>F#>NT7Z3};%!#mZ(J+7dfQ zKO1wql+Iu8Yu#S4M^@0bilSIEEZJ3YtLSWDp|&y`O^VJH(p4Hd+K*h(W%0W@G%3bZ zp8Ervzj>6{E31#7d!{0?0(g>iO33zT4%MlmM2& zY_-E$#()cc=na`FWdoXG`Jwe+u}dnCw^X!XCf_zHUteF3Z41DMy}%ywE;_flUdmUj zo*#Vie09qGk^=ZB2p9x53zHS}%K~nUn?|gWC-!s7NK_0ezX=5$;sdA`!MQ9$u6+32^ zE;C0he`XKE;-c%igopfOq|c+ob=ZOliIAR z>z%7%V3)~t{Z@HhMti72uEgB+o$^5r>79lBbwS!g`bKF5zZ)`QN%=048e2K(#NI%f zlpU(Ao2~hF5UYB&9X$Di_*m}p)AH68fn1|hWY}v?9ryryyFSfhBp;o{ylzyN>bAcA zG*ef4rxt+UQ+uTk90qDQF^Dh>LzvPSRjs5h!CaIbW9>AZWjLeBgA`{5cV7T&qsW&g z+w~P!XFTkX50_SG2>2MJ%mz!Hsx{wj4FfV+fntNNi>?7(XNIhIsjNDiOu2y>2BuE&8vPB>;BJ$;zA(OkV68?;u{@ zDH?NVf)N29B%MZ2BZk?4h_u`78v7nm-DQ?P%e;0r>E;f));-Rs)Rg%Kx6ij9 zwwK$dAAS%mGeek}FWc?Q*Ef=i{inGDNV)ulgGZ@n0NNun4@E*r*b_{lbSwU&BxVUPbyHS=!U**FWnq z#pUP4k$pP2b;|AOTDbOFQ`bxvm&(!3#6k>8+D;~_ezu}SiJTN3-J|`q%ATkBDFyS3ZsUl2C7p_I+ZkBVx^+;FMQR?8$3{~V$Qpp znY){x&=y%`W)(1bEru+jN_J<#I?j=(9af?i=44r@Be|GFMDO#}^{JnTnqpjjoWo^u zI0pwuAnF|@^Ja72L$itTD%03Ze{vD_Rb?R;z6BnL->8|yECsGX^FgmD^E9724H6+~ zCXaXO2tG{mDnFP?&6ur6-Gv9CBZ_)xj!b}r5oVo?SzB7o^lDwlwb82|4QXcXbocTn za}nP&GZSfzRM!)!NLs4TIt*qNdHXO7H)k-04Ig97MR)H^@P|R?Bg^Tj0Qa(Ce7F`K zG>WgsJR-1%f;D~f2*=Wrgv@1kOFsd{j5g3fOA&PNW^@S3PJ-sld8c9wFVv^xo6U<0 zXArA8=3DLqNvkr3qu5T7HIZ!l^!bPF)5}c6+nuCnZ+p0HIraDd@W&rMzYN;z>#M(f z`ttU+iy;LBdW142ZL1ZL2(mh&HTHJ2WbGo5HK01Am~pxbRqM{RoI4_{-yimsz(=<9 z@%h^&)HqVVTG8Y=F&3GpW2w^~pN#Ae2laUK!Qp$R4m`)Zmqk@4GGFsVCB%MQet)s< zyV{4#D7)6Rocr}<3U-?R5K`7d{lR6jo)>exav9x=8_}Tn`x(_2usn~m(XS4Df}{TM zAf{Tyz`P*K4^u!o>C!8|c(7F-)|8G%eyNTrSzO?{tV^4(0h#Qk0Sa{yhE(bqJY5*S61a{taCuDh`*u^)J5|sMbkc48Q^W$@<6@quJY0!5fKqnQyH;P<+Y4^ z`KgVK88`Rs=9>?$W&k;JkC{=+nX6@06nlljN}`#hZ5wVw^26pOF=s>|qFOqs#jVu# z4D5lib30hD|I%$I38tBqW(6tlh3U?Gd(+%vP( z>n%kSt3P$F`DBJFX0A>Ut9w_knJ%lTZPn?JISh0+Gdf7i;lmxBd`@JJ%uKhO8J4!Z zqMYH?oI#+l6IB{YVgSQ!5NBGU+z8wM^SFY@zL`Bad}-tp*817QlVx zVgNI`GZ9q|TQ=0kt=a*7dAmDc+qS2^?EA3o&p&}50P z)^vIHbk2>b71xnkL9ia7>5C|Aky!eB3phQUrNc0+>G4SKde<-aWRUk zjw3$Y$}769;>v55Gc#4-=_*({9HuAMZsUJsJPBX0U2S$>sTTj~C!{WAJX#p~=@pbd zUS!+D8Z6Ug{A(heYmFxuyD~dKi>X8%LF*&M9C(kJoeTEDJvbiqVeeN8NmpsmZ*CN; zc)A2bE<3~Oqj*IZ&TL;5qn|70`pDKP9w%efhycK2%IQq~91O<>hkHLMWMt6M7Os3qudCA#* z_k8en^G`3^peYi}F^1p9JuCwv3h3Ksv{ZFg6=3aVme6o;K*HRW8D=(|4(=v*7|m=* zjLO2816VL>vHb=lv+hgJ)h*b}NXyI>>%&PS-J9i9m~dvcmGDnL}~fskieON z8`BbmZbkhXG39(l?uCawW!hv~k`3(7y~-Bb#()f*~R zM6hLcP8hk}<@N6r&ALqM*u?w6MbiwI8dX*eYG>4QDVp111ulGzE;ETvbs4SIe^x^u zR=E!yj7ne?LuEOLl1YmO0g{|E*KWI-C@w3QEvIvIJ1fn3ztALo<=JBRnH7F$%2F2S zB7ec^9IX=lsr}s)*F8NBNsa6tq-{2;Z{WfR1;Fi4lv?ZJVt}s}B`>ZsB`GM;!u~H_9&eS@|9>iL*d3G5;RF>PQ9Z}F)2ze>(#qtOr zT$~EN%n4S?uXDQBE?7syvx}jnPG_qiqDMN;6UK8SmHVU*+=%sw;{Ti6(8PUo;|t z4*51G(SZ$S%lZxojKmaK-4Ii7Sa?T`-A~LDW2tq=n*iE27 zq?c+^b#gXN>Q;^Bit;Bqv4L*pnpI{>Q!Xj6%&vW{P^Ogq>Y02e-u;!Y?;k;rvCH9H zU*9=*2MUA}TV>NJ%c^-R-v#jUfRbrPJD~Ec#uzp>z%n1&1a<35r72m!k)3;Pr7aFL zX{9WVix0bPFSk$Ir%#a{DG8QH45bV+mQIia$W=hg%D-eM2v%EhtXAh*thp7RAER-J zK8^ffcn@5oHHTGQD6?yDq^VO|WO2$`^WBd3t1YBy)yzs2_620JCK>yo5_UAT$VDDl zK;EhPgjUtBF=(O1Sk#N7IQopplQ`;G3r8f$Ts?HPv@*&}Y98;i!`I-!xLeSQ`Ne*a zJW1Dw2Nge}hd1M>TgMOl^D$-KmseMwhAVRf~RtWu{H#WmibHRn5| z=2L4gT~yiZ+5fI=h6rB3{CZr+9W=;(igui~^GLn0G>X^0w$kX27Pwl}bUEFD?yMg4 zkKC^MW&H5z1(g_&P!!&QSqXACv*Av&GN>jaBBwGUW`-gQ<1&Mj=G?Y1hTRH~jEpE& z3T!ZQtI+Zu+N=1|MDt1+)}WXfQq>37Oxw_H)2NzA+BOKm9I+JkQpUZ>@q-x7Y6uj{ z6qAfh5B$y<`IvJ(ODp&@7|!dIWW+FTPIsf0 zRh9<=!|tq!;?4)dw04mMB-qas&$oz>-U>iO7-xT3QOe-F~2Lb4v7tB>;}fn5_V-_74NV zoa&mls`m8q*&DiCEzp9ttjSX z|0z1G>^R{lxY4R&Efn%pd@9EHd7Y0wB5+iy;e=NncLwWvoQkvgfUR|NhY$H0t0Ly` zV7keY*$K8^cJe%C{;}a)+|7pvRKJYPtt^Cr0V@c$YfqfRs?;Vy8k><)u@jZSu#P2t zI7vF>N>_Dv2`GoTyASh1Wh27wGGL}AlccvoSD6he#B!RE)UHf&7%|+)DoP7u!j#=Q zOC+qtY?g4P(#;jo%@PhR&(#f~=Z5-BOjOf1!s@`O2_$7SJ7fnkmzg{|CrO#JN-Q$1 zK&1BXfZ{xpq}$Qh_;@z^zDsf2I{$J6BNek2SZmDU%9Q^J!5v4Bi8Y~<4RE%*Gi(km~mFv8m=712?)(DqRcXwcA5 zPf4CP{;%upaK0hZ&Ri>pK+rvlNtxw?cO zRm_=fgA!S{U{J(0=e%~eBhcu?2D0T2QRPEulek(+8`DZPt{N@@Zd`zEwN^)w5IZ_v zM4TETbt@+NN#m&c5C^+Aj@ejoPaqrA1=76AH`skc%XKeBt#cUL5h66qy8)i@=)IN@ zYTrxw$}%ewP(m$6q_XcVh?bGX2$e*0tTKVkilw1l1(L{xbPhmHhbkMqx)fUlA-$E9 zby`|sWp66AS8llSRXwRojOcel;(bTHTf5lBjUr0 zdG8soU;67;FRG`S$zibJpuB384>+f?V_jsP-E~ZrM)+te=q>jQY)bLE^W+KeNM00d z;w=$(YRZcYH1u7TYA9#3?@E-_0I-oR zvX#)QEF0w&29(N)YLG&>!(D@I zf#H;(h=>_G%&=`f=1iwDu`HPZR76Fc23jt9H@reFAtGjUr<6>lSzTN^8Kt?aUB(%l9ZR1KqGj$t&Ufk$8=WTj!Kgo24oDPdVWtd67E zzJRP;OP5JqK|l(+-Nqiajp3XI&L#X?_)+pw1bJ%0KP}ORU%qcL-+vt+8SkRtKft@~ z+&EC$J1l(IC5J{W6tTMx7sOgYhsj_BGo#jk`(|{Odh2r1J3q7@70IGj4oQkM9DPvP z7qRpLYjYyX&#SaOiXbgS=A2Q+0X(GjxGuLui(-XO6r!lt?&h$}R27&nxdSd&0vC-q z0K-fyMYs~1lNI%crBPGn3lbbORx56+>}JjOf<%KI)dlL#50vkkmBdk`l<1=MN}U&< zWYye@(!E>`ZcUy9jC=qY~?x#)|GmIF{oB3_vC2Wtm&A9I|*^1!}JAgDxK(Z_=6qyQ= z6HsJkmL2MRM9kXkRBmq)o@OIbnYr)#OaT*sS-5kQ9OLP`!5m100jbGpv=;l!DHv^J zflCyPlxRk4C_|7fx!T$#wlONrpHL|F=+Sg8q`|6iT;*WIv|3|6IEJ~KIR}f*8aZ?B z8EXr4FZNDzB`D10FD|AzhuKjff<&bQtkj%SrSvS#4p=E6TflbFgc5d9k4sj&i^W89 z(m`)|6u>Q-#}Ukh-BwoMSo@c9+xO=4FS51xhK0VY`CqW#2Q)<1U0{eTS=~y;rJ%S7 z!YnRKg_$szB^VJ!b!o&5C(75}mLVc-^-Sv4vgP(szEY>lVTV$XwBMl^G-J+qOSn>1 zW?ehyVgb0VEqCdnsER4NaNm#$1BT(;14~;}odqlq&`c!9uuG_9ZPO~xTVq~o=>Q9s z2dxVQjZ`SNL@0A@h=ny}Bd#cy`Ggl&NYOi(VFi zOhoA9<~%fzY^S``-^@@t#;c$10nuyj>0tmYFp<(s{C_C>*DgttBs&nhS47P{GOPMA z@4;&UEcYDp@c;i7F29fjxxnHvXiRriWk$HEid=pWQFG7g>YhQI>OPfOnI0Z)W-20A z?t^u75b&meI3ct0X7QpLiuA*iiLfPT#S#uHCNyOll>}vl+#`u4jId;D_Z@a&yQRG? zpwq!kK-n5ogUJ?FbDpg;!nb2V_MdzKv|lRV)#>88Mn9`uWPuG&!B|z4&5-5xZR-kg zeaJ=fdeR|xWA}@VGRecd3{j{BdfRp(%xqU+h*=6?N>P%4EKl>7GM}k$pZK3^#b16! z(z7=vU?vkAJE)OmHm?&4DN(EjT|5Gl5l~{vHoYwoq+nK#CQZp-3yUKuKo0<$&kTT2Nb3D5Y}9 zG7pJ#cZ4=GqkUhE=CpBiDu$;d8*LlX(`(7GA|h0r16k1A z!P{_mHUY{gYGN)b17>imHzngvzS^e5R{?(ZsOVO6?~I=}==K{FmBZYI4P#g=S7dU~ zjJD^k!kJ6v=HxKDxjU|;3GD&x5oy=$ptjyYnn(qzi z2FQ2?coc+i;UUf4Z=7w-cziX#Gbfe_=EY}MaPI_3CWCY${pHhhs#Xj}-|2%{bizyC zovExN0&>XR$KmdN)X2P_^pXokL;~GI_6!V?!zxIe=5%);17#SJr61@59FhAJJC5T8 z{O&)HnU`OUS&8MY1eB{nh$&Q8YMq9AjPPo=4>J zTx&&lI*HBnxdyPF$}4zh-<3|Im$@sdw##@(UT9e_aSZ0gZOLFLU`!y4`#nF`0+LEO zsZJb>l2`QUQE~4jJ2$`3(|p^_eth?!adFPiq!q2`&c4v{% zR`8jr+*Za_fX5gYc0{`}vAwLXxleyYV5{DEpHy^hH+x?0{#GKPgM3fnI`Gyr% z59A`@UX*K6bE$$pi6orumkXBlR&H^zz3}o1v&+m&Km~wsm=M-joej2B3>nADIFV*J zXeL?19n~`zJ|j09W{0;~-EkWL{4jIGN|A|(5WG2)je_Z$hvE5tzGW%@lV$j|-2Rhg z`}LrZb|f-)?3`_Zs)H78Y|l=gK;wtFZueSalsX3{Eo_XpYFlD*b<#SVmym1MxVH z=OG2l%(Ye~QqK<3o%Z5)k*TC2LbmagrXY6o)P+{of6|`PF6SQr6>36?hRvT6pnfJ= zr{kGvc3B3c`ODoSmvp(zULW#S_p*c%D$8P!V_dGkHF?*+CwMLLcE-})t?KpNTvP*Z z8L+c*j?LT*Fk>X?rB!*c@@?zGP)0;sO6_IT=Gf^;&fKGO8FkiPp05S^<=J@-VEZp# zC(O4G9?D*+#vnO{P%>#N4JO{bIl5&I@2P9EIvwwL+Olve=}` zG+}A&Ph6LmVS*8|_WVgV0~oa;?vE|afKh`&6(@spglUX(&73RNvaIhIN*FAaZilm& zCF+Mh;q-`bnAtE`^>;LwS#{n85SmGHfl)QF7gNM62$drvj3t?u$hzKaTN9S(yg)}dcMJ$bRxchPNHpXBbZx=7x z1F4WP9KLF$tY?PZ+@#YY%j_=aiC9F;tazn@n^%~@%~nJmL*~vVsSvPfi$cvf4)&k? zW=D1XzU>`p>24izsQqUoFx?GVF4kEYWJHgTq_4F;;_-f_-QH4j2K^W_&%MTGb+k=0GBePt5#9qk zJNGw>&_}6uon~e-Hwz)bDxWvg+ie`T`Vl*SbND#1G$)2FWoAWvTiMRIL$S<@3M!VB zYlY$#c1V(@(T4`fqga~Vmm-tXG-tkELvy$@ptY9R9y4YvtCX&wTiaT!<;)=D#)w|y z(#nH6cY#rv)@|lXRHsy%tlbIOwGav1q*jya(_EWQAW27n{${;Opvz22*FaRxN|APqB+vsav$%9 z;&M>wpEoj#-~cg2Q+v{EPF~{_=;g`w2$@{tKt6YZ4%(NL4Dbn?@MEC5BUU`n+`$JpHAR4UKPFX z+am~dgWKxPpbVx`5Djh_l^L_p0V<9IEurOesAO5LUoAmzyQMctF*hMxCb-8M(=F5`F9|=U}HFGJXH%*5jh* z{iRhGxsGO;k%MB}tpn)BXCe`zuuT<;O>ot-t1bN& z_Nf>Qg=DG|7MU7eb5Y%F1-8%(N6&mq(u!P>ij)C#n5Gm8`grrhoK(8faw?}3^g%FE zXN1u^d`6wFh(BFoe^zDxnP30>zp~xi(*UCe;Z|7-dKr52=UCRu2iwroOS;DEe=T8Y zH*tbBiJ`pju%lh})BEB=T)%JCI>Kt(VaNFV>AUmCpJv7ktrT*ZSup`hSpro%*i1rR zkAxKmL~StWB{@Sd%B;qC17yr(y89S*A9g=@8}!4RR<;tcC}-w?fwFie$(QSnHKUmq z8R!D-fojy)qiR9cwh2W0!{p(d+gjs!BpEFPLnx92mk<&&7kO0qKru+O_c+_ja}$7z zTD1*62TceoHucL`%N|2_0hVGDx?aymbPjHA*QVlt*&ey}?xlY;-$S-%bzXh5lun_L z>)PpZSJ|@7$zd+9NAJ0oE~ypUoRKZrKvXP3xfNX2dfdVuPo{ZlDH#Z|`MaucJWIn6 z6RAY!pchZ4S?!y)w!6>EueQL#{s0TfyBezIt6u=f9@w@O$@8oE2T#KGHvEzRt)GAX z-yCc8EGJ8|q6R&cKo)(xt(QC2tV$}M9D*jGRovh8?|I$KPr&X^oGtrKOBt^XdV?`2 z1#A>ZU-bwtg+{7G;cs4Wtmy9)V6wD)tae5QSaXd^)xrc>W?LjIX(~pJ_nS^-is}S= zBBgT`5RqET$Kf32Vn%8PVsTBZ>Ri!V!^EmhrS;TV1+N-R*3?@EfC#12EE$NX3@9m= ze6!=Aq!tuFakA+(?_ZAsyb#1Lq5!@5+{{#)IJ$3iuJQTnL9M&TtVn~l%3AaVgM#vJAa`9QvTxz|bRX0;4bGBXR@S?#`t8U-^~#99fO5_0&J z%wENl3S=ltl8Z7`1c+<_c91NKt}AStZ6(X()=Ag!&^x%ReP!*NRHg$3Ig4da*oy`l zB3tucB-;zl-q3o-yg&Qtvgi>z?G0UXH@mHNn?`wa zWfD}Bg{3!Pj8<_q&0!msC>MnK{B+rK?gESqyFk?FKBj0QuTO#HhJSo>1*|sY_B@@g znsjwe{S;7eV-{-v7( zGtvl+r*2@Iq=R5)*+z5oOP*-Ve)ppQp_Rc!VrJ&DobF}|z{*%tQ(RIk0g?@eWt3>T zD1uHS%3D*g`teEy&#JBHneHlz$YJ`l zmF15pY|2Abhv&^*G?Qy#ACQ>JR%=w3VN4RU6m>q#UN(`1-LFJu06zr5;h?McW^ zR&ergI^nddrPsAi{PwFJt!G11m!mO`X1GZ}#+B|x!HsQRgm!_bCGj8k4caW|vN8|h z>*M3TzE7!=M=qXS5|*o%cx@f0lCxSldoT`n)Cr}`Tu}7bV@4JvonyJARsGz3TpGu){*+oSQSP9j zQaeP%Tv^Dhs9cFmz&G35D*zP=C=?Ph+L=qJ_2d(F#^p=_LJ152s-vK<>NC-%rww$? z1fG^szI$Iu3bCa6{Uwu$vC+eEymrvlT!fjK#>&?!v6}aLe;p-D)oqy>CcxWNMNzyb_6m?J87iOUs&d%;qK5Sw z9(dVwnzca2%!YMT&z@mcEW5yMi4oy$nYl6&v|gv9g=D)0=~V%>mK_`AslDMnn+3Kc|(_)5x@oGx0iZ2{IN+WMCMX<-E;sL-f(iQk|4T(k?59 z@8*ELw((3!BbspLZk~-s0Km$5aooQ-kFvbhu-1Z!CaZOeHFW~U=6gz#4m$v3U}nNu zHEGqLEUiGKg;a|8cA(7+38n&ggEW=Q+bDrMdmxVwfbk=P|4- zzm}r(wK)UnX6DDO;O$Y*ufdG~*IJ!XT?b`ZLiJl{pPA}ll(CeqhT7Iz=bV{Yrg2US zaKNh*+gF!4&w{788TSR;#OWkqBO=ZyA{4>BUB`M3zCO6Ur0f5q(`lq;pgae)-R{>X zn-q=`W})_G%)sMZT45Qv=9%$OJmTRizF*_lKiRMEw_ksrJ}gJtr~7aG_P)+H;0As^ z?!)}+LgdaFdy%}gUw>Zx<~Q_>KZ*JLnd$hKimoZ27Pa5pH zjbiDvXD_ ztBPEp(iAB$LNf#)EXBN;*SxUDP+W$d%H`jrj@EUv8a=|s}UzXYUl6zb4dFj9I_ zaf#xn3;?xPL+)=c6=jyW_NqghZ%>1HyHi(fyHMFEmWgf1ZNT-(KOcjnrFkU^G-=uKGmva*KVVt0zlR?AB2OK`d0o5nr^)#qS)(YyOqfDf|` zBGzm8G?ji#eM*({0T@aMS#Sc>y2@QpV`ZkWoRJKgEIYBPZfm<*A3nzlwBQ9~MlW?k zIWzVixz-0MvjHY)^~OoYlD4y9Jsd1wfMg`IxJy|EIJA!WYS>9qb(!w0)m~NR9qz}F zM!}~o$m!TxNvcQX!cni*sn#1AqG{z40x>dk98a!%e}k;FheN84Rx4A+vatj`ASFXA zq0q=xBCVyyqcT@S-!q4k$N;;|F_H9!6u>5bnq0PI)*LRk6jBG;5XvPp3#W-I*HmO8 z1^2KR9aLSy+%_aU{8o#V;ww~NuC_^nnO`StdBn^)uS2aDQHZL?QaFd%jeGocL%MK1 z!TY`;84+VVISc&=XA{h0@1Ctv;`;_ILi1o=O;AYok=2|fq&bfHT z%Jo?Dq4{q4m>+NFdb78`$?buWx$9P}oN?Va@t#XI6!Q&WyE3$JQ#=#xVs=!X3 zUTbA0w@-D1iqCFjZ@~AN1SE{1$XrqdeICL+0wIG+u~R9g*iDg;&yC9|AM9V$7ZxVykbw`GIJ_bg>r78prYA>SM51U-V+DXMMl zRB&%S!)(`rus|qj=9UG;xJXtA3|&~yO1VV{7psv)xol2MwR_moqe?L(kR`%jGIC%6SvafmO}vmce$(Vm1zAlzDoGU@GasIR$fL2oL+kNL{b@A z)MBp))Ys00`lfJLHrQds$Lc@V;t3;ULsfv=L@~Wn>`F*oU4VmQ@NjGEN>k^~(=s^| zgDFB738G>Q>JpA3l6<=lD?m1xVoG6i!3@P( zYnmYU!+AVAv6h1~egpqEeFiJ+ozN+{tU6Xf4M7boKqk8vM-`wlY=Pb`-r9dEsyvIm}y?t!NPp06eR2dtyMP zU~B1N>}*43GDpKL7SR9mgk) zDMTnjE25|jW0>E4jA4dB40pm?!y3vNnSqiOc4*bpFN&mDn2j-xI!lX2Kj+L&RSatu z&9QCF{DN?+(58}tFj6zJ(96mSTq0M>I!9t8tSYV(xftNeR1_m2M3BCndyt6$RjhKl zF%NJ1iv|n~KKy=^3P^^cD>9u%`O0NnLWV-v?pW~h$Z>Z91~;Q4W_nm!4E2ow2`qrQ z#z{H}x5Ef`uNawfRLE%YP>lj*oLhR?sOjWdA5tA3hYKG}>|bXK@{ugHqBUPw1w#)* zRs9#Z2r5FQl`f-O^gSaPv%+K&?NG)|^-@b}Q_59$Ub21vdXZXQoLTT}xtMkBBaox$ zvDI627rSALRHXKBBFTp-N)JB_unu_5{WRjJZ9c`=Xo!1_p%LXM;8i}yW$RdDO8p>h z8X84js==j2u*k9(5+N*9C$-nj2CO_YB4cG_1r}sx;YV;sk{XF|aVLnjPA$h$15I!z zfJ~dIZS7lWasrCJ0~FW9G+f2>rs&{sHB2M6NEh9|An}}luZfmheGI^D>}~5Mfr6wJ zWjqPSDkFB^D=R&23$3oFZt zs>4I-J`FcZ2@EouYEFR~MvUU;ky9$Zuga$ynU=}HBBaaB#vo)%sid2-Wc9Ea3jlMQ zynn+-h-=?hJ+ITsZrIt!f2nWZ?ng)9$ujed)x1vWJXi5Vimi}=^IY$b$K%n~FES2} zWFXAi!&}X_+`}0x=d9>(D;57mPklaEb@?)4<%)c)e8fa#D$W^Uf^;l>ru_!v(~S9F zfA`~DpWcr9UwkqfKZU+LzI^$^59il+zkM3+19a!u<8QUU_#^M!osrVjlr2*VS-Uj}K%%?HNO%PSjs0$RvRAjv z-Gp>$|DzwPF4YDxa~#M0e*1bp?rw6s8xvz?WU%V16fhpc{ATWayWNU=zvg&6&N<^$ zEw=J{W>dCjvby@OVDENCW!7_wKvHD5jY2p}{R5T6ti>TUPBr%e<=LVTZ{vWOl5!&k zI0y@+5@dz=a0iO3mQ0uBKwmwz8hDKHk~bg+%X5B=^0RA;C@L~R4sw>4d(s2SsHwDO zeYm^%Md3z{oUzubNx9HILbh4%UWQc8B8$}l7`4c^Ryy$dRc5ZNEg*zY+WwF$!lDM< zZs@9BsCZ$uWkniCg@UkCPXtFXQuNGME_h=bvs0H>41hs1$Et-m0+N{z@5`M9LdFYw zv2hWUkn*M@U;ok~&7GQm7Z;J)dQ+ z>=v>2ktB^OW?mqwHeJSE87q;4)m$xC03j{2v@7hZ$j?_c$reRXK`F5qWd- zu9fp#E5ks#VYrUNm|+QlZUs2^2C9%sreJD`l)N#6I+9iSK9E>e3y1=@#^|c!gU4ZJ zmQp5%9iveA*aWZ6JCWLW*jgkyHbZRAsSvZV=#>!d;2~tL4h*17m{~DY$p|epi5Dc? zGOCMe{-LDHj+E{NXgAv=GPC{At$cjU$H)3uMS<*r-;$PzkjYF)_&)hblF3-rl%-YF zUS}+%-) z`|WpJYyJ3mXEKo&PDjB>Lxtk?3i3}^)Sqz2+(GKwT= z=60!QhLkJL8L`$LOSm#Ohu)gAtEi*f%rujPDJd|+FmA)yG`bWUvAp1Z(o1?hSCDl2 zaI2ri%!usJVgp0wxE&nkRTpo@5Ec~5)zX&Y!bORBtgLb}7^?uw6#@6#?PfM?6JE=Q zb(ILG%EjKytvD}kb10QJ;{H&MF^=OHV*s{dRm%~|h%C{O!=2s?777&I1(YILic%6d zB}{Sw8C*5T4Tu>9S4DTlbs^Q;qk%vI4!05sDkIm-b>_-kt3Zp)l@sZnd3PMNTP1*- zsIq;%&@6WrS-2l;ZpRxq8B4W17NX}^EM+KjjB%LDYTr# zRBolD3R>tOTmZQ$xQ!(P$SerOK$IuZm69PWbzJvEnB(js%tIL~vfJm;E^ z^*Gl`6SMfvX&QxLh~O$_XkWff=Y-p3dRU&I^)}|5waY9Ys3<*lpdO*AOen=6e}jK# z_N&jo`ugL4{g3Y-Z?-;vH@?tr2D=|WzJL74HA5T+nz{jZk3TWH8uUL&gnsfWuPm1* zDdV*aZ^klq?1-^cA9Uz2I-3q%s&_-;$?^Z=Z>lZ#Y%9w8n4Jd<@L}4r2jPX@{CvT} z?Mjyl(bbRYE{flLKxSsj63ouW1JrT28+?r6wuH98ZcWxL?rPZK6 z8_0ah5MM;k%4|Pm?Sz?%PRK+t4vBLT@*%n@MQdkt`Qxe724;YP61T+Do{RCn z7QZf6F4Hj(2k+1@GmPP|QT-SI0Lwr$ztHEL*fMOhk(rz^l|rJ1epPFzk_Oi7`zjU! zfKo znli0$6|lFAQOUlLmU1a5S?WmMdCYVD5b+N@^EPjv?EAOFL*|e5orzVVmmFaO2Xb9X;iK4lng!`*8IzJp0idTD>6 zQMg|An?-eDGPE%U+Lrs9Kfj5@SE(yQv|fGrX5s<>(;VKM*7R@E&(q9~;~2yI7{_s2 zGvO>5Ze~W#%owF$H-np!(NUGLeTA?kR%%n|+M4waF}Luz8Prj~*}J8*9I*g|9dFhA zq8yd8iz?|*XC$YhO-^=BS5+#p%on$ea(g>><6G!;tQw&}rR6ZXW0)OdZ@wH1l>zQb zZLcwz7X~~{B?FAioS}%wDB*7%`k>2@PIt3ma6__tL^8CPjx4^J0hI!j0@95>x&Zq{ zc`vQWc4RvYyMvKA#$l;GANh={Xa$a$_2RBhT4Q>xP^_s8q-x8cHjObiLYWcs zJnP}gc8hBDb0H{&yk29#OM{ErP&uljFexKKxy}`4FdOb1;|BN`H&SDFF-@=4MXP^u zYx|g~7@^CT>s3ar#44R-)(9+lNxA8=Y>;9<5;RHf!yuMOvbIxIlAqapt&m%p`x$Pd zJKJHmLcAW(`SK<9FV|Wt;(B1r#$35ptjNf%jVUDtrK#GK>@B$GQ3U#iT;9Pn{o~ac|8Xab? zZdgrf*_D)}#}(hfx^s=i3bf`}E7a_92wvknZq6birXjWG<09f2c7W~^2Ef;0{v z1YkZGG{@MbH`ZEZr`qWgdr&M9fQnm``f6MvRhKqbwh zQVTjV1VTxxxFbh9L(;b6JZqUzC9ENoEi`0i&elUl?^J51-0!JwzxJ@A zJF?*AoC3Mrf?Q*abyO62Uj`zF(`eQN3JAFOmWlPckr|QiR3{-)1zfMS%xZ-V8ZwQv zB2{H(>I@+wX5_~?A8VcwGdP2>gTPkF3oEIXRzyKiE4gh-QIfy(mZF- zNFOwm7epD**CE&O*jMb~KdVIzeSEVd&iSrhaMdM^UJxWDnRm)q;6%6}r+U^y&$?A19(=f(3-j45n_4)hnzb``- z12d-6rB%C|SdWZlhTFJ*`gH&9yYFuIJ76>P_3KAbH2j@3SO~rJFE?W}Vam!RL1yWr zEOgRX?dU325fIRzir!LLZ>N#V7r7C$$o@OIgz_zC81=3h3 z$C5-wbZBddg?i*rvq-sMG-0hZSAR)#KMstw0wvJ0Es!mn7Q`4lj^h2%cS@*|v20pq z(##@yPrNsNWhfF-WGtbuJ(yFjslCe-!X6mdKKB8Pi3HP#P?bN&W;}pG8(U6r( z@_3JD`Z9wU6Bbcno~H9cC60g)g0*s@=(vwe*^6xmy^_hXiFlJ|>KbQMCUVYlcF3 zp7UJ!m}?cozvjAr%*@Jhqu5(X6fRwGMTIV83H>FnjW`TK77He1$`yNyR;Jd>R3x(2 zd7YkMx$2S11&S8(G!|^5#jmH%!^4!cnGuOAJ+~%QDvc$NV>MB}n}lDOFE1YKw`K38 z@cz6oUk8s>?n+nb@?h>3K5@s`_taR&sTj!kTS%;y?{7Q4GgQB3%(t>Z?Rfze(FdwvN1=cAd zLn|Xgb5-BIq{v+Tw<0ggk6{>=ZfRH*+5uo?`EVymce@!#SXrY)OD@~ynS`NjnYO_N zEWIp1mF~VEILh*{Oj|>|v^)?qWMYITcUJFIZ3B07)(4DwNTOQw&yxr1rOtesf)HwM~a(ahYnQiju-mV%$zpjSgL zK(N5}9;6A8TgTS5vkS1y+=*c@SC!sDjH7RumAROicJ9~)D-Xxr7L0N?D-~@C?>E)C zX3fl8p@^-?+j7e~drRV04_gVR44{0s4GN)XS;t&H*6ntX1dYWrqRIlJlEB@0_y7=5 z!Kj9nE5{itXC<0eY1Fsddy9;^nsU@VeR?aGYA<=elc9{~?D?OdaDH=<-crn?m z2E;N1V`GC^+!tjis!iTqi&>kQ)mWKXhv`Cm)%q#tTRa{esRkzRo;|u*@dq#b#)} zpD1qgLGy3IEPlBF*N2XmQhb$US}A5|+pZD~#HdaD3yi-Cw&LXnY1Yy;x7}~|U;o8# z|KhLy5{`&?swznlbDe9gb4F2KMfkYgj<@QGD+I5-!eIE7n>iRjXr zWtv-Q-E-7|#dMl^+)PywQY)lYCL0lwOi)^)*|Vr@*h^kyohGI}ORUcAtkeRtjky+e zpc3KQI@-!MtUhHjqPg$}RvvTTW+B@#Jl7Faj>TP}J2G*HSOwr-$(lWa*9^RtRD9~I zv||hnaB*7`J1ru~e4**KL@zrb1*0Jid+N#d6tcN^yzD|qDplb?jULk|kr?A}!%>|w z;lmE24?Z-8ZdS&P&1T&E&~3hvVQy3 zdZE{RoQ3a8{D#Xx+Q2R+_AVRnM zaZ;|>dDul_O@jvg=B!d@W}`C_6DX}CGOA1>0&6WBUUD91pj~*h&Y4izSxb>x5o;}E zGBPWwCo@*eiY{YwFKW?~bsxHW3?0gfW6VS-ot6mfmCY*?Ga<9#?gFC}ozlkGvL-ws z6mzXv2I=dt$opDnUBoel8>9-KsL3FaWu9Hwi#>_`*6kH(xi3$EMG%k7NQ^PE{3Ocl zDgYp$!HW_vrp6eAuQ>%}_}WlFqKUYjC0&kzy}hDSwR7#;SzIeL3PKegmvJ9{v}n{rdti-rjBz!C)p_j1X2t#8D5nJBKIYWsM*2=Xa11x838DtfG%4QtM z28UUAXcH8ghG!<}FmGyH1hD-zt;g|B_}p}f%ybsHCL@C8V~jZ`;KWMeFwcyPXxSPY zKbMLJUPY)o`)XZlW5nT^8l%|S%uKlN25Qy#T^x9jE43neztW3aTAgv`QU`D}HeyU5 zmF^Y_D2>I)Cy#FS6rTY{-!uVc-%Q@v97sg66M3psfZJ|F#l7NFlw9wy zZ;>MH(=NsBaU3P%8DrQn{_bD=%fI@Yzy9g*<coJTJveQ zBv=V{r}9*WuCc%{EN)|bx?v2tV{9^Wgxp5Gy`>bj07`ziDi_i*$l*pQa`r;DEwV~C zffc9HVn5E@QLE1jWY|IJ<*S1VS5z(pZVpc$v|wOCZ7$G9XH~*ssWC7NgAB-OWo}Y1 zL60NiNw{kO!1X8g88GU4Er9~6E>l_Hu3y#W_q^J~IV-6oq z?>pX;nRcD~FZ+=dD-mpFnWwTt6uF5A`zH6cp+(a)_q3b2s)wl;9vCz_2V`1WjZ;UN z!L5}u+oE7atw>6IUl~!zw&KYZr%zBOGbGCq1t~MQ(STuevb^-ukTW7y)rpyrYZ*0x z@@ghV9WFtxT(PNVnSd%s!6dZxbxXxC=mZp6g?POzF4vWmBLU^eyV`D;PFkiS@;Hv| zv%_J&vx(9GDioQDSWEQcAYSo2Z5sds(t?V_Z5Ww>r5sH*?u@!R<-u$-8thnHlm(vC z)nbFJz@Mc#=UREY-L6yYnuDtkFj}3pzK3^`!`xY=uqM~`m96Z?-9A(xM`xS%M6Sck z&141xP;Sn8&bxapFi8nUT@%KK>s;g`*k67_0HG+=+A#`aEP@*sk#-=*T={I@-P1F-~Eff zrw`f?(?*(EX>Br-oYx*FmQI}?=X}idnBg}o)1XkUwa)X5bH>iLWp?507Ft#TL^~P5 z>Unf$rhKr`Av7`309~Gwucu#yc^G=LS*?@#$ zob`Q-&R$EhmZGUT^=jc7xytW%5NDgLS5iQ>Z2-P;De#tQHV4OG0hw$mnLb%?LS~9t z;Y*G5m+++U&y*$9u7iwi@M6QDk$2sao+xc`Az@oL6_J^b_mATk^Eljnn3uRn1Tm6U znXToWlNi`Bf4gaGo`H~V4k5Hp4zz%Gqj6VGGbF+60$;JU2DU>0uY1+5UaDdH%5J$x zSP@y!8jQotSp4&hm1fzJQVJwX_ zQ!v69dzr{oZU}ea# zZ^vyI%q+x+IM4Y(5o@i}t3FXB_0G&Ipt}mZkp(!@a=&LufsE$Inyy5t6eAE(qJjp^ z>jQFHuWE}jw-L4dO*zJ>y;QXk0V@_^xhw3z48pig>CK*o9z=V8Z)!$FM6BdAr|B@W zambj!QgZL=Vx4o&xiSd}E8;x+lDu5qevgg$JZ+seIz$(303(7F9c8!(#ttn=O>iyA)}=e=iSWM-m#) zpgGmB3a`BM>&NWmMaRo;^P7g?brdc{2mKwd>7o7BfXY&?PVt|tzL(OyH>PV%x~)hX zevI3%fBRb-w=eHs(`tidYGo%HOpp-{dgz>IuAjcxxI?b*KhGoFea`vi%a=d=@WW3( z{q*ti5q&5Hd*QX6fy(c!Hlb`p(*TFpd?-R4&4+L{?_uKCc;)|Pon zFjp)TvnYe=+*mes9m84s;j-+@L^7??7y+Or`;5pr=Q(4}S@>Od&v+=8>cptb;R^Lb zRyR{~6`C7TVa!Pm?2)-G0xLfkl}i`|Mmr8w^cfXdNr{wNFfSl!qm9X;CY_))Yp=&CwvlgUk#3Tquk4-{@8WawPA11?+6glY~}kBqcr*$Xql z8MH(@{ET6_2Hlst`Jg9<>^3@4Q;HO3AnV4hILb(*XgJKH7yYp^g%K;xTFHmjia@)G z)I(|o9e1CR{piaj<)#5=KgE4>ULVD#^Y(}LvH+(0@MBmF6#Lw6Md+@;Sv#oy^s6UB zDe?rW_}}#pIBHTgUOIU$(Wdx$#j2nL+!^dI35*!h)L(H}N+zV{tLhZ{A+v{_2 zFH^0W&R@owECUKNqR510V;qIGyL%Wa>%GNJWx^71p6i^C8NCQ7>W8GFArA8$1zE_| zOt_GU$keK=UNf4UUa?d+A2~`|U#GUU>26EVn?*JV2Yfg!1`kpj%yu)Y0^F;j%(YS9 zj)-|?KU5hJGH!qrPSctue0sZozTf`)k3U4TB40goW{TEv7;rEY^^NtcvxQ1M%iAl_ z`P#EyH4l3&`f@?5Q+Tdp3k`9gcvU;E2Ug5D%Aw}p?&+UIVyAdKkDy=px+dV=z}odV zzW$llN&U~3UArchYf)5{fNsbAey%lcx4-$Dzq!5LfB(ZDL?km5u{up@KZDnPpCmK# zJl79@_-Q@X$4@^V!%3d!`To&gmngHOkR`gv?bgGj+hN|$=MfVyl&CTBPscU#;mQ)s# z*`SnMX)ej#Lrvx?gO1{$#99$tE62#?@DUCMWPaH2k+(93H_DN4V_#&yV3K<48_Rh5 za6G%ctSw-)b4a#zzP92qqdcos@E)syMde#o5Kxq7R%E#)W@g_5bw~~y>?II#WoXT{ zqAnDzLcdmG7J*5n-z`m%uM8m-F)e&)STxgim>G_nyW=>H>2r>8j57VoSPH3v17;25 ztt~7w^90ehp@Knx3r5K3F}N`qO#LFkuMie8u0pQb`mXyJ@6vTEs+Pwf&iw$WS>5Nw)^pQJ|?x? zmSL6r6Y1T(KlQ}dtb?7Ny&JE#H|+0n6|?=1wRkCe2fTe$j0B>O;EmGkQxXO_RR`)Y z90ZZYj@*$%?0FnJ8~KVMYF_y-%&$L##QF03HPP?L->VXDB1TX7&lmJdTSZ2txJVFg z$0v6`NO%A4H^2E<@zcjopFZ6`&iAseBx!J(wh?BXg57j0^5f%Uo#zj~k5OueEekAp z(3~^&!Mz74Dbi#H`eBrtI$xH^qRelwfndgpwPL;GH}ATo8Zb@r4onuLj0uD1I9K@N zk(rUcGL9UZ7TXulvF&Mdle87Zj4P+6IU|Cximz#9$R{l+3@PL&&)dzO?US-ZD@xQB zQZ2IH@!ActR_K@c$kgtolI#cJ0c}AHol3tnFHGS6QvvSx>Mz+gile`lZ=njC)^2uFF zQz|th2$?1TH@I^g=5ELGabT>x4W6#y^{G}HV}VM?(OT_p5LW1>Nx6cNIu|}3^NIT! zyla(j>oMCOmlfz0xOy*1DuC`smq zIJ5;!{kN2oW<>8LM2V>c+p+#?Ofp+(M|+V`?yYmDpKR{VhIHuec<#eW1?j~)&Rr#% z+-?LiwIWwh!1i}Pyqb4&_rs4d#t=d)9sq6DXN+Ga&+f~po z1`P_x6WeB`Mpzwm_mUS|-=r|(ZTRhWyxqoe_;4M!akve$?b6}}!8HvGpiJ0a8c(#r-AjGkwDv!)zOTRetg$b; z;nzX=&woiTJ0vvZUZaCDj{6(kK0ZDeD-)0TAqA-6NBx*It+lwR64F)hm}@0aZAI?1Y=1;s3(jkcUq*j)CXQIpS1T? zT5CPPh*)dHJtB@R_oyz~W#o=AV85$kyecAM=2|&d&RA+s{c9~3Qqr<){+fLa(uz&8 zho#+0m@Id0lOYG6aPb(UrD6@PqbY=5CCUsaGwJ%gQKs)zQ4$Y*k{I9JYv`p6A|F`7u0qGd7#1eCNyu25hpETGu4 zBip(<86kwr0;n6MeA(RS&XF{qBVq)P12b@pJgj65(kidqa#ziofB{5H4^psLI#YAT zob!xKZC;GkTm>|43~Y8wlFE){6sgjdu{e56g?$U7axZtU9_8BcWAiaDw(rwm*sNWw zc%5LnNK~)QdLbo}#^W*j?z@nOf~(8ysel^*$T4snX2y~Nr69RmR%%!^mAS*KxL0f5 zSai=0nH|5q4=)q3TNhDUO+HX&;ll$gdPW7HmODubLF;2)*8o?W@JlxZxLeOGXi54g zcQd-cOj}Vb$qLcz&0^VFs2^0XP>wO|I1V2?hTm?taXZGXT3B0vu+P+4u88JZ@1%c95=s> zYWzsjIKX6a^h2R>9C@yMtT-bh!lIZ{DBFr&SNI_58knM)KF(u|_b*@985TU+52SAZ zf??5)%A3%{Y;QB{Gp*APc#SD9;^6&*Z_?mv!}G>i_;65Ma8sU6*z)VJxkj z5i!C>jFmp-yu2XXkK;JppD=#y#3GT2x$<0^GtL>0HCL3YzSf$vrIf`O%2B~39m4Q@ zdfMx>XozOp2BoN~X_W5`h4q4e?-I5q5w$AL?cmye{$k2hwm-E@pS64TGVD-FRd(lj zp67YaRUdvkaU(g*AWJQhMEq)gBIX$p63l(Aj1gn`2#ou1nxH5TmU1kJ#kEjqf2a}&n3==OHz-m-W{1cn>: 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

y!#cTpbuoMA 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

JBEx!unS$f!EB^lIulplAPt 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 GyZ-}j3EMRQ literal 39467 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%0DcYx|b;=|aMcQcJ zQK6(w(!M^&C-;4SzpvNxA3XPO_jO&eb7aFR3>_vUh+OsX|0|HK|~1r+T`w{yBYpCRZbP8+#NKs_1G6EV@5V zms1YXg{Dw@KNPfiXxV9LZ~kP)h}2_SoFD0E0X70kCylYrH3bvlSV~dOrSE=F zLS4GF%jSq$p%9_nvaV21686Q0BgjHjwbd&Jyh&Eb!?cLJ-O|#PWo5Ui+~zoFLreIU zT29N0v!xFwg+x$e1tb(DGoQ zG?=x1Pt$*~Cm*qXtY>IXQ5K-s-Fv1DAukm?G_Rs^+|rf~Ee!#YBniI)b9;3E;jON> z^@7|sELpzyN$9NR?2quSIj46dYW1HxDlv5vikAHn_Z^f|-#){7W0J`#*4o&rq?6kL


@+Y(#@b;R!y5sQO~ko_q1)`$ccPJSKm| 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 Date: Sun, 14 Apr 2024 03:23:31 +0800 Subject: [PATCH 427/503] Add support for small window/screen/big font size to the help feature --- src/main/java/classify/ui/UI.java | 65 ++++++++++++++++--------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 6cc14b8948..b69b3d7854 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -114,72 +114,73 @@ public static void printHelp() { System.out.println(""); printUnarchiveHelpMessage(); System.out.println(""); - printProcessTextFileInputMessage(); + printProcessTextFileHelpMessage(); System.out.println(""); printHelpHelpMessage(); } private static void printHelpHelpMessage() { - System.out.println("help Prints this help message"); + System.out.println("help\n Prints this help message"); } private static void printSortHelpMessage() { - System.out.println("sort Sorts the student list by the input parameter, expects an" + - " attribute to sort by, can be used directly by sort [type]."); - System.out.println(" Currently available types: name, classes, payment"); + System.out.println("sort\n Sorts the student list by the\n input parameter, expects an" + + " attribute\n to sort by," + + "\n can be used directly by sort [type]."); + System.out.println(" Currently available types:\n Name\n Classes\n Payment"); } private static void printRestoreHelpMessage() { - System.out.println("restore Restore a student deleted within the current session, expects" + - " a name, can be used directly by restore [name]."); + System.out.println("restore\n Restore a student deleted within the\n current session, expects" + + " a name,\n can be used directly by restore [name]."); } private static void printUndoHelpMessage() { - System.out.println("undo Restores the last student deleted in the current session."); + System.out.println("undo\n Restores the last student deleted\n in the current session."); } private static void printArchiveHelpMessage() { - System.out.println("archive " + - "Removes the specified student from the list and archives them, can be used directly by archive" + - " [name]."); + System.out.println("archive\n " + + "Removes the specified student from\n the list and archives them," + + "\n expects a name, can be used directly by\n archive [name]."); } private static void printUnarchiveHelpMessage() { - System.out.println("unarchive " + - "Removes the specified student from the archive and adds them to the list, can be used directly by" + - " unarchive [name]."); + System.out.println("unarchive\n " + + "Removes the specified student from the\n archive and adds them to the list," + + "\n expects a name, can be used directly by\n unarchive [name]."); } //@@ author Cryolian private static void printByeHelpMessage() { - System.out.println("bye Exits Classify"); + System.out.println("bye\n Exits Classify"); } private static void printListHelpMessage() { - System.out.println("list Displays the list of all students"); - System.out.println(" Currently available types: Whole student list, with " + - "with total classes attended, with phone number, "); - System.out.println(" the archived list, the recently deleted list or " + - "by certain subject only."); + System.out.println("list\n Displays the list of all students"); + System.out.println(" Currently available types:\n Whole student list" + + "\n With total classes attended\n With phone number, "); + System.out.println(" The archived list\n The recently deleted list" + + "\n By certain subject only."); } private static void printDeleteHelpMessage() { - System.out.println("delete Deletes a student from the student list, expects a name" + - ", can be used directly with a name e.g. add [name]"); + System.out.println("delete\n Deletes a student from the student list,\n expects a name," + + "\n can be used directly with a name\n e.g. add [name]"); } private static void printViewHelpMessage() { - System.out.println("view Views a students details, expects a name" + - ", can be used directly with a name e.g. add [name]"); + System.out.println("view\n Views a students details, expects a name," + + "\n can be used directly with a name\n e.g. add [name]"); } private static void printEditHelpMessage() { - System.out.println("edit Edits a students details, expects a name" + - ", can be used directly with a name e.g. edit [name]"); + System.out.println("edit\n Edits a students details, expects a name," + + "\n can be used directly with a name\n e.g. edit [name]"); } private static void printAddHelpMessage() { - System.out.println("add Adds a student to the student list, " + - "expects a name, grade and lessons attended e.g. add [name]"); + System.out.println("add\n Adds a student to the student list," + + "\n expects a name, grade and lessons attended\n e.g. add [name]"); } //@@author ParthGandhiNUS @@ -206,10 +207,10 @@ public static void printEndConversation() { printDivider(); } - public static void printProcessTextFileInputMessage() { - System.out.println("process " + - "Processes a text file containing a list of students taking the same subject and the same number " + - "of classes."); + public static void printProcessTextFileHelpMessage() { + System.out.println("process\n " + + "Processes a text file containing\n a list of students" + + "\n taking the same subject and the\n same number of classes."); } //@@author blackmirag3 From 12db8a5a4ffb2a168a4b4b21a767c181115491cf Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sun, 14 Apr 2024 03:27:03 +0800 Subject: [PATCH 428/503] Reformat code to make it more readable --- src/main/java/classify/ui/UI.java | 87 ++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 29 deletions(-) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index b69b3d7854..de2cc704e9 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -120,67 +120,94 @@ public static void printHelp() { } private static void printHelpHelpMessage() { - System.out.println("help\n Prints this help message"); + System.out.println("help" + + "\n Prints this help message"); } private static void printSortHelpMessage() { - System.out.println("sort\n Sorts the student list by the\n input parameter, expects an" + - " attribute\n to sort by," + + System.out.println("sort\n Sorts the student list by the" + + "\n input parameter, expects an attribute" + + "\n to sort by," + "\n can be used directly by sort [type]."); - System.out.println(" Currently available types:\n Name\n Classes\n Payment"); + System.out.println(" Currently available types:" + + "\n Name" + + "\n Classes" + + "\n Payment"); } private static void printRestoreHelpMessage() { - System.out.println("restore\n Restore a student deleted within the\n current session, expects" + - " a name,\n can be used directly by restore [name]."); + System.out.println("restore" + + "\n Restore a student deleted within the" + + "\n current session, expects a name," + + "\n can be used directly by restore [name]."); } private static void printUndoHelpMessage() { - System.out.println("undo\n Restores the last student deleted\n in the current session."); + System.out.println("undo" + + "\n Restores the last student deleted" + + "\n in the current session."); } private static void printArchiveHelpMessage() { - System.out.println("archive\n " + - "Removes the specified student from\n the list and archives them," + - "\n expects a name, can be used directly by\n archive [name]."); + System.out.println("archive" + + "\n Removes the specified student from" + + "\n the list and archives them," + + "\n expects a name, can be used directly by" + + "\n archive [name]."); } private static void printUnarchiveHelpMessage() { - System.out.println("unarchive\n " + - "Removes the specified student from the\n archive and adds them to the list," + - "\n expects a name, can be used directly by\n unarchive [name]."); + System.out.println("unarchive" + + "\n Removes the specified student from the" + + "\n archive and adds them to the list," + + "\n expects a name, can be used directly by" + + "\n unarchive [name]."); } //@@ author Cryolian private static void printByeHelpMessage() { - System.out.println("bye\n Exits Classify"); + System.out.println("bye" + + "\n Exits Classify"); } private static void printListHelpMessage() { - System.out.println("list\n Displays the list of all students"); - System.out.println(" Currently available types:\n Whole student list" + - "\n With total classes attended\n With phone number, "); - System.out.println(" The archived list\n The recently deleted list" + + System.out.println("list" + + "\n Displays the list of all students"); + System.out.println(" Currently available types:" + + "\n Whole student list" + + "\n With total classes attended" + + "\n With phone number, "); + System.out.println(" The archived list" + + "\n The recently deleted list" + "\n By certain subject only."); } private static void printDeleteHelpMessage() { - System.out.println("delete\n Deletes a student from the student list,\n expects a name," + - "\n can be used directly with a name\n e.g. add [name]"); + System.out.println("delete" + + "\n Deletes a student from the student list," + + "\n expects a name," + + "\n can be used directly with a name" + + "\n e.g. add [name]"); } private static void printViewHelpMessage() { - System.out.println("view\n Views a students details, expects a name," + - "\n can be used directly with a name\n e.g. add [name]"); + System.out.println("view" + + "\n Views a students details, expects a name," + + "\n can be used directly with a name" + + "\n e.g. add [name]"); } private static void printEditHelpMessage() { - System.out.println("edit\n Edits a students details, expects a name," + - "\n can be used directly with a name\n e.g. edit [name]"); + System.out.println("edit" + + "\n Edits a students details, expects a name," + + "\n can be used directly with a name" + + "\n e.g. edit [name]"); } private static void printAddHelpMessage() { - System.out.println("add\n Adds a student to the student list," + - "\n expects a name, grade and lessons attended\n e.g. add [name]"); + System.out.println("add" + + "\n Adds a student to the student list," + + "\n expects a name, grade and lessons attended" + + "\n e.g. add [name]"); } //@@author ParthGandhiNUS @@ -208,9 +235,11 @@ public static void printEndConversation() { } public static void printProcessTextFileHelpMessage() { - System.out.println("process\n " + - "Processes a text file containing\n a list of students" + - "\n taking the same subject and the\n same number of classes."); + System.out.println("process" + + "\n Processes a text file containing" + + "\n a list of students" + + "\n taking the same subject and the" + + "\n same number of classes."); } //@@author blackmirag3 From d255111c29a4913507300fdaa5d9e6c5d4ecc921 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sun, 14 Apr 2024 03:37:20 +0800 Subject: [PATCH 429/503] Update alalal47.md and UG to reflect latest version of help function --- docs/UserGuide.md | 88 +++++++++++++++++++++++++++++++++++-------- docs/team/alalal47.md | 10 ++++- 2 files changed, 81 insertions(+), 17 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index aa018c6f7f..fe69a4ec45 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -634,21 +634,79 @@ Format: `help` #### Example usage: ``` help -add Adds a student to the student list, expects a name, grade and lessons attended, can be used directly with a name e.g. add [name] -edit Edits a students details, expects a name, can be used directly with a name e.g. edit [name] -view Views a students details, expects a name, can be used directly with a name e.g. add [name] -delete Deletes a student from the student list, expects a name, can be used directly with a name e.g. add [name] -restore Restore a student deleted within the current session, expects a name, can be used directly by restore [name]. -undo Restores the last student deleted in the current session. -list Displays the list of all students - Currently available types: Whole student list, with total classes attended, with phone number, the archived list, the recently deleted list or by certain subject only. -bye Exits Classify -sort Sorts the student list by the input parameter, expects an attribute to sort by, can be used directly by sort [type]. - Currently available types: name, classes, payment -archive Removes the specified student from the list and archives them, can be used directly by archive [name]. -unarchive Removes the specified student from the archive and adds them to the list, can be used directly by unarchive [name]. -process Processes a text file containing a list of students taking the same subject and the same number of classes. -help Prints this help message +add + Adds a student to the student list, + expects a name, grade and lessons attended + e.g. add [name] + +edit + Edits a students details, expects a name, + can be used directly with a name + e.g. edit [name] + +view + Views a students details, expects a name, + can be used directly with a name + e.g. add [name] + +delete + Deletes a student from the student list, + expects a name, + can be used directly with a name + e.g. add [name] + +restore + Restore a student deleted within the + current session, expects a name, + can be used directly by restore [name]. + +undo + Restores the last student deleted + in the current session. + +list + Displays the list of all students + Currently available types: + Whole student list + With total classes attended + With phone number, + The archived list + The recently deleted list + By certain subject only. + +bye + Exits Classify + +sort + Sorts the student list by the + input parameter, expects an attribute + to sort by, + can be used directly by sort [type]. + Currently available types: + Name + Classes + Payment + +archive + Removes the specified student from + the list and archives them, + expects a name, can be used directly by + archive [name]. + +unarchive + Removes the specified student from the + archive and adds them to the list, + expects a name, can be used directly by + unarchive [name]. + +process + Processes a text file containing + a list of students + taking the same subject and the + same number of classes. + +help + Prints this help message ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` diff --git a/docs/team/alalal47.md b/docs/team/alalal47.md index 228a31fdd4..2b9349adb7 100644 --- a/docs/team/alalal47.md +++ b/docs/team/alalal47.md @@ -33,9 +33,12 @@ all Tuition Centres can employ for ease of student management. - Prevents invalid inputs in the data file from crashing Classify. - Does not allow the user to resume use of Classify before the file is deleted, or the corruption is rectified. + - **Feature: Create and maintain the help function** + - Ensures users do not have to bring up the UG at every instance, they can instead refer to the help function for a quick guide on how to use all features. + - #### Contributions to the [UG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/UserGuide.md) - - Wrote the Usage guide for the edit, delete, restore, undo and sort features. + - Wrote the Usage guide for the help, edit, delete, restore, undo and sort features. - #### Contributions to the [DG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/DeveloperGuide.md) - Wrote the instructions for manual testing. @@ -48,4 +51,7 @@ all Tuition Centres can employ for ease of student management. - #### Review/mentoring contributions - **Links to some PRs reviewed** - [PR1](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/148) - - [PR2](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/164) \ No newline at end of file + - [PR2](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/164) + +- #### Contributions beyond the project team + - Participated in a mutual debugging session with T13-4 link to GitHub [Discussion](https://github.com/orgs/AY2324S2-CS2113-T13-4/discussions/256) \ No newline at end of file From 8f30d57538fa516d12d84bba88bbc3e9b47f03f8 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sun, 14 Apr 2024 11:32:39 +0800 Subject: [PATCH 430/503] Fix typos and junit --- src/main/java/classify/ui/UI.java | 32 ++--- .../java/classify/user/InputParsingTest.java | 118 +++++++++++------- 2 files changed, 90 insertions(+), 60 deletions(-) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index de2cc704e9..e3fe36ddd2 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -93,29 +93,29 @@ public class UI { */ public static void printHelp() { printAddHelpMessage(); - System.out.println(""); + System.out.println(); printEditHelpMessage(); - System.out.println(""); + System.out.println(); printViewHelpMessage(); - System.out.println(""); + System.out.println(); printDeleteHelpMessage(); - System.out.println(""); + System.out.println(); printRestoreHelpMessage(); - System.out.println(""); + System.out.println(); printUndoHelpMessage(); - System.out.println(""); + System.out.println(); printListHelpMessage(); - System.out.println(""); + System.out.println(); printByeHelpMessage(); - System.out.println(""); + System.out.println(); printSortHelpMessage(); - System.out.println(""); + System.out.println(); printArchiveHelpMessage(); - System.out.println(""); + System.out.println(); printUnarchiveHelpMessage(); - System.out.println(""); + System.out.println(); printProcessTextFileHelpMessage(); - System.out.println(""); + System.out.println(); printHelpHelpMessage(); } @@ -175,10 +175,10 @@ private static void printListHelpMessage() { System.out.println(" Currently available types:" + "\n Whole student list" + "\n With total classes attended" + - "\n With phone number, "); + "\n With phone number"); System.out.println(" The archived list" + "\n The recently deleted list" + - "\n By certain subject only."); + "\n By certain subject only"); } private static void printDeleteHelpMessage() { @@ -186,14 +186,14 @@ private static void printDeleteHelpMessage() { "\n Deletes a student from the student list," + "\n expects a name," + "\n can be used directly with a name" + - "\n e.g. add [name]"); + "\n e.g. delete [name]"); } private static void printViewHelpMessage() { System.out.println("view" + "\n Views a students details, expects a name," + "\n can be used directly with a name" + - "\n e.g. add [name]"); + "\n e.g. view [name]"); } private static void printEditHelpMessage() { diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index e1cbca2edc..8eece9cf7b 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -141,50 +141,80 @@ public void testHelpCommand() { System.setOut(System.out); String printedOutput = outputStream.toString().trim(); - String expectedOutput = - "add Adds a student to the student list, expects a name" + - ", grade and lessons attended e.g. add [name]" - + System.lineSeparator() + System.lineSeparator() + - "edit Edits a students details, expects a name" + - ", can be used directly with a name e.g. edit [name]" - + System.lineSeparator() + System.lineSeparator() + - "view Views a students details, expects a name" + - ", can be used directly with a name e.g. add [name]" - + System.lineSeparator() + System.lineSeparator() + - "delete Deletes a student from the student list, expects a name" + - ", can be used directly with a name e.g. add [name]" - + System.lineSeparator() + System.lineSeparator() + - "restore Restore a student deleted within the current session, expects a name, " + - "can be used directly by restore [name]." - + System.lineSeparator() + System.lineSeparator() + - "undo Restores the last student deleted in the current session." - + System.lineSeparator() + System.lineSeparator() + - "list Displays the list of all students" - + System.lineSeparator() + - " Currently available types: Whole student list, with " + - "with total classes attended, with phone number, " - + System.lineSeparator() + - " the archived list, the recently deleted list or " + - "by certain subject only." - + System.lineSeparator() + System.lineSeparator() + - "bye Exits Classify" - + System.lineSeparator() + System.lineSeparator() + - "sort Sorts the student list by the input parameter, expects an" + - " attribute to sort by, can be used directly by sort [type]." - + System.lineSeparator() + - " Currently available types: name, classes, payment" - + System.lineSeparator() + System.lineSeparator() + - "archive Removes the specified student from the list and archives them," + - " can be used directly by archive [name]." - + System.lineSeparator() + System.lineSeparator() + - "unarchive Removes the specified student from the archive and adds them to the list" + - ", can be used directly by unarchive [name]." - + System.lineSeparator() + System.lineSeparator() + - "process Processes a text file containing a list of students taking the same"+ - " subject and the same number of classes." - + System.lineSeparator() + System.lineSeparator() + - "help Prints this help message" + - System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; + String expectedOutput = "add" + "\n" + + " " + "Adds a student to the student list," + "\n" + + " " + "expects a name, grade and lessons attended" + "\n" + + " " + "e.g. add [name]" + System.lineSeparator() + + System.lineSeparator() + + "edit" + "\n" + + " " + "Edits a students details, expects a name," + "\n" + + " " + "can be used directly with a name" + "\n" + + " " + "e.g. edit [name]" + System.lineSeparator() + + System.lineSeparator() + + "view" + "\n" + + " " + "Views a students details, expects a name," + "\n" + + " " + "can be used directly with a name" + "\n" + + " " + "e.g. view [name]" + System.lineSeparator() + + System.lineSeparator() + + "delete" + "\n" + + " " + "Deletes a student from the student list," + "\n" + + " " + "expects a name," + "\n" + + " " + "can be used directly with a name" + "\n" + + " " + "e.g. delete [name]" + System.lineSeparator() + + System.lineSeparator()+ + "restore" + "\n" + + " " + "Restore a student deleted within the" + "\n" + + " " + "current session, expects a name," + "\n" + + " " + "can be used directly by restore [name]." + System.lineSeparator() + + System.lineSeparator() + + "undo" + "\n" + + " " + "Restores the last student deleted" + "\n" + + " " + "in the current session." + System.lineSeparator() + + System.lineSeparator() + + "list" + "\n" + + " " + "Displays the list of all students" + System.lineSeparator() + + " " + "Currently available types:" + "\n" + + " " + "Whole student list" + "\n" + + " " + "With total classes attended" + "\n" + + " " + "With phone number" + System.lineSeparator() + + " " + "The archived list" + "\n" + + " " + "The recently deleted list" + "\n" + + " " + "By certain subject only" + System.lineSeparator() + + System.lineSeparator() + + "bye" + "\n" + + " " + "Exits Classify" + System.lineSeparator() + + System.lineSeparator() + + "sort" + "\n" + + " " + "Sorts the student list by the" + "\n" + + " " + "input parameter, expects an attribute" + "\n" + + " " + "to sort by," + "\n" + + " " + "can be used directly by sort [type]." + System.lineSeparator() + + " " + "Currently available types:" + "\n" + + " " + "Name" + "\n" + + " " + "Classes" + "\n" + + " " + "Payment" + System.lineSeparator() + + System.lineSeparator() + + "archive" + "\n" + + " " + "Removes the specified student from" + "\n" + + " " + "the list and archives them," + "\n" + + " " + "expects a name, can be used directly by" + "\n" + + " " + "archive [name]." + System.lineSeparator() + + System.lineSeparator() + + "unarchive" + "\n" + + " " + "Removes the specified student from the" + "\n" + + " " + "archive and adds them to the list," + "\n" + + " " + "expects a name, can be used directly by" + "\n" + + " " + "unarchive [name]." + System.lineSeparator() + + System.lineSeparator() + + "process" + "\n" + + " " + "Processes a text file containing" + "\n" + + " " + "a list of students" + "\n" + + " " + "taking the same subject and the" + "\n" + + " " + "same number of classes." + System.lineSeparator() + + System.lineSeparator() + + "help" + "\n" + + " " + "Prints this help message" + System.lineSeparator() + + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; assertEquals(expectedOutput.trim(), printedOutput); } From ef35ec36ffa6c566b281091fb71c9b83febf0b53 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 11:39:49 +0800 Subject: [PATCH 431/503] Edit Test Case to remove empty directory which is created --- src/test/java/classify/textfilecode/TextFileReaderTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/classify/textfilecode/TextFileReaderTest.java b/src/test/java/classify/textfilecode/TextFileReaderTest.java index 8984eb1855..c38840d8da 100644 --- a/src/test/java/classify/textfilecode/TextFileReaderTest.java +++ b/src/test/java/classify/textfilecode/TextFileReaderTest.java @@ -19,11 +19,13 @@ public void testPrintCurrentInputFolderWhenEmpty() { System.setOut(new PrintStream(outContent)); TextFileHandler.createTextFileDirectory(VALID_FILE_DIRECTORY); - + File currentDir = new File (VALID_FILE_DIRECTORY); TextFileReader.printCurrentInputFolder(VALID_FILE_DIRECTORY); assertEquals("No files in your Input Folder!\n" + "Please add some new files in the correct format!", outContent.toString().trim()); + + currentDir.delete(); } @Test From 98744a5970aa83c9d82329c4f979563d8ceb02cc Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 11:40:25 +0800 Subject: [PATCH 432/503] Add more test cases for TextFileParser --- .../classify/textfilecode/TextFileParser.java | 3 +- .../textfilecode/TextFileParserTest.java | 36 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index ce5b860744..c4bcaaf7ed 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -36,6 +36,7 @@ public class TextFileParser { private static final String CLASSES_ATTENDED_REGEX = ": "; private static final String INVALID_PHONE_NUMBER_MESSAGE="'s phone number is not a valid Singapore phone number." + " Please edit this students' phone number with the edit command!"; + private static final String EXIT_INTERFACE = "Exiting interface."; /** * Boolean that checks for the filetype of the files. @@ -86,7 +87,7 @@ public static void parseUserSelection(File currentDirectory, Scanner in, ArrayLi if (matchIndex == -1) { System.out.println(NO_MATCH_FOUND); - System.out.println("Exiting interface"); + System.out.println(EXIT_INTERFACE); return; } parseTextFile(fileList, matchIndex, masterStudentList); diff --git a/src/test/java/classify/textfilecode/TextFileParserTest.java b/src/test/java/classify/textfilecode/TextFileParserTest.java index 5e38c8d4cf..699d977d13 100644 --- a/src/test/java/classify/textfilecode/TextFileParserTest.java +++ b/src/test/java/classify/textfilecode/TextFileParserTest.java @@ -23,6 +23,42 @@ class TextFileParserTest { public static final Integer MATH_CLASSES = 10; private static final String INVALID_PHONE_NUMBER_MESSAGE="'s phone number is not a valid Singapore phone number." + " Please edit this students' phone number with the edit command!"; + private static final String VALID_TEXT_FILE = "File.txt"; + private static final String INVALID_TEXT_FILE = "File"; + private static final String FILE_SELECTION_PROMPT = "Please enter the exact name of the file " + + "you'd like to process:"; + private static final String REQUEST_TO_TRY_AGAIN = "Please try again!"; + + @Test + public void testTextFileCheckerValidCase() { + assertTrue(TextFileParser.textFileChecker(VALID_TEXT_FILE)); + } + + @Test + public void testTextFileCheckerInvalidCase() { + assertFalse(TextFileParser.textFileChecker(INVALID_TEXT_FILE)); + } + + @Test + public void testPromptForFileSelection(){ + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + + TextFileParser.promptForFileSelection(); + + assertEquals(FILE_SELECTION_PROMPT, outContent.toString().trim()); + } + + @Test + public void testPromptForFileSelectionAgain(){ + ByteArrayOutputStream outContent = new ByteArrayOutputStream(); + System.setOut(new PrintStream(outContent)); + + TextFileParser.promptForFileSelectionAgain(); + + assertEquals((REQUEST_TO_TRY_AGAIN + System.lineSeparator() + + FILE_SELECTION_PROMPT).trim(), outContent.toString().trim()); + } @Test public void testAddPhoneNumberValidCase() { From 27b8236118c27ec0f9e8029d4146f26411abb892 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sun, 14 Apr 2024 11:40:54 +0800 Subject: [PATCH 433/503] Update UG with fixed typos in help function --- docs/UserGuide.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index fe69a4ec45..a89c3a2c12 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -647,13 +647,13 @@ edit view Views a students details, expects a name, can be used directly with a name - e.g. add [name] + e.g. view [name] delete Deletes a student from the student list, expects a name, can be used directly with a name - e.g. add [name] + e.g. delete [name] restore Restore a student deleted within the @@ -669,10 +669,10 @@ list Currently available types: Whole student list With total classes attended - With phone number, + With phone number The archived list The recently deleted list - By certain subject only. + By certain subject only bye Exits Classify From 6b0df3c7ba26f6cfcab58b08c65cfc571eb22b04 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 12:54:24 +0800 Subject: [PATCH 434/503] Update DG --- docs/DeveloperGuide.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 90159df513..d9656a459f 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -10,7 +10,7 @@ - [AddStudent Component](#addstudent-component) - [StudentSorter Component](#studentsorter-component) - [Data Commands Component](#data-commands-component) - - [Process Componenent](#process-component) + - [Process Component](#process-component) - [Project Scope](#product-scope) - [User Stories](#user-stories) - [Non-Functional Requirements](#non-functional-requirements) @@ -220,7 +220,12 @@ The two text files are will be created under a directory called data, in which t ![DataStoringObjectDiagramUML](./diagrams/src/DataStoring/ObjectDiagram.png) ### Process Component -This section refers to `TextFileHandler.java`, `TextFileParser.java`, and `TextFileReader.java` classes. +This section refers to `TextFileHandler.java`, `TextFileParser.java`, and `TextFileReader.java` classes. It ensures that we are able to put new files in the folder in data which is named Input Folder. + +#### Design Considerations + +#### Implementation and Rationale + --- From 8944de8da37d69e22c8c5476343574174859f63b Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 12:54:37 +0800 Subject: [PATCH 435/503] Update UG --- docs/UserGuide.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index fe69a4ec45..6ef0820dfe 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -526,7 +526,10 @@ Sort complete! ### Process a list of students from a text file `process` Reads a text file in the inputFolder folder located inside the data folder. -The text file which is being processed **MUST** follow the format shown here[insert stuff here]. +> The text file which is being processed **MUST** follow the format shown here in the [SampleFile.txt](./SampleFile.txt) +> You can change the subject name, classes attended, name, phone number and grades of the student. When doing so, please follow the given format below. + +![Text File Format](./Text%20File%20Format%20Picture.jpg) Format: `process`, press enter, `filename` (without filetype) **or** `filename.txt` (with file extension) @@ -559,8 +562,9 @@ shui hon ~~ 91231234 ~~ 99.0 ``` process Current Files in your Input Folder: -1. mathclass.txt -2. scienceclass.txt +1. SampleFile.txt +2. mathclass.txt +3. scienceclass.txt Please enter the exact name of the file you'd like to process: mathclass @@ -572,8 +576,9 @@ Fetching the data from mathclass.txt. ``` process Current Files in your Input Folder: -1. mathclass.txt -2. scienceclass.txt +1. SampleFile.txt +2. mathclass.txt +3. scienceclass.txt Please enter the exact name of the file you'd like to process: scienceclass.txt From 6288b44e6bbdc1a57bea177f39579b863b9a3a0f Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 12:54:55 +0800 Subject: [PATCH 436/503] Add SampleFile for Process Command --- docs/SampleFile.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 docs/SampleFile.txt diff --git a/docs/SampleFile.txt b/docs/SampleFile.txt new file mode 100644 index 0000000000..7228a6b025 --- /dev/null +++ b/docs/SampleFile.txt @@ -0,0 +1,7 @@ +Subject: Math +Classes Attended: 10 +Luigi ~~ 98989898 ~~ 90.0 +Daisy ~~ 98989888 ~~ 95.0 +Mario ~~ 98988888 ~~ 98.0 +Peach ~~ 98888888 ~~ 95.0 +Tai Lung ~~ 90909090 ~~ 99.0 \ No newline at end of file From 5bd629752e833a6c0c3f9191039e34c0aaddc840 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 12:55:11 +0800 Subject: [PATCH 437/503] Add Image for the format of the text file --- docs/Text File Format Picture.jpg | Bin 0 -> 130763 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docs/Text File Format Picture.jpg diff --git a/docs/Text File Format Picture.jpg b/docs/Text File Format Picture.jpg new file mode 100644 index 0000000000000000000000000000000000000000..183e594bf58322a34e5380cc9dfddd8ff1fb8016 GIT binary patch literal 130763 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 literal 0 HcmV?d00001 From 6fb093062728041bd40f125843da4fb9045b2096 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 12:58:56 +0800 Subject: [PATCH 438/503] Update code to meet checkstyle requirements --- src/test/java/classify/textfilecode/TextFileParserTest.java | 2 +- src/test/java/classify/textfilecode/TextFileReaderTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/classify/textfilecode/TextFileParserTest.java b/src/test/java/classify/textfilecode/TextFileParserTest.java index 699d977d13..356f4e923c 100644 --- a/src/test/java/classify/textfilecode/TextFileParserTest.java +++ b/src/test/java/classify/textfilecode/TextFileParserTest.java @@ -57,7 +57,7 @@ public void testPromptForFileSelectionAgain(){ TextFileParser.promptForFileSelectionAgain(); assertEquals((REQUEST_TO_TRY_AGAIN + System.lineSeparator() + - FILE_SELECTION_PROMPT).trim(), outContent.toString().trim()); + FILE_SELECTION_PROMPT).trim(), outContent.toString().trim()); } @Test diff --git a/src/test/java/classify/textfilecode/TextFileReaderTest.java b/src/test/java/classify/textfilecode/TextFileReaderTest.java index c38840d8da..f68abb8b30 100644 --- a/src/test/java/classify/textfilecode/TextFileReaderTest.java +++ b/src/test/java/classify/textfilecode/TextFileReaderTest.java @@ -25,7 +25,7 @@ public void testPrintCurrentInputFolderWhenEmpty() { assertEquals("No files in your Input Folder!\n" + "Please add some new files in the correct format!", outContent.toString().trim()); - currentDir.delete(); + currentDir.delete(); } @Test From 749cf953a55e9f4d08b58028f24ecee2ab00356a Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 14:53:05 +0800 Subject: [PATCH 439/503] Update image for About Us Page --- docs/AboutUs.md | 2 +- docs/team/Parth Image.JPG | Bin 0 -> 50173 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 docs/team/Parth Image.JPG diff --git a/docs/AboutUs.md b/docs/AboutUs.md index f561238dfa..6ee565fd43 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,7 +1,7 @@ # About us Display | Name | Github Profile | Portfolio --------|:---------:|:--------------:|:---------: -![](./team/yellowamogus.jpg) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) +![](./team/Parth%20Image.JPG) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) ![](./team/purpleamogus.png) | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) ![](./team/magentaamogus.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) ![](./team/tayponghee.png) | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) diff --git a/docs/team/Parth Image.JPG b/docs/team/Parth Image.JPG new file mode 100644 index 0000000000000000000000000000000000000000..2211d89b34e4d6158c5eb482ec6d5c0ca187dc32 GIT binary patch literal 50173 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�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 literal 0 HcmV?d00001 From 51b598287a2b9202523c8b11219f6832a9150075 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 14:53:15 +0800 Subject: [PATCH 440/503] Update PPP --- docs/team/parthgandhinus.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/team/parthgandhinus.md b/docs/team/parthgandhinus.md index 2d8207d10e..0e331d064e 100644 --- a/docs/team/parthgandhinus.md +++ b/docs/team/parthgandhinus.md @@ -45,13 +45,16 @@ Overall, the code base has more than 7000 Lines of Code, and is written in Java. **Documentation:** * [Contributions to UG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/UserGuide.md): * Did the preface for the project. - * Wrote out the functionalities for Process Command + * Wrote out the functionalities for Process Command + [Sample File](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/SampleFile.txt) + [Format for writing text file](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/Text%20File%20Format%20Picture.jpg) * Made the command summary in Tabular form for easy referencing * Refactored and cleaned the UG * Made the table of contents for the UG, linking the relevant parts of the markdown file * [Contributions to DG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/DeveloperGuide.md): - * Listed out the workflow for Process and Data commands in DG + * Wrote out the workflow for Process and Data commands in DG * Made the table of contents for the DG + * Assisted in the various UML Diagrams --- @@ -65,3 +68,5 @@ Overall, the code base has more than 7000 Lines of Code, and is written in Java. * [TextFileReaderTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/textfilecode/TextFileReaderTest.java) * [DataReaderTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/data/DataReaderTest.java) * [DataWriterTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/data/DataWriterTest.java) + +--- \ No newline at end of file From 2c0fd4b76679833c40f89c7a4835eb3a395d6079 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 14:53:25 +0800 Subject: [PATCH 441/503] Update UG --- docs/UserGuide.md | 90 +++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 9726355ef4..dc8d9f8315 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -177,7 +177,7 @@ Example: - james WONG BING XUAN -> James Wong Bing Xuan - jaMeS WONG binG Xuan -> James Wong Bing Xuan -Format: `add` or `add NAME` +**Format:** `add` or `add NAME` Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. @@ -214,7 +214,7 @@ Please input a valid Phone number: Views a student's details. Allows the user to do view [name] or just view. -Format: `view` or `view NAME` +**Format:** `view` or `view NAME` Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. If user enters different letter cases from name stored data, the system will still match strings regardless of letter case for user intuitiveness. @@ -259,7 +259,7 @@ Student and Phone number pair found. If not found in the list, please restore or ### Delete a student from the working list `delete` Deletes the student from the list. Allows the user to do delete [student] or just delete. -Format: `delete` or `delete NAME` +**Format:** `delete` or `delete NAME` Depending on whether the user entered the student's name or not during the command, a field will be printed out in the terminal, awaiting a user input. @@ -275,7 +275,7 @@ Student removed successfully! ### Edit details of a student `edit` Edit a student's details and subjects. Allows the user to do edit [student] or just edit. -Format: `edit` or `edit NAME` +**Format:** `edit` or `edit NAME` If user has not entered a name, they will be prompted to input a name. Once programme received name input, the student master list will be searched for the name. Name search is not case-sensitive. @@ -347,7 +347,7 @@ No student found to edit! ### Restore a student to the working list `restore` Restores a student deleted in the current session. Allows the user to do restore [student] or just restore. -Format: `restore` or `restore NAME` +**Format:** `restore` or `restore NAME` Depending on whether the user entered the student's name or not during the command, a field will be printed out in the terminal, awaiting a user input. @@ -364,7 +364,7 @@ Student has been restored! ### Undo a delete and restore the deleted student to the working list `undo` Undoes the latest "delete student". Used by typing `undo` -Format: `undo` +**Format:** `undo` #### Example Usage: ``` @@ -380,7 +380,7 @@ Displays the list of all students, or students with a specified subject. The user can further specify if they would like to display the full student list, the list with the total classes attended, as well as the list of students in the archive or in the recently deleted list. -Format: `list` +**Format:** `list` Allows the user to specify a subject, then displays all students with that subject. If the field is left blank, students will be displayed regardless of the subjects they have. @@ -492,7 +492,7 @@ Currently, there are 4 students in the list. ### Sort the list of students `sort` Sorts the list of students based on the following input. Allows the user to do sort [type] or just sort. -Format: `sort`, `sort name`, `sort classes` or `sort payment` +**Format:** `sort`, **`sort name`**, `sort classes` or `sort payment` Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. @@ -526,39 +526,39 @@ Sort complete! ### Process a list of students from a text file `process` Reads a text file in the inputFolder folder located inside the data folder. -> The text file which is being processed **MUST** follow the format shown here in the [SampleFile.txt](./SampleFile.txt) -> You can change the subject name, classes attended, name, phone number and grades of the student. When doing so, please follow the given format below. + **Format:** `process`, press enter, `filename` (without filetype) **or** `filename.txt` (with file extension) -![Text File Format](./Text%20File%20Format%20Picture.jpg) - -Format: `process`, press enter, `filename` (without filetype) **or** `filename.txt` (with file extension) - -The processed file will add the students into the masterStudentList with relevant attributes for subject name, grades, and classes attended. +The processed file will add the students into the masterStudentList with relevant attributes for subject name, grades, and classes attended. -All other student attributes (eg. gender, phone number, remarks, etc) must be updated by the user. +> **All other student attributes (eg. gender, last payment date, remarks, etc) must be updated by the user.** Please make sure that the proper format for the input file is followed. Only one subject and class attended value should be present per text file. Otherwise, the program will read in the first subject and class attended, and apply it to all students present in the text file. Any students with missing or invalid grades or phone number will be skipped. -``` -Subject: SUBJECT -Classes Attended: INTEGER -NAME ~~ NUMBER ~~ GRADE -``` +> The text file which is being processed **MUST** follow the format shown here in the [SampleFile.txt](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/SampleFile.txt) +> +> You can change the subject name, classes attended, name, phone number and grades of the student. +> When doing so, please follow the given format below: + + +##### An example is seen below: + +![Text File Format](./Text%20File%20Format%20Picture.jpg) -An example is seen below: ``` -Subject: Math -Classes Attended: 10 -parth ~~ 98989898 ~~ 90.0 -pong hee ~~ 98989888 ~~ 95.0 -Yi xin ~~ 98988888 ~~ 98.0 -gerard ~~ 98888888 ~~ 95.0 -shui hon ~~ 91231234 ~~ 99.0 +Subject: CS2113 +Classes Attended: 12 +Luigi ~~ 98989898 ~~ 90.0 +Daisy ~~ 98989888 ~~ 95.0 +Mario ~~ 98988888 ~~ 98.0 +Peach ~~ 98888888 ~~ 95.0 +Tai Lung ~~ 90909090 ~~ 99.0 ``` -#### Without File extension: +#### Different types of Processing Possible: + +##### Without File extension: ``` process Current Files in your Input Folder: @@ -567,12 +567,12 @@ Current Files in your Input Folder: 3. scienceclass.txt Please enter the exact name of the file you'd like to process: -mathclass +mathclass <--- Fetching the data from mathclass.txt. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` -#### With File extension: +##### With File extension: ``` process Current Files in your Input Folder: @@ -581,14 +581,14 @@ Current Files in your Input Folder: 3. scienceclass.txt Please enter the exact name of the file you'd like to process: -scienceclass.txt +scienceclass.txt <--- Fetching the data from scienceclass.txt. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` ### Move a student from the master list to the archive `archive` Adds a student to the archive and removes them from the master list. -Format: `archive`, `archive NAME` +**Format:** `archive`, `archive NAME` Depending on whether the user entered the student's name or not during the command, a field will be printed out in the terminal, awaiting a user input. @@ -607,7 +607,7 @@ The user can then view currently archived students using the `list` command. ### Move a student from the archive back to the master list `unarchive` Removes a student from the archive and adds them back to the master list. -Format: `unarchive`, `unarchive NAME` +**Format:** `unarchive`, `unarchive NAME` Depending on whether the user entered the student's name or not during the command, a field will be printed out in the terminal, awaiting a user input. @@ -634,7 +634,7 @@ the archived student will not be loaded into the archive list and will be overwr ### Display instructions on how to use Classify `help` Prints instructions which detail how to use all the features of Classify. -Format: `help` +**Format:** `help` #### Example usage: ``` @@ -718,7 +718,7 @@ help ### Exit Classify `bye` Exits the Classify program. -Format: `bye` +**Format:** `bye` #### Example usage: ``` @@ -742,17 +742,17 @@ This section provides a quick overview of all the commands used in our Classify. | `delete ` |Deletes the student from the list.
If the name of the student is not specified in the initial command, the program will prompt the user for the name.|[Delete](#delete-a-student-from-the-working-list-delete)| | `edit ` |Allows the user to edit the details of the student.
If the name of the student is not specified in the initial command, the program will prompt the user for the name.|[Edit](#edit-details-of-a-student-edit)| | **Listing** | | -| `list`, press enter,
[subject] |Displays the list of students that has taken that subject.|[List](#display-the-list-of-students-list)| -| `list`, press enter,
press enter, [1] |Displays the list of students that is registered in the tuition centre.|[List](#display-the-list-of-students-list)| -| `list`, press enter,
press enter, [2] |Displays the list of students that is registered in the tuition centre with the total number of classes taken.|[List](#display-the-list-of-students-list)| -| `list`, press enter,
press enter, [3] |Displays the list of students that is registered in the tuition centre with their phone numbers beside their names|[List](#display-the-list-of-students-list)| -| `list`, press enter,
press enter, [4] |Displays the list of students who were archived.|[List](#display-the-list-of-students-list)| -| `list`, press enter,
press enter, [5] |Displays the list of students who were recently deleted from the master list.|[List](#display-the-list-of-students-list) | -| **Sorting** | [List](#display-the-list-of-students-list)| +| `list`, press enter,
`` |Displays the list of students that has taken that subject.|[List](#display-the-list-of-students-list)| +| `list`, press enter,
press enter, `<1>` |Displays the list of students that is registered in the tuition centre.|[List](#display-the-list-of-students-list)| +| `list`, press enter,
press enter, `<2>` |Displays the list of students that is registered in the tuition centre with the total number of classes taken.|[List](#display-the-list-of-students-list)| +| `list`, press enter,
press enter, `<3>` |Displays the list of students that is registered in the tuition centre with their phone numbers beside their names|[List](#display-the-list-of-students-list)| +| `list`, press enter,
press enter, `<4>` |Displays the list of students who were archived.|[List](#display-the-list-of-students-list)| +| `list`, press enter,
press enter, `<5>` |Displays the list of students who were recently deleted from the master list.|[List](#display-the-list-of-students-list) | +| **Sorting** | | | `sort ` |Sorts the list lexicographically.
If the word `name` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| | `sort ` |Sorts the list by the last fee payment date of a student.
If the word `payment` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| | `sort ` |Sorts the list by the number of classes a student has attended.
If the word `classes` is not specified in the initial command, the program will prompt the user for an appropriate flag.|[Sort](#sort-the-list-of-students-sort)| -| **Processing** | | +| **Process Text File** | | | `process`, press enter,
`` | Processes a text file containing a list of students taking the same subject and having attended the same number of lessons.
Adds all of them into the current list with their individual grades for the subject.
Will need to manually input their other attributes (eg. phone number, gender, etc) |[Process](#process-a-list-of-students-from-a-text-file-process)| | **Archiving** | | | `archive ` |Archives specified student. Removes student from current list and adds student to archive.|[Archive](#move-a-student-from-the-master-list-to-the-archive-archive)| From 08d1af9d2e1735ce957c8a26aaa6dfd502c316d2 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 15:25:01 +0800 Subject: [PATCH 442/503] Clean everyone's peepee poopoo for boolean stuff --- .../java/classify/commands/AddStudent.java | 4 ++-- .../commands/ListStudentsCommand.java | 6 ++--- src/main/java/classify/data/DataReader.java | 10 ++++---- .../classify/textfilecode/TextFileParser.java | 14 +++++------ .../classify/textfilecode/TextFileReader.java | 2 +- src/main/java/classify/user/InputParsing.java | 4 ++-- .../java/classify/data/DataReaderTest.java | 16 ++++++------- .../textfilecode/TextFileParserTest.java | 24 +++++++++---------- 8 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index aec1e28b96..c324a33301 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -215,7 +215,7 @@ public static void addSubject(Scanner in, StudentAttributes attributes) { UI.printSubjectAlreadyExists(); break; - } else if (checkForValidSubjectResponse(in, attributes, subject)) { + } else if (isValidSubjectResponse(in, attributes, subject)) { //@@author tayponghee return; } @@ -230,7 +230,7 @@ public static void addSubject(Scanner in, StudentAttributes attributes) { * @param subject The subject to be added. * @return True if the user chooses not to add another subject and grade, false otherwise. */ - private static boolean checkForValidSubjectResponse(Scanner in, StudentAttributes attributes, String subject) { + private static boolean isValidSubjectResponse(Scanner in, StudentAttributes attributes, String subject) { double grade = Math.max(InputParsing.promptForGrade(in), 0); int classesAttended = promptForClassesAttended(in); diff --git a/src/main/java/classify/commands/ListStudentsCommand.java b/src/main/java/classify/commands/ListStudentsCommand.java index 6835f3ae11..f162788e39 100644 --- a/src/main/java/classify/commands/ListStudentsCommand.java +++ b/src/main/java/classify/commands/ListStudentsCommand.java @@ -58,7 +58,7 @@ public static void chooseListType(ArrayList masterStudentList, ArrayLis * @param subject The subject to filter the list of students. */ public static void listStudentsBySubject(ArrayList masterStudentList, String subject) { - boolean found = false; + boolean isFound = false; UI.printStudentsWithSubject(subject); for (Student student : masterStudentList) { @@ -70,11 +70,11 @@ public static void listStudentsBySubject(ArrayList masterStudentList, S } else { UI.println("- " + student.getName() + " - " + "No Classes Attended found for " + subject); } - found = true; + isFound = true; } } - if (!found) { + if (!isFound) { UI.printNoStudentsWithSubject(subject); } diff --git a/src/main/java/classify/data/DataReader.java b/src/main/java/classify/data/DataReader.java index 967614a94c..2be26cb0bf 100644 --- a/src/main/java/classify/data/DataReader.java +++ b/src/main/java/classify/data/DataReader.java @@ -70,7 +70,7 @@ public static void restoreStudentList(String studentFileInput, ArrayList list, */ private static void promptDataDeletion() { String input = in.nextLine(); - if (checkDeletionRequestInput(input)) { + if (isDeletionRequestInput(input)) { DataUI.printDataDeletionFinalConfirmationMessage(); input = in.nextLine(); - if (deletionRequestFinalConfirmation(input)) { + if (isDeletionRequestFinalConfirmation(input)) { DataHandler.deleteStudentInfo(); } else { DataUI.printDeletionConfirmationInputMismatchMessage(); @@ -264,11 +264,11 @@ private static void promptDataDeletion() { } } - static boolean checkDeletionRequestInput(String input) { + static boolean isDeletionRequestInput(String input) { return input.equals("YES"); } - static boolean deletionRequestFinalConfirmation(String input) { + static boolean isDeletionRequestFinalConfirmation(String input) { return input.equals("CONFIRM"); } } diff --git a/src/main/java/classify/textfilecode/TextFileParser.java b/src/main/java/classify/textfilecode/TextFileParser.java index c4bcaaf7ed..cbdcae77ff 100644 --- a/src/main/java/classify/textfilecode/TextFileParser.java +++ b/src/main/java/classify/textfilecode/TextFileParser.java @@ -45,7 +45,7 @@ public class TextFileParser { * @param textFileName Name of the file * @return True or False depending on the filetype of file */ - public static Boolean textFileChecker(String textFileName) { + public static Boolean isTextFile(String textFileName) { String type = ""; int i = textFileName.lastIndexOf(DOT); if (i >= 0) { @@ -196,7 +196,7 @@ private static void deconstructTextFile (String textFileInput, String subjectNam //Set phone_number int phoneNumber = Integer.parseInt(inputArr[PHONE_NUMBER].trim()); - if (!InputParsing.checkNumberValidity(phoneNumber)) { + if (!InputParsing.isValidNumber(phoneNumber)) { UI.println("Invalid number found. Skipping entry."); return; } @@ -231,9 +231,9 @@ private static void deconstructTextFile (String textFileInput, String subjectNam private static void masterStudentListAddition(ArrayList masterStudentList, String studentNameString, Student student,int phoneNumber, String subjectName, SubjectGrade newSubject) { - if (matchingNameNumber (masterStudentList, studentNameString, phoneNumber)) { + if (isMatchingNameNumber (masterStudentList, studentNameString, phoneNumber)) { Integer indexOfStudent = matchingStudentIndex(masterStudentList, studentNameString, phoneNumber); - if (!(matchingSubject(masterStudentList, subjectName, indexOfStudent))) { + if (!(isMatchingSubject(masterStudentList, subjectName, indexOfStudent))) { masterStudentList.get(indexOfStudent).getAttributes().addSubjectGrade(newSubject); } } else { @@ -251,7 +251,7 @@ private static void masterStudentListAddition(ArrayList masterStudentLi * @param phoneNumber Phone number of the student */ static void addPhoneNumber(String studentNameString, Student student, int phoneNumber) { - if (InputParsing.checkNumberValidity(phoneNumber)) { + if (InputParsing.isValidNumber(phoneNumber)) { student.getAttributes().setPhoneNumber(phoneNumber); } else { UI.println(studentNameString + INVALID_PHONE_NUMBER_MESSAGE); @@ -286,7 +286,7 @@ static Integer matchingStudentIndex(ArrayList masterStudentList, String * @param subjectName name of the subject that is getting added * @return True if subject is found attributed to that particular student. False otherwise. */ - static boolean matchingSubject(ArrayList masterStudentList, String subjectName, + static boolean isMatchingSubject(ArrayList masterStudentList, String subjectName, Integer indexOfStudent) { List studentSubjects = masterStudentList.get(indexOfStudent).getAttributes().getSubjectGrades(); for (SubjectGrade subject : studentSubjects) { @@ -307,7 +307,7 @@ static boolean matchingSubject(ArrayList masterStudentList, String subj * @param number Phone number of the student to find. * @return True if a student with the same name and number is found in the list,false otherwise. */ - static boolean matchingNameNumber(ArrayList masterStudentList, String name, int number) { + static boolean isMatchingNameNumber(ArrayList masterStudentList, String name, int number) { for (Student student : masterStudentList) { if (student.getName().equalsIgnoreCase(name) && student.getPhoneNumber() == number) { return true; diff --git a/src/main/java/classify/textfilecode/TextFileReader.java b/src/main/java/classify/textfilecode/TextFileReader.java index 12a9652967..8352e53efc 100644 --- a/src/main/java/classify/textfilecode/TextFileReader.java +++ b/src/main/java/classify/textfilecode/TextFileReader.java @@ -32,7 +32,7 @@ private static void getCurrentFiles(File currentDirectory) { Integer index = 1; for (File newFile : fileList) { - if (newFile.isFile() && TextFileParser.textFileChecker(newFile.getName())) { + if (newFile.isFile() && TextFileParser.isTextFile(newFile.getName())) { System.out.println(index +". " + newFile.getName()); index++; } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index c79accb888..ea5d8252a2 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -358,7 +358,7 @@ public static int promptForPhoneNumber(Scanner in) throws NumberFormatException{ do { UI.printPhoneNumberPrompt(); number = readInPhoneNumber(in); - } while (!checkNumberValidity(number)); + } while (!isValidNumber(number)); LOGGER.log(Level.INFO, "Storing number: " + number); return number; @@ -388,7 +388,7 @@ private static int readInPhoneNumber(Scanner in) throws NumberFormatException { * @return True if the number is a valid Singapore Number, false otherwise */ //@@author Cryolian - public static boolean checkNumberValidity(int number) { + public static boolean isValidNumber(int number) { return number >= NUMBER_TOO_SMALL && number < NUMBER_TOO_BIG; } diff --git a/src/test/java/classify/data/DataReaderTest.java b/src/test/java/classify/data/DataReaderTest.java index f8ba65ecca..ce1188ce80 100644 --- a/src/test/java/classify/data/DataReaderTest.java +++ b/src/test/java/classify/data/DataReaderTest.java @@ -159,41 +159,41 @@ public void convertStringToLocalDateInvalidDateTest(){ @Test public void checkDeletionRequestInputTest(){ - assertTrue(DataReader.checkDeletionRequestInput("YES")); + assertTrue(DataReader.isDeletionRequestInput("YES")); } @Test public void checkDeletionRequestInvalidTest1(){ - assertFalse(DataReader.checkDeletionRequestInput("yes")); + assertFalse(DataReader.isDeletionRequestInput("yes")); } @Test public void checkDeletionRequestInvalidTest2(){ - assertFalse(DataReader.checkDeletionRequestInput("YEs")); + assertFalse(DataReader.isDeletionRequestInput("YEs")); } @Test public void checkDeletionRequestInvalidTest3(){ - assertFalse(DataReader.checkDeletionRequestInput("NO")); + assertFalse(DataReader.isDeletionRequestInput("NO")); } @Test public void deletionRequestFinalConfirmationValidTest(){ - assertTrue(DataReader.deletionRequestFinalConfirmation("CONFIRM")); + assertTrue(DataReader.isDeletionRequestFinalConfirmation("CONFIRM")); } @Test public void deletionRequestFinalConfirmationInvalidTest1(){ - assertFalse(DataReader.deletionRequestFinalConfirmation("confirm")); + assertFalse(DataReader.isDeletionRequestFinalConfirmation("confirm")); } @Test public void deletionRequestFinalConfirmationInvalidTest2(){ - assertFalse(DataReader.deletionRequestFinalConfirmation("CONfirm")); + assertFalse(DataReader.isDeletionRequestFinalConfirmation("CONfirm")); } @Test public void deletionRequestFinalConfirmationInvalidTest3(){ - assertFalse(DataReader.deletionRequestFinalConfirmation("BANANA")); + assertFalse(DataReader.isDeletionRequestFinalConfirmation("BANANA")); } } diff --git a/src/test/java/classify/textfilecode/TextFileParserTest.java b/src/test/java/classify/textfilecode/TextFileParserTest.java index 356f4e923c..9b9c60f925 100644 --- a/src/test/java/classify/textfilecode/TextFileParserTest.java +++ b/src/test/java/classify/textfilecode/TextFileParserTest.java @@ -31,12 +31,12 @@ class TextFileParserTest { @Test public void testTextFileCheckerValidCase() { - assertTrue(TextFileParser.textFileChecker(VALID_TEXT_FILE)); + assertTrue(TextFileParser.isTextFile(VALID_TEXT_FILE)); } @Test public void testTextFileCheckerInvalidCase() { - assertFalse(TextFileParser.textFileChecker(INVALID_TEXT_FILE)); + assertFalse(TextFileParser.isTextFile(INVALID_TEXT_FILE)); } @Test @@ -94,9 +94,9 @@ public void testMatchingStudentIndexAllTrue() { masterStudentList.add(student); student.getAttributes().setPhoneNumber(NORMAL_SG_NUMBER); - boolean checker = TextFileParser.matchingStudentIndex(masterStudentList, + boolean isTrue = TextFileParser.matchingStudentIndex(masterStudentList, JOHN_DOE, NORMAL_SG_NUMBER) == 0; - assertTrue(checker); + assertTrue(isTrue); } @Test @@ -106,9 +106,9 @@ public void testMatchingStudentIndexWrongNumber() { masterStudentList.add(student); student.getAttributes().setPhoneNumber(NORMAL_SG_NUMBER); - boolean checker = TextFileParser.matchingStudentIndex(masterStudentList, + boolean isFalse = TextFileParser.matchingStudentIndex(masterStudentList, JOHN_DOE, 98989898) == 0; - assertFalse(checker); + assertFalse(isFalse); } @Test @@ -118,9 +118,9 @@ public void testMatchingStudentIndexWrongName() { masterStudentList.add(student); student.getAttributes().setPhoneNumber(NORMAL_SG_NUMBER); - boolean checker = TextFileParser.matchingStudentIndex(masterStudentList, + boolean isFalse = TextFileParser.matchingStudentIndex(masterStudentList, "Jane Doe", NORMAL_SG_NUMBER) == 0; - assertFalse(checker); + assertFalse(isFalse); } @@ -134,7 +134,7 @@ public void testMatchingSubjectTrueCase() { student.getAttributes().addSubjectGrade(newSubject); - assertTrue(TextFileParser.matchingSubject(masterStudentList, MATH, 0)); + assertTrue(TextFileParser.isMatchingSubject(masterStudentList, MATH, 0)); } @Test @@ -147,7 +147,7 @@ public void testMatchingSubjectFalseCase() { student.getAttributes().addSubjectGrade(newSubject); - assertFalse(TextFileParser.matchingSubject(masterStudentList, SCIENCE, 0)); + assertFalse(TextFileParser.isMatchingSubject(masterStudentList, SCIENCE, 0)); } @Test @@ -157,7 +157,7 @@ public void testMatchingNameNumberTrueCase() { masterStudentList.add(student); student.getAttributes().setPhoneNumber(NORMAL_SG_NUMBER); - assertTrue(TextFileParser.matchingNameNumber(masterStudentList, JOHN_DOE, NORMAL_SG_NUMBER)); + assertTrue(TextFileParser.isMatchingNameNumber(masterStudentList, JOHN_DOE, NORMAL_SG_NUMBER)); } @Test @@ -167,6 +167,6 @@ public void testMatchingNameNumberFalseCase() { masterStudentList.add(student); student.getAttributes().setPhoneNumber(98989898); - assertFalse(TextFileParser.matchingNameNumber(masterStudentList, JOHN_DOE, NORMAL_SG_NUMBER)); + assertFalse(TextFileParser.isMatchingNameNumber(masterStudentList, JOHN_DOE, NORMAL_SG_NUMBER)); } } From f060f10d493a0433fff9d03675555059515c8c35 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 15:25:35 +0800 Subject: [PATCH 443/503] Update DG for Process Component --- docs/DeveloperGuide.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index d9656a459f..132d5f47a9 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -223,8 +223,15 @@ The two text files are will be created under a directory called data, in which t This section refers to `TextFileHandler.java`, `TextFileParser.java`, and `TextFileReader.java` classes. It ensures that we are able to put new files in the folder in data which is named Input Folder. #### Design Considerations + * Support for adding multiple students taking the same class/subject at once + * Need to take down students' name and phone number as these are used to prevent duplicate entries in masterStudentList + * Need to have a different parser to make it easy for the users to add many studetns #### Implementation and Rationale + * **Standardised Subject and Classes Attended**: Simplify adding users in text file for user + * **Common Regex**: Using " ~~ " to separate all other attributes like Student Name, Phone Number and Grade ensures it is easy for the user to add many students + * **Checker for same student**: Ensures that we dont have duplicate entries of one student. + * **Checker for same subject**: Ensures that an existing student does not get duplicate entries of the same subject (Not applicable for new students for obvious reasons) --- From 273fb71cf5c3ae506e96a84e9aa6a1cb3ad8d0df Mon Sep 17 00:00:00 2001 From: blackmirag3 <78994143+blackmirag3@users.noreply.github.com> Date: Sun, 14 Apr 2024 17:25:23 +0800 Subject: [PATCH 444/503] Add logging to archive commands --- .../src/EditStudent/Architecture Diagram.puml | 26 ++++++++++++++++++ docs/diagrams/src/EditStudent/EditStudent.PNG | Bin 0 -> 25794 bytes docs/team/blackmirag3.md | 7 +++-- .../classify/commands/ArchiveCommands.java | 19 ++++++++++--- .../java/classify/commands/EditStudent.java | 8 ++++++ 5 files changed, 53 insertions(+), 7 deletions(-) create mode 100644 docs/diagrams/src/EditStudent/Architecture Diagram.puml create mode 100644 docs/diagrams/src/EditStudent/EditStudent.PNG diff --git a/docs/diagrams/src/EditStudent/Architecture Diagram.puml b/docs/diagrams/src/EditStudent/Architecture Diagram.puml new file mode 100644 index 0000000000..f5581451dd --- /dev/null +++ b/docs/diagrams/src/EditStudent/Architecture Diagram.puml @@ -0,0 +1,26 @@ +@startuml +title Sequence Diagram: Calling editStudent and editing subject + +actor User +participant "InputParsing" as InputParsing <> + +participant "EditCommand" as EditCommand<> +participant "StudentList" as StudentList<> +activate EditCommand +activate StudentList +activate InputParsing + +User->InputParsing: String: EDIT +"InputParsing"->EditCommand: editStudent() +User-> EditCommand: String: NAME +EditCommand -> StudentList: getStudent(NAME) +EditCommand <-- StudentList: Student:student +EditCommand -> EditCommand: editStudentDetails(student) +User-> EditCommand: String:EDIT_GENDER +EditCommand -> EditCommand: editGender(student.attributes) +User-> EditCommand: String:GENDER +EditCommand -> StudentList: setGrade(GENDER) +deactivate EditCommand +deactivate StudentList +hide footbox +@enduml \ No newline at end of file diff --git a/docs/diagrams/src/EditStudent/EditStudent.PNG b/docs/diagrams/src/EditStudent/EditStudent.PNG new file mode 100644 index 0000000000000000000000000000000000000000..e5fce4faeabe854b982c2406e1865a37aaec2a41 GIT binary patch literal 25794 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

KlWBdN>-okL`SzC=s!37H`;`p)jJ5d>Q~Fy5)Q_ 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 K-E197&_4k@x1s<5 literal 0 HcmV?d00001 diff --git a/docs/team/blackmirag3.md b/docs/team/blackmirag3.md index 7278052b46..4317e5caca 100644 --- a/docs/team/blackmirag3.md +++ b/docs/team/blackmirag3.md @@ -27,13 +27,14 @@ all Tuition Centres can employ for ease of student management. - **Contributions to [UG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/UserGuide.md)** - * Wrote content related to `edit`, `archive`, `unarchive` features. - * Finalised formatting in UG, such as standardising the layout in `Usage` section. + * Wrote for `edit`, `archive`, `unarchive` features. + * Finalised formatting in UG, such as standardising the layout under `Usage` section. - **Contributions to [DG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/DeveloperGuide.md)** - * ... + * Wrote `EditStudent` and `ArchiveCommands` component + * Wrote `Archiving/unarchiving a student` and `Editing a student's details` under manual testing. - **Contributions to Team-Based tasks:** diff --git a/src/main/java/classify/commands/ArchiveCommands.java b/src/main/java/classify/commands/ArchiveCommands.java index 64362a6a81..87c9502f5d 100644 --- a/src/main/java/classify/commands/ArchiveCommands.java +++ b/src/main/java/classify/commands/ArchiveCommands.java @@ -9,8 +9,11 @@ import java.util.ArrayList; import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; public class ArchiveCommands { + public static final Logger logger = Logger.getLogger(InputParsing.class.getName()); //@@author blackmirag3 /*** @@ -45,7 +48,12 @@ public static void unarchiveStudent(ArrayList masterList, ArrayList masterList, ArrayList archiveList, String name, S Student student = InputParsing.findStudentByName(archiveList, name, in); if (student == null) { UI.printStudentNotFound(); + logger.log(Level.INFO, "Student not found."); return null; } + logger.log(Level.INFO, "found " + student.getName()); return student; } - - public static void viewArchive() { - - } } diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index 187e515bfe..5df2b27586 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -144,6 +144,14 @@ private static void editRemarks(Scanner in, StudentAttributes attributes) { UI.printDivider(); } + //@@author blackmirag3 + /** + * Edits gender for a particular student + * + * @param in The scanner object to read user input. + * @param attributes The attributes object of the student that the user has chosen to edit. + */ + //@@author Cryolian private static void editGender(Scanner in, StudentAttributes attributes) { UI.println(attributes.getGender()); UI.printDivider(); From 66be268da23508ef41cf7bdd8a9d1999e9ebe48b Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 18:28:49 +0800 Subject: [PATCH 445/503] Remove redundant println --- src/main/java/classify/textfilecode/TextFileReader.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/classify/textfilecode/TextFileReader.java b/src/main/java/classify/textfilecode/TextFileReader.java index 8352e53efc..633db76e0e 100644 --- a/src/main/java/classify/textfilecode/TextFileReader.java +++ b/src/main/java/classify/textfilecode/TextFileReader.java @@ -37,8 +37,5 @@ private static void getCurrentFiles(File currentDirectory) { index++; } } - System.out.println(""); - } - } From 38574505aa7d46b09b71dc7f7ce9e6193bb47e8d Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 18:29:22 +0800 Subject: [PATCH 446/503] Update DG with manual testing for Process --- docs/DeveloperGuide.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 132d5f47a9..f9f15859d4 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -342,6 +342,27 @@ Classify serves as an attempt to modernise administrative tasks in education ins 2. Test case: `list`, enter, enter, `5`
Expected: A list of all students that have been deleted in the current session is printed. +### Processing a Test File +1. **No file** in inputFolder + 1. Prerequisites: **Empty** inputFolder folder in Data. + 2. Expected: `No files in your Input Folder!` & `Please add some new files in the correct format!`. + Should be redirected to the main commands menu. + +2. **No text file** in inputFolder + 1. Prerequisites: inputFolder folder in Data **with no text files**. + 2. Expected: `Files in your inputFolder are not Text Files!` & `Add some text files and try processing again!`. + Should be redirected to the main commands menu. + +3. Ingesting a full list of Students using a Text File (without using file extension) + 1. Prerequisites: Have at least one text file in the inputFolder in Data. The text file present (eg. **File.txt**) is properly formatted according to the requirements stated in the User Guide and is present in the inputFolder. + 2. Test case: `Process`, enter, **`File`** + Expected: `Fetching the data from File.txt.` will be displayed. Can use the `list`, enter,enter,`1` to ensure that all the students in the file are added. + +4. Ingesting a full list of Students using a Text File (using file extension) + 1. Prerequisites: Have at least one text file in the inputFolder in Data. The text file present (eg. **File.txt**) is properly formatted according to the requirements stated in the User Guide and is present in the inputFolder. + 2. Test case: `Process`, enter, **`File.txt`** + Expected: `Fetching the data from File.txt.` will be displayed. Can use the `list`, enter,enter,`1` to ensure that all the students in the file are added. + ### Restoring a recently deleted student 1. Restore a student from the recently deleted list 1. Prerequisites: Have at least one student named `joe` deleted in the current session with the `delete joe` command @@ -444,4 +465,3 @@ Classify serves as an attempt to modernise administrative tasks in education ins
Expected: Prints invalid phone number error message and prompts for another phone number. 6. Test Case: `6`, `20 jan 2001`
Expected: Prints error message for invalid date and prompts for another date. - From 3dd7f463aa3ac3104bcae72cb8c33ee491a95123 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 18:29:49 +0800 Subject: [PATCH 447/503] Refactor process functionality to handle bugs due to different filetypes --- .../textfilecode/TextFileHandler.java | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/textfilecode/TextFileHandler.java b/src/main/java/classify/textfilecode/TextFileHandler.java index cda10f43f5..c0155b1307 100644 --- a/src/main/java/classify/textfilecode/TextFileHandler.java +++ b/src/main/java/classify/textfilecode/TextFileHandler.java @@ -21,14 +21,42 @@ public class TextFileHandler { "your data folder!"; public static final File CURRENT_DIRECTORY = new File (INPUT_TEXT_FILE_DIRECTORY); private static final String INVALID_PATH_MESSAGE = "Path is invalid!"; + private static final String NOT_TEXT_FILE_MESSAGE = "Files in your inputFolder are not Text Files!"; + private static final String ADD_TEXT_FILE_MESSAGE = "Add some text files and try processing again!"; + /** + * Function runs the whole process command, from every input all the way to the final output + * + * @param masterStudentList StudentList where students will be added + * @param in Scanner which scans for the users' inputs + */ public static void process(ArrayList masterStudentList, Scanner in) { createTextFileDirectory(INPUT_TEXT_FILE_DIRECTORY); // Print out the current files in your folder UI.println(CURRENT_FILES); TextFileReader.printCurrentInputFolder(INPUT_TEXT_FILE_DIRECTORY); - TextFileParser.promptForFileSelection(); - TextFileParser.parseUserSelection(CURRENT_DIRECTORY, in, masterStudentList); + + File currentDirectory =new File (INPUT_TEXT_FILE_DIRECTORY); + File[] fileList = currentDirectory.listFiles(); + assert fileList != null; + if (fileList.length == 0) { + return; + } + + boolean isTextFilePresent = false; + for (File file : fileList){ + if (file.isFile() && TextFileParser.isTextFile(file.getName())) { + isTextFilePresent = true; + } + } + + if (isTextFilePresent){ + TextFileParser.promptForFileSelection(); + TextFileParser.parseUserSelection(CURRENT_DIRECTORY, in, masterStudentList); + } else { + System.out.println(NOT_TEXT_FILE_MESSAGE); + System.out.println(ADD_TEXT_FILE_MESSAGE); + } } /** From b5da854aac8f7284d8e5bef47490abfba9693b36 Mon Sep 17 00:00:00 2001 From: blackmirag3 <78994143+blackmirag3@users.noreply.github.com> Date: Sun, 14 Apr 2024 18:44:38 +0800 Subject: [PATCH 448/503] Add exceptions for editing subject --- .../java/classify/commands/AddStudent.java | 19 ++-- .../classify/commands/ArchiveCommands.java | 2 +- .../java/classify/commands/EditStudent.java | 52 ++++++++--- .../java/classify/student/StudentList.java | 25 +++++- src/main/java/classify/user/InputParsing.java | 86 ++++++++++--------- .../user/InvalidSubjectException.java | 18 ++++ 6 files changed, 141 insertions(+), 61 deletions(-) create mode 100644 src/main/java/classify/user/InvalidSubjectException.java diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index aec1e28b96..4485584e76 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -8,6 +8,7 @@ import classify.ui.UI; import classify.user.InputParsing; import classify.user.InvalidCharacterException; +import classify.user.InvalidSubjectException; import classify.user.NameNumberMatchException; import java.util.ArrayList; import java.util.Scanner; @@ -46,7 +47,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, UI.printDivider(); return; } - + Student student = new Student(name); addSubject(in, student.getAttributes()); @@ -202,20 +203,24 @@ private static String capitaliseFirstLetters(String[] words, StringBuilder resul */ public static void addSubject(Scanner in, StudentAttributes attributes) { while (true) { - //@@ author blackmirag3 + //@@author blackmirag3 System.out.print(SUBJECT_ENTER_NOTHING_TO_SKIP); String subject = readInString(in); + assert subject != null; if (subject.isBlank() || subject.equals(InputParsing.DEFAULT_STRING_VALUE)) { UI.printNoSubjectsAdded(); break; + } - } else if (attributes.findSubject(subject) != null) { - // rejects subject if existing subject of same name exists in students' - UI.printSubjectAlreadyExists(); - break; + try { + StudentList.checkExistingSubject(attributes, subject, null); + } catch (InvalidSubjectException e) { + e.printMessage(); + return; + } - } else if (checkForValidSubjectResponse(in, attributes, subject)) { + if (checkForValidSubjectResponse(in, attributes, subject)) { //@@author tayponghee return; } diff --git a/src/main/java/classify/commands/ArchiveCommands.java b/src/main/java/classify/commands/ArchiveCommands.java index 87c9502f5d..326abc673b 100644 --- a/src/main/java/classify/commands/ArchiveCommands.java +++ b/src/main/java/classify/commands/ArchiveCommands.java @@ -13,7 +13,7 @@ import java.util.logging.Logger; public class ArchiveCommands { - public static final Logger logger = Logger.getLogger(InputParsing.class.getName()); + private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); //@@author blackmirag3 /*** diff --git a/src/main/java/classify/commands/EditStudent.java b/src/main/java/classify/commands/EditStudent.java index 5df2b27586..d0cd99ffb0 100644 --- a/src/main/java/classify/commands/EditStudent.java +++ b/src/main/java/classify/commands/EditStudent.java @@ -4,17 +4,21 @@ import java.util.ArrayList; import java.util.Scanner; +import java.util.logging.Level; +import java.util.logging.Logger; import classify.student.Student; import classify.student.StudentAttributes; import classify.student.StudentList; import classify.student.SubjectGrade; import classify.user.InputParsing; +import classify.user.InvalidSubjectException; import classify.user.NameNumberMatchException; import classify.ui.UI; //@@author blackmirag3 public class EditStudent extends Commands { + private static final Logger logger = Logger.getLogger(InputParsing.class.getName()); private static final String ADD_SUBJECT = "1"; private static final String EDIT_SUBJECT = "2"; private static final String DELETE_SUBJECT = "3"; @@ -25,11 +29,16 @@ public class EditStudent extends Commands { private static final String DEFAULT_STRING_VALUE = "Unknown"; public static void editStudent(Scanner in, String name) { + logger.log(Level.INFO,"Finding " + name + "."); Student student = getStudent(in, name); + if (student == null) { + logger.log(Level.INFO, name + " not found."); UI.printStudentNotFound(); return; } + + logger.log(Level.INFO, name + " found."); editStudentDetails(in, student); } @@ -56,6 +65,7 @@ private static Student getStudent(Scanner in, String name) { private static void editStudentDetails(Scanner in, Student student) { + assert student != null; StudentAttributes attributes = student.getAttributes(); ViewStudent.showStudentInfo(student); @@ -72,31 +82,39 @@ private static void editStudentDetails(Scanner in, Student student) { switch (command) { case ADD_SUBJECT: + logger.log(Level.INFO, "Entering add subject mode for " + student); AddStudent.addSubject(in, attributes); student.setAttributes(attributes); break; case EDIT_SUBJECT: + logger.log(Level.INFO, "Entering edit subject mode for " + student); editSubject(in, attributes); break; case DELETE_SUBJECT: + logger.log(Level.INFO, "Entering delete subject mode for " + student); + logger.log(Level.INFO, "Entering delete subject mode for " + student); deleteSubject(in, attributes); break; case EDIT_NUMBER: + logger.log(Level.INFO, "Entering edit number mode for " + student); editNumber(in, attributes); break; case EDIT_REMARKS: + logger.log(Level.INFO, "Entering edit remarks mode for " + student); editRemarks(in, attributes); break; case EDIT_PAYMENT_DATE: + logger.log(Level.INFO, "Entering edit payment mode for " + student); editPaymentDate(in, attributes); break; case EDIT_GENDER: + logger.log(Level.INFO, "Entering edit gender mode for " + student); editGender(in, attributes); break; @@ -117,6 +135,9 @@ private static void editStudentDetails(Scanner in, Student student) { */ //@@author Cryolian private static void editPaymentDate(Scanner in, StudentAttributes attributes) { + //@@author blackmirag3 + assert attributes != null; + //@@author Cryolian UI.println("Current stored date: " + attributes.getLastPaymentDate()); attributes.setLastPaymentDate(InputParsing.readInDate(in)); } @@ -130,6 +151,9 @@ private static void editPaymentDate(Scanner in, StudentAttributes attributes) { */ //@@author Cryolian private static void editRemarks(Scanner in, StudentAttributes attributes) { + //@@author blackmirag3 + assert attributes != null; + //@@author Cryolian UI.println(attributes.getRemarks()); UI.printDivider(); UI.println("Enter blank to stop editing."); @@ -153,6 +177,9 @@ private static void editRemarks(Scanner in, StudentAttributes attributes) { */ //@@author Cryolian private static void editGender(Scanner in, StudentAttributes attributes) { + //@@author blackmirag3 + assert attributes != null; + //@@author Cryolian UI.println(attributes.getGender()); UI.printDivider(); UI.println("Enter blank to stop editing."); @@ -178,6 +205,9 @@ private static void editGender(Scanner in, StudentAttributes attributes) { //@@author Cryolian private static void editNumber(Scanner in, StudentAttributes attributes) { try { + //@@author blackmirag3 + assert attributes != null; + //@@author Cryolian openNumberEditInterface(in, attributes); UI.println("Number updated successfully: " + String.valueOf(attributes.getPhoneNumber())); } catch (NameNumberMatchException e) { @@ -200,7 +230,9 @@ private static void editNumber(Scanner in, StudentAttributes attributes) { //@@author Cryolian private static void openNumberEditInterface(Scanner in, StudentAttributes attributes) throws NameNumberMatchException, NumberFormatException { - + //@@author blackmirag3 + assert attributes != null; + //@@author Cryolian UI.printDivider(); UI.println("Current Number: " + String.valueOf(attributes.getPhoneNumber())); UI.println("Type in and enter the letter a if you wish to stop editing."); @@ -225,7 +257,9 @@ private static void openNumberEditInterface(Scanner in, StudentAttributes attrib * student. */ private static void editSubject(Scanner in, StudentAttributes attributes) { - + //@@author blackmirag3 + assert attributes != null; + //@@author Cryolian SubjectGrade currentSubject = promptForSubject(in, attributes); updateSubjectName(in, attributes, currentSubject); updateSubjectGrade(in, currentSubject); @@ -290,18 +324,12 @@ private static void updateSubjectName(Scanner in, StudentAttributes attributes, if (newName.isBlank() || newName.equals(DEFAULT_STRING_VALUE)) { return; } - - SubjectGrade foundSubject = attributes.findSubject(newName); - - if (foundSubject == currentSubject) { - System.out.println("New subject name same as current."); - - } else if (foundSubject != null) { - UI.printSubjectAlreadyExists(); - - } else { + try { + StudentList.checkExistingSubject(attributes, newName, currentSubject.getSubject()); currentSubject.setSubject(newName); return; + } catch (InvalidSubjectException e) { + e.printMessage(); } } } diff --git a/src/main/java/classify/student/StudentList.java b/src/main/java/classify/student/StudentList.java index f0e8752823..297d4fec92 100644 --- a/src/main/java/classify/student/StudentList.java +++ b/src/main/java/classify/student/StudentList.java @@ -2,6 +2,7 @@ import java.util.ArrayList; +import classify.user.InvalidSubjectException; import classify.user.NameNumberMatchException; /** @@ -123,8 +124,7 @@ public static void checkNameNumberPair(ArrayList studentList, String na "name and phone number found."); } //@@author blackmirag3 - assert (s.getName().equalsIgnoreCase(name) && s.getPhoneNumber() == number) - == false: "something went wrong"; + assert !(s.getName().equalsIgnoreCase(name) && s.getPhoneNumber() == number) : "something went wrong"; //@@author Cryolian } @@ -155,4 +155,25 @@ public static void checkNameNumberPair(StudentList studentList, String name, int } + //@@author blackmirag3 + /** + * Checks if a new subject name matches that of any subject under a student + * Throws exception if match is found + * @param attributes Student's subjects to compare to + * @param newSubject New subject name to search for in student's subjects + * @param oldName Current subject name + * @throws InvalidSubjectException Thrown if match is found + */ + public static void checkExistingSubject(StudentAttributes attributes, String newSubject, + String oldName) throws InvalidSubjectException { + if (newSubject.equals(oldName)) { + throw new InvalidSubjectException("New subject name same as current."); + } + SubjectGrade foundSubject = attributes.findSubject(newSubject); + + if (foundSubject != null) { + throw new InvalidSubjectException("Subject already exists."); + } + } + } diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index c79accb888..30ed063a24 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -36,7 +36,7 @@ public class InputParsing { private static final String SORT = "sort"; private static final String ARCHIVE = "archive"; private static final String UNARCHIVE = "unarchive"; - private static final String ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK = + private static final String ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK = "Enter the subject name (type 'exit' to go back):"; private static final String EXIT = "exit"; private static final String EXITED_THE_COMMAND = "Exited the command."; @@ -51,15 +51,15 @@ public class InputParsing { private static final String CLASSES_ATTENDED_MUST_BE_LESS = "Classes attended must be less than 500."; public static void parseUserCommand(String[] userCommand, ArrayList masterStudentList, - ArrayList recentlyDeletedList, - ArrayList archiveList, Scanner in) { + ArrayList recentlyDeletedList, + ArrayList archiveList, Scanner in) { //@@author blackmirag3 if (masterStudentList == null) { System.out.println("Student list is null."); } //@@author tayponghee - - if (userCommand == null ) { + + if (userCommand == null) { UI.printDivider(); return; } @@ -106,7 +106,7 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas parseListCommand(masterStudentList, archiveList, recentlyDeletedList, in); } break; - + case PROCESS_FILE: TextFileHandler.process(masterStudentList, in); break; @@ -136,15 +136,16 @@ public static void parseUserCommand(String[] userCommand, ArrayList mas } //ParthGandhiNUS + /** * Function which leads to the chooseListType Function - * + * * @param masterStudentList List of the students used in the chooseListType function - * @param scanner Scanner used for the chooseListType function + * @param scanner Scanner used for the chooseListType function */ //@@author tayponghee public static void parseListCommand(ArrayList masterStudentList, ArrayList archiveList - , ArrayList deletedList, Scanner scanner) { + , ArrayList deletedList, Scanner scanner) { UI.printListCommandStart(); String subject = scanner.nextLine().trim(); ListStudentsCommand.chooseListType(masterStudentList, archiveList, deletedList, scanner, subject); @@ -190,6 +191,7 @@ private static void sortStudents(ArrayList masterStudentList, Scanner i } //@@author blackmirag3 + /** * Prompts for grade from user input and checks format * Prompts the user to enter a valid double within the range [0, 100] until one @@ -261,10 +263,10 @@ public static Student findStudentByName(ArrayList masterStudentList, St /** * Function looks through a list of students with the same name, * prints them out, and expects an Integer input to specify a student. - * + * * @param studentList List of students to look for. * @param in Scanner to parse in the user input. - * @return Student with right name and number pair. + * @return Student with right name and number pair. */ private static Student findStudentByNumber(ArrayList studentList, Scanner in) { assert studentList.size() > 1 : "List should contain more than one Student"; @@ -295,12 +297,12 @@ private static Student findStudentByNumber(ArrayList studentList, Scann } //@@author ParthGandhiNUS + /** * Returns a true or false depending on user input for number of lines - * - * @param classesAttended Takes in the integer input by the user + * + * @param classesAttended Takes in the integer input by the user * @return True if number of classes attended is greater than 0 and false otherwise. - * */ public static boolean isValidClassesAttended(int classesAttended) { @@ -317,14 +319,14 @@ public static boolean isValidClassesAttended(int classesAttended) { } return true; } - + //@@author ParthGandhiNUS + /** * Returns a true or false depending on user input for grade input - * - * @param grade Takes in the double input by the user for the subject grade - * @return False if number of subject grade is less than 0 or more than 100 - * Returns true otherwise + * + * @param grade Takes in the double input by the user for the subject grade + * @return False if number of subject grade is less than 0 or more than 100. Returns true otherwise */ //@@author blackmirag3 private static boolean isValidGrade(double grade) { @@ -339,19 +341,19 @@ private static boolean isValidGrade(double grade) { } //@@author Cryolian + /** * Creates a looping prompt asking for a phone number. * Only exits the loop when either an exception is thrown, * or when the number is either 8 or 10 digits to account for * the length of a Singaporean number, with or without * the country code. - * + * * @param in The scanner class to read inputs from. - * @return -1 if an exception was thrown. An 8 - * or 10-digit number if not. + * @return -1 if an exception was thrown. An 8 or 10-digit number if not. * @throws NumberFormatException thrown if invalid number is give */ - public static int promptForPhoneNumber(Scanner in) throws NumberFormatException{ + public static int promptForPhoneNumber(Scanner in) throws NumberFormatException { int number = 0; @@ -365,11 +367,12 @@ public static int promptForPhoneNumber(Scanner in) throws NumberFormatException{ } //@@author ParthGandhiNUS + /** * Uses the scanner to read the all the characters input by the user - * + * * @param in Scanner takes in the next line input by user - * @return integer value of the characters input by the user + * @return integer value of the characters input by the user * @throws NumberFormatException in the event that the characters input by the user are not numbers */ //@@author Cryolian @@ -381,9 +384,10 @@ private static int readInPhoneNumber(Scanner in) throws NumberFormatException { } //@@author ParthGandhiNUS + /** * Returns true or false depending on whether the number is a valid Singapore phone number - * + * * @param number Integer number input by user * @return True if the number is a valid Singapore Number, false otherwise */ @@ -393,14 +397,14 @@ public static boolean checkNumberValidity(int number) { } //@@author ParthGandhiNUS + /** * A prompting input to scan in a string from the user input. - * If special characters are found, the default string value + * If special characters are found, the default string value * is returned. - * + * * @param in The scanner class to scan inputs from. - * @return "Unknown" if blank was inputted, or the - * trimmed string inputted by the user. + * @return "Unknown" if blank was inputted, or the trimmed string inputted by the user. */ //@@author Cryolian public static String readInString(Scanner in) { @@ -409,7 +413,7 @@ public static String readInString(Scanner in) { if (string.isBlank()) { return DEFAULT_STRING_VALUE; } - + try { InputParsing.checkForSpecialCharacters(string); } catch (InvalidCharacterException e) { @@ -423,10 +427,12 @@ public static String readInString(Scanner in) { } //@@author Cryolian + /** * Prompts the user for a date in a format of YYYY--MM--DD + * * @param in The scanner object to read in the user input. - * @return A valid LocalDate object from the user input. + * @return A valid LocalDate object from the user input. */ public static LocalDate readInDate(Scanner in) { @@ -443,14 +449,15 @@ public static LocalDate readInDate(Scanner in) { return paymentDate; } - + //@@author Cryolian + /** - * Converts a string into a date format. If blank is entered, the current date is + * Converts a string into a date format. If blank is entered, the current date is * returned. - * + * * @param string The String to convert to a LocalDate object. - * @return A date parsed from the string or the current date as a LocalDate object. + * @return A date parsed from the string or the current date as a LocalDate object. */ protected static LocalDate parseDateFromString(String string) { @@ -471,6 +478,7 @@ protected static LocalDate parseDateFromString(String string) { return paymentDate; } + //@@author Cryolian private static LocalDate printInvalidDateMessage() { LOGGER.log(Level.WARNING, "Invalid date format entered." + '\n'); @@ -494,8 +502,8 @@ private static boolean isDateValid(LocalDate paymentDate) { /** * Checks if a string contains the special characters #,- or ~ - * - * @param string String to check. + * + * @param string String to check. * @throws InvalidCharacterException Thrown if the special characters are found. */ public static void checkForSpecialCharacters(String string) @@ -507,7 +515,7 @@ public static void checkForSpecialCharacters(String string) if (string.contains("~") || string.contains("-") || string.contains("#") - ) { + ) { throw new InvalidCharacterException(); diff --git a/src/main/java/classify/user/InvalidSubjectException.java b/src/main/java/classify/user/InvalidSubjectException.java new file mode 100644 index 0000000000..e48f76cafd --- /dev/null +++ b/src/main/java/classify/user/InvalidSubjectException.java @@ -0,0 +1,18 @@ +package classify.user; + +//@@author blackmirag3 +public class InvalidSubjectException extends Exception { + private String message; + public InvalidSubjectException() { + super(); + } + + public InvalidSubjectException(String message) { + super(); + this.message = message; + } + + public void printMessage() { + System.out.println(message); + } +} From a17625bc775a40565cdf0001faf16784d7ecfd92 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 14 Apr 2024 19:09:37 +0800 Subject: [PATCH 449/503] Update UG and sort function UI --- docs/UserGuide.md | 18 +++++++++++------- src/main/java/classify/user/InputParsing.java | 4 +--- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index dc8d9f8315..29e3d8aa08 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -492,11 +492,15 @@ Currently, there are 4 students in the list. ### Sort the list of students `sort` Sorts the list of students based on the following input. Allows the user to do sort [type] or just sort. -**Format:** `sort`, **`sort name`**, `sort classes` or `sort payment` +**Format:** `sort`, `sort name`, `sort classes` or `sort payment` Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. +In the event the commands **`sort name`**, `sort classes` or `sort payment` was typed, the program would immediately +go into the sort type. + + #### Example usage: ``` @@ -507,18 +511,18 @@ Sort by: (Choose index) 3. Date of last fee payment: 1 List of Students: -1. mario -2. toad -3. wario +1. Mario +2. Toad +3. Wario Currently, there are 3 students in the list. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sort complete! sort payment -1.toad - Date of last payment: 2015-10-21 -2.mario - Date of last payment: 2024-03-30 -3.wario - Date of last payment: 2024-03-30 +1.Toad - Date of last payment: 2015-10-21 +2.Mario - Date of last payment: 2024-03-30 +3.Wario - Date of last payment: 2024-03-30 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sort complete! ``` diff --git a/src/main/java/classify/user/InputParsing.java b/src/main/java/classify/user/InputParsing.java index ea5d8252a2..d5f5947ac3 100644 --- a/src/main/java/classify/user/InputParsing.java +++ b/src/main/java/classify/user/InputParsing.java @@ -36,12 +36,10 @@ public class InputParsing { private static final String SORT = "sort"; private static final String ARCHIVE = "archive"; private static final String UNARCHIVE = "unarchive"; - private static final String ENTER_THE_SUBJECT_NAME_TYPE_EXIT_TO_GO_BACK = - "Enter the subject name (type 'exit' to go back):"; private static final String EXIT = "exit"; private static final String EXITED_THE_COMMAND = "Exited the command."; private static final String LIST_SORTED = "Sort complete!"; - private static final String SORT_BY_CHOOSE_INDEX = "Sort by: (Choose index)"; + private static final String SORT_BY_CHOOSE_INDEX = "Sort by: (Choose index) or press enter to escape"; private static final String NAME_A_TO_Z = "1. Name (A to Z):"; private static final String TOTAL_NUMBER_OF_CLASSES_ATTENDED = "2. Total number of classes attended:"; private static final String LAST_PAID_DATE = "3. Date of last fee payment: "; From a99c3240073add73fed2a11903d19c7ea467ae02 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 14 Apr 2024 19:17:13 +0800 Subject: [PATCH 450/503] Update UG --- docs/UserGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 29e3d8aa08..acd1c89ca1 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -505,7 +505,7 @@ go into the sort type. ``` sort -Sort by: (Choose index) +Sort by: (Choose index) or press enter to escape 1. Name (A to Z): 2. Total number of classes attended: 3. Date of last fee payment: From 3086ba905aca816d3121b6ef996783f9a8e1255c Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 19:26:45 +0800 Subject: [PATCH 451/503] Test photo fix --- docs/AboutUs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 6ee565fd43..0b3836b7a5 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,8 +1,8 @@ # About us Display | Name | Github Profile | Portfolio --------|:---------:|:--------------:|:---------: -![](./team/Parth%20Image.JPG) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) -![](./team/purpleamogus.png) | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) -![](./team/magentaamogus.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) -![](./team/tayponghee.png) | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) -![](./team/Portrait_placeholder.png) | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) \ No newline at end of file +![](./team/Parth%20Image.JPG =100x20) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html)| +![](./team/purpleamogus.png) | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html)| +![](./team/magentaamogus.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html)| +![](./team/tayponghee.png) | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html)| +![](./team/Portrait_placeholder.png) | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html)| \ No newline at end of file From 44c1de4bfbeec6f003285d8c8f8124802c009679 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 19:32:40 +0800 Subject: [PATCH 452/503] Fix image size --- docs/AboutUs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 0b3836b7a5..75bf349d74 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,8 +1,8 @@ # About us Display | Name | Github Profile | Portfolio --------|:---------:|:--------------:|:---------: -![](./team/Parth%20Image.JPG =100x20) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html)| -![](./team/purpleamogus.png) | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html)| -![](./team/magentaamogus.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html)| -![](./team/tayponghee.png) | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html)| -![](./team/Portrait_placeholder.png) | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html)| \ No newline at end of file +| Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html)| +| Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html)| + | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html)| +| Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html)| +| Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html)| \ No newline at end of file From d0056965baa7f89bf2878d55359041d5f1528d65 Mon Sep 17 00:00:00 2001 From: blackmirag3 <78994143+blackmirag3@users.noreply.github.com> Date: Sun, 14 Apr 2024 19:44:11 +0800 Subject: [PATCH 453/503] Update PPP --- docs/AboutUs.md | 2 +- docs/DeveloperGuide.md | 80 ++++++++++++-------------------------- docs/team/blackmirag3.jpg | Bin 0 -> 151253 bytes docs/team/blackmirag3.md | 18 +++++---- 4 files changed, 36 insertions(+), 64 deletions(-) create mode 100644 docs/team/blackmirag3.jpg diff --git a/docs/AboutUs.md b/docs/AboutUs.md index f561238dfa..55680ebe03 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -2,7 +2,7 @@ Display | Name | Github Profile | Portfolio --------|:---------:|:--------------:|:---------: ![](./team/yellowamogus.jpg) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) -![](./team/purpleamogus.png) | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) +![](./team/blackmirag3.jpg) | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) ![](./team/magentaamogus.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) ![](./team/tayponghee.png) | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) ![](./team/Portrait_placeholder.png) | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) \ No newline at end of file diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 9fe8e21a72..7b7aaf5714 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -8,6 +8,7 @@ - [InputParsing component](#inputparsing-component) - [Student Details](#student-details) - [AddStudent Component](#addstudent-component) + - [EditStudent Component](#editstudent-component) - [StudentSorter Component](#studentsorter-component) - [Data Commands Component](#data-commands-component) - [Process Component](#process-component) @@ -175,6 +176,27 @@ or duplicate names are encountered. The `AddStudent` class contributes to the overall functionality of the application by providing a streamlined process for adding new students and ensuring data integrity within the student database. +### EditStudent Component +The `EditStudent` class is responsible for editing the subjects or details of an existing student. +This class contains the `editStudent` method which is called by `InputParsing` class when user chooses to enter edit mode for a student. + +The following is a sequence diagram for an example of when `editStudent` is called to find and modify a student's gender. + +![EditStudentSequenceUML](./diagrams/src/EditStudent/EditStudent.PNG) + +#### Design Considerations +- **Preventing Duplicate Subjects/Name-Number Pairs**: Checks if new subject name matches the name of any other existing subjects or if new phone number matches that of another student with same name. +- **Input Validation**: It validates the format of input attributes such as phone number, gender, last payment date, and remarks before overwriting student's details. +- **Modular Approach**: The class is designed with modularity in mind, + allowing easy addition of new attributes or modifications in the future. + +#### Implementation and Rationale +- **Case Commands**: Depending on what the user wishes to edit for the student, `addSubject`, `editSubject`, `deleteSubject`, `editNumber`, `editRemarks`, `editPaymentDate` and `editGender` methods are called. +- **Attribute Validation**: For adding and editing subject, the `InvalidSubjectException` is used to catch invalid subject names to prevent duplicate subjects from existing under a student. For modifying phone number, the `InvalidPhoneNumber` and `NameNumberMatchException` is used to catch invalid phone numbers and prevent duplicates in student-phone number pairs in the student list. +- **Error Handling**: Appropriate error messages are printed if invalid input or duplicate names are encountered. + +The `EditStudent` class contributes to the overall functionality of the application by providing a holistic process for editing existing students and ensuring data integrity within the student database. + ### StudentSorter Component The `StudentSorter` class facilitates sorting of the list of students based on various criterion. @@ -363,7 +385,7 @@ Classify serves as an attempt to modernise administrative tasks in education ins 3. Test Case: `unarchive`, `tim`
Expected: `tim` will be removed from archive and added back to student list. -#### 2. Archiving/unarchiving student that does not exist: +#### 3. Archiving/unarchiving student that does not exist: 1. Prerequisites: Have an empty student list 2. Test Case: `archive joe`
Expected: Error message printed for no student found and prompts for new command. @@ -387,61 +409,7 @@ Classify serves as an attempt to modernise administrative tasks in education ins 4. Test Case: `1`, ` `
Expected: Returns to edit mode for 'tim' and no change in subjects is made for 'tim'. -#### 3. Modifying existing subject under existing student -1. Prerequisites: Add student 'tim' with subject 'CS2113' and initiate edit mode for 'tim'. -2. Test Case: `2`, `CS2113`, `CS3223`, `2`, `0` -
Expected: Returns to edit mode for 'tim' and 'tim' now has subject 'CS3223' with '2' marks and '0' classes attended. -3. Test Case: `2`, ` ` -
Expected: Returns to edit mode for 'tim' and no change in subjects is made for 'tim'. - -#### 4. Deleting existing subject under existing student -1. Prerequisites: Add student 'tim' with subject 'CS2113' and initiate edit mode for 'tim'. -2. Test Case: `3`, `CS2113` -
Expected: Returns to edit mode for 'tim', subject 'CS2113' is deleted and 'tim' now has no subjects. -3. Test Case: `3`, ` ` -
Expected: Returns to edit mode for 'tim' and no change in subjects is made for 'tim'. - -#### 5. Modify existing phone number under existing student -1. Prerequisites: Add student 'tim' with phone number '88888888' and initiate edit mode for 'tim'. -2. Test Case: `4`, `88888887` -
Expected: Returns to edit mode for 'tim' and phone number for 'tim' is now '88888887'. -3. Test Case: `4`, ` ` -
Expected: Returns to edit mode for 'tim' and no change in phone number is made for 'tim'. -4. Test Case: `4`, `lol` -
Expected: Returns to edit mode for 'tim' and no change in phone number is made for 'tim'. - -#### 6. Modify remarks under existing student -1. Prerequisites: Add student 'tim' and initiate edit mode for 'tim'. -2. Test Case: `5`, `deans list material` -
Expected: Returns to edit mode for 'tim' and remarks for 'tim' is now 'deans list material'. -3. Test Case: `5`, ` ` -
Expected: Returns to edit mode for 'tim' and no change in remarks is made for 'tim'. - -#### 7. Modify payment date under existing student -1. Prerequisites: Add student 'tim' and initiate edit mode for 'tim'. -2. Test Case: `6`, ` ` -
Expected: Returns to edit mode for 'tim' and payment date for 'tim' is system's current date in YYYY-MM-DD format. -3. Test Case: `6`, `2000-11-20` -
Expected: Returns to edit mode for 'tim' and payment date for 'tim' is now '2000-11-20'. -4. -#### 8. Modify gender under existing student -1. Prerequisites: Add student 'tim' and initiate edit mode for 'tim'. -2. Test Case: `7`, `undefined` -
Expected: Returns to edit mode for 'tim' and gender for 'tim' is now 'undefined'. -3. Test Case: `7`, ` ` -
Expected: Returns to edit mode for 'tim' and no change in remarks is made for 'tim'. - -#### 9. Editing student in empty list -1. Prerequisites: Have empty list with no students added. -2. Test Case: `edit` -
Expected: Error message for empty list will be printed. - -#### 10. Editing non-existent student in non-empty list -1. Prerequisites: Add student `tim` -2. Test Case: `edit john` -
Expected: Error message for non-existed student will be printed. - -#### 11. Testing invalid entries for editing student +#### 3. Testing invalid entries for editing student 1. Prerequisites: Add student 'tim' with subjects 'CS2113', 'CS2040' and phone number '88888888' and initiate edit mode for 'tim'. 2. Test Case: `1`, `cs2113`
Expected: Returns to edit mode for 'tim', no new subject added and error message printed for adding existing subject. diff --git a/docs/team/blackmirag3.jpg b/docs/team/blackmirag3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c462fc27c2c5aee98f63e71a3e921ef69ca09d67 GIT binary patch literal 151253 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 Y?dw+6Q-yHJ(1Lo8YJBn+D(-*(*^9P{#{d8T literal 0 HcmV?d00001 diff --git a/docs/team/blackmirag3.md b/docs/team/blackmirag3.md index 4317e5caca..c03cbd2564 100644 --- a/docs/team/blackmirag3.md +++ b/docs/team/blackmirag3.md @@ -16,14 +16,18 @@ all Tuition Centres can employ for ease of student management. * Feature: `Edit` * Added base feature to access students' attributes and details. * Implemented sub-features such as adding, removing or editing existing subjects. - + * Feature: `Archive` and `Unarchive` * Implemented archiving and unarchiving feature. * Implemented `DataHandler` class to manage reading and writing of archived students within a data file. * Non-features: - * Implemented `SubjectGrade` class. - * Implemented and maintained heavily re-used helper functions for the team, such as `findSubject` which finds whether a subject exists under a student and `isValidGrade` which validates input format for grade. + * Implemented `SubjectGrade` class. + * Wrote `EditTest` class to test edit feature. + * Implemented helper functions and exceptions re-used by the team, such as: + * `findSubject` method which finds whether a subject exists under a student + * `isValidGrade` method which validates input format for grade. + * `InvalidSubjectException` exception which prevents duplicate subjects. Used by `AddSubject` and `EditSubject` classes. - **Contributions to [UG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/UserGuide.md)** @@ -37,16 +41,16 @@ all Tuition Centres can employ for ease of student management. * Wrote `Archiving/unarchiving a student` and `Editing a student's details` under manual testing. -- **Contributions to Team-Based tasks:** - * Wrote `EditTest` class to test edit feature. +- **Contributions to Team-Based tasks:** * Refactored/rewrote at least 300 LoC (authored by teammates) to improve code quality, such as for [input checking](https://github.com/AY2324S2-CS2113-T13-3/tp/commit/23f3ac553d243b9d31d80fdd05ff2ac3b3a2d57e) and [file IO](https://github.com/AY2324S2-CS2113-T13-3/tp/commit/932b51fbdb542b59f3ecdcaa1c04c65eda873ff1). * Established TP's current code organisation, such as refactoring project into respective packages `commands`, `data`, `ui` etc. * Maintained team's GitHub Project, such as updating status and priority of project items. - * Monitored and maintained repo's issues, such as opening, closing and re-assigning issues. + * Created group demo video. - **Review/mentoring contributions** * Actively reviewed and approved team's PRs, with some recent examples [here](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/258) or [here](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/246). + - **Contributions beyond project team** - * Did [exploratory testing of T13-4's TP] (https://github.com/orgs/AY2324S2-CS2113-T13-4/discussions/256) before their final release. \ No newline at end of file + * Did [exploratory testing of T13-4's TP](https://github.com/orgs/AY2324S2-CS2113-T13-4/discussions/256) before their final release. \ No newline at end of file From e3bcbba13cfc3afdb6fd0e4518adf796451189de Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 19:44:24 +0800 Subject: [PATCH 454/503] Add image --- docs/AboutUs.md | 4 ++-- docs/team/ssh.jpg | Bin 0 -> 146913 bytes 2 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 docs/team/ssh.jpg diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 75bf349d74..1dd08c6d88 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -2,7 +2,7 @@ Display | Name | Github Profile | Portfolio --------|:---------:|:--------------:|:---------: | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html)| -| Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html)| - | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html)| +| Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html)| + | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html)| | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html)| | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html)| \ No newline at end of file diff --git a/docs/team/ssh.jpg b/docs/team/ssh.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1ce0c7cc0d4fc2b04d9696f149de375846fa1ba0 GIT binary patch literal 146913 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Ư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

chFhvM_ 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 literal 0 HcmV?d00001 From 87431f7dcc23ac68cce986e42e73e5768a2f86d9 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 19:44:57 +0800 Subject: [PATCH 455/503] Edit PPP --- docs/team/parthgandhinus.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/team/parthgandhinus.md b/docs/team/parthgandhinus.md index 0e331d064e..17b2d1c4ed 100644 --- a/docs/team/parthgandhinus.md +++ b/docs/team/parthgandhinus.md @@ -15,6 +15,7 @@ Overall, the code base has more than 7000 Lines of Code, and is written in Java. * Refers to the writing of data in Student_Information.txt in Classify * Highlights: Creates a directory and file on your computer if it does not exist. Updates the Student_Information.txt file with all the students' attributes (eg. Name, Phone Number, Gender, Last Payment Date, All subject information, etc). The file is constantly overwritten when a command (eg. Add Student, Delete Student, etc) is used. There is a standardised format used to store all the data. Different Regex are used to differentiate the different types of data and to assist in data parsing (mentioned below). * Justification: Since the data inputted by the user is what forms our "database" of students we need to constantly update our database with every change to ensure our "database" is updated. +

**Feature: Data Retrieval and Parsing from Student_Information.txt** * Refers to the retrieval and parsing of retrieved data in Classify @@ -36,6 +37,7 @@ Overall, the code base has more than 7000 Lines of Code, and is written in Java. Otherwise this functionality either attributes the subject in this text file to the existing student or makes a new student with info about this subject and the students' phone number. * Just like the data parser, the process here has a separate fully functional parser which parses information a bit differently as compared to the data parser. In the process parser, the only regex used is ```~~``` to ensure that it is simple for users to make the text file for entering into the system. * Justification: Process is meant to be a one-stop fast and easy way for administrators to add students. The system already checks for matching students and matching subjects for every student which makes this functionality quite useful in real life. +
--- **Code contributed:** [Link to Reposense contribution graph](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=ParthGandhiNUS&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2024-02-23&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) @@ -46,8 +48,10 @@ Overall, the code base has more than 7000 Lines of Code, and is written in Java. * [Contributions to UG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/UserGuide.md): * Did the preface for the project. * Wrote out the functionalities for Process Command - [Sample File](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/SampleFile.txt) - [Format for writing text file](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/Text%20File%20Format%20Picture.jpg) + + [Sample File](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/SampleFile.txt) + + [Format for writing text file](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/Text%20File%20Format%20Picture.jpg) * Made the command summary in Tabular form for easy referencing * Refactored and cleaned the UG * Made the table of contents for the UG, linking the relevant parts of the markdown file From 0f4bcaf49c53123e6f92ba8e3df02920d175c51d Mon Sep 17 00:00:00 2001 From: blackmirag3 <78994143+blackmirag3@users.noreply.github.com> Date: Sun, 14 Apr 2024 19:49:58 +0800 Subject: [PATCH 456/503] Update AddStudent.java --- src/main/java/classify/commands/AddStudent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index d1ca562048..6b54d8e46c 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -220,7 +220,7 @@ public static void addSubject(Scanner in, StudentAttributes attributes) { return; } - if (checkForValidSubjectResponse(in, attributes, subject)) { + if (isValidSubjectResponse(in, attributes, subject)) { //@@author tayponghee return; } From d24497faba344e17157465717be6312cc80104c0 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 19:54:06 +0800 Subject: [PATCH 457/503] Fix spacing --- docs/AboutUs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index e6315f0f70..6fc79d474f 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,8 +1,8 @@ # About us Display | Name | Github Profile | Portfolio --------|:---------:|:--------------:|:---------: -| Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html)| -| Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html)| - | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html)| -| Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html)| -| Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html)| \ No newline at end of file +| Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) +| Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) + | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) +| Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) +| Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) \ No newline at end of file From 433ae42f7209590a57227f4bbaaa32eabd81e0bd Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 19:55:25 +0800 Subject: [PATCH 458/503] Fix spacing --- docs/AboutUs.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 6fc79d474f..23ce2ce819 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -2,7 +2,11 @@ Display | Name | Github Profile | Portfolio --------|:---------:|:--------------:|:---------: | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) + | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) + | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) + | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) + | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) \ No newline at end of file From 5c248dac85065bdb1304dfdd7a1a8c8e67cb811e Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 19:59:19 +0800 Subject: [PATCH 459/503] Another fix attempt --- docs/AboutUs.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 23ce2ce819..ecc2d05671 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,12 +1,8 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:---------:|:--------------:|:---------: +|Display | Name | Github Profile | Portfolio +|--------|---------|--------------|---------| | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) - | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) - | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) - | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) - | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) \ No newline at end of file From cc0bc00364e1f4b6d776d3d73739e03b7c9beaa5 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sun, 14 Apr 2024 20:00:27 +0800 Subject: [PATCH 460/503] Add photo to aboutus.md --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index bd117e192d..457bb92d00 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -3,6 +3,6 @@ Display | Name | Github Profile | Portfolio --------|:---------:|:--------------:|:---------: ![](./team/Parth%20Image.JPG) | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) ![](./team/blackmirag3.jpg) | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) -![](./team/magentaamogus.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) +![](./team/Portrait_placeholder.png) | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) ![](./team/tayponghee.png) | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) ![](./team/Portrait_placeholder.png) | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) \ No newline at end of file From 9ceb6ed5979d56210f05b376d6cbdcdcb930e17c Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 20:04:20 +0800 Subject: [PATCH 461/503] Add pagebreaks for UG --- docs/UserGuide.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index dc8d9f8315..5186f22ad1 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -21,6 +21,7 @@ - [`Bye`](#exit-classify-bye) - [Command Summary](#command-summary) - [FAQ](#faq) + ---
@@ -188,6 +189,8 @@ Some may debate that our time zone is actually GMT+7.5 or GMT+7, but it was chan Last payment date must be within a range from 1970-01-01 to the day after the current date. This is a buffer to account for situations when storing dates, such as for audit reasons. +
+ #### Example usage: ``` add wario @@ -226,6 +229,8 @@ How it works (cases for input): - view JAMES WONG -> JAMES WONG * Regardless of what capitalisation the user uses for the name, the program will recognise that upper and lower cases should return the same student. +
+ #### Example usage: ``` view wario From 980f74efc0dec056627544a7b8a18878fe5f9ea5 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 20:05:54 +0800 Subject: [PATCH 462/503] Another fix attempt --- docs/AboutUs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index ecc2d05671..cf1243a79e 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,8 +1,8 @@ # About us |Display | Name | Github Profile | Portfolio |--------|---------|--------------|---------| -| Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) -| Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) - | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) -| Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) -| Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) \ No newline at end of file +| | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) +| | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) +| | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) +| | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) +| | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) \ No newline at end of file From e994201000f0ba4785247ec0ff2e7037448b4405 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 20:06:55 +0800 Subject: [PATCH 463/503] Another fix attempt --- docs/AboutUs.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index b89a635446..de7b0e0289 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,17 +1,8 @@ # About us |Display | Name | Github Profile | Portfolio |--------|---------|--------------|---------| -<<<<<<< HEAD -| Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) -| Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) - | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) -| Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) -| Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) - -======= | | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) | | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) | | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) | | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) | | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) ->>>>>>> master From 8811dc9c875600f9eee0c8c297dd30a3dbad6126 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 20:10:11 +0800 Subject: [PATCH 464/503] Remove space --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index de7b0e0289..19cb40779b 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -5,4 +5,4 @@ | | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) | | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) | | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) -| | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) +| | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) From a0687e1975f28ac76a5aa51ad9d67ebb4e744085 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 20:11:12 +0800 Subject: [PATCH 465/503] Add lines --- docs/AboutUs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 19cb40779b..7c66d8c29c 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,8 +1,8 @@ # About us |Display | Name | Github Profile | Portfolio |--------|---------|--------------|---------| -| | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) -| | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) -| | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) -| | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) -| | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) +| | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html)| +| | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html)| +| | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html)| +| | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html)| +| | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html)| \ No newline at end of file From 38b37cf2d639e3646ded286b4e32133828a340b0 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 20:12:32 +0800 Subject: [PATCH 466/503] Add missing line --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 7c66d8c29c..274983b969 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,5 +1,5 @@ # About us -|Display | Name | Github Profile | Portfolio +| Display | Name | Github Profile | Portfolio | |--------|---------|--------------|---------| | | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html)| | | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html)| From 4e39cc39203ead47301bf0aa72eace418f4f8970 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 20:14:49 +0800 Subject: [PATCH 467/503] insn --- docs/AboutUs.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 274983b969..01731a1e9c 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,8 +1,8 @@ # About us -| Display | Name | Github Profile | Portfolio | -|--------|---------|--------------|---------| -| | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html)| -| | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html)| -| | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html)| -| | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html)| -| | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html)| \ No newline at end of file +Display | Name | Github Profile | Portfolio +--------|:----:|:--------------:|:---------: + | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) + | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) + | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) + | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) + | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) \ No newline at end of file From 96886ee8cf657cfbd153794b15bf86c0bf323bdc Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 20:17:17 +0800 Subject: [PATCH 468/503] last try before i do html --- docs/AboutUs.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 01731a1e9c..590040a1d8 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,8 +1,8 @@ # About us -Display | Name | Github Profile | Portfolio ---------|:----:|:--------------:|:---------: - | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html) - | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html) - | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html) - | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html) - | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html) \ No newline at end of file +| Display | Name | Github Profile | Portfolio +|--------|:----:|:--------------:|:---------:| +| | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html)| +| | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html)| +| | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html)| +| | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html)| +| | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html)| \ No newline at end of file From b9169fa110837bbb6a3be8ebec9761917c961cb7 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 20:20:46 +0800 Subject: [PATCH 469/503] 1 --- docs/AboutUs.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 590040a1d8..47b36f4fc9 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,8 +1,8 @@ # About us | Display | Name | Github Profile | Portfolio |--------|:----:|:--------------:|:---------:| -| | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html)| -| | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html)| -| | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html)| -| | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html)| -| | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html)| \ No newline at end of file +| | Gandhi Parth Sanjay | [Github](https://github.com/ParthGandhiNUS) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/parthgandhinus.html)| +| | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html)| +| | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html)| +| | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html)| +| | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html)| \ No newline at end of file From d2e25b17472395f4ace4dc54683e305c1a75fdf6 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 20:21:33 +0800 Subject: [PATCH 470/503] 12 --- docs/AboutUs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index 47b36f4fc9..f433b5c0b0 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -5,4 +5,4 @@ | | Siew Shui Hon | [Github](https://github.com/blackmirag3) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/blackmirag3.html)| | | Tan Bingxue Gerard | [Github](https://github.com/#5alalal47) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/alalal47.html)| | | Tay Pong Hee | [Github](https://github.com/tayponghee) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/tayponghee.html)| -| | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html)| \ No newline at end of file +| | Tan Yi Xin | [Github](https://github.com/Cryolian) | [Portfolio](https://ay2324s2-cs2113-t13-3.github.io/tp/team/cryolian.html)| \ No newline at end of file From 93a44ca09959a478df740e85d0fcb457b46794ae Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 20:24:38 +0800 Subject: [PATCH 471/503] Update UG to make it more printable --- docs/UserGuide.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 9b3125b615..5e7b5f3ddc 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -269,6 +269,8 @@ Deletes the student from the list. Allows the user to do delete [student] or jus Depending on whether the user entered the student's name or not during the command, a field will be printed out in the terminal, awaiting a user input. +
+ #### Example usage: ``` delete @@ -302,6 +304,8 @@ The user can enter the action's index to execute the respective action, e.g. use Each action has its own step by step prompts for user to follow, as seen in below. +
+ #### Example usages: ``` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -348,6 +352,7 @@ Name of student to edit (blank to exit): luigi No student found to edit! ``` +
### Restore a student to the working list `restore` Restores a student deleted in the current session. Allows the user to do restore [student] or just restore. @@ -494,6 +499,8 @@ List of students in recently deleted: Currently, there are 4 students in the list. ``` +
+ ### Sort the list of students `sort` Sorts the list of students based on the following input. Allows the user to do sort [type] or just sort. @@ -532,6 +539,8 @@ sort payment Sort complete! ``` +
+ ### Process a list of students from a text file `process` Reads a text file in the inputFolder folder located inside the data folder. @@ -565,6 +574,8 @@ Peach ~~ 98888888 ~~ 95.0 Tai Lung ~~ 90909090 ~~ 99.0 ``` +
+ #### Different types of Processing Possible: ##### Without File extension: @@ -657,7 +668,11 @@ edit Edits a students details, expects a name, can be used directly with a name e.g. edit [name] +``` + +
+``` view Views a students details, expects a name, can be used directly with a name @@ -706,7 +721,10 @@ archive the list and archives them, expects a name, can be used directly by archive [name]. +``` +
+``` unarchive Removes the specified student from the archive and adds them to the list, From 8c7ca223c65bb0efc83619b1a47e4d917e0beb5f Mon Sep 17 00:00:00 2001 From: Cryolian Date: Sun, 14 Apr 2024 20:29:03 +0800 Subject: [PATCH 472/503] html attempt --- docs/AboutUs.md | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/docs/AboutUs.md b/docs/AboutUs.md index f433b5c0b0..6c860309ce 100644 --- a/docs/AboutUs.md +++ b/docs/AboutUs.md @@ -1,8 +1,50 @@ # About us + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DisplayNameGithub ProfilePortfolio
Gandhi Parth SanjayGithubPortfolio
Siew Shui HonGithubPortfolio
Tan Bingxue GerardGithubPortfolio
Tay Pong HeeGithubPortfolio
Tan Yi XinGithubPortfolio
+ + + + \ No newline at end of file From 226692b37b0de73c2b5eda107c6ebd09bc2e859e Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sun, 14 Apr 2024 22:09:20 +0800 Subject: [PATCH 473/503] Add a few more test cases to be more comprehensive --- .../textfilecode/TextFileParserTest.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/test/java/classify/textfilecode/TextFileParserTest.java b/src/test/java/classify/textfilecode/TextFileParserTest.java index 9b9c60f925..24c078a435 100644 --- a/src/test/java/classify/textfilecode/TextFileParserTest.java +++ b/src/test/java/classify/textfilecode/TextFileParserTest.java @@ -161,7 +161,7 @@ public void testMatchingNameNumberTrueCase() { } @Test - public void testMatchingNameNumberFalseCase() { + public void testMatchingNameNumberFalseCase1() { ArrayList masterStudentList = new ArrayList<>(); Student student = new Student("Jane Doe"); masterStudentList.add(student); @@ -169,4 +169,24 @@ public void testMatchingNameNumberFalseCase() { assertFalse(TextFileParser.isMatchingNameNumber(masterStudentList, JOHN_DOE, NORMAL_SG_NUMBER)); } + + @Test + public void testMatchingNameNumberFalseCase2() { + ArrayList masterStudentList = new ArrayList<>(); + Student student = new Student(JOHN_DOE); + masterStudentList.add(student); + student.getAttributes().setPhoneNumber(98989898); + + assertFalse(TextFileParser.isMatchingNameNumber(masterStudentList, JOHN_DOE, NORMAL_SG_NUMBER)); + } + + @Test + public void testMatchingNameNumberFalseCase3() { + ArrayList masterStudentList = new ArrayList<>(); + Student student = new Student("Jane Doe"); + masterStudentList.add(student); + student.getAttributes().setPhoneNumber(NORMAL_SG_NUMBER); + + assertFalse(TextFileParser.isMatchingNameNumber(masterStudentList, JOHN_DOE, NORMAL_SG_NUMBER)); + } } From 09110f75a9069e0d38bbed985a8a9d200de9f1e5 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 14 Apr 2024 23:26:42 +0800 Subject: [PATCH 474/503] Add exception handling and remove unrelated NFR --- docs/DeveloperGuide.md | 3 +-- src/main/java/classify/commands/AddStudent.java | 8 +++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 6e31d3f6af..7e46e8f3d9 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -294,14 +294,13 @@ Classify serves as an attempt to modernise administrative tasks in education ins 1. **Performance**: - The system should respond to user actions within 1 second under normal operating conditions. - - It should be able to handle a minimum of 100 concurrent users without significant degradation in performance. - The system should encompass all basic data types that an administrator would need to know about a student to register them for classes in the tuition centre. 2. **Reliability**: - In the event the program crashes, the data that was last updated into the storage should not be destroyed. 3. **Scalability**: - - The system should be designed to accommodate future growth in the number of students and users. + - The system should be designed to accommodate future growth in the number of students. 4. **Usability**: - The user interface should be intuitive and easy to navigate, requiring minimal training for users to become proficient. diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 6b54d8e46c..645d4a309f 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -83,7 +83,13 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, return; } - setAttributesForStudent(masterStudentList, in, student, number); + //@@author tayponghee + try { + setAttributesForStudent(masterStudentList, in, student, number); + } catch (Exception e) { + UI.println("An error occurred while setting attributes for the student: " + e.getMessage()); + UI.printDivider(); + } } /** From 068ce271e81b1dc18361b1c320fa0e76c441be13 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 14 Apr 2024 23:34:07 +0800 Subject: [PATCH 475/503] Add nullpointerexception handling, fix author tag --- src/main/java/classify/commands/AddStudent.java | 1 + src/main/java/classify/commands/ViewStudent.java | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/main/java/classify/commands/AddStudent.java b/src/main/java/classify/commands/AddStudent.java index 645d4a309f..724d949713 100644 --- a/src/main/java/classify/commands/AddStudent.java +++ b/src/main/java/classify/commands/AddStudent.java @@ -92,6 +92,7 @@ public static void addStudent(ArrayList masterStudentList, Scanner in, } } + //@@author cryolian /** * Sets attributes for a given student, including phone number, gender, last payment date, and remarks. * diff --git a/src/main/java/classify/commands/ViewStudent.java b/src/main/java/classify/commands/ViewStudent.java index 7e73cb4236..8264a0cd08 100644 --- a/src/main/java/classify/commands/ViewStudent.java +++ b/src/main/java/classify/commands/ViewStudent.java @@ -85,11 +85,20 @@ public static void showStudentInfo(Student foundStudent) { */ private static int getTotalClassesAttended(Student student) { int totalClassesAttended = 0; - for (classify.student.SubjectGrade subjectGrade : student.getAttributes().getSubjectGrades()) { - if (subjectGrade.getClassesAttended() >= 0) { - totalClassesAttended += subjectGrade.getClassesAttended(); + + try { + for (classify.student.SubjectGrade subjectGrade : student.getAttributes().getSubjectGrades()) { + if (subjectGrade != null && subjectGrade.getClassesAttended() >= 0) { + totalClassesAttended += subjectGrade.getClassesAttended(); + } } + } catch (NullPointerException e) { + UI.println("A NullPointerException occurred while calculating total classes attended for student: " + + student.getName()); + UI.printDivider(); + return -1; } + return totalClassesAttended; } From 20605ed20e20dde8c26eb8547eac6f835c03a0b5 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 14 Apr 2024 23:51:43 +0800 Subject: [PATCH 476/503] Update UG --- docs/UserGuide.md | 20 +++++++++++++++++-- .../java/classify/commands/ViewStudent.java | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 5e7b5f3ddc..a02d1be37b 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -187,8 +187,13 @@ Thus, please be informed and educated that our software only works in countries To be specific, this is referring to a city-state republic in South East Asia, that lies in the timezone GMT +8 in the Straits of Johor. Some may debate that our time zone is actually GMT+7.5 or GMT+7, but it was changed to facilitate business deals and decisions with other financial hubs in the region thanks to our capitalistic overlords. +Do note that the subject field will allow numbers as well, since lessons such as Chinese1E and Chinese1H are legitimate class names, which could signify express and higher mother tongue respectively. +As such, it is on the onus of the user to not use nonsensical names for the subjects, to ensure that the database is sensible. + Last payment date must be within a range from 1970-01-01 to the day after the current date. This is a buffer to account for situations when storing dates, such as for audit reasons. +The gender field and remarks section are optional, hence if the user presses `enter`, they would proceed with the next command or end the add student interface respectively. +
#### Example usage: @@ -208,9 +213,20 @@ Do you want to add another subject and grade? (yes/no) no Please input a valid Phone number: +Enter a non-number or blank to exit interface. 89718971 -. -. + +Please input the student's gender: +male + +Please input their last payment date in the format of YYYY-MM-DD. Enter blank to input today's date. +14-04-2024 + +Please input any remarks: +He likes turtles + +Student added successfully! +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` ### View details of a student `view` diff --git a/src/main/java/classify/commands/ViewStudent.java b/src/main/java/classify/commands/ViewStudent.java index 8264a0cd08..83f65b22f2 100644 --- a/src/main/java/classify/commands/ViewStudent.java +++ b/src/main/java/classify/commands/ViewStudent.java @@ -98,7 +98,7 @@ private static int getTotalClassesAttended(Student student) { UI.printDivider(); return -1; } - + return totalClassesAttended; } From c8624f5fb35396c9c9120145832ac0ff03e5cd45 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 14 Apr 2024 23:54:26 +0800 Subject: [PATCH 477/503] Fix errorneous add example location --- docs/UserGuide.md | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index a02d1be37b..873ab05d7f 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -228,6 +228,21 @@ He likes turtles Student added successfully! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` +For any student that exists within the programme's master, archive and recently deleted list, the user cannot add new students with a name-phone number pair that matches that of the existing student. + +The following is an example of trying to add a new student that matches the name and phone number of an already existing student. + +#### Example usage: +``` +add melodie +Subject (enter nothing to skip): +No subjects added. +Please input a valid phone number: +Enter a non-number or blank to exit interface. +88888888 +Student and Phone number pair found. If not found in the list, please restore or unarchive the student instead. +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``` ### View details of a student `view` @@ -261,21 +276,7 @@ Subject: subject Current marks out of 100: 100.0 Classes Attended: 1 ``` -For any student that exists within the programme's master, archive and recently deleted list, the user cannot add new students with a name-phone number pair that matches that of the existing student. - -The following is an example of trying to add a new student that matches the name and phone number of an already existing student. -#### Example usage: -``` -add melodie -Subject (enter nothing to skip): -No subjects added. -Please input a valid phone number: -Enter a non-number or blank to exit interface. -88888888 -Student and Phone number pair found. If not found in the list, please restore or unarchive the student instead. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -``` ### Delete a student from the working list `delete` Deletes the student from the list. Allows the user to do delete [student] or just delete. From 5dfdd228943a17356b208e629dd120fa7f51c34e Mon Sep 17 00:00:00 2001 From: tayponghee Date: Mon, 15 Apr 2024 19:54:12 +0800 Subject: [PATCH 478/503] Update UG --- docs/UserGuide.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 873ab05d7f..82d231fd74 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -160,7 +160,7 @@ Exits the program. # Usage -**Please note that if any of the following characters are entered in any string prompts, `#, - and ~`, they will be replaced and your command may be deemed invalid.** +**Please note that any of the following characters are banned in any string prompts, `#, -` and `~` in all fields except for the date of payment field.** ### Adding a student: `add` Initialises an interface for adding a student and their relevant details to the database. Allows the user to do add or add [name] @@ -228,7 +228,7 @@ He likes turtles Student added successfully! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` -For any student that exists within the programme's master, archive and recently deleted list, the user cannot add new students with a name-phone number pair that matches that of the existing student. +For any student that exists within the program's master, archive and recently deleted list, the user cannot add new students with a name-phone number pair that matches that of the existing student. The following is an example of trying to add a new student that matches the name and phone number of an already existing student. @@ -277,6 +277,8 @@ Current marks out of 100: 100.0 Classes Attended: 1 ``` +Note that if 2 people of the same name are present in the list, the program will prompt the user to differentiate them through a choice between the available phone numbers tagged to them. + ### Delete a student from the working list `delete` Deletes the student from the list. Allows the user to do delete [student] or just delete. @@ -302,7 +304,7 @@ Edit a student's details and subjects. Allows the user to do edit [student] or j **Format:** `edit` or `edit NAME` If user has not entered a name, they will be prompted to input a name. -Once programme received name input, the student master list will be searched for the name. Name search is not case-sensitive. +Once program received name input, the student master list will be searched for the name. Name search is not case-sensitive. If the name input matches that of an existing student, edit mode will be entered for that student. If 2 students with the same name is found, the user will be prompted to enter the desired student's phone number to select them. @@ -359,7 +361,7 @@ Do you want to add another subject and grade? (yes/no) >> no ``` -If no student is found in the master student list, edit mode will not be entered and the programme will resume as per normal. +If no student is found in the master student list, edit mode will not be entered and the program will resume as per normal. #### No student found to edit: @@ -369,8 +371,11 @@ Name of student to edit (blank to exit): luigi No student found to edit! ``` + +Similar to View Student, if the there are 2 or more students with the same name, the program would prompt the user to input the corresponding phone number of the student that they would like to edit.
+ ### Restore a student to the working list `restore` Restores a student deleted in the current session. Allows the user to do restore [student] or just restore. @@ -424,6 +429,9 @@ Do note that there is a difference between 0 and no classes attended found. If t it means that the user entered the field 0 when adding the student. If it says no classes found, it means the user skipped that field when adding the student. +Important: If the input is invalid in the indexed portion of the list, e.g. the user types in `6`, `hello` or presses `enter`, the +list command would terminate. + #### Example usage: ``` list From 9c7482615598af5bda506201452dd95beb04bbeb Mon Sep 17 00:00:00 2001 From: blackmirag3 Date: Mon, 15 Apr 2024 20:38:14 +0800 Subject: [PATCH 479/503] Add archive component to Dg --- docs/DeveloperGuide.md | 16 ++++++++++--- .../src/ArchiveCommands/ArchiveCommands.png | Bin 0 -> 25177 bytes .../archiveSequenceDiagram.puml | 21 ++++++++++++++++++ docs/diagrams/src/EditStudent/EditStudent.PNG | Bin 25794 -> 31028 bytes ... Diagram.puml => editSequenceDiagram.puml} | 2 +- 5 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 docs/diagrams/src/ArchiveCommands/ArchiveCommands.png create mode 100644 docs/diagrams/src/ArchiveCommands/archiveSequenceDiagram.puml rename docs/diagrams/src/EditStudent/{Architecture Diagram.puml => editSequenceDiagram.puml} (92%) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 6e31d3f6af..d6c2ee9564 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -255,6 +255,19 @@ This section refers to `TextFileHandler.java`, `TextFileParser.java`, and `TextF * **Checker for same student**: Ensures that we dont have duplicate entries of one student. * **Checker for same subject**: Ensures that an existing student does not get duplicate entries of the same subject (Not applicable for new students for obvious reasons) +### ArchiveCommands Component +The `ArchiveCommands` class is responsible for transferring students from the student list to archive list and vice versa, using methods `archiveStudent` and `unarchiveStudent`. +This class contains the `editStudent` method which is called by `InputParsing` class when user chooses to enter edit mode for a student. + +The following is a sequence diagram for an example of when `archiveStudent` is called to move a student from the student list to archive. + +![ArchiveCommandsSequenceDiagram](./diagrams/src/ArchiveCommands/ArchiveCommands.PNG) +#### Design Considerations +* Write data using `Data Commands` component into archive and student data file whenever there is change. +* Check for student-number pairs whenever student is archived or unarchived to ensure there are no duplicate students amongst all student lists. + +#### Implementation and Rationale +* **Exception Handling**: Uses the 'checkNameNumberPair' method and catches 'NameNumberMatchException' --- @@ -317,9 +330,6 @@ Classify serves as an attempt to modernise administrative tasks in education ins 7. **Data Management**: - File saving should done whenever a change has been made to the Master List. -## Glossary - -* *glossary item* - Definition ## Instructions for manual testing diff --git a/docs/diagrams/src/ArchiveCommands/ArchiveCommands.png b/docs/diagrams/src/ArchiveCommands/ArchiveCommands.png new file mode 100644 index 0000000000000000000000000000000000000000..c2d139b42c258304ef44478783248b23040d31f4 GIT binary patch literal 25177 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 literal 0 HcmV?d00001 diff --git a/docs/diagrams/src/ArchiveCommands/archiveSequenceDiagram.puml b/docs/diagrams/src/ArchiveCommands/archiveSequenceDiagram.puml new file mode 100644 index 0000000000..4b3ce121fb --- /dev/null +++ b/docs/diagrams/src/ArchiveCommands/archiveSequenceDiagram.puml @@ -0,0 +1,21 @@ +@startuml +title Sequence Diagram: Calling editStudent and editing gender + +actor User +participant "InputParsing" as InputParsing <> +participant "ArchiveCommands" as ArchiveCommands<> +activate StudentList +activate ArchiveCommands +activate InputParsing + +User->InputParsing: String: ARCHIVE +"InputParsing"->"ArchiveCommands": archiveStudent() +User-> ArchiveCommands: String: NAME +ArchiveCommands -> StudentList: getStudent(NAME) +ArchiveCommands <-- StudentList: Student:student +ArchiveCommands -> StudentList: masterList.remove(student) +ArchiveCommands -> StudentList: archiveList.add(student) +deactivate ArchiveCommands +deactivate StudentList +hide footbox +@enduml \ No newline at end of file diff --git a/docs/diagrams/src/EditStudent/EditStudent.PNG b/docs/diagrams/src/EditStudent/EditStudent.PNG index e5fce4faeabe854b982c2406e1865a37aaec2a41..87bbce472f528b14dac1a01b3e4155a329559f2a 100644 GIT binary patch literal 31028 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
Q{Z0)6@9nt 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 literal 25794 zcmce;by!y2yERHG4N4;+3W6XhNP~bPAkqj*iG0ume?d8ZsWP6}(_Ail{VmI5OoeSJ(HCt{3G`RwFH{7LWn-Qf6S>@agf zHeLw%Xur6cAxzaOBG^sKEhi*3#wt=iLtbpTKa*yx%re+^XP%2oQo|g%(^CL;)YVgI zZ=L?)Yf1={x>_gijzqe8b(MT_F`M_)P{A5GXdG}}`E=<@9tK}1e^6Xrg`lk)Y4SPwf zAWWTaTxPTHPiH7#fpO=%sdPp)F7R}*(bJtg8}ftm6X$CaS{;$>%aPg2#ghHCnK@;x zE%;bF!-&?L6sX78PD>gimfyENJe6q)V%m;2It@-&1ky+*%iKee6mAVgD@ zu0~(Qrt5#HZRB+mKqY&-SP)L4RsJF~$Uhj!1nS=0&QI$^Ms70!e40k=Y>SS!A zHJZyjx(}i5T#-XP|<=!7poemwJWO zC&JY1#Bxfe(T?Uhsv|y4IQnC6tv@ELWD7Ru;{6&>R z>DMqA>_8~&|-q7!>Pu_T<5dQ;6#&Bwsjk_ z#!{IpA;{X14-6xN6X6b=Zm#Yzw%%EsiM-B{&xN!QZSH^UHgVKxJxf@9=+Pd-Qyd77 zuu-w&A40Dvsc>_&cJ0U4C&#->iTfT2Y{pebDL(omMcD@96)#YW#t5&EXt#Z`6iPK& zK(|+`RNtBJ=vU=BNA#4qc2G}o{=J3z%iHc-=}P$t%ghsYD-1`2)#ub72$`OTD&X!% zt1X(9yvTd?&c}GHtPmRBk59;DuIz74)o)M0&L-#_Hz#W)Gnz+?tFxzH&2ktHCm}Ui zP(1aL$v5SzIzQH@Np|_Xvv|fbw)KrrowiA+NyCQ1a~}L(UL)jj;*Psu*p0zE7#eL^ zs5h`O?rY?h63P@rCDcXctqmJHH+bmAX|%aP#cV)avKl9Rvzp2BUd}f4A_%i zwbkj0%@#=;$WhHS@@&6LpX8OU$(_}0LEVatx z76FWRUKTqY9BnzO<2Q%`UFX$F18na_Fc(4_{Y2z%6{r< zn7*7nD+Adp4etx|2PMBnh~TLepD1ykc0ZxuVmY^od9qP$HYbiRl4#ZBxYw_kAsA=c zNKA)e5z9RJ@+K3BUJ;&x&a)vC=@?Y|j>`85V|e%j?uLU-C$||TPB4_$Rf;uZayju7 ztX(^AKymgG#F=`?o?3wDEdk$fLQ!nFCJUm$hl#mYThmN82>0#0@=@0{o1Ph9!E;)z zhHr~I?|+R;kHtvlbbe(vk`;G+ zuc6sXGFk9*l(dQPlK3>nSkE;2ne{&7NY|jpFkH4U(En0eg|j&DEPQ8?lgQD}|9(LF zjF0dGEWrob1MZkt`y=uOM?cUGKaN-*De@c&c$}e3QXbQa`EjV^m7du!P*SKM0f3R-(8Vw5UlCIS5*gcRT*BkIU zPtG=+)ji^D=ZOnTu*k}Iq)d6xgP9k$h6M~%luQ`%jKlA`O^0xe$K$AZ(De5y24}92_72? z6rZb>e07{if`iHn^sN_>nLLjJ$5-LFUb?`|lIoeChm%aZJ1X#BB(dP=@H*Q)<{O?1wKQ=Kva|u@jrYAy zd?HylZ?)T2>|^6Dgf?Nf&rlkNKlb=`*Stu>kB5Ji{ovN%S|eFwh#xT{S}u4R=b?S# zqR~>LrXQyp(*xF%{@5qZm9*JqI0bQyWa>e7#$TLa=fNv}?bmwpEG4{5G1-po@YuC+ zF2d_aUoq|b4$8L!SrNQj4Y+#OkUb@^NI7p-pRF19$2H*uT(LHlzWMw^g6l)?@TalN z8m2>x9lq&$6V{lves78&nx?iu#V`fzu*qY4(Sv`HZPMd} zVb|2_SzUCKK8)E^&DLkypJ!eAXiw9tM7RcLBkRT2zR}nePVLSIS*A^1mGf$|Wn(4v zHp7Th`1H>?S&%PgotNRyM6{}C#N?wq@eT|gY%if;S?IeHiM4~+G9LllYf9E(*5TdL zqn&APN&Q6NiLmz;^|@~3D|TJCE0}$)&$6^)Shd9|wWqcSc;{U;(!X}` zEAwG(x6djW$%80fjp9#>e)ZW`kf>WR&3^cwwXQ+4VAJO! za{S70@CIzY5f+cb){LEl)hg}M&#?!|-s)DtY$OiA&KElqGlc>67+IoZy1pi{QI2X~ zv(P$9e!qpRVxG!xR=Bds^@qUe6n2Kne8S_X&%zHKYNLvnD?I!2ZB7X04>u8TuKzyL zOSQIuDE4I?il?8_0uBI$lvMVM7eC#x;2~`I^TRCCzn~(78_f{7k-!ls@xl+Gk3TZ7CC z;6fTwH%IXzgC9&!KV|V>gH`bE4{0vzKZmX$M!;o?Lcnk=P42LH?M1QCpxBd|rwD)Ea`-NQB?{2To@Fj2v%$sUI^Qy%uljeiPLk6qB+bknMH7o%|!u=IZf zZXmEH=@C|KzGl;0PWd{$)~cIUy=T{~Vl~MesRuNS$TpPFyIJd{eYB15|NP5BuCt@MqkG%RVaO~hf6%^{K*c?E$Gy-*!Phrdl@r50R|R7U ze)1(dDY&On!aK9m8FHxo&4*$8aHjgxSh+P%Bx)DHJy&g~y;IR0Q=)G?R_moJk@zQapEeS|P}jYngGB-dsy#scMwd+37~LS8pjg}iFi zhKd{MEl|wh=ncQPV+oeIW4)`)Gxk$l#F>SAKCFdG=4ydThF}l)c37 z;NN~-6}wuza3G?RZZNe4N)PzA>fxwg0nU4MRyoTE)Jv;0>WnLK7LH2_p4sIl_o4TP^N83`#&ahh9%;$y>8CSn51(l6 zavG2_%vFa)_})0Ea9H5!P^dC?F8A~$Ka+3FCwD&8Eu9S_py8dmKL>Jm@D1aN7yL(B zj*GiJI8kJ-1uFwj7jcH3>K

KlWBdN>-okL`SzC=s!37H`;`p)jJ5d>Q~Fy5)Q_ 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 K-E197&_4k@x1s<5 diff --git a/docs/diagrams/src/EditStudent/Architecture Diagram.puml b/docs/diagrams/src/EditStudent/editSequenceDiagram.puml similarity index 92% rename from docs/diagrams/src/EditStudent/Architecture Diagram.puml rename to docs/diagrams/src/EditStudent/editSequenceDiagram.puml index f5581451dd..1ddc3a2854 100644 --- a/docs/diagrams/src/EditStudent/Architecture Diagram.puml +++ b/docs/diagrams/src/EditStudent/editSequenceDiagram.puml @@ -1,5 +1,5 @@ @startuml -title Sequence Diagram: Calling editStudent and editing subject +title Sequence Diagram: Calling editStudent and editing gender actor User participant "InputParsing" as InputParsing <> From 511ee2131526274a6cac898014dec01ff1a97e71 Mon Sep 17 00:00:00 2001 From: blackmirag3 Date: Mon, 15 Apr 2024 20:50:16 +0800 Subject: [PATCH 480/503] Update UG and PPP --- docs/DeveloperGuide.md | 36 ++++++++++++++++++------------------ docs/team/blackmirag3.md | 6 +++--- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index d6c2ee9564..c51adb5f5e 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -263,12 +263,12 @@ The following is a sequence diagram for an example of when `archiveStudent` is c ![ArchiveCommandsSequenceDiagram](./diagrams/src/ArchiveCommands/ArchiveCommands.PNG) #### Design Considerations -* Write data using `Data Commands` component into archive and student data file whenever there is change. -* Check for student-number pairs whenever student is archived or unarchived to ensure there are no duplicate students amongst all student lists. +* To always update data into archive and student data file whenever there is change in student or archive list. +* Have proper checks whenever student is archived or unarchived to ensure there are no duplicate students amongst all student lists. #### Implementation and Rationale -* **Exception Handling**: Uses the 'checkNameNumberPair' method and catches 'NameNumberMatchException' - +* **Exception Handling**: To prevent duplicate students (especially from corrupted archive data file), the class uses the 'checkNameNumberPair' method and catches 'NameNumberMatchException' to catch instances of duplicate students existing in any list in the programme. +* **File Saving**: Uses the `Data Commands` component to write archive and main student data file whenever 'archiveStudent' or `unarchiveStudent' method is called. --- ## Product scope @@ -335,10 +335,10 @@ Classify serves as an attempt to modernise administrative tasks in education ins ### Adding a student to the student list 1. Adding a student with a name and phone number only - 1. Prerequisites: View if a student with the name `joe` and phone number `88888888` exists by using the `view joe` command. + 1. Prerequisites: View if a student with the name 'joe' and phone number `88888888` exists by using the `view joe` command. 2. Test case: `add joe` and when prompted for phone number enter `88888888`, while pressing enter to skip other optional fields.
- Expected: `view joe` now shows the Student details of a student with Name: joe, Phone Number: 11111111. + Expected: `view joe` now shows the Student details of a student with Name: joe, Phone Number: 88888888.
Other fields that were left blank will reflect 'Unknown' or for date fields, today's date. 3. Test case: `add` and when prompted for Name, `joe`. `88888888` when prompted for phone number, press enter to skip other fields. @@ -347,16 +347,16 @@ Classify serves as an attempt to modernise administrative tasks in education ins ### Viewing a student's details 1. View a student who has been added to the student list - 1. Prerequisites: Add one student named `joe` to the list with the `add` command + 1. Prerequisites: Add one student named 'joe' to the list with the `add` command 2. Test case: `view joe`
Expected: Student's details shown correspond to the details input when `add` was used to add a student. ### Deleting a student from the student list 1. Deleting a student that exists in the student list - 1. Prerequisites: Add one student named `joe` to the list with the `add` command + 1. Prerequisites: Add one student named 'joe' to the list with the `add` command 2. Test case: `delete joe`
Expected: `view joe` shows Student not found!
- `list` followed by enter, enter again, and `1` which displays a list of all students, does not show any student named `joe`. + `list` followed by enter, enter again, and `1` which displays a list of all students, does not show any student named 'joe'. ### Displaying a list of students 1. Listing all students enrolled in the tuition centre @@ -365,7 +365,7 @@ Classify serves as an attempt to modernise administrative tasks in education ins Expected: A list of all students that are enrolled in the tuition centre is printed.
2. Listing all students with a specific subject in the tuition centre - 1. Prerequisites: Have at least one student with the subject `Math` added to the list with the `add` command + 1. Prerequisites: Have at least one student with the subject 'Math' added to the list with the `add` command 2. Test case: `list`, `Math`
Expected: A list of all the students with the subject `Math` in the tuition centre is printed.
@@ -397,10 +397,10 @@ Classify serves as an attempt to modernise administrative tasks in education ins ### Restoring a recently deleted student 1. Restore a student from the recently deleted list - 1. Prerequisites: Have at least one student named `joe` deleted in the current session with the `delete joe` command + 1. Prerequisites: Have at least one student named 'joe' deleted in the current session with the `delete joe` command 2. Test case: `restore joe`
- Expected: `view joe` will display the attributes that `joe` had before being deleted.
- `joe` will be shown in any lists that specify attributes they possess. + Expected: `view joe` will display the attributes that 'joe' had before being deleted.
+ 'joe' will be shown in any lists that specify attributes they possess. ### Undoing the latest deletion 1. Undo two deletes successively @@ -412,23 +412,23 @@ Classify serves as an attempt to modernise administrative tasks in education ins #### 1. Archiving a student: 1. Prerequisites: Add 2 students named 'tim' and 'joe' to the student list. 2. Test Case: `archive joe` -
Expected: `joe` will be removed from student list and will appear in the list of students added to the archive. +
Expected: 'joe' will be removed from student list and will appear in the list of students added to the archive. 3. Test Case: `archive`, `tim` -
Expected: `tim` will be removed from student list and will appear in the list of students added to the archive. + Expected: 'tim' will be removed from student list and will appear in the list of students added to the archive. #### 2. Unarchiving a student: 1. Prerequisites: Have 2 students named 'tim' and 'joe' already archived. 2. Test Case: `unarchive joe` -
Expected: `joe` will be removed from archive and added back to student list. + Expected: 'joe' will be removed from archive and added back to student list. 3. Test Case: `unarchive`, `tim` -
Expected: `tim` will be removed from archive and added back to student list. + Expected: 'tim' will be removed from archive and added back to student list. #### 3. Archiving/unarchiving student that does not exist: 1. Prerequisites: Have an empty student list 2. Test Case: `archive joe`
Expected: Error message printed for no student found and prompts for new command. 3. Test Case: `unarchive`, `tim` -
Expected: Error message printed for no student found and prompts for new command. + Expected: Error message printed for no student found and prompts for new command. ### Editing a student's details #### 1. Entering edit mode for an existing student: diff --git a/docs/team/blackmirag3.md b/docs/team/blackmirag3.md index c03cbd2564..3d8d4b7a55 100644 --- a/docs/team/blackmirag3.md +++ b/docs/team/blackmirag3.md @@ -38,15 +38,15 @@ all Tuition Centres can employ for ease of student management. - **Contributions to [DG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/DeveloperGuide.md)** * Wrote `EditStudent` and `ArchiveCommands` component - * Wrote `Archiving/unarchiving a student` and `Editing a student's details` under manual testing. + * Wrote `Archiving/unarchiving a student` and `Editing a student's details` manual testing. + * Created UML sequence diagram for 'EditStudent' and 'ArchiveCommands' component each. - **Contributions to Team-Based tasks:** * Refactored/rewrote at least 300 LoC (authored by teammates) to improve code quality, such as for [input checking](https://github.com/AY2324S2-CS2113-T13-3/tp/commit/23f3ac553d243b9d31d80fdd05ff2ac3b3a2d57e) and [file IO](https://github.com/AY2324S2-CS2113-T13-3/tp/commit/932b51fbdb542b59f3ecdcaa1c04c65eda873ff1). * Established TP's current code organisation, such as refactoring project into respective packages `commands`, `data`, `ui` etc. * Maintained team's GitHub Project, such as updating status and priority of project items. - * Created group demo video. - + - **Review/mentoring contributions** * Actively reviewed and approved team's PRs, with some recent examples [here](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/258) or [here](https://github.com/AY2324S2-CS2113-T13-3/tp/pull/246). From b90ab50ace3ef9d040ac4e626f506e780c21642e Mon Sep 17 00:00:00 2001 From: blackmirag3 Date: Mon, 15 Apr 2024 21:00:28 +0800 Subject: [PATCH 481/503] Update typos in DG --- docs/DeveloperGuide.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index c51adb5f5e..a768fe7c95 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -37,19 +37,17 @@ Do note that the Classify class is the "main" class in the diagram, with all oth ## Project Components -### Ui component +### UI component -The `Ui` class handles message output for the user within the terminal. - -The `UI`component, -- stores message output strings for user feedback -- holds methods for printing messages to be called by other classes, such as `InputParsing`. +The `UI` class handles message output for the user within the terminal. +- Stores message output strings for user feedback +- Holds methods for printing messages to be called by other classes, such as `InputParsing`. #### Design considerations -Being a CLI application, UI/UX is minimal and user IO is confined within the terminal. +* Being a CLI application, UI/UX should be minimal and user IO should be confined within the terminal. -Hence, public methods within the`Ui` class are static for easy access by other classes, without the need to instantiate an instance of the `Ui` class to call. +* public methods within the `UI` class are static for easy access by other classes, without the need to instantiate an instance of the `UI` class to call. ### InputParsing component @@ -225,7 +223,7 @@ providing a mechanism to organize and present student information based on user ### Data Commands Component -This section refers to `DataHandler.java`, `DataReader.java`, and `DataStorage.java` classes. +This section refers to `DataHandler`, `DataReader`, and `DataStorage` classes. We have currently implemented a basic data handler which has the abilities to store a student's name into a text file. @@ -242,7 +240,7 @@ The two text files are will be created under a directory called data, in which t ![DataStoringObjectDiagramUML](./diagrams/src/DataStoring/ObjectDiagram.png) ### Process Component -This section refers to `TextFileHandler.java`, `TextFileParser.java`, and `TextFileReader.java` classes. It ensures that we are able to put new files in the folder in data which is named Input Folder. +This section refers to `TextFileHandler`, `TextFileParser`, and `TextFileReader` classes. It ensures that we are able to put new files in the folder in data which is named Input Folder. #### Design Considerations * Support for adding multiple students taking the same class/subject at once @@ -330,12 +328,14 @@ Classify serves as an attempt to modernise administrative tasks in education ins 7. **Data Management**: - File saving should done whenever a change has been made to the Master List. +## Glossary +* *` `* - Refers to empty user input, where user just presses `enter` key. ## Instructions for manual testing ### Adding a student to the student list 1. Adding a student with a name and phone number only - 1. Prerequisites: View if a student with the name 'joe' and phone number `88888888` exists by using the `view joe` command. + 1. Prerequisites: View if a student with the name 'joe' and phone number '88888888' exists by using the `view joe` command. 2. Test case: `add joe` and when prompted for phone number enter `88888888`, while pressing enter to skip other optional fields.
Expected: `view joe` now shows the Student details of a student with Name: joe, Phone Number: 88888888. @@ -367,7 +367,7 @@ Classify serves as an attempt to modernise administrative tasks in education ins 2. Listing all students with a specific subject in the tuition centre 1. Prerequisites: Have at least one student with the subject 'Math' added to the list with the `add` command 2. Test case: `list`, `Math`
- Expected: A list of all the students with the subject `Math` in the tuition centre is printed. + Expected: A list of all the students with the subject 'Math' in the tuition centre is printed.
3. Listing all students that have been deleted in the current session 1. Prerequisites: Delete at least one student in the list with the `delete` command @@ -388,12 +388,12 @@ Classify serves as an attempt to modernise administrative tasks in education ins 3. Ingesting a full list of Students using a Text File (without using file extension) 1. Prerequisites: Have at least one text file in the inputFolder in Data. The text file present (eg. **File.txt**) is properly formatted according to the requirements stated in the User Guide and is present in the inputFolder. 2. Test case: `Process`, enter, **`File`** - Expected: `Fetching the data from File.txt.` will be displayed. Can use the `list`, enter,enter,`1` to ensure that all the students in the file are added. + Expected: `Fetching the data from File.txt.` will be displayed. Can use the `list`, ` `, ` `, `1` to ensure that all the students in the file are added. 4. Ingesting a full list of Students using a Text File (using file extension) 1. Prerequisites: Have at least one text file in the inputFolder in Data. The text file present (eg. **File.txt**) is properly formatted according to the requirements stated in the User Guide and is present in the inputFolder. 2. Test case: `Process`, enter, **`File.txt`** - Expected: `Fetching the data from File.txt.` will be displayed. Can use the `list`, enter,enter,`1` to ensure that all the students in the file are added. + Expected: `Fetching the data from File.txt.` will be displayed. Can use the `list`, ` `, ` `, `1` to ensure that all the students in the file are added. ### Restoring a recently deleted student 1. Restore a student from the recently deleted list From bbe6974898df7fcae2c0388d7cace4176c372c71 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Mon, 15 Apr 2024 21:09:50 +0800 Subject: [PATCH 482/503] Edit UG --- docs/UserGuide.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 82d231fd74..4cbecb866d 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -184,8 +184,6 @@ Depending on whether the user entered the student's name or not during the comma Please note that the user input NUMBER (shown below) must be an *8-digit number starting with 8 or 9*. Thus, please be informed and educated that our software only works in countries that have phone numbers that are 8 digits long and start with 8 or 9. -To be specific, this is referring to a city-state republic in South East Asia, that lies in the timezone GMT +8 in the Straits of Johor. -Some may debate that our time zone is actually GMT+7.5 or GMT+7, but it was changed to facilitate business deals and decisions with other financial hubs in the region thanks to our capitalistic overlords. Do note that the subject field will allow numbers as well, since lessons such as Chinese1E and Chinese1H are legitimate class names, which could signify express and higher mother tongue respectively. As such, it is on the onus of the user to not use nonsensical names for the subjects, to ensure that the database is sensible. @@ -232,6 +230,8 @@ For any student that exists within the program's master, archive and recently de The following is an example of trying to add a new student that matches the name and phone number of an already existing student. +
+ #### Example usage: ``` add melodie @@ -260,7 +260,6 @@ How it works (cases for input): - view JAMES WONG -> JAMES WONG * Regardless of what capitalisation the user uses for the name, the program will recognise that upper and lower cases should return the same student. -
#### Example usage: ``` @@ -279,7 +278,6 @@ Classes Attended: 1 Note that if 2 people of the same name are present in the list, the program will prompt the user to differentiate them through a choice between the available phone numbers tagged to them. - ### Delete a student from the working list `delete` Deletes the student from the list. Allows the user to do delete [student] or just delete. @@ -288,7 +286,6 @@ Deletes the student from the list. Allows the user to do delete [student] or jus Depending on whether the user entered the student's name or not during the command, a field will be printed out in the terminal, awaiting a user input. -
#### Example usage: ``` @@ -298,6 +295,8 @@ wario Student removed successfully! ``` +
+ ### Edit details of a student `edit` Edit a student's details and subjects. Allows the user to do edit [student] or just edit. From c72a9b4ac671a7d61a6a687a144b3ed3fb48eb7d Mon Sep 17 00:00:00 2001 From: blackmirag3 Date: Mon, 15 Apr 2024 21:10:25 +0800 Subject: [PATCH 483/503] Update DG --- docs/DeveloperGuide.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index a768fe7c95..38b247c741 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -4,7 +4,7 @@ - [Acknowledgements](#acknowledgements) - [Overall Design and Implementation](#overall-design-and-implementation) - [Project Components](#project-components) - - [Ui component](#ui-component) + - [UI component](#ui-component) - [InputParsing component](#inputparsing-component) - [Student Details](#student-details) - [AddStudent Component](#addstudent-component) @@ -12,6 +12,7 @@ - [StudentSorter Component](#studentsorter-component) - [Data Commands Component](#data-commands-component) - [Process Component](#process-component) + - [ArchiveCommands Component](#archivecommands-component) - [Project Scope](#product-scope) - [User Stories](#user-stories) - [Non-Functional Requirements](#non-functional-requirements) @@ -59,7 +60,7 @@ This component ensures that the user parses in commands in a format that makes s - The parser must be effective in breaking down the user's input into its constituent commands, with further breakdown if an associated argument is added. - The parser should be quick and effective in understanding the user's input, with simple prompts given to help the user in correctly parsing the command through the input parser. - Allowing the user to input optional arguments. For example, the user could type `view `, which takes in the "student name" as an optional argument. This is to increase the robustness of the program, which accounts for the two types of users, one who just types in `view`, and the other as formerly mentioned above. -- Error handling must be intuitive for the user, so that appropriate error messages are produced if the user does not input a valid command. The error handling should also be robust, to account for the event a user is incapable in following instructions. +- Error handling must be intuitive for the user, so that appropriate error messages are produced if the user does not input a valid command. The error handling should also be robust, to account for the event a user is incapable of following instructions. #### Implementation and rationale @@ -67,7 +68,7 @@ This component ensures that the user parses in commands in a format that makes s The InputParsing class is designed to handle the considerations above by breaking down the input given by the user in a well structured process. Below is how the InputParsing class works: -1. Splitting User Input: The Parser would take on the user's input and split it into 2 parts, which is the command and the argument, if any. this is done by the `UserInput` Class +1. Splitting User Input: The Parser would take in the user's input and split it into 2 parts, command and argument, if any. This is done using the `UserInput` Class. 2. Command recognition: Depending on the command and the argument given, if any, the parser would execute the command as per defined by the program. If the command and/or argument given is invalid/undefined, the input parser would generate a message to the user, informing them of the command's invalidity. This is done by the `InputParsing` Class. @@ -265,8 +266,8 @@ The following is a sequence diagram for an example of when `archiveStudent` is c * Have proper checks whenever student is archived or unarchived to ensure there are no duplicate students amongst all student lists. #### Implementation and Rationale -* **Exception Handling**: To prevent duplicate students (especially from corrupted archive data file), the class uses the 'checkNameNumberPair' method and catches 'NameNumberMatchException' to catch instances of duplicate students existing in any list in the programme. -* **File Saving**: Uses the `Data Commands` component to write archive and main student data file whenever 'archiveStudent' or `unarchiveStudent' method is called. +* **Exception Handling**: To prevent duplicate students (especially from corrupted archive data file), the class uses the `checkNameNumberPair` method and catches `NameNumberMatchException` to catch instances of duplicate students existing in any list in the programme. +* **File Saving**: Uses the `Data Commands` component to write archive and main student data file whenever `archiveStudent` or `unarchiveStudent` method is called. --- ## Product scope @@ -329,7 +330,7 @@ Classify serves as an attempt to modernise administrative tasks in education ins - File saving should done whenever a change has been made to the Master List. ## Glossary -* *` `* - Refers to empty user input, where user just presses `enter` key. +* *` `* - Refers to empty user input, where user just presses `enter` key. ## Instructions for manual testing From 9be443bcb93df6694b3167c388f020d2c318ac7f Mon Sep 17 00:00:00 2001 From: blackmirag3 Date: Mon, 15 Apr 2024 21:14:00 +0800 Subject: [PATCH 484/503] Fix typo in DG --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 38b247c741..03854fefa9 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -234,7 +234,7 @@ Currently there is a polling system set in place where every change in the list As stated above, all the names and attributes associated with each student will be saved to the main text file, named Student_Information.txt. -If the user chooses to delete or archive a student, it would be saved to an archive file, named student_archive.txt. If the user chooses to unarchive a student or undo a recent deletion, it will be brought back to the main text file. +If the user chooses to archive a student, it would be saved to an archive file, named student_archive.txt. If the user chooses to unarchive a student, the student will be re-added to the student list and consequently be written to the main text file. The two text files are will be created under a directory called data, in which two separate file paths will be created if it is not already found on the user's desktop. From 4cf5cee5c07a7847574f56859f744cd62a6635ec Mon Sep 17 00:00:00 2001 From: alalal47 Date: Mon, 15 Apr 2024 21:21:10 +0800 Subject: [PATCH 485/503] Fix typos in DG --- docs/DeveloperGuide.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index b138735074..e82de3ee21 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -64,9 +64,9 @@ This component ensures that the user parses in commands in a format that makes s #### Implementation and rationale -![InputParsingSequenceDigram](./diagrams/src/InputParsing/InputParsingSequenceDiagram.png) +![InputParsingSequenceDiagram](./diagrams/src/InputParsing/InputParsingSequenceDiagram.png) -The InputParsing class is designed to handle the considerations above by breaking down the input given by the user in a well structured process. Below is how the InputParsing class works: +The InputParsing class is designed to handle the considerations above by breaking down the input given by the user in a well-structured process. Below is how the InputParsing class works: 1. Splitting User Input: The Parser would take in the user's input and split it into 2 parts, command and argument, if any. This is done using the `UserInput` Class. @@ -82,7 +82,7 @@ The InputParsing class uses the method below to achieve its functionality: This method takes in the user's input as the userCommand, the master student list, a list of the recently deleted students and the next input as parameters, which then proceeds with executing the command as associated with the user's input. -Given below is an example of how a user may add a student to the data base. +Given below is an example of how a user may add a student to the database. - Suppose the user types in the command `add wario`. The parser first splits the input into two, checking for the command and the argument. - It then recognises the `add` command, which then further checks if there is an argument given. @@ -97,7 +97,7 @@ All the while these commands are being processed, the runtime database `masterSt To facilitate the management of students within a tuition centre, it is imperative to have easy access and storage of important information regarding said personnel. -Seen below is an UML diagram of the relevant classes dealing with storing a student's details within the program runtime. +Seen below is a UML diagram of the relevant classes dealing with storing a student's details within the program runtime. This text file would have the details of the student's name and their attributes, in the following order: subject, grade, classes taken for that subject, phone number, last paid date and remarks. @@ -230,13 +230,13 @@ We have currently implemented a basic data handler which has the abilities to st This text file is created locally on the users' computer for easy access and retrieval. -Currently there is a polling system set in place where every change in the list of students (eg, addition, deletion, modification) would override the current working text file on the users' computer. +Currently, there is a polling system set in place where every change in the list of students (eg, addition, deletion, modification) will override the current working text file on the users' computer. As stated above, all the names and attributes associated with each student will be saved to the main text file, named Student_Information.txt. If the user chooses to archive a student, it would be saved to an archive file, named student_archive.txt. If the user chooses to unarchive a student, the student will be re-added to the student list and consequently be written to the main text file. -The two text files are will be created under a directory called data, in which two separate file paths will be created if it is not already found on the user's desktop. +The two text files will be created under a directory called data, in which two separate file paths will be created if it is not already found on the user's desktop. ![DataStoringObjectDiagramUML](./diagrams/src/DataStoring/ObjectDiagram.png) @@ -246,13 +246,13 @@ This section refers to `TextFileHandler`, `TextFileParser`, and `TextFileReader` #### Design Considerations * Support for adding multiple students taking the same class/subject at once * Need to take down students' name and phone number as these are used to prevent duplicate entries in masterStudentList - * Need to have a different parser to make it easy for the users to add many studetns + * Need to have a different parser to make it easy for the users to add many students #### Implementation and Rationale - * **Standardised Subject and Classes Attended**: Simplify adding users in text file for user - * **Common Regex**: Using " ~~ " to separate all other attributes like Student Name, Phone Number and Grade ensures it is easy for the user to add many students - * **Checker for same student**: Ensures that we dont have duplicate entries of one student. - * **Checker for same subject**: Ensures that an existing student does not get duplicate entries of the same subject (Not applicable for new students for obvious reasons) + * **Standardised Subject and Classes Attended**: Simplify adding users in text file for user. + * **Common Regex**: Using " ~~ " to separate all other attributes like Student Name, Phone Number and Grade ensures it is easy for the user to add many students. + * **Checker for same student**: Ensures that we don't have duplicate entries of one student. + * **Checker for same subject**: Ensures that an existing student does not get duplicate entries of the same subject (Not applicable for new students for obvious reasons). ### ArchiveCommands Component The `ArchiveCommands` class is responsible for transferring students from the student list to archive list and vice versa, using methods `archiveStudent` and `unarchiveStudent`. @@ -266,7 +266,7 @@ The following is a sequence diagram for an example of when `archiveStudent` is c * Have proper checks whenever student is archived or unarchived to ensure there are no duplicate students amongst all student lists. #### Implementation and Rationale -* **Exception Handling**: To prevent duplicate students (especially from corrupted archive data file), the class uses the `checkNameNumberPair` method and catches `NameNumberMatchException` to catch instances of duplicate students existing in any list in the programme. +* **Exception Handling**: To prevent duplicate students (especially from a corrupted archive data file), the class uses the `checkNameNumberPair` method and catches `NameNumberMatchException` to catch instances of duplicate students existing in any list in the programme. * **File Saving**: Uses the `Data Commands` component to write archive and main student data file whenever `archiveStudent` or `unarchiveStudent` method is called. --- @@ -326,7 +326,7 @@ Classify serves as an attempt to modernise administrative tasks in education ins - Logging and monitoring mechanisms should be in place to track system usage and identify potential issues. 7. **Data Management**: - - File saving should done whenever a change has been made to the Master List. + - File saving should be done whenever a change has been made to the Master List. ## Glossary * *` `* - Refers to empty user input, where user just presses `enter` key. @@ -386,12 +386,12 @@ Classify serves as an attempt to modernise administrative tasks in education ins Should be redirected to the main commands menu. 3. Ingesting a full list of Students using a Text File (without using file extension) - 1. Prerequisites: Have at least one text file in the inputFolder in Data. The text file present (eg. **File.txt**) is properly formatted according to the requirements stated in the User Guide and is present in the inputFolder. + 1. Prerequisites: Have at least one text file in the inputFolder in Data. The text file present (e.g. **File.txt**) is properly formatted according to the requirements stated in the User Guide and is present in the inputFolder. 2. Test case: `Process`, enter, **`File`** Expected: `Fetching the data from File.txt.` will be displayed. Can use the `list`, ` `, ` `, `1` to ensure that all the students in the file are added. 4. Ingesting a full list of Students using a Text File (using file extension) - 1. Prerequisites: Have at least one text file in the inputFolder in Data. The text file present (eg. **File.txt**) is properly formatted according to the requirements stated in the User Guide and is present in the inputFolder. + 1. Prerequisites: Have at least one text file in the inputFolder in Data. The text file present (e.g. **File.txt**) is properly formatted according to the requirements stated in the User Guide and is present in the inputFolder. 2. Test case: `Process`, enter, **`File.txt`** Expected: `Fetching the data from File.txt.` will be displayed. Can use the `list`, ` `, ` `, `1` to ensure that all the students in the file are added. From a1fe5725920fdb910bebb8ec1dd95587f7e3a328 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Mon, 15 Apr 2024 21:26:02 +0800 Subject: [PATCH 486/503] UG is frustrating --- docs/UserGuide.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 4cbecb866d..09325d6ccb 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -192,7 +192,6 @@ Last payment date must be within a range from 1970-01-01 to the day after the cu The gender field and remarks section are optional, hence if the user presses `enter`, they would proceed with the next command or end the add student interface respectively. -
#### Example usage: ``` From a480fbf93f23b3dee47dc3bb31fef17f8f8b4bec Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Mon, 15 Apr 2024 21:28:34 +0800 Subject: [PATCH 487/503] UG is not stonks --- docs/UserGuide.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 09325d6ccb..9610c0c2d3 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -371,7 +371,6 @@ No student found to edit! ``` Similar to View Student, if the there are 2 or more students with the same name, the program would prompt the user to input the corresponding phone number of the student that they would like to edit. -
### Restore a student to the working list `restore` From 7de0bd5605a543f662b162c43fa8b0e8356f45e7 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Mon, 15 Apr 2024 21:40:52 +0800 Subject: [PATCH 488/503] Update PPP --- docs/team/parthgandhinus.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/team/parthgandhinus.md b/docs/team/parthgandhinus.md index 17b2d1c4ed..bf17063ffb 100644 --- a/docs/team/parthgandhinus.md +++ b/docs/team/parthgandhinus.md @@ -59,6 +59,7 @@ Overall, the code base has more than 7000 Lines of Code, and is written in Java. * Wrote out the workflow for Process and Data commands in DG * Made the table of contents for the DG * Assisted in the various UML Diagrams + * Added manual testing cases for Process Command --- From 4a9927c2b0fc3c298b51a1eb808ade61df75ae95 Mon Sep 17 00:00:00 2001 From: Cryolian <102575848+Cryolian@users.noreply.github.com> Date: Mon, 15 Apr 2024 22:04:07 +0800 Subject: [PATCH 489/503] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index e82de3ee21..d057de1919 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -260,7 +260,7 @@ This class contains the `editStudent` method which is called by `InputParsing` c The following is a sequence diagram for an example of when `archiveStudent` is called to move a student from the student list to archive. -![ArchiveCommandsSequenceDiagram](./diagrams/src/ArchiveCommands/ArchiveCommands.PNG) +![ArchiveCommandsSequenceDiagram](./diagrams/src/ArchiveCommands/ArchiveCommands.png) #### Design Considerations * To always update data into archive and student data file whenever there is change in student or archive list. * Have proper checks whenever student is archived or unarchived to ensure there are no duplicate students amongst all student lists. From e163cc522c7a6550fff2822affb7409a235b715d Mon Sep 17 00:00:00 2001 From: Cryolian <102575848+Cryolian@users.noreply.github.com> Date: Mon, 15 Apr 2024 22:06:21 +0800 Subject: [PATCH 490/503] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index d057de1919..5fd6e7ed41 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -441,7 +441,7 @@ Classify serves as an attempt to modernise administrative tasks in education ins #### 2. Adding single or multiple subjects to an existing student 1. Prerequisites: Add student 'tim' and initiate edit mode for 'tim'. 2. Test Case: `1`, `CS2113`, `11`, `1`, `no` -
Expected: 'tim' has subject 'CS2112' with marks '11' and '1' class attended. +
Expected: 'tim' has subject 'CS2113' with marks '11' and '1' class attended. 3. Test Case: `1`, `CS2030`, ` `, ` `, `yes`, `CS2040`, ` `, ` `, `no`
Expected: 'tim' has subjects 'CS2030' and 'CS2040' with no marks and attendance. 4. Test Case: `1`, ` ` From b797228ae836e613e257632e6565e7c62fbaa0dc Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Mon, 15 Apr 2024 22:12:03 +0800 Subject: [PATCH 491/503] Update DG --- docs/DeveloperGuide.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index e82de3ee21..7298d6152a 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -412,7 +412,7 @@ Classify serves as an attempt to modernise administrative tasks in education ins #### 1. Archiving a student: 1. Prerequisites: Add 2 students named 'tim' and 'joe' to the student list. 2. Test Case: `archive joe` -
Expected: 'joe' will be removed from student list and will appear in the list of students added to the archive. + Expected: 'joe' will be removed from student list and will appear in the list of students added to the archive. 3. Test Case: `archive`, `tim` Expected: 'tim' will be removed from student list and will appear in the list of students added to the archive. @@ -426,7 +426,7 @@ Classify serves as an attempt to modernise administrative tasks in education ins #### 3. Archiving/unarchiving student that does not exist: 1. Prerequisites: Have an empty student list 2. Test Case: `archive joe` -
Expected: Error message printed for no student found and prompts for new command. + Expected: Error message printed for no student found and prompts for new command. 3. Test Case: `unarchive`, `tim` Expected: Error message printed for no student found and prompts for new command. @@ -434,28 +434,28 @@ Classify serves as an attempt to modernise administrative tasks in education ins #### 1. Entering edit mode for an existing student: 1. Prerequisites: Add student named 'tim' to the student list with the `add` command. 2. Test Case: `edit`, `tim` -
Expected: Name will be prompted first, then edit mode will be initiated for student 'tim'. + Expected: Name will be prompted first, then edit mode will be initiated for student 'tim'. 3. Test Case: `edit tim` -
Expected: Edit mode will be initiated for student 'tim'. + Expected: Edit mode will be initiated for student 'tim'. #### 2. Adding single or multiple subjects to an existing student 1. Prerequisites: Add student 'tim' and initiate edit mode for 'tim'. 2. Test Case: `1`, `CS2113`, `11`, `1`, `no` -
Expected: 'tim' has subject 'CS2112' with marks '11' and '1' class attended. + Expected: 'tim' has subject 'CS2112' with marks '11' and '1' class attended. 3. Test Case: `1`, `CS2030`, ` `, ` `, `yes`, `CS2040`, ` `, ` `, `no` -
Expected: 'tim' has subjects 'CS2030' and 'CS2040' with no marks and attendance. + Expected: 'tim' has subjects 'CS2030' and 'CS2040' with no marks and attendance. 4. Test Case: `1`, ` ` -
Expected: Returns to edit mode for 'tim' and no change in subjects is made for 'tim'. + Expected: Returns to edit mode for 'tim' and no change in subjects is made for 'tim'. #### 3. Testing invalid entries for editing student 1. Prerequisites: Add student 'tim' with subjects 'CS2113', 'CS2040' and phone number '88888888' and initiate edit mode for 'tim'. 2. Test Case: `1`, `cs2113` -
Expected: Returns to edit mode for 'tim', no new subject added and error message printed for adding existing subject. + Expected: Returns to edit mode for 'tim', no new subject added and error message printed for adding existing subject. 3. Test Case: `2`, `CS2113`, `CS2040` -
Expected: Prints error message for existing subject and new subject name is prompted to update 'CS2113'. + Expected: Prints error message for existing subject and new subject name is prompted to update 'CS2113'. 4. Test Case: `3`, `CG2023` -
Expected: Prints error message for no subject found and prompts for another subject name to delete. + Expected: Prints error message for no subject found and prompts for another subject name to delete. 5. Test Case: `4`, `11111111` -
Expected: Prints invalid phone number error message and prompts for another phone number. + Expected: Prints invalid phone number error message and prompts for another phone number. 6. Test Case: `6`, `20 jan 2001` -
Expected: Prints error message for invalid date and prompts for another date. + Expected: Prints error message for invalid date and prompts for another date. From ec14ffe4fa6c1293f6d83096b925bf5f8a1b4288 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Mon, 15 Apr 2024 22:16:50 +0800 Subject: [PATCH 492/503] Update DG --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 53bb078494..ae560fa96f 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -12,7 +12,7 @@ - [StudentSorter Component](#studentsorter-component) - [Data Commands Component](#data-commands-component) - [Process Component](#process-component) - - [ArchiveCommands Component](#archivecommands-component) + - [Archive Commands Component](#archivecommands-component) - [Project Scope](#product-scope) - [User Stories](#user-stories) - [Non-Functional Requirements](#non-functional-requirements) From 45613aaa6922dd4945ec5095db98a292619832ec Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Mon, 15 Apr 2024 22:18:51 +0800 Subject: [PATCH 493/503] Update DG --- docs/DeveloperGuide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index ae560fa96f..c662955eb9 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -12,7 +12,7 @@ - [StudentSorter Component](#studentsorter-component) - [Data Commands Component](#data-commands-component) - [Process Component](#process-component) - - [Archive Commands Component](#archivecommands-component) + - [Archive Commands Component](#archive-commands-component) - [Project Scope](#product-scope) - [User Stories](#user-stories) - [Non-Functional Requirements](#non-functional-requirements) @@ -254,7 +254,7 @@ This section refers to `TextFileHandler`, `TextFileParser`, and `TextFileReader` * **Checker for same student**: Ensures that we don't have duplicate entries of one student. * **Checker for same subject**: Ensures that an existing student does not get duplicate entries of the same subject (Not applicable for new students for obvious reasons). -### ArchiveCommands Component +### Archive Commands Component The `ArchiveCommands` class is responsible for transferring students from the student list to archive list and vice versa, using methods `archiveStudent` and `unarchiveStudent`. This class contains the `editStudent` method which is called by `InputParsing` class when user chooses to enter edit mode for a student. From 498f275330871b03599abc5e0c31610007f3a902 Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Mon, 15 Apr 2024 22:24:22 +0800 Subject: [PATCH 494/503] Update DG --- docs/DeveloperGuide.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index c662955eb9..140f47dab4 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -10,9 +10,9 @@ - [AddStudent Component](#addstudent-component) - [EditStudent Component](#editstudent-component) - [StudentSorter Component](#studentsorter-component) - - [Data Commands Component](#data-commands-component) - - [Process Component](#process-component) - - [Archive Commands Component](#archive-commands-component) + - [Data Component](#data-component) + - [TextFileCode Component](#textfilecode-component) + - [ArchiveCommands Component](#archivecommands-component) - [Project Scope](#product-scope) - [User Stories](#user-stories) - [Non-Functional Requirements](#non-functional-requirements) @@ -222,7 +222,7 @@ total classes attended, and last payment date. The `StudentSorter` class contributes to the overall functionality of the application by providing a mechanism to organize and present student information based on user preferences. -### Data Commands Component +### Data Component This section refers to `DataHandler`, `DataReader`, and `DataStorage` classes. @@ -240,7 +240,7 @@ The two text files will be created under a directory called data, in which two s ![DataStoringObjectDiagramUML](./diagrams/src/DataStoring/ObjectDiagram.png) -### Process Component +### TextFileCode Component This section refers to `TextFileHandler`, `TextFileParser`, and `TextFileReader` classes. It ensures that we are able to put new files in the folder in data which is named Input Folder. #### Design Considerations @@ -254,7 +254,7 @@ This section refers to `TextFileHandler`, `TextFileParser`, and `TextFileReader` * **Checker for same student**: Ensures that we don't have duplicate entries of one student. * **Checker for same subject**: Ensures that an existing student does not get duplicate entries of the same subject (Not applicable for new students for obvious reasons). -### Archive Commands Component +### ArchiveCommands Component The `ArchiveCommands` class is responsible for transferring students from the student list to archive list and vice versa, using methods `archiveStudent` and `unarchiveStudent`. This class contains the `editStudent` method which is called by `InputParsing` class when user chooses to enter edit mode for a student. @@ -441,7 +441,7 @@ Classify serves as an attempt to modernise administrative tasks in education ins #### 2. Adding single or multiple subjects to an existing student 1. Prerequisites: Add student 'tim' and initiate edit mode for 'tim'. 2. Test Case: `1`, `CS2113`, `11`, `1`, `no` - Expected: 'tim' has subject 'CS2112' with marks '11' and '1' class attended. + Expected: 'tim' has subject 'CS2113' with marks '11' and '1' class attended. 3. Test Case: `1`, `CS2030`, ` `, ` `, `yes`, `CS2040`, ` `, ` `, `no` Expected: 'tim' has subjects 'CS2030' and 'CS2040' with no marks and attendance. 4. Test Case: `1`, ` ` From be125fea90e0c13978ffdcd9321b6d745edb458e Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Mon, 15 Apr 2024 22:29:17 +0800 Subject: [PATCH 495/503] Update DG --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 140f47dab4..4cad30d0e5 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -457,5 +457,5 @@ Classify serves as an attempt to modernise administrative tasks in education ins Expected: Prints error message for no subject found and prompts for another subject name to delete. 5. Test Case: `4`, `11111111` Expected: Prints invalid phone number error message and prompts for another phone number. -6. Test Case: `6`, `20 jan 2001` +6. Test Case: `5`, `20 jan 2001` Expected: Prints error message for invalid date and prompts for another date. From b18b319187f3e5426464ce9e7139f9248dd3b19a Mon Sep 17 00:00:00 2001 From: Cryolian Date: Mon, 15 Apr 2024 22:37:03 +0800 Subject: [PATCH 496/503] test fix --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 4cad30d0e5..a9bd1ff898 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -268,7 +268,7 @@ The following is a sequence diagram for an example of when `archiveStudent` is c #### Implementation and Rationale * **Exception Handling**: To prevent duplicate students (especially from a corrupted archive data file), the class uses the `checkNameNumberPair` method and catches `NameNumberMatchException` to catch instances of duplicate students existing in any list in the programme. * **File Saving**: Uses the `Data Commands` component to write archive and main student data file whenever `archiveStudent` or `unarchiveStudent` method is called. ---- + ## Product scope From 2c3321abf64aff537b9be132f9337a0b2657e57c Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Mon, 15 Apr 2024 22:37:38 +0800 Subject: [PATCH 497/503] Add User Story --- docs/DeveloperGuide.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 4cad30d0e5..309b454f03 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -300,6 +300,7 @@ Classify serves as an attempt to modernise administrative tasks in education ins |v2.0|existing user|sort all students by classes attended|track who will likely score the highest in their national examinations. |v2.0|existing user|edit subject details for students|stop tracking these subjects when they are no longer being taken. |v2.0|existing user|sort students by their subjects taken|know who exactly are taking those subjects +|v2.1|existing user|add students with the same subject and classes attended|add a list of students taking the same class ## Non-Functional Requirements From 1e07c96202c7cd94d9562e333c2d7c6fa61f9bfb Mon Sep 17 00:00:00 2001 From: Cryolian Date: Mon, 15 Apr 2024 22:40:25 +0800 Subject: [PATCH 498/503] fix apos --- docs/DeveloperGuide.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index a9bd1ff898..41e99055e8 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -410,18 +410,18 @@ Classify serves as an attempt to modernise administrative tasks in education ins ### Archiving/unarchiving a student #### 1. Archiving a student: - 1. Prerequisites: Add 2 students named 'tim' and 'joe' to the student list. + 1. Prerequisites: Add 2 students named "tim" and 'joe' to the student list. 2. Test Case: `archive joe` Expected: 'joe' will be removed from student list and will appear in the list of students added to the archive. 3. Test Case: `archive`, `tim` - Expected: 'tim' will be removed from student list and will appear in the list of students added to the archive. + Expected: "tim" will be removed from student list and will appear in the list of students added to the archive. #### 2. Unarchiving a student: - 1. Prerequisites: Have 2 students named 'tim' and 'joe' already archived. + 1. Prerequisites: Have 2 students named "tim" and 'joe' already archived. 2. Test Case: `unarchive joe` Expected: 'joe' will be removed from archive and added back to student list. 3. Test Case: `unarchive`, `tim` - Expected: 'tim' will be removed from archive and added back to student list. + Expected: "tim" will be removed from archive and added back to student list. #### 3. Archiving/unarchiving student that does not exist: 1. Prerequisites: Have an empty student list @@ -432,25 +432,25 @@ Classify serves as an attempt to modernise administrative tasks in education ins ### Editing a student's details #### 1. Entering edit mode for an existing student: -1. Prerequisites: Add student named 'tim' to the student list with the `add` command. +1. Prerequisites: Add student named "tim" to the student list with the `add` command. 2. Test Case: `edit`, `tim` - Expected: Name will be prompted first, then edit mode will be initiated for student 'tim'. + Expected: Name will be prompted first, then edit mode will be initiated for student "tim". 3. Test Case: `edit tim` - Expected: Edit mode will be initiated for student 'tim'. + Expected: Edit mode will be initiated for student "tim". #### 2. Adding single or multiple subjects to an existing student -1. Prerequisites: Add student 'tim' and initiate edit mode for 'tim'. +1. Prerequisites: Add student "tim" and initiate edit mode for "tim". 2. Test Case: `1`, `CS2113`, `11`, `1`, `no` - Expected: 'tim' has subject 'CS2113' with marks '11' and '1' class attended. + Expected: "tim" has subject 'CS2113' with marks '11' and '1' class attended. 3. Test Case: `1`, `CS2030`, ` `, ` `, `yes`, `CS2040`, ` `, ` `, `no` - Expected: 'tim' has subjects 'CS2030' and 'CS2040' with no marks and attendance. + Expected: "tim" has subjects 'CS2030' and 'CS2040' with no marks and attendance. 4. Test Case: `1`, ` ` - Expected: Returns to edit mode for 'tim' and no change in subjects is made for 'tim'. + Expected: Returns to edit mode for "tim" and no change in subjects is made for "tim". #### 3. Testing invalid entries for editing student -1. Prerequisites: Add student 'tim' with subjects 'CS2113', 'CS2040' and phone number '88888888' and initiate edit mode for 'tim'. +1. Prerequisites: Add student "tim" with subjects 'CS2113', 'CS2040' and phone number '88888888' and initiate edit mode for "tim". 2. Test Case: `1`, `cs2113` - Expected: Returns to edit mode for 'tim', no new subject added and error message printed for adding existing subject. + Expected: Returns to edit mode for "tim", no new subject added and error message printed for adding existing subject. 3. Test Case: `2`, `CS2113`, `CS2040` Expected: Prints error message for existing subject and new subject name is prompted to update 'CS2113'. 4. Test Case: `3`, `CG2023` From 991db77ad4bb4ed2d5118e69cc6a5e606557601e Mon Sep 17 00:00:00 2001 From: Cryolian Date: Mon, 15 Apr 2024 22:42:15 +0800 Subject: [PATCH 499/503] typo --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 41e99055e8..2aa806923b 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -445,7 +445,7 @@ Classify serves as an attempt to modernise administrative tasks in education ins 3. Test Case: `1`, `CS2030`, ` `, ` `, `yes`, `CS2040`, ` `, ` `, `no` Expected: "tim" has subjects 'CS2030' and 'CS2040' with no marks and attendance. 4. Test Case: `1`, ` ` - Expected: Returns to edit mode for "tim" and no change in subjects is made for "tim". + Expected: Returns to edit mode for "tim" and no changes in subjects are made for "tim". #### 3. Testing invalid entries for editing student 1. Prerequisites: Add student "tim" with subjects 'CS2113', 'CS2040' and phone number '88888888' and initiate edit mode for "tim". From 2f9832d8ae4ed7fe923347abe24ddb2c53bb69de Mon Sep 17 00:00:00 2001 From: Cryolian Date: Mon, 15 Apr 2024 22:42:52 +0800 Subject: [PATCH 500/503] change back to 6 --- docs/DeveloperGuide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index fd812678cb..a2b6c8c315 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -458,5 +458,5 @@ Classify serves as an attempt to modernise administrative tasks in education ins Expected: Prints error message for no subject found and prompts for another subject name to delete. 5. Test Case: `4`, `11111111` Expected: Prints invalid phone number error message and prompts for another phone number. -6. Test Case: `5`, `20 jan 2001` +6. Test Case: `6`, `20 jan 2001` Expected: Prints error message for invalid date and prompts for another date. From e2a33921b1663276c1711ac0976aa9053b322842 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Mon, 15 Apr 2024 22:43:46 +0800 Subject: [PATCH 501/503] change enter --- docs/DeveloperGuide.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index a2b6c8c315..68656fec28 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -327,10 +327,7 @@ Classify serves as an attempt to modernise administrative tasks in education ins - Logging and monitoring mechanisms should be in place to track system usage and identify potential issues. 7. **Data Management**: - - File saving should be done whenever a change has been made to the Master List. - -## Glossary -* *` `* - Refers to empty user input, where user just presses `enter` key. + - File saving should be done whenever a change has been made to the Master List. ## Instructions for manual testing @@ -389,12 +386,12 @@ Classify serves as an attempt to modernise administrative tasks in education ins 3. Ingesting a full list of Students using a Text File (without using file extension) 1. Prerequisites: Have at least one text file in the inputFolder in Data. The text file present (e.g. **File.txt**) is properly formatted according to the requirements stated in the User Guide and is present in the inputFolder. 2. Test case: `Process`, enter, **`File`** - Expected: `Fetching the data from File.txt.` will be displayed. Can use the `list`, ` `, ` `, `1` to ensure that all the students in the file are added. + Expected: `Fetching the data from File.txt.` will be displayed. Can use the `list`, `enter`, `enter`, `1` to ensure that all the students in the file are added. 4. Ingesting a full list of Students using a Text File (using file extension) 1. Prerequisites: Have at least one text file in the inputFolder in Data. The text file present (e.g. **File.txt**) is properly formatted according to the requirements stated in the User Guide and is present in the inputFolder. 2. Test case: `Process`, enter, **`File.txt`** - Expected: `Fetching the data from File.txt.` will be displayed. Can use the `list`, ` `, ` `, `1` to ensure that all the students in the file are added. + Expected: `Fetching the data from File.txt.` will be displayed. Can use the `list`, `enter`, `enter`, `1` to ensure that all the students in the file are added. ### Restoring a recently deleted student 1. Restore a student from the recently deleted list @@ -443,9 +440,9 @@ Classify serves as an attempt to modernise administrative tasks in education ins 1. Prerequisites: Add student "tim" and initiate edit mode for "tim". 2. Test Case: `1`, `CS2113`, `11`, `1`, `no` Expected: "tim" has subject 'CS2113' with marks '11' and '1' class attended. -3. Test Case: `1`, `CS2030`, ` `, ` `, `yes`, `CS2040`, ` `, ` `, `no` +3. Test Case: `1`, `CS2030`, `enter`, `enter`, `yes`, `CS2040`, `enter`, `enter`, `no` Expected: "tim" has subjects 'CS2030' and 'CS2040' with no marks and attendance. -4. Test Case: `1`, ` ` +4. Test Case: `1`, `enter` Expected: Returns to edit mode for "tim" and no changes in subjects are made for "tim". #### 3. Testing invalid entries for editing student From 99eed624d2e0bc35aa4c7ef72ee4fe5728cc7144 Mon Sep 17 00:00:00 2001 From: Cryolian Date: Mon, 15 Apr 2024 22:47:20 +0800 Subject: [PATCH 502/503] change back --- docs/DeveloperGuide.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 68656fec28..05328a55f1 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -408,18 +408,18 @@ Classify serves as an attempt to modernise administrative tasks in education ins ### Archiving/unarchiving a student #### 1. Archiving a student: - 1. Prerequisites: Add 2 students named "tim" and 'joe' to the student list. + 1. Prerequisites: Add 2 students named 'tim' and 'joe' to the student list. 2. Test Case: `archive joe` Expected: 'joe' will be removed from student list and will appear in the list of students added to the archive. 3. Test Case: `archive`, `tim` - Expected: "tim" will be removed from student list and will appear in the list of students added to the archive. + Expected: 'tim' will be removed from student list and will appear in the list of students added to the archive. #### 2. Unarchiving a student: - 1. Prerequisites: Have 2 students named "tim" and 'joe' already archived. + 1. Prerequisites: Have 2 students named 'tim' and 'joe' already archived. 2. Test Case: `unarchive joe` Expected: 'joe' will be removed from archive and added back to student list. 3. Test Case: `unarchive`, `tim` - Expected: "tim" will be removed from archive and added back to student list. + Expected: 'tim' will be removed from archive and added back to student list. #### 3. Archiving/unarchiving student that does not exist: 1. Prerequisites: Have an empty student list @@ -430,25 +430,25 @@ Classify serves as an attempt to modernise administrative tasks in education ins ### Editing a student's details #### 1. Entering edit mode for an existing student: -1. Prerequisites: Add student named "tim" to the student list with the `add` command. +1. Prerequisites: Add student named 'tim' to the student list with the `add` command. 2. Test Case: `edit`, `tim` - Expected: Name will be prompted first, then edit mode will be initiated for student "tim". + Expected: Name will be prompted first, then edit mode will be initiated for student 'tim'. 3. Test Case: `edit tim` - Expected: Edit mode will be initiated for student "tim". + Expected: Edit mode will be initiated for student 'tim'. #### 2. Adding single or multiple subjects to an existing student -1. Prerequisites: Add student "tim" and initiate edit mode for "tim". +1. Prerequisites: Add student 'tim' and initiate edit mode for 'tim'. 2. Test Case: `1`, `CS2113`, `11`, `1`, `no` - Expected: "tim" has subject 'CS2113' with marks '11' and '1' class attended. + Expected: 'tim' has subject 'CS2113' with marks '11' and '1' class attended. 3. Test Case: `1`, `CS2030`, `enter`, `enter`, `yes`, `CS2040`, `enter`, `enter`, `no` - Expected: "tim" has subjects 'CS2030' and 'CS2040' with no marks and attendance. + Expected: 'tim' has subjects 'CS2030' and 'CS2040' with no marks and attendance. 4. Test Case: `1`, `enter` - Expected: Returns to edit mode for "tim" and no changes in subjects are made for "tim". + Expected: Returns to edit mode for 'tim' and no changes in subjects are made for 'tim'. #### 3. Testing invalid entries for editing student -1. Prerequisites: Add student "tim" with subjects 'CS2113', 'CS2040' and phone number '88888888' and initiate edit mode for "tim". +1. Prerequisites: Add student 'tim' with subjects 'CS2113', 'CS2040' and phone number '88888888' and initiate edit mode for 'tim'. 2. Test Case: `1`, `cs2113` - Expected: Returns to edit mode for "tim", no new subject added and error message printed for adding existing subject. + Expected: Returns to edit mode for 'tim', no new subject added and error message printed for adding existing subject. 3. Test Case: `2`, `CS2113`, `CS2040` Expected: Prints error message for existing subject and new subject name is prompted to update 'CS2113'. 4. Test Case: `3`, `CG2023` From c0b6de8699e4097aecdb32213636bfdb5de523cb Mon Sep 17 00:00:00 2001 From: Cryolian <102575848+Cryolian@users.noreply.github.com> Date: Mon, 15 Apr 2024 22:53:15 +0800 Subject: [PATCH 503/503] Update DeveloperGuide.md --- docs/DeveloperGuide.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index 05328a55f1..03ac469294 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -16,7 +16,6 @@ - [Project Scope](#product-scope) - [User Stories](#user-stories) - [Non-Functional Requirements](#non-functional-requirements) - - [Glossary](#glossary) - [Instructions for manual testing](#instructions-for-manual-testing)

$}?fO5%QE@X6Kr`ubfAAxM*R%#^ph)g-Dqs-&pI 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 Date: Sat, 13 Apr 2024 22:21:55 +0800 Subject: [PATCH 421/503] Update PPP --- docs/team/parthgandhinus.md | 61 +++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/docs/team/parthgandhinus.md b/docs/team/parthgandhinus.md index 8c65210585..2d8207d10e 100644 --- a/docs/team/parthgandhinus.md +++ b/docs/team/parthgandhinus.md @@ -5,8 +5,63 @@ Classify is a desktop application used for Tuition Centres to allow for easier management of their enrolled students. From allowing users to add new students to sorting them based on their last paid date, Classify is the one-stop app that all Tuition Centres can employ for ease of student management. To use the app, users can interact with it using CLI. -Overall, the code base has more than 3kLoC, and is written in Java. +Overall, the code base has more than 7000 Lines of Code, and is written in Java. -Given below are my contributions to the project: +--- -**Code contributed:** [Link to Reposense contribution graph](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=ParthGandhiNUS&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2024-02-23&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) \ No newline at end of file +#### Given below are my contributions to the project: + +**Feature: Data Writing to Student_Information.txt** +* Refers to the writing of data in Student_Information.txt in Classify +* Highlights: Creates a directory and file on your computer if it does not exist. Updates the Student_Information.txt file with all the students' attributes (eg. Name, Phone Number, Gender, Last Payment Date, All subject information, etc). The file is constantly overwritten when a command (eg. Add Student, Delete Student, etc) is used. There is a standardised format used to store all the data. Different Regex are used to differentiate the different types of data and to assist in data parsing (mentioned below). +* Justification: Since the data inputted by the user is what forms our "database" of students we need to constantly update our database with every change to ensure our "database" is updated. + +**Feature: Data Retrieval and Parsing from Student_Information.txt** +* Refers to the retrieval and parsing of retrieved data in Classify +* Highlights: All the data retrieved goes through a parser which uses 3 types of regex (```~~```, ```##```, and ```#~~#```). Each of the regex serves to break every line of Student_Text.txt into various domains. + * ```~~``` separates all the different identifiers of a student (eg. name, phone number etc). + * ```##``` separates all the different attributes of a subject that the student is taking (eg. Subject name, Subject Grade, Classes Attended). + * ```#~~#``` separates all the different subjects that a student is taking. + This process is repeated for every line of code in Student_Information.txt while checking for duplicate entries of a student. All the data is then re-added to the masterStudentList everytime we run the Classify Application +* Justification: Different Regex allows for a much cleaner separation of the different types of information in the Student_Information.txt file. + +**Feature: Process (Text File)** +* Refers to the addition of a class of students via a text file. In that text file, students would be taking a common subject and having the same number of classes attended. This simulates batches of students in a tuition centre. +* Highlights: User can type ```Process```. After that, the user will be able to view all the text files in the folder labelled as InputFolder where they are allowed to add or remove text files. + * These text files need to be formatted according to the standard template given to ensure that the process functionality runs smoothly. + * The user can then select the text file which they want to add to the masterStudentList. + * All students in the selected text file will be added to the masterStudentList. In this part of the functionality checks are put in place to see if a student taking this subject already exists in the system. + * If a student exists, then the system also performs a check to see if the same subject is already attributed to the student. + If true, then the systems skips this student and goes on to process the next student. + Otherwise this functionality either attributes the subject in this text file to the existing student or makes a new student with info about this subject and the students' phone number. + * Just like the data parser, the process here has a separate fully functional parser which parses information a bit differently as compared to the data parser. In the process parser, the only regex used is ```~~``` to ensure that it is simple for users to make the text file for entering into the system. +* Justification: Process is meant to be a one-stop fast and easy way for administrators to add students. The system already checks for matching students and matching subjects for every student which makes this functionality quite useful in real life. + +--- +**Code contributed:** [Link to Reposense contribution graph](https://nus-cs2113-ay2324s2.github.io/tp-dashboard/?search=ParthGandhiNUS&breakdown=true&sort=groupTitle%20dsc&sortWithin=title&since=2024-02-23&timeframe=commit&mergegroup=&groupSelect=groupByRepos&checkedFileTypes=docs~functional-code~test-code~other) + +--- + +**Documentation:** +* [Contributions to UG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/UserGuide.md): + * Did the preface for the project. + * Wrote out the functionalities for Process Command + * Made the command summary in Tabular form for easy referencing + * Refactored and cleaned the UG + * Made the table of contents for the UG, linking the relevant parts of the markdown file +* [Contributions to DG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/DeveloperGuide.md): + * Listed out the workflow for Process and Data commands in DG + * Made the table of contents for the DG + +--- + +**Contributions to Team-Based tasks:** +* Built the groundwork for Main.java and main input Parser which enables us to access different functionalities +* Cleared Issues and settled quite a few bugs in our application +* Handling of Pull Requests +* Contributions to Junit tests + * [TextFileHandlerTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/textfilecode/TextFileHandlerTest.java) + * [TextFileParserTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/textfilecode/TextFileParserTest.java) + * [TextFileReaderTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/textfilecode/TextFileReaderTest.java) + * [DataReaderTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/data/DataReaderTest.java) + * [DataWriterTest](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/src/test/java/classify/data/DataWriterTest.java) From 602b8fe4c185363130456e79067266b1803ddb8a Mon Sep 17 00:00:00 2001 From: Parth Sanjay Gandhi Date: Sat, 13 Apr 2024 23:07:12 +0800 Subject: [PATCH 422/503] Add table of content to DG --- docs/DeveloperGuide.md | 61 +++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index dfd753442c..8d5fc6027f 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -1,5 +1,23 @@ # Developer Guide +## Table of Contents +- [Acknowledgements](#acknowledgements) +- [Overall Design and Implementation](#overall-design-and-implementation) +- [Project Components](#project-components) + - [Ui component](#ui-component) + - [InputParsing component](#inputparsing-component) + - [Student Details](#student-details) + - [AddStudent Component](#addstudent-component) + - [StudentSorter Component](#studentsorter-component) + - [Data Commands Component](#data-commands-component) + - [Process Componenent](#process-component) +- [Project Scope](#product-scope) + - [User Stories](#user-stories) + - [Non-Functional Requirements](#non-functional-requirements) + - [Glossary](#glossary) + - [Instructions for manual testing](#instructions-for-manual-testing) + + ## Acknowledgements 1. Reference to AB-3 Developer Guide @@ -7,7 +25,7 @@ - [Source](https://se-education.org/addressbook-level3/DeveloperGuide.html#proposed-undoredo-feature) - Used as template to structure this Developer Guide -## Design & implementation +## Overall Design and implementation Main architectural diagram: ![Overall architecture diagram](./diagrams/src/ArchitectureDiagram/MainArchitecture.png) @@ -16,6 +34,8 @@ Do note that the Classify class is the "main" class in the diagram, with all oth --- +## Project Components + ### Ui component The `Ui` class handles message output for the user within the terminal. @@ -105,24 +125,6 @@ We created a parent `Details` class as those are information not specifically re However, our current implementation is not very secure as one can access every field of a `Student` object just by having access to it or the `StudentAttribute` object, which can be done via accessing the `static masterStudentList` variable.In future updates, we could possibly implement a Facade Pattern to better hide sensitive details. -### Data Commands Component - -This section refers to `DataHandler.java`, `DataReader.java`, and `DataStorage.java` classes. - -We have currently implemented a basic data handler which has the abilities to store a student's name into a text file. - -This text file is created locally on the users' computer for easy access and retrieval. - -Currently there is a polling system set in place where every change in the list of students (eg, addition, deletion, modification) would override the current working text file on the users' computer. - -As stated above, all the names and attributes associated with each student will be saved to the main text file, named Student_Information.txt. - -If the user chooses to delete or archive a student, it would be saved to an archive file, named student_archive.txt. If the user chooses to unarchive a student or undo a recent deletion, it will be brought back to the main text file. - -The two text files are will be created under a directory called data, in which two separate file paths will be created if it is not already found on the user's desktop. - -![DataStoringObjectDiagramUML](./diagrams/src/DataStoring/ObjectDiagram.png) - #### Design Considerations In order to ensure the proper usage of OOP principles (such as encapsulation), we have segregated the 3 classes to read, store and handle the data. @@ -199,6 +201,27 @@ total classes attended, and last payment date. The `StudentSorter` class contributes to the overall functionality of the application by providing a mechanism to organize and present student information based on user preferences. +### Data Commands Component + +This section refers to `DataHandler.java`, `DataReader.java`, and `DataStorage.java` classes. + +We have currently implemented a basic data handler which has the abilities to store a student's name into a text file. + +This text file is created locally on the users' computer for easy access and retrieval. + +Currently there is a polling system set in place where every change in the list of students (eg, addition, deletion, modification) would override the current working text file on the users' computer. + +As stated above, all the names and attributes associated with each student will be saved to the main text file, named Student_Information.txt. + +If the user chooses to delete or archive a student, it would be saved to an archive file, named student_archive.txt. If the user chooses to unarchive a student or undo a recent deletion, it will be brought back to the main text file. + +The two text files are will be created under a directory called data, in which two separate file paths will be created if it is not already found on the user's desktop. + +![DataStoringObjectDiagramUML](./diagrams/src/DataStoring/ObjectDiagram.png) + +### Process Component +This section refers to `TextFileHandler.java`, `TextFileParser.java`, and `TextFileReader.java` classes. + --- ## Product scope From e0ab961dd4893fe5e5056ec1a296e0b1201f1945 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sat, 13 Apr 2024 23:33:54 +0800 Subject: [PATCH 423/503] Clean up code and update help function to be more readable on small screens --- docs/DeveloperGuide.md | 12 +------- docs/UserGuide.md | 25 ++++++++-------- docs/team/alalal47.md | 12 ++++++++ src/main/java/classify/ui/UI.java | 29 +++++++++++-------- .../java/classify/user/InputParsingTest.java | 24 +++++++-------- 5 files changed, 54 insertions(+), 48 deletions(-) diff --git a/docs/DeveloperGuide.md b/docs/DeveloperGuide.md index dfd753442c..dd14fc365b 100644 --- a/docs/DeveloperGuide.md +++ b/docs/DeveloperGuide.md @@ -326,16 +326,6 @@ Classify serves as an attempt to modernise administrative tasks in education ins 2. Test case: `archive joe`
Expected: `joe` will be removed from the list, and added to the archive, `joe` will appear in the list of students added to the archive. -### Archive -#### 1. Adding a student with a name and phone number only: -1. Prerequisites: View if a student with the name 'joe' exists by using the `view joe` command. -2. Test case: `add joe` and when prompted for phone number enter `11111111`, while pressing enter to skip other optional fields. -
-Expected: `view joe` now shows the Student details of a student with Name: joe, Phone Number: 11111111. Other fields that were left blank will reflect 'Unknown' or for date fields, today's date. -3. Test case: `add` and when prompted for Name, `joe`. `11111111` when prompted for phone number, press enter to skip other fields. -
-Expected: `view joe` shows the same results as when a student was added via `add joe`. - ### Editing a student's details #### 1. Entering edit mode for an existing student: 1. Prerequisites: Add student named 'tim' to the student list with the `add` command. @@ -402,7 +392,7 @@ Expected: `view joe` shows the same results as when a student was added via `add 2. Test Case: `edit`
Expected: Error message for empty list will be printed. -#### 10. Editing non-existing student in non-empty list +#### 10. Editing non-existent student in non-empty list 1. Prerequisites: Add student `tim` 2. Test Case: `edit john`
Expected: Error message for non-existed student will be printed. diff --git a/docs/UserGuide.md b/docs/UserGuide.md index d7501fdbb9..271915ba8d 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -181,7 +181,7 @@ Format: `add` or `add NAME` Depending on whether the user entered the student's name or not during the command, fields will be printed out in the terminal, awaiting a user input each time. -Please note that the user input NUMBER (shown below) must be an *8 digit number starting with 8 or 9*. +Please note that the user input NUMBER (shown below) must be an *8-digit number starting with 8 or 9*. Thus, please be informed and educated that our software only works in countries that have phone numbers that are 8 digits long and start with 8 or 9. To be specific, this is referring to a city-state republic in South East Asia, that lies in the timezone GMT +8 in the Straits of Johor. Some may debate that our time zone is actually GMT+7.5 or GMT+7, but it was changed to facilitate business deals and decisions with other financial hubs in the region thanks to our capitalistic overlords. @@ -205,7 +205,7 @@ Do you want to add another subject and grade? (yes/no) no Please input a valid Phone number: -NUMBER +89718971 . . ``` @@ -267,7 +267,6 @@ a field will be printed out in the terminal, awaiting a user input. #### Example usage: ``` delete - Enter student name: wario Student removed successfully! @@ -389,9 +388,12 @@ Format: `list` Allows the user to specify a subject, then displays all students with that subject. If the field is left blank, students will be displayed regardless of the subjects they have. -The user can then select by index, from 4 additional options to either display all students in the master list, -all students in the master list as well as the total number of classes they have attended. - +The user can then select by index, from 5 additional options. +1. Full student list +2. List of students with total classes attended +3. List of students with phone number shown +4. List of students in archive +5. List of students in recently deleted Alternatively, the user can choose to display either the students in the recently deleted list or the archive. Do note that there is a difference between 0 and no classes attended found. If the program displays 0 classes attended, @@ -556,7 +558,7 @@ gerard ~~ 98888888 ~~ 95.0 shui hon ~~ 91231234 ~~ 99.0 ``` -#### Without Filetype: +#### Without File extension: ``` process Current Files in your Input Folder: @@ -569,7 +571,7 @@ Fetching the data from mathclass.txt. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` -#### With Filetype: +#### With File extension: ``` process Current Files in your Input Folder: @@ -596,9 +598,7 @@ For any archived student, the user will be unable to add a student with the same ``` archive wario Archive successful. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Runtime Database: - +What else can I do for you today? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` @@ -619,8 +619,7 @@ The user can then view currently archived students using the `list` command. ``` unarchive wario Unarchive successful. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Runtime List: +What else can I do for you today? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` diff --git a/docs/team/alalal47.md b/docs/team/alalal47.md index 4bb92f1ecb..228a31fdd4 100644 --- a/docs/team/alalal47.md +++ b/docs/team/alalal47.md @@ -16,12 +16,24 @@ all Tuition Centres can employ for ease of student management. - Along with the add feature, the other crucial feature that composes Classify's basic functionality. - Above being a simple delete feature, also implements a recently deleted list which is only cleared at the end of every session, allowing the user to restore accidental deletes. + - **Feature: Restore a student deleted in the current session** - Works in tandem with the delete function to ensure that users do not have to re-add all the student information in the case of an accidental or unwanted deletion. + - **Feature: Undo last deletion in the current session** - A more convenient way for users to use the restore function if they immediately want to reverse a deletion before any other deletes have been made. + + - **Feature: Sort list of students by last date of payment** + - Allows the user to conveniently track any students that might have overdue fees. + + + - **Feature: Handle corrupted Student_Information.txt files** + - Prevents invalid inputs in the data file from crashing Classify. + - Does not allow the user to resume use of Classify before the file is deleted, or the corruption is rectified. + + - #### Contributions to the [UG](https://github.com/AY2324S2-CS2113-T13-3/tp/blob/master/docs/UserGuide.md) - Wrote the Usage guide for the edit, delete, restore, undo and sort features. diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 9e923a3132..4a5ea19acb 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -31,7 +31,7 @@ public class UI { "(eg. from 2010 until today.)"; //@@author ParthGandhiNUS private static final String WELCOME_TO_CLASSIFY = "Welcome to Classify!"; - private static final String WHAT_CAN_I_DO_FOR_YOU_TODAY = "What can I do for you today?"; + private static final String WHAT_ELSE_CAN_I_DO_FOR_YOU_TODAY = "What can I do for you today?"; private static final String CLASSIFY_GOODBYE_MESSAGE = "Hope you've had a productive day. See you again! Goodbye!"; private static final String WRONG_INPUT_MESSAGE = "No such command, type \"help\" to view all commands"; //@@author blackmirag3 @@ -45,7 +45,6 @@ public class UI { private static final String EDIT_COMMAND_MODIFY_PAYMENT_DATE_PROMPT = "6. Modify payment date"; private static final String EDIT_COMMAND_DELETED_SUBJECT_MESSAGE = "Subject deleted successfully!"; private static final String EDIT_COMMAND_MODIFY_GENDER_PROMPT = "7. Edit Gender"; - private static final String WHAT_ELSE_CAN_I_DO_FOR_YOU_TODAY = "What else can I do for you today?"; private static final String STUDENT_DETAILS_PROMPT = "Enter student details: "; private static final String STUDENT_NAME_PROMPT = "Enter student name: "; private static final String STUDENT_DETAILS_MESSAGE = "Student details: "; @@ -94,17 +93,33 @@ public class UI { */ public static void printHelp() { printAddHelpMessage(); + System.out.println(""); printEditHelpMessage(); + System.out.println(""); printViewHelpMessage(); + System.out.println(""); printDeleteHelpMessage(); + System.out.println(""); printRestoreHelpMessage(); + System.out.println(""); printUndoHelpMessage(); + System.out.println(""); printListHelpMessage(); + System.out.println(""); printByeHelpMessage(); + System.out.println(""); printSortHelpMessage(); + System.out.println(""); printArchiveHelpMessage(); + System.out.println(""); printUnarchiveHelpMessage(); + System.out.println(""); printProcessTextFileInputMessage(); + System.out.println(""); + printHelpHelpMessage(); + } + + private static void printHelpHelpMessage() { System.out.println("help Prints this help message"); } @@ -181,7 +196,6 @@ public static void printDivider() { public static void printWelcomeMessage() { printDivider(); System.out.println(WELCOME_TO_CLASSIFY); - System.out.println(WHAT_CAN_I_DO_FOR_YOU_TODAY); } /** @@ -208,10 +222,6 @@ public static void printWrongInput() { printDivider(); } - public static void printStudentDetailsPrompt() { - System.out.println(STUDENT_DETAILS_PROMPT); - } - public static void printStudentNamePrompt() { System.out.println(STUDENT_NAME_PROMPT); } @@ -235,11 +245,6 @@ public static void printStudentName(String name) { System.out.println(STUDENT_NAME_MESSAGE + name + "\n"); } - //@@author Cryolian - public static void printStudentName(Student student) { - System.out.println(STUDENT_NAME_MESSAGE + student.getName() + "\n"); - } - //@@author blackmirag3 /*** diff --git a/src/test/java/classify/user/InputParsingTest.java b/src/test/java/classify/user/InputParsingTest.java index b1e25b0f6d..e1cbca2edc 100644 --- a/src/test/java/classify/user/InputParsingTest.java +++ b/src/test/java/classify/user/InputParsingTest.java @@ -144,21 +144,21 @@ public void testHelpCommand() { String expectedOutput = "add Adds a student to the student list, expects a name" + ", grade and lessons attended e.g. add [name]" - + System.lineSeparator() + + + System.lineSeparator() + System.lineSeparator() + "edit Edits a students details, expects a name" + ", can be used directly with a name e.g. edit [name]" - + System.lineSeparator() + + + System.lineSeparator() + System.lineSeparator() + "view Views a students details, expects a name" + ", can be used directly with a name e.g. add [name]" - + System.lineSeparator() + + + System.lineSeparator() + System.lineSeparator() + "delete Deletes a student from the student list, expects a name" + ", can be used directly with a name e.g. add [name]" - + System.lineSeparator() + + + System.lineSeparator() + System.lineSeparator() + "restore Restore a student deleted within the current session, expects a name, " + "can be used directly by restore [name]." - + System.lineSeparator() + + + System.lineSeparator() + System.lineSeparator() + "undo Restores the last student deleted in the current session." - + System.lineSeparator() + + + System.lineSeparator() + System.lineSeparator() + "list Displays the list of all students" + System.lineSeparator() + " Currently available types: Whole student list, with " + @@ -166,23 +166,23 @@ public void testHelpCommand() { + System.lineSeparator() + " the archived list, the recently deleted list or " + "by certain subject only." - + System.lineSeparator() + + + System.lineSeparator() + System.lineSeparator() + "bye Exits Classify" - + System.lineSeparator() + + + System.lineSeparator() + System.lineSeparator() + "sort Sorts the student list by the input parameter, expects an" + " attribute to sort by, can be used directly by sort [type]." + System.lineSeparator() + " Currently available types: name, classes, payment" - + System.lineSeparator() + + + System.lineSeparator() + System.lineSeparator() + "archive Removes the specified student from the list and archives them," + " can be used directly by archive [name]." - + System.lineSeparator() + + + System.lineSeparator() + System.lineSeparator() + "unarchive Removes the specified student from the archive and adds them to the list" + ", can be used directly by unarchive [name]." - + System.lineSeparator() + + + System.lineSeparator() + System.lineSeparator() + "process Processes a text file containing a list of students taking the same"+ " subject and the same number of classes." - + System.lineSeparator() + + + System.lineSeparator() + System.lineSeparator() + "help Prints this help message" + System.lineSeparator() + "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"; From c46e9511e86071a7e39e5595eb293de0ccd68a90 Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sat, 13 Apr 2024 23:36:18 +0800 Subject: [PATCH 424/503] Fix naming for magic literal --- src/main/java/classify/ui/UI.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/classify/ui/UI.java b/src/main/java/classify/ui/UI.java index 4a5ea19acb..6cc14b8948 100644 --- a/src/main/java/classify/ui/UI.java +++ b/src/main/java/classify/ui/UI.java @@ -31,7 +31,7 @@ public class UI { "(eg. from 2010 until today.)"; //@@author ParthGandhiNUS private static final String WELCOME_TO_CLASSIFY = "Welcome to Classify!"; - private static final String WHAT_ELSE_CAN_I_DO_FOR_YOU_TODAY = "What can I do for you today?"; + private static final String WHAT_CAN_I_DO_FOR_YOU_TODAY = "What can I do for you today?"; private static final String CLASSIFY_GOODBYE_MESSAGE = "Hope you've had a productive day. See you again! Goodbye!"; private static final String WRONG_INPUT_MESSAGE = "No such command, type \"help\" to view all commands"; //@@author blackmirag3 @@ -214,7 +214,7 @@ public static void printProcessTextFileInputMessage() { //@@author blackmirag3 public static void printSubsequentUserPrompt() { - System.out.println(WHAT_ELSE_CAN_I_DO_FOR_YOU_TODAY); + System.out.println(WHAT_CAN_I_DO_FOR_YOU_TODAY); printDivider(); } public static void printWrongInput() { From 75e7e94b26e0878fbb47e7e4c3afddd20aeb9edf Mon Sep 17 00:00:00 2001 From: alalal47 Date: Sat, 13 Apr 2024 23:39:43 +0800 Subject: [PATCH 425/503] Fix examples in ug to match product --- docs/UserGuide.md | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index 271915ba8d..aa018c6f7f 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -331,8 +331,7 @@ Enter Classes Attended (blank to skip): >> 10 Do you want to add another subject and grade? (yes/no) >> no -What else can I do for you today? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ``` If no student is found in the master student list, edit mode will not be entered and the programme will resume as per normal. @@ -343,8 +342,6 @@ edit Name of student to edit (blank to exit): luigi No student found to edit! -What else can I do for you today? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` ### Restore a student to the working list `restore` @@ -598,8 +595,6 @@ For any archived student, the user will be unable to add a student with the same ``` archive wario Archive successful. -What else can I do for you today? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` The user can then view currently archived students using the `list` command. @@ -619,8 +614,6 @@ The user can then view currently archived students using the `list` command. ``` unarchive wario Unarchive successful. -What else can I do for you today? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` #### Invalid student: @@ -628,8 +621,6 @@ What else can I do for you today? ``` unarchive yeeter No student found! -What else can I do for you today? -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` If a student that exists in the archive data file matches the name and phone number of an already existing student, the archived student will not be loaded into the archive list and will be overwritten subsequently. From 17232dc167c0505209af1a9ece35192256dd8441 Mon Sep 17 00:00:00 2001 From: tayponghee Date: Sun, 14 Apr 2024 00:11:59 +0800 Subject: [PATCH 426/503] Remove circle from Architecture Diagram --- .../Architecture Diagram.puml | 1 + .../ArchitectureDiagram/MainArchitecture.png | Bin 39467 -> 38693 bytes 2 files changed, 1 insertion(+) diff --git a/docs/diagrams/src/ArchitectureDiagram/Architecture Diagram.puml b/docs/diagrams/src/ArchitectureDiagram/Architecture Diagram.puml index 88b5b11afb..9301ab2506 100644 --- a/docs/diagrams/src/ArchitectureDiagram/Architecture Diagram.puml +++ b/docs/diagrams/src/ArchitectureDiagram/Architecture Diagram.puml @@ -1,4 +1,5 @@ @startuml MainArchitecture +hide circle package data { } diff --git a/docs/diagrams/src/ArchitectureDiagram/MainArchitecture.png b/docs/diagrams/src/ArchitectureDiagram/MainArchitecture.png index e481dc0b34f749ddb243335ec64b1301da41872a..3815611519440e820f9a61b623fd3aeadfbe3eeb 100644 GIT binary patch literal 38693 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