diff --git a/.gitignore b/.gitignore index 823d175eb670..af5ce29fb4aa 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,6 @@ classes/ /bin/ src/main/resources/docs/ out/ + +# https://github.com/nus-cs2103-AY1819S1/forum/issues/74 Allow _reposense/config.json +!_reposense/config.json diff --git a/README.adoc b/README.adoc index 450054624f48..523ba687af1c 100644 --- a/README.adoc +++ b/README.adoc @@ -1,10 +1,10 @@ -= Address Book (Level 4) += TutorPal ifdef::env-github,env-browser[:relfileprefix: docs/] -https://travis-ci.org/se-edu/addressbook-level4[image:https://travis-ci.org/se-edu/addressbook-level4.svg?branch=master[Build Status]] -https://ci.appveyor.com/project/damithc/addressbook-level4[image:https://ci.appveyor.com/api/projects/status/3boko2x2vr5cc3w2?svg=true[Build status]] -https://coveralls.io/github/se-edu/addressbook-level4?branch=master[image:https://coveralls.io/repos/github/se-edu/addressbook-level4/badge.svg?branch=master[Coverage Status]] -https://www.codacy.com/app/damith/addressbook-level4?utm_source=github.com&utm_medium=referral&utm_content=se-edu/addressbook-level4&utm_campaign=Badge_Grade[image:https://api.codacy.com/project/badge/Grade/fc0b7775cf7f4fdeaf08776f3d8e364a[Codacy Badge]] +https://travis-ci.com/CS2103-AY1819S1-T13-1/main[image:https://travis-ci.com/CS2103-AY1819S1-T13-1/main.svg?branch=master[Build Status]] +https://ci.appveyor.com/project/chenlu-chua/main/branch/master[image:https://ci.appveyor.com/api/projects/status/2xd9spc31800oyf9/branch/master?svg=true[Build status]] +https://coveralls.io/github/CS2103-AY1819S1-T13-1/main?branch=master[image:https://coveralls.io/repos/github/CS2103-AY1819S1-T13-1/main/badge.svg?branch=master[Coverage Status]] +image:https://api.codacy.com/project/badge/Grade/d3e0052076014d05b17685f5d61307bf["Codacy code quality", link="https://www.codacy.com/app/hrxiong/TutorPal-T13-1?utm_source=github.com&utm_medium=referral&utm_content=CS2103-AY1819S1-T13-1/main&utm_campaign=Badge_Grade"] https://gitter.im/se-edu/Lobby[image:https://badges.gitter.im/se-edu/Lobby.svg[Gitter chat]] ifdef::env-github[] @@ -15,26 +15,25 @@ ifndef::env-github[] image::images/Ui.png[width="600"] endif::[] -* This is a desktop Address Book application. It has a GUI but most of the user interactions happen using a CLI (Command Line Interface). -* It is a Java sample application intended for students learning Software Engineering while using Java as the main programming language. -* It is *written in OOP fashion*. It provides a *reasonably well-written* code example that is *significantly bigger* (around 6 KLoC)than what students usually write in beginner-level SE modules. -* What's different from https://github.com/se-edu/addressbook-level3[level 3]: -** A more sophisticated GUI that includes a list panel and an in-built Browser. -** More test cases, including automated GUI testing. -** Support for _Build Automation_ using Gradle and for _Continuous Integration_ using Travis CI. +* This is a desktop TutorPal application. It has a GUI but most of the user interactions happen using a CLI (Command Line Interface). +* It is an application intended to help private tutors to manage their students information. +* It has features specifically catered to tutors' needs: +** Users can store student information such as name, address, contact number, education level, tuition timing and fees of a student. +** Users are able to assign grades to students based on their examination result. +** Users are able to calculate their tuition earnings. +** Users can review the effectiveness of their teaching methods through a analysis of students' grades over time. == Site Map * <> * <> -* <> * <> * <> == Acknowledgements -* Some parts of this sample application were inspired by the excellent http://code.makery.ch/library/javafx-8-tutorial/[Java FX tutorial] by -_Marco Jakob_. +* The original source of code: AddressBook-Level4 project created by SE-EDU initiative at https://github.com/se-edu/ * Libraries used: https://github.com/TestFX/TestFX[TextFX], https://bitbucket.org/controlsfx/controlsfx/[ControlsFX], https://github.com/FasterXML/jackson[Jackson], https://github.com/google/guava[Guava], https://github.com/junit-team/junit5[JUnit5] +* Done by team CS2103-AY1819S1-T13-1 == Licence : link:LICENSE[MIT] diff --git a/_reposense/config.json b/_reposense/config.json new file mode 100644 index 000000000000..100dca1a131c --- /dev/null +++ b/_reposense/config.json @@ -0,0 +1,30 @@ +{ + "authors": + [ + { + "githubId": "CJuanvip", + "displayName": "CHE...UAN", + "authorNames": ["CJuanvip", "cj"] + }, + { + "githubId": "chenlu-chua", + "displayName": "CHUA ...EN LU", + "authorNames": ["chenlu-chua", "chenlu"] + }, + { + "githubId": "LZYAndy", + "displayName": "LIU Z...HAOYU", + "authorNames": ["LZYAndy", "刘照宇"] + }, + { + "githubId": "junjiee", + "displayName": "ONG J...N JIE", + "authorNames": ["junjiee", "Ong Jun Jie"] + }, + { + "githubId": "hrxiong", + "displayName": "XIONG...AORAN", + "authorNames": ["hrxiong"] + } + ] +} diff --git a/build.gradle b/build.gradle index f8e614f8b49b..0227433c28cb 100644 --- a/build.gradle +++ b/build.gradle @@ -207,9 +207,8 @@ asciidoctor { idprefix: '', // for compatibility with GitHub preview idseparator: '-', 'site-root': "${sourceDir}", // must be the same as sourceDir, do not modify - 'site-name': 'AddressBook-Level4', - 'site-githuburl': 'https://github.com/se-edu/addressbook-level4', - 'site-seedu': true, // delete this line if your project is not a fork (not a SE-EDU project) + 'site-name': 'TutorPal', + 'site-githuburl': 'https://github.com/CS2103-AY1819S1-T13-1/main', ] options['template_dirs'].each { diff --git a/docs/AboutUs.adoc b/docs/AboutUs.adoc index e647ed1e715a..0e849f2d6215 100644 --- a/docs/AboutUs.adoc +++ b/docs/AboutUs.adoc @@ -4,53 +4,57 @@ :imagesDir: images :stylesDir: stylesheets -AddressBook - Level 4 was developed by the https://se-edu.github.io/docs/Team.html[se-edu] team. + -_{The dummy content given below serves as a placeholder to be used by future forks of the project.}_ + -{empty} + +TutorPal was developed by the CS2103-AY1819S1-T13-1 team. + We are a team based in the http://www.comp.nus.edu.sg[School of Computing, National University of Singapore]. == Project Team -=== John Doe -image::damithc.jpg[width="150", align="left"] -{empty}[http://www.comp.nus.edu.sg/~damithch[homepage]] [https://github.com/damithc[github]] [<>] +=== Chua Chenlu +image::chenlu-chua.png[width="150", align="left"] +{empty}[https://github.com/chenlu-chua[github]] [<>] -Role: Project Advisor +Role: Team lead + Testing + +Responsibilities: UI ''' -=== John Roe -image::lejolly.jpg[width="150", align="left"] -{empty}[http://github.com/lejolly[github]] [<>] +=== Chen Juan +image::cjuanvip.png[width="150", align="left"] +{empty}[http://github.com/CJuanvip[github]] [<>] -Role: Team Lead + -Responsibilities: UI +Role: Deliverables and deadline + Scheduling and tracking + +Responsibilities: Logic ''' -=== Johnny Doe -image::yijinl.jpg[width="150", align="left"] -{empty}[http://github.com/yijinl[github]] [<>] +=== Liu Zhaoyu +image::lzyandy.png[width="150", align="left"] +{empty}[http://github.com/LZYAndy[github]] [<>] -Role: Developer + -Responsibilities: Data +Role: Documentation + Code quality + +Responsibilities: Model ''' -=== Johnny Roe -image::m133225.jpg[width="150", align="left"] -{empty}[http://github.com/m133225[github]] [<>] +=== Ong Junjie +image::junjiee.png[width="150", align="left"] +{empty}[http://github.com/junjiee[github]] [<>] + +Role: Code quality -Role: Developer + -Responsibilities: Dev Ops + Threading +Responsibilities: Storage ''' -=== Benson Meier -image::yl_coder.jpg[width="150", align="left"] -{empty}[http://github.com/yl-coder[github]] [<>] +=== Xiong Haoran +image::hrxiong.png[width="150", align="left"] +{empty}[http://github.com/hrxiong[github]] [<>] + +Role: Testing + Integration -Role: Developer + Responsibilities: UI ''' diff --git a/docs/ContactUs.adoc b/docs/ContactUs.adoc index 5de5363abffd..d0b7dc3134dc 100644 --- a/docs/ContactUs.adoc +++ b/docs/ContactUs.adoc @@ -2,6 +2,4 @@ :site-section: ContactUs :stylesDir: stylesheets -* *Bug reports, Suggestions* : Post in our https://github.com/se-edu/addressbook-level4/issues[issue tracker] if you noticed bugs or have suggestions on how to improve. -* *Contributing* : We welcome pull requests. Follow the process described https://github.com/oss-generic/process[here] -* *Email us* : You can also reach us at `damith [at] comp.nus.edu.sg` +* *Bug reports, Suggestions* : Post in our https://github.com/CS2103-AY1819S1-T13-1/main/issues[issue tracker] if you noticed bugs or have suggestions on how to improve. diff --git a/docs/DeveloperGuide.adoc b/docs/DeveloperGuide.adoc index 817ec81d7832..614e0ed13fab 100644 --- a/docs/DeveloperGuide.adoc +++ b/docs/DeveloperGuide.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 4 - Developer Guide += Tutor Pal - Developer Guide :site-section: DeveloperGuide :toc: :toc-title: @@ -13,9 +13,9 @@ ifdef::env-github[] :warning-caption: :warning: :experimental: endif::[] -:repoURL: https://github.com/se-edu/addressbook-level4/tree/master +:repoURL: https://github.com/CS2103-AY1819S1-T13-1/main -By: `Team SE-EDU`      Since: `Jun 2016`      Licence: `MIT` +By: `CS2103-T13-1`      Since: `Aug 2018`      Licence: `MIT` == Setting up @@ -164,6 +164,7 @@ Note how the event is propagated through the `EventsCenter` to the `Storage` and The sections below give more details of each component. +// tag::ui[] [[Design-Ui]] === UI component @@ -172,7 +173,7 @@ image::UiClassDiagram.png[width="800"] *API* : link:{repoURL}/src/main/java/seedu/address/ui/Ui.java[`Ui.java`] -The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `PersonListPanel`, `StatusBarFooter`, `BrowserPanel` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class. +The UI consists of a `MainWindow` that is made up of parts e.g.`CommandBox`, `ResultDisplay`, `PersonListPanel`, `StatusBarFooter`, `StudentPanel` etc. All these, including the `MainWindow`, inherit from the abstract `UiPart` class. The `UI` component uses JavaFx UI framework. The layout of these UI parts are defined in matching `.fxml` files that are in the `src/main/resources/view` folder. For example, the layout of the link:{repoURL}/src/main/java/seedu/address/ui/MainWindow.java[`MainWindow`] is specified in link:{repoURL}/src/main/resources/view/MainWindow.fxml[`MainWindow.fxml`] @@ -183,6 +184,8 @@ The `UI` component, * Responds to events raised from various parts of the App and updates the UI accordingly. [[Design-Logic]] +// end::ui[] + === Logic component [[fig-LogicClassDiagram]] @@ -324,6 +327,411 @@ image::UndoRedoActivityDiagram.png[width="650"] ** Cons: Requires dealing with commands that have already been undone: We must remember to skip these commands. Violates Single Responsibility Principle and Separation of Concerns as `HistoryManager` now needs to do two different things. // end::undoredo[] +// tag::findfeature[] +=== Find Related Feature + +The find related features include four commands, which are `FindCommand`, `FindAddressCommand`, `FindEmailCommand`, and `FindPhoneCommand`. They support finding by name, address, email, and phone numbers. + +==== Current Implementation + +===== Find command (`find KEYWORD [MORE_KEYWORDS]...`) + +The `find` command has been implemented to find students by their names. + +* The `find` command accepts one or more arguments, each argument represent a keyword. + +* The `find` command finds persons whose names contain any of the given keywords. + +* The number of students found will be displayed on the PersonCard GUI. + +* All the keywords are put into a List and converted to a stream. Perform .anyMatch(...) on the keywords stream to find all the students whose names match any of the keywords. + +* The matching process is case insensitive and support fuzzy matching. Fuzzy matching is achieved by applying Levenshtein Distance method. The condition for using fuzzy matching in this command is the length of the keyword is greater than 3 and if the condition is satisfied, we set the Levenshtein Distance to be less than 3, which means at most two differences. + +image::FindCommandLogicDiagram.png[width="800"] + +===== Find by address command (`find/a KEYWORD [MORE_KEYWORDS]...`) + +The `find/a` command has been implemented to find students by their address. + +* The `find/a` command accepts one or more arguments, each argument represent a keyword. + +* The `find/a` command finds persons whose addresses contain all the given keywords. + +* The number of students found will be displayed on the PersonCard GUI. + +* All the keywords are put into a List and converted to a stream. Perform .allMatch(...) on the keywords stream to find all the students whose addresses match all the keywords. + +* The matching process is case insensitive and support fuzzy matching. Fuzzy matching is achieved by applying Levenshtein Distance method. The condition for using fuzzy matching in this command is the length of the keyword is greater than 3 and if the condition is satisfied and the length of keyword is 4 to 7, we set the Levenshtein Distance to be less than 3; if the length of keyword is more than 8, we set the Levenshtein Distance to be less than 4. + +image::FindAddressCommandLogicDiagram.png[width="800"] + +===== Find by email command (`find/e EMAIL [MORE_EMAILS]...`) + +The `find/e` command has been implemented to find students by their email. + +* The `find/e` command accepts one or more arguments, each argument represent an email address keyword. + +* The `find/e` command finds persons whose emails are the same as any of the keywords. + +* The number of students found will be displayed on the PersonCard GUI. + +* All the keywords are put into a List and converted to a stream. Perform .anyMatch(...) on the keywords stream to find all the students whose emails match any of the keywords. + +* The matching process is case insensitive and support fuzzy matching. Fuzzy matching is achieved by applying Levenshtein Distance method. We set the Levenshtein Distance to be less than 4, which means at most three differences. + +image::FindEmailCommandLogicDiagram.png[width="800"] + +===== Find by phone number command (`find/p PHONE_NUMBER [MORE_PHONE_NUMBERS]...`) + +The `find/p` command has been implemented to find students by their phone number. + +* The `find/p` command accepts one or more arguments, each argument represent a phone number keyword. + +* The `find/p` command finds persons whose phone numbers are the same as any of the keywords. + +* The number of students found will be displayed on the PersonCard GUI. + +* All the keywords are put into a List and converted to a stream. Perform .anyMatch(...) on the keywords stream to find all the students whose phone numbers match any of the keywords. + +* The matching process is case insensitive and support fuzzy matching. Fuzzy matching is achieved by applying Levenshtein Distance method. We set the Levenshtein Distance to be less than 3, which means at most two differences. + +image::FindPhoneCommandLogicDiagram-1.png[width="800"] + +==== Design considerations + +===== Aspect: Fuzzy matching + +* **Alternative 1 (current choice):** Allow fuzzy matching in searching. +** Pros: +. Small typos will not affect the searching output. +. Make the application much more practical and easier to use. +** Cons: +. Some minor mistakes in spelling might lead to totally different meanings. We have tried to prevent this from happening by limiting the minimum length of keywords for fuzzy matching, however, there might still be a few cases that exist problems. +// end::findfeature[] + +// tag::gradesfeature[] + +=== Grades Feature + +==== Current Implementation + +The grades feature has been implemented to store the grade records of the student. A `Grades` class has been created to record a score of a student. +A HashMap has been added to the list of attributes of Person class. + +Each student's grade records are also displayed on the PersonCard GUI. + +Add a new attribute into the person class, we have to change the structure of the model part as follow: + +image::ModelForGrade.png[width="800"] + +Because the adding of the grades attribute, the storage part have to add XmlAdaptedGrade to adapt grade attribute during the interaction with the storage. + +The following UML diagram shows the new structure of the storage: + +image::StorageForGrade.png[width="800"] + +===== Add Grade Using Add Command +* The add command now can add grade records, Using the format of "g/examName examScore". +The exam name can be any string without space, and the exam score can be integer between 0 to 100 including 0 and 100. + +The graph to illustrate the behavior of add grade attribute is quite similar to the edit attribute. So we do not overtalk about it here. + +===== Add or Edit Grade Using Edit Command +* The edit command now can edit or add grade records, Using the format of "g/examName examScore". +The exam name can be any string without space, and the exam score can be integer between 0 to 100 including 0 and 100. + +* The grade attribute has a different behavior from tag attribute. + +When editing a tag, the previous tags will be discarded by the APP. But grades attribute is more like a recording function. +So the previous grade records will not be deleted. +If user edit a non-existing exam, the app will create a new record. +If user edit a existing exam, the app will update the score of the grade record. + +To Keep the undo and redo feature, edit will create a new person(not the copy of the reference) and then edit it. + +The following sequence diagram shows how the edit function works with the grades attribute: + +image::EditDiagram.png[width="800"] + +===== Delete Grade Using `deleteGrade` Command +* The deleteGrade command accepts an INDEX of the student and one exam name to delete. + +To Keep the undo and redo feature, deleteGrade will create a new person(not the copy of the reference) as well and then edit it. + +The following sequence diagram shows how the deleteGrade function works: + +image::DeleteGradeDiagram.png[width="800"] + +==== Future Implementation + +* Add more action for grade record such as sorting students by grades, analysing the grades fluctuation of a students. + +* Use Gui feature to layout the grades, so that the analysing the grades of a student will be more straightforward and easier. + +* Add more Convenient way to add grades, such as add grades for a exam to every student at once and so on. + +==== Design considerations + +===== Aspect: Command for adding and editing grades attribute + +* **Alternative 1 (current choice):** enhance the add Command and edit Command. +** Pros: +. Follow the tradition of the command. +. Use the origin code fully. +** Cons: +. Break the test existing a lot. +* **Alternative 2:** add now command for adding and editing grade. +** Pros: +. Easier to implement. +. Will not change or break the previous code structure. +** Cons: +. Too many commands for user to remember. + +===== Aspect: Delete of a grade record + +* **Alternative 1 (current choice):** Add a new command to delete the grade command. +** Pros: +. Easy to understand and use the function. +** Cons: +. Too many commands for user to remember. +* **Alternative 2:** Use the undo feature to delete. +** Pros: +. Existing feature already. +** Cons: +. To complicated for user to use this feature. + +// end::gradesfeature[] + +// tag::earningfeature[] +=== Earnings Feature + +==== Current Implementation + +The earnings feature has been implemented to retrieve the sum of tuition fees earned from all students +between a period of time. A `Fee` class has been added to the list of attributes of Person class. + +* The earnings command accepts two arguments, the first being the beginning date followed by + the ending date. The total tuition fees earned between the range of dates will be displayed. + +* Each student's educational level and tuition fee per hour are also displayed on the PersonCard GUI. The tuition +fee of an individual student is determined by his or her educational level and grade. ++ +image::PersonCardExample.png[width="170"] + +* The earnings command word and two arguments which contains a start and end date are taken as an +input into the `AddressBookParser` class. An `EarningsCommand` object is returned, +which executes and displays the calculated sum of tuition fees earned between a range of dates. + +The earnings command uses the information in UniquePersonList from `VersionedAddressBook` to obtain the fees information +of every student contained in the AddressBook. Using the list of students, `EarningsCommand` then uses the +Java 8 Stream API to calculate and return the total amount of tuition fees earned within the period provided by +the user. + +The following sequence diagram shows how the earnings function works: + +image::EarningsCommandSequenceDiagram.png[width="800"] + +==== Future Implementation + +* Implement an option to allow tutors to assign tuition fees to students rather than fixing it based on the +market rate of student's educational level and grade. +* To be able to calculate past earnings, taking into account that certain students may have +changed their tuition time slots. +* Calculate tuition earnings based on attendance, including extra lessons. + +==== Design considerations + +===== Aspect: The type of arguments acceptable + +* **Alternative 1 (current choice):** Accepts a range of date in ddmm format. +** Pros: +. Gives users a less restrictive option to calculate tuition fees earned. +** Cons: +. Harder to implement. +* **Alternative 2:** Accept a single argument of any month. +** Pros: +. Easier to implement. +. Allow accurate retrieval of past earnings in the event that a student's time slot changed as monthly earnings can be calculated +and stored. +** Cons: +. Users are restricted to obtaining fees earned only in period of months. +// end::earningfeature[] + +// tag::promotefeature[] +=== Promote Feature + +==== Current Implementation + +The promote feature has been implemented to allow users to manually promote his/her students to the next +educational grade. The promote command can either promote all students stored in TutorPal, or selectively through the index of students. + +* `PromoteCommandParser` parses the arguments to determine which command to be returned. + +* The former is facilitated by the `PromoteAllCommand`. + +* The latter is facilitated by the `PromoteIndividualCommand` + +* Both command classes are subclasses of `PromoteCommand`. + +* Both subclasses inherit the `PromoteCommand#createPromotedPerson()` and `PromoteCommand#getNumberOfGraduatedStudents()` +methods and implements their own overridden `execute()` function. + +* As the promote feature do not promote students across educational levels (e.g. Primary to Secondary), a "Graduated" tag +is assigned to a student if the promote function is called on a student who is in his/her final year. ++ +image::GraduateExample.png[width="170"] + +==== Future Implementation + +Implement a function to allow automated promotion of all students in TutorPal at the beginning of the year and +allow users to configure TutorPal the promote feature to be automatic or manual. + +==== Design considerations + +===== Aspect: Promote feature to be automated by time or by manual user input + +* **Alternative 1 (current choice):** Manual user input +** Pros: +. Easier to implement. +. Prevent undesired situations like promoting all students if system time is set to a new year unintentionally. +. Provides tutors with higher autonomy in editing student information (e.g. if students retain). +** Cons: +. Some users may prefer automatic promotion. +* **Alternative 2:** Automatic promotion +** Pros: +. Convenient for users (subjective). +** Cons: +. Undesirable side effects like unintended promotion of student if system time is changed. +// end::promotefeature[] + +// tag::timefeature[] +=== Time Feature + +==== Current Implementation + +A `Time` class has been created. It represents the tuition time of the student, consisting of the day, start and end time of the tuition. + +* When creating a new `Time`, input for day should only include the first 3 letters of the day, and it must be in small letters. + +** For example: mon, tue, wed, thu, fri, sat, sun. + +* The input for start and end time should be in 24hour format. + +A `timings` attribute has been added into the list of attributes of Person class. + +* It is an array list of `Time` class, hence this allows user to add multiple tuition timings for a student. + +* Every time a new student is added into Tutor Pal, an empty `Time` array list will be created for the student. + +==== Design Considerations + +===== Aspect: Input for `Time` class +* **Alternative 1 (current choice):** Standardise the inputs for `Time` class. +** Pros: +. Easier to implement as we only need to account for one particular style of input. +. Furthermore, it also ensures consistency in Tutor Pal, which makes information more readily interpretable. Hence, even though users may not be used to the particular style of input, in the long run, it will be more convenient for users as there will not be any confusion in the information due to different styles of input. +** Cons: +. It may take some time for new users to get used to the style of input. +* **Alternative 2:** Allows other styles of inputs, for example a 12hour clock format instead of a 24hour clock format, for `Time` class. +** Pros: +. Easier for new users to use. +** Cons: +. If user did not fix to one style of inputs, there may be confusion of information due to conflicting input styles. +. Implementation will be much harder as we need to account for countless different situations to try to minimise or totally prevent such confusions. + +===== Aspect: Data structure to support the `timings` attribute +* **Alternative 1 (current choice):** Use an array list to store the tuition timings of a student. +** Pros: +. Easy to implement and the API already have functions we can use to manage the array list. +** Cons: +. The order of `Time` in the array list depends on the order it is added in, not the `Time` itself. However, it is preferable to display `Time` according to the order of the timings for better visual representation. Hence, sorting has to be done first. +* **Alternative 2:** Use a priority queue to store the tuition timings of a student. +** Pros: +. The priority queue API allows us to ensure that the `Time` are in a particular order, either descending or ascending, depending on how we implement it. +** Cons: +. We can only fix it to one particular order. Hence, if we want to display the `Time` in another order, sorting still has to be done. + +// end::timefeature[] + +// tag::addtimecommand[] +=== Addition of Tuition Time feature + +==== Current Implementation + +Since the `timings` attribute of a person is an array list, we created a new command to add `Time` for a student, called `AddTimeCommand`. + +* The add time command takes in 2 parameters, `Index` and the `Time` to be added. + +* `Index` refers to the index number shown in the displayed person list in Tutor Pal, while `Time` represents the tuition timing to be added for the student. + +* The start time of `Time` must be earlier than the end time of the tuition. + +* The `Time` to be added must not clash with any other timings already in Tutor Pal. + +* The added `Time` will be displayed on the PersonCard GUI. + +* After inputing the command, the inputs will be taken into `AddressBookParser` class and an `AddTimeCommand` object will be returned. The command will then be executed and `Time` will be added for the student at `Index`. + +* During the execution of the command, a `Time` object will be created. It will then search through Tutor Pal to see if the `timings` of student at `Index` contains the `Time`. If it does, it will then check if there are any clashes with the timings already in Tutor Pal. If there are no errors, `Time` will be added into his `timings`, otherwise, an error message, depending on the type of error, will be shown. + +The following sequence diagram shows how the `addTime` operation works: + +image::AddTimeSequenceDiagram.png[width="800"] + +==== Future Implementation + +* Currently, if there are clashes in the timings, then `Time` will not be added. User will then have to search through Tutor Pal to check for available timings. + +* In the future, instead of just displaying the error messages, it will also display the available timings for that particular day, or trigger another command to display all the timings available. + +* Furthermore, there may be tutors who are teaching a group of students at once. Hence these students have the same addresses. In such cases, we should allow such students to have same tuition timings since it means both of them will be tutored at the same time. + +==== Design Considerations +===== Aspect: Parameter used to find the student for the addition of `Time`. +* **Alternative 1 (current choice):** Using index. +** Pros: +. Since there may be students with the same name, using index will prevent such confusion and allow the command to function correctly. +** Cons: +. If a user has a lot of students, he may need to search through the long displayed list to find the student's index, causing some inconvenience to the user. + +* **Alternative 2:** Using Name. +** Pros: +. It will be more convenient for user as user do not need to spend time searching for the index of the student. +** Cons: +. If there are students with the same name, there may be situations where `Time` are not added to the correct student. Hence, in order to handle such situations, implementation will be much harder. + +// end::addtimecommand[] + +// tag::deletetimecommand[] +=== Deletion of Tuition Time feature + +==== Current Implementation + +Since `timings` is an array list, we created a new command to delete the `Time` of a student, called `DeleteTimeCommand`. + +* The add time command takes in 2 parameters, `Index` and the `Time` to be added. + +* `Index` refers to the index number shown in the displayed person list in Tutor Pal, while `Time` represents the tuition timing to be added for the student. + +* The deleted `Time` will be removed from the PersonCard GUI. + +* After inputing the command, the inputs will be taken into `AddressBookParser` class and an `DeleteTimeCommand` object will be returned. The command will then be executed and `Time` will be deleted for the student at `Index`. + +* During the execution of the command, a `Time` object will be created. It will then search through Tutor Pal to see if the `timings` of student at `Index` contains the `Time` to be deleted. If it does, `Time` will be deleted from his `timings`, otherwise, an error message, depending on the type of error, will be shown. + +The following sequence diagram shows how the `deleteTime` operation works: + +image::DeleteTimeSequenceDiagram.png[width="800"] + +==== Design Considerations +===== Aspect: Lesser restrictions to the inputs of the command + +* There are lesser exceptions handled in `deleteTime` command compared to `addTime` command. + +** For example, in `addTime` it ensures that the start time of `Time` must be bigger than the end time of `Time`. However, in `deleteTime` it does not. The rationale is that there is no need for it since such timings will never exist in Tutor Pal, hence there will never be a situation where you need to delete it. + +// end::deletetimecommand[] + // tag::dataencryption[] === [Proposed] Data Encryption @@ -820,13 +1228,12 @@ See this https://github.com/se-edu/addressbook-level4/pull/599[PR] for the step- *Target user profile*: -* has a need to manage a significant number of contacts -* prefer desktop apps over other types -* can type fast -* prefers typing over mouse input -* is reasonably comfortable using CLI apps +* Full-time private tutor +* manages a huge number of student contacts +* has to constantly review and update students' academic progress +* comfortable with CLI applications -*Value proposition*: manage contacts faster than a typical mouse/GUI driven app +*Value proposition*: Manage an address book containing list of students faster than a typical mouse driven application [appendix] == User Stories @@ -838,23 +1245,49 @@ Priorities: High (must have) - `* * \*`, Medium (nice to have) - `* \*`, Low (un |Priority |As a ... |I want to ... |So that I can... |`* * *` |new user |see usage instructions |refer to instructions when I forget how to use the App -|`* * *` |user |add a new person | +|`* * *` |tutor |add a new student | -|`* * *` |user |delete a person |remove entries that I no longer need +|`* * *` |tutor |delete a student |remove entries that I no longer need -|`* * *` |user |find a person by name |locate details of persons without having to go through the entire list +|`* * *` |tutor |find a student by name |locate details of students without having to go through the entire list + +|`* * *` |tutor |record the current grades of a student | + +|`* * *` |tutor |sort the students by their grades |track the performance of each student relative to their peers + +|`* * *` |tutor |retrieve the list of grades and the number of students with each grade |identify students who need more help + +|`* * *` |tutor |undo the most recent modification |recover unintentional changes + +|`* * *` |tutor |access and modify the info of students |updates any changes to student information + +|`* * *` |tutor |have fuzzy matching when i do the searching |search for something i can't remember the name clearly + +|`* *` |tutor |plan my tutoring schedules |manage my time more efficiently + +|`* *` |tutor |calculate my total earnings from tuition fees within a certain range of date | + +|`* *` |tutor |record the attendance of a student | + +|`* *` |tutor |create and allocate students into different groups |categorise the students according to their ability to learn + +|`* *` |tutor |write and check teaching log and plan for a student or a group |trace teaching progress for every student or every group and can store the plan for them in the system easily as well + +|`*` |tutor |have a short description of my students' distinct features |it will help me remember their names better + +|`*` |tutor |see the graphical representation of a student’s performance over the year |track the performance of a student + +|`*` |tutor |the system to require username and password to log in and verify the user by requiring password again if user want to change something very important such as deleting a student directly |decide which one can access the system and change the content -|`* *` |user |hide <> by default |minimize chance of someone else seeing them by accident |`*` |user with many persons in the address book |sort persons by name |locate a person easily |======================================================================= -_{More to be added}_ [appendix] == Use Cases -(For all use cases below, the *System* is the `AddressBook` and the *Actor* is the `user`, unless specified otherwise) +(For all use cases below, the *System* is the `Tutor Pal` and the *Actor* is the `user`, unless specified otherwise) [discrete] === Use case: Delete person @@ -882,16 +1315,384 @@ Use case ends. + Use case resumes at step 2. -_{More to be added}_ +=== Use case: Adding the tuition time of a student + +*MSS* + +1. User enters index and the tuition time to be added +2. System displays successful message ++ +Use case ends + +*Extensions* + +[none] +* 1a. An invalid tuition time is entered ++ +[none] +** 1a1. System displays invalid tuition time message. + +* 1a*. There is a clash in the tuition time to be added with the ones already in the address book. ++ +[none] +** 1a*1. System displays tuition timing clash message. + + +=== Use case: Deleting the tuition time of a student + +*MSS* + +1. User enters index and the tuition time to be deleted +2. System displays successful message ++ +Use case ends + +*Extensions* + +[none] +* 1a. The student does not have the tuition time allocated to him. ++ +[none] +** 1a1. System displays tuition time not found message. + +=== Use case: Editing a student + +*MSS* + +1. User enters the name of student and the details to be edited +2. System displays the new details of the students for confirmation +3. System displays successful message ++ +Use case ends + +*Extensions* + +[none] +* 1a. Multiple students with the same name are shown. ++ +[none] +** 1a1. System displays a list of students with the same name. ++ +** 1a2. System request for the index of the student to be edited. + +* 1a*. No student with such name is found. ++ +[none] +** 1a*1. System displays no such student found message. + +* 2a. User chooses to cancel the modification. ++ +[none] +** 2a1. System displays command cancelled message. + + + + + +// tag::filter1[] +=== Use case: Filter by grade + +*MSS* + +1. User requests to get the list of students whose grade in certain given range +2. System filter the personList and displays the qualified list ++ +Use case ends + +*Extensions* + +[none] +* 1a. User inputs an invalid range of grade. ++ +[none] +** 1a1. System displays an error message. ++ +** 1a2. System prompts user for a corrected input. ++ +Use case resumes from step 2. +// end::filter1[] + +// tag::filter2[] +=== Use case: Filter by fee + +*MSS* + +1. User requests to get the list of students whose fee is over the given number. +2. System filter the personList and displays the qualified list ++ +Use case ends + +*Extensions* + +[none] +* 1a. User inputs an invalid double. ++ +[none] +** 1a1. System displays an error message. ++ +** 1a2. System prompts user for a corrected input. ++ +Use case resumes from step 2. +// end::filter2[] + +// tag::exchange[] +=== Use case: Exchange time slot between students + +*MSS* + +1. User requests to exchange time slot between students whose Education is the same. +2. System filter the personList and displays the qualified list ++ +Use case ends + +*Extensions* + +[none] +* 1a. User inputs an invalid double. ++ +[none] +** 1a1. System displays an error message. ++ +** 1a2. System prompts user for a corrected input. ++ +Use case resumes from step 2. +// end::exchange[] + +// tag::suggest1[] +=== Use case: Provide suggestions to certain student + +*MSS* + +1. User requests to get the suggestion for certain student by his or her name. +2. System filter the personList and displays the qualified list ++ +Use case ends + +*Extensions* + +[none] +* 1a. User inputs an invalid double. ++ +[none] +** 1a1. System displays an error message. ++ +** 1a2. System prompts user for a corrected input. ++ +Use case resumes from step 2. +// end::suggest1[] + +// tag::suggest2[] +=== Use case: Provide suggestions to certain student with index + +*MSS* + +1. User requests to get the suggestion for certain student by his or her index number. +2. System filter the personList and displays the qualified list ++ +Use case ends + +*Extensions* + +[none] +* 1a. User inputs an invalid double. ++ +[none] +** 1a1. System displays an error message. ++ +** 1a2. System prompts user for a corrected input. ++ +Use case resumes from step 2. +// end::suggest2[] + +// tag::filter3[] +=== Use case: Find students list of the given Education + +*MSS* + +1. User requests to get the list of students whose is in the given education level +2. System filter the personList and displays the qualified list ++ +Use case ends + +*Extensions* + +[none] +* 1a. User inputs an invalid education level. ++ +[none] +** 1a1. System displays an error message. ++ +** 1a2. System prompts user for a corrected input. ++ +Use case resumes from step 2. +// end::filter3[] + +// tag::filter4[] +=== Use case: Filter by Timeslot + +*MSS* + +1. User requests to get the name of the student who takes class at given timeslot +2. System find out the student and show his or her name ++ +Use case ends + +*Extensions* + +[none] +* 1a. User inputs an invalid time slot. ++ +[none] +** 1a1. System displays an error message. ++ +** 1a2. System prompts user for a corrected input. ++ +Use case resumes from step 2. +// end::filter4[] + + +=== Use case: Calculate total earnings + +*MSS* + +1. User requests to calculate and display earning in a certain month +2. System calculates and displays total earnings in that month ++ +Use case ends + +*Extensions* + +[none] +* 1a. User inputs an invalid date. ++ +[none] +** 1a1. System displays an error message. ++ +** 1a2. System prompts user for a corrected input. ++ +Use case resumes from step 2. + +=== Use case: Find information of students + +*MSS* + +1. User requests to find and indicates the retrieve information, method & required information +2. System retrieve information and display them ++ +Use case ends + +*Extensions* + +[none] +* 1a. User inputs invalid commands ++ +[none] +** 1a1. System displays error messages. ++ +** 1a2. System displays the correct format of find command. ++ +Use case ends. + +* 1b. System is unable to find the record satisfying the requirement ++ +[none] +** 1b1. System print a “unable to find” warning ++ +Use case ends. + + +// tag::grades1[] +=== Use case: add grade records for the student when creating a new student + +*MSS* + +1. User indicate the names of the exams and the scores when adding a student. +2. System add the student with some grade records. +Use case ends + +*Extensions* + +[none] +* 1a. User inputs an invalid score. ++ +[none] +** 1a1. System displays an error message. ++ +** 1a2. System prompts user for a corrected input. ++ +Use case resumes from step 2. +// end::grades1[] + +// tag::grades2[] +=== Use case: add or edit grade record for a student using edit + +*MSS* + +1. User indicate the index of the student and the grade record when editing a student. +2. System edit the student with some grade records. +Use case ends + +*Extensions* + +[none] +* 1a. User inputs an invalid score. ++ +[none] +** 1a1. System displays an error message. ++ +** 1a2. System prompts user for a corrected input. ++ +Use case resumes from step 2. + +[none] +* 1b. User input a non-existing exam name. ++ +[none] +** 1b1. System add a new grade record for the student. ++ +Use case ends +// end::grades2[] + +// tag::grades3[] +=== Use case: delete a grade record + +*MSS* + +1. User indicate the index of the student and the exam name. +2. System delete the grade record from the student. +Use case ends + +*Extensions* + +[none] +* 1a. User inputs a non-existing exam name. ++ +[none] +** 1a1. System displays an error message. ++ +** 1a2. System prompts user for a corrected input. ++ +Use case resumes from step 2. + +[none] +* 1b. User input command in error format. ++ +[none] +** 1b1. System displays an error message. ++ +** 1b2. System prompts user for a corrected input. ++ +Use case resumes from step 2. +// end::grades3[] + [appendix] == Non Functional Requirements . Should work on any <> as long as it has Java `9` or higher installed. -. Should be able to hold up to 1000 persons without a noticeable sluggishness in performance for typical usage. +. Should be able to hold up to 10000 students without a noticeable sluggishness in performance for typical usage. . A user with above average typing speed for regular English text (i.e. not code, not system admin commands) should be able to accomplish most of the tasks faster using commands than using the mouse. - -_{More to be added}_ +. Does not require an Internet connection [appendix] == Glossary @@ -902,22 +1703,8 @@ Windows, Linux, Unix, OS-X [[private-contact-detail]] Private contact detail:: A contact detail that is not meant to be shared with others -[appendix] -== Product Survey - -*Product Name* - -Author: ... - -Pros: - -* ... -* ... - -Cons: - -* ... -* ... +[[fuzzyFind]] fuzzyFind:: +Find something whose edit distance with keyword is less than or equal to 2. [appendix] == Instructions for Manual Testing @@ -941,26 +1728,82 @@ These instructions only provide a starting point for testers to work on; testers .. Re-launch the app by double-clicking the jar file. + Expected: The most recent window size and location is retained. -_{ more test cases ... }_ +=== Adding a new student + +. Adding a student to TutorPal + +.. Test case: `add n/John Doe p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 el/Primary 4 g/Y1819S1_Final 100 g/Y1819S1_Mid 89 t/friends t/owesMoney` + + Expected: A new student with the above details is added to TutorPal. + + Details of the new student will be shown in the status message. +.. Test case: `add n/Desmond Hume p/91234567 e/Hume.D@example.com` + + Expected: No student is added. Error details shown in the status message. Status bar remains the same. -=== Deleting a person +=== Deleting a student -. Deleting a person while all persons are listed +. Deleting a student while all students are listed -.. Prerequisites: List all persons using the `list` command. Multiple persons in the list. +.. Prerequisites: List all students using the `list` command. Multiple students in the list. .. Test case: `delete 1` + Expected: First contact is deleted from the list. Details of the deleted contact shown in the status message. Timestamp in the status bar is updated. .. Test case: `delete 0` + - Expected: No person is deleted. Error details shown in the status message. Status bar remains the same. + Expected: No student is deleted. Error details shown in the status message. Status bar remains the same. .. Other incorrect delete commands to try: `delete`, `delete x` (where x is larger than the list size) _{give more}_ + Expected: Similar to previous. -_{ more test cases ... }_ +=== Promoting student(s) + +. Promote all students in TutorPal + +.. Test case: `promote all` + + Expected: Promotes all student in TutorPal to the next educational grade. + The number of students promoted and new graduates are shown in the status message. + A red colour "Graduated" tag is assigned to newly graduated students who were in their final year + + before the execution this command. + +. Promote a certain number of students in TutorPal + +.. Prerequisites: The use of `List` command in conjunction with the following test case is *optional*. +.. Test case: `promote 1 2 5` + + Expected: Promotes the first, second and fifth student in the displayed list to the next educational grade. + The number of students promoted and new graduates are shown in the status message. + A red colour "Graduated" tag is assigned to newly graduated students who were in their final year + + before the execution this command. + +=== Adding a tuition time of a student + +. Adding a tuition time for a student while all persons are listed + +.. Prerequisites: List all persons using the list command. Multiple persons in the list. +.. Test case: `addTime 1 ts/mon 1800 2000` + + Expected: Student at index 1 has a tuition time "Monday 1800 2000" added. Status message display command success message and timestamp in the status bar is updated. +.. Test case: `addTime 2 ts/mon 1800 2000` + + Expected: Nothing happened. Error details shown in the status message. Status bar remains the same. +.. Test case: `addTime 1 ts/mon 1700 2100` + + Expected: Nothing happened. Error details shown in the status message. Status bar remains the same. +.. Test case: `addTime 1 ts/tues 1800 2000` + + Expected: Nothing happened. Error details shown in the status message. Status bar remains the same. +.. Test case: `addTime 1 ts/tue 6 8` + + Expected: Nothing happened. Error details shown in the status message. Status bar remains the same. +.. Test case: `addTime 1 ts/tue 1800 2000` + + Expected: Student at index 1 has a tuition time "Tuesday 1800 2000" added. Status message display command success message and timestamp in the status bar is updated. + +=== Deleting a tuition time of a student + +. Deleting a tuition time for a student while all persons listed -=== Saving data +.. Prerequisites: List all persons using the list command. Multiple persons in the list. Performed `addTime 1 ts/mon 1800 2000`. +.. Test case: `deleteTime 2 ts/mon 1800 2000` + + Expected: Nothing happened. Error details shown in the status message. Status bar remains the same. +.. Test case: `deleteTime 1 ts/mon 1700 2000` + + Expected: Nothing happened. Error details shown in the status message. Status bar remains the same. +.. Test case: `deleteTime 1 ts/mon 1800 2000` + + Expected: Student at index 1 has a tuition time "Monday 1800 2000" removed. Status message display command success message and timestamp in the status bar is updated. -. Dealing with missing/corrupted data files +=== Retrieving earnings -.. _{explain how to simulate a missing/corrupted file and the expected behavior}_ +. Retrieve earnings between two dates. -_{ more test cases ... }_ +.. Test case: `earnings 0712 2412` + + Expected: The amount in dollar of tuition fees earned between the two dates (current year) are shown in the status message. +.. Test case: `earnings 0912 0912` + + Expected: The amount in dollar of tuition fees earned on 9 December 2018. diff --git a/docs/UserGuide.adoc b/docs/UserGuide.adoc index 7e0070e12f49..1e779d70d261 100644 --- a/docs/UserGuide.adoc +++ b/docs/UserGuide.adoc @@ -1,4 +1,4 @@ -= AddressBook Level 4 - User Guide += Tutor Pal - User Guide :site-section: UserGuide :toc: :toc-title: @@ -12,19 +12,19 @@ ifdef::env-github[] :tip-caption: :bulb: :note-caption: :information_source: endif::[] -:repoURL: https://github.com/se-edu/addressbook-level4 +:repoURL: https://github.com/CS2103-AY1819S1-T13-1/main -By: `Team SE-EDU` Since: `Jun 2016` Licence: `MIT` +By: `CS2103-AY1819S1-T13-1` Since: `Aug 2018` Licence: `MIT` == Introduction -AddressBook Level 4 (AB4) is for those who *prefer to use a desktop app for managing contacts*. More importantly, AB4 is *optimized for those who prefer to work with a Command Line Interface* (CLI) while still having the benefits of a Graphical User Interface (GUI). If you can type fast, AB4 can get your contact management tasks done faster than traditional GUI apps. Interested? Jump to the <> to get started. Enjoy! +TutorPal is for private tutors who *prefer to use a desktop app for managing students information*. More importantly, TutorPal is *optimized for those who prefer to work with a Command Line Interface* (CLI) while still having the benefits of a Graphical User Interface (GUI). TutorPal is a great tool to track students' academic performance and schedule. Jump to the <> to get started. Enjoy! == Quick Start . Ensure you have Java version `9` or later installed in your Computer. -. Download the latest `addressbook.jar` link:{repoURL}/releases[here]. -. Copy the file to the folder you want to use as the home folder for your Address Book. +. Download the latest `Tutor Pal.jar` link:{repoURL}/releases[here]. +. Copy the file to the folder you want to use as the home folder for your Tutor Pal. . Double-click the file to start the app. The GUI should appear in a few seconds. + image::Ui.png[width="790"] @@ -34,7 +34,7 @@ e.g. typing *`help`* and pressing kbd:[Enter] will open the help window. . Some example commands you can try: * *`list`* : lists all contacts -* **`add`**`n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` : adds a contact named `John Doe` to the Address Book. +* **`add`**`add n/John Doe p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 el/Primary 4 g/Y1819S1_Mid 89 t/friends t/owesMoney` : adds a contact named `John Doe` to the Address Book. * **`delete`**`3` : deletes the 3rd contact shown in the current list * *`exit`* : exits the app @@ -46,77 +46,300 @@ e.g. typing *`help`* and pressing kbd:[Enter] will open the help window. ==== *Command Format* -* Words in `UPPER_CASE` are the parameters to be supplied by the user e.g. in `add n/NAME`, `NAME` is a parameter which can be used as `add n/John Doe`. -* Items in square brackets are optional e.g `n/NAME [t/TAG]` can be used as `n/John Doe t/friend` or as `n/John Doe`. -* Items with `…`​ after them can be used multiple times including zero times e.g. `[t/TAG]...` can be used as `{nbsp}` (i.e. 0 times), `t/friend`, `t/friend t/family` etc. -* Parameters can be in any order e.g. if the command specifies `n/NAME p/PHONE_NUMBER`, `p/PHONE_NUMBER n/NAME` is also acceptable. + +* Words in `UPPER_CASE` are the parameters to be supplied by the user. + +e.g. in `add n/NAME`, `NAME` is a parameter which can be used as `add n/John Doe`. +* Items,Grades in square brackets are optional. + +e.g `n/NAME [t/TAG]` can be used as `n/John Doe t/friend` or as `n/John Doe`. +* Items,Grades with `…`​ after them can be used multiple times including zero times. + +e.g. `[t/TAG]...` can be used as `{nbsp}` (i.e. 0 times or grades), `t/friend`, `g/midterm 100`, `t/friend t/family`, `g/test1 100 g/test2 99` etc. +* Grade consists of two parts, exam name and exam score. +** The name and score should be separated by space. +** Score should be between 0 and 100. +** Considering the grades are just some records, the APP didn't implement the delete function temporarily. If you input a wrong exam name, use undo to fix it. +* Parameters can be in any order. + +e.g. if the command specifies `n/NAME p/PHONE_NUMBER`, `p/PHONE_NUMBER n/NAME` is also acceptable. ==== + + === Viewing help : `help` Format: `help` +// tag::add[] === Adding a person: `add` -Adds a person to the address book + -Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]...` + +Adds a person to the student list + +Format: `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS el/EDUCATIONAL_LEVEL [g/GRADE]... [t/TAG]...` + +**** +* If the student added has exactly the same name as an existing student in the student list, new student cannot be added. +* `EDUCATIONAL_LEVEL` must be `Primary`, `Secondary` or `JC`. + +e.g. `... el/Primary ...` is valid; however, `... el/primary ...`, `... el/University ...` or other inputs like these are invalid +* The format of `GRADE` is `exam name` + `exam score`. + +e.g. `... g/mid-test 100 ...` +**** + [TIP] -A person can have any number of tags (including 0) +==== +* A person can have any number of tags and grades (including 0). +* Name of the exam should be different. Otherwise, they will be considered as the same one and the APP will store the score of the last one. +==== Examples: -* `add n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01` -* `add n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/criminal` +* `add n/John Doe p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 el/Primary 4` + +Add a person without grade and tag. +* `add n/John Doe p/98765432 e/johnd@example.com a/311, Clementi Ave 2, #02-25 el/Primary 4 g/Y1819S1_Final 100 g/Y1819S1_Mid 89 t/friends t/owesMoney` + +Add a person with one or more than one grades and tags. + +// end::add[] -=== Listing all persons : `list` -Shows a list of all persons in the address book. + -Format: `list` +// tag::edit[] +[[edit]] === Editing a person : `edit` -Edits an existing person in the address book. + -Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]...` +Edits an existing person in the student list. + +Format: `edit INDEX [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [el/EDUCATIONAL_LEVEL] [g/GRADE] [t/TAG]...` + **** * Edits the person at the specified `INDEX`. The index refers to the index number shown in the displayed person list. The index *must be a positive integer* 1, 2, 3, ... * At least one of the optional fields must be provided. * Existing values will be updated to the input values. -* When editing tags, the existing tags of the person will be removed i.e adding of tags is not cumulative. +* When editing tags, the existing tags of the person will be removed. + +i.e adding of tags is not cumulative. * You can remove all the person's tags by typing `t/` without specifying any tags after it. +* Edit grade will not delete the previous grades as the tap attribute. If the exam name exists already, it will cover the previous one and edit the score only. **** Examples: -* `edit 1 p/91234567 e/johndoe@example.com` + -Edits the phone number and email address of the 1st person to be `91234567` and `johndoe@example.com` respectively. +* `edit 1 p/91234567 e/alex@example.com` + +Edits the phone number and email address of the 1st person to be `91234567` and `alex@example.com` respectively. * `edit 2 n/Betsy Crower t/` + Edits the name of the 2nd person to be `Betsy Crower` and clears all existing tags. +* `edit 5 el/Secondary 1` + +Edits the educational level of the 5th student to Secondary 1. +* `edit 2 g/Y1819S1_Mid 100 ` + +Change the score of an exam. +* `edit 1 g/test1 100 g/test2 99` + +Add more new grade records for a student. + +[NOTE] +==== +By editing the educational level of any student using this command will remove any "Graduated" + +tag by default. To promote the educational grade of a student, please use the `promote` command. +==== +// end::edit[] + +=== Listing all persons : `list` + +Shows a list of all persons in Tutor Pal. + +Format: `list` + +// tag::addtimecommand[] +=== Adding tuition time of a student : `addTime` + +Adds a tuition timing for a student in Tutor Pal. + +Format: `addTime INDEX ts/TIME` + +**** +* Adds tuition timing `TIME` for a student at the specified INDEX. The index refers to the index number shown in the displayed person list. The index must be a positive integer 1, 2, 3, ... +* `TIME` must not clash with any other tuition timings already in Tutor Pal. +**** + +Example: + +* `addTime 1 ts/mon 1300 1500` + +Adds the tuition timing that is on Monday which starts on 1300hour and ends on 1500hour for the 1st person shown in the displayed person list in Tutor Pal. +// end::addtimecommand[] + +// tag::exchange[] +=== Edit certain class time of certain student: `exchangeTime` + +Exchange class time between two students who are in the same grade of same education level + +Format: `exchangeTime A_TIME_SLOT_ORDINAL_NUMBER B_TIME_SLOT_ORDINAL_NUMBER n/NAME_A n/NAME_B` + +**** +* exchange result: exchanged the time between the given students with given time found by the ordinal number. +**** + +Examples: + +* `exchangeTime 0 0 Alice Bob` +Exchange Alice first time slot and Bob first time slot. + +[NOTE] +==== +The reason this command exists is that when two student want to swap time +it cannot only use edit because the existing time-slot will crush. + +If the two students are not in the same grade of same education level +It will be considered as invalid command. + +The ordinal number of the time is 0 base. +If the the corresponding time-slot doesn't exit based on the ordinal number, then return invalid input. +==== +// end::exchange[] + +// tag::deletetimecommand[] +=== Deleting tuition time of a student : `deleteTime` + +Deletes a tuition timing for a student in Tutor Pal. +Format: `deleteTime INDEX ts/TIME` + +**** +* Deletes tuition timing `TIME` for the student at the specified INDEX. The index refers to the index number shown in the displayed person list. The index must be a positive integer 1, 2, 3, ... +* `TIME` must already exist for the student's tuition timings in Tutor Pal. +**** + +Example: + +* `deleteTime 1 ts/mon 1300 1500` + +Deletes the tuition timing that is on Monday which starts on 1300hour and ends on 1500hour for the 1st person shown in the displayed person list in Tutor Pal. +// end::deletetimecommand[] + +// tag::deleteGrade[] +=== Deleting grade of a student : `deleteGrade` + +Deletes a grade record for a student in the address book. +Format: `deleteGrade INDEX NAME_OF_EXAM` + +* `NAME_OF_EXAM` must already exist in the student's grade records. +* The student with the index `INDEX` will have the grade named `NAME_OF_EXAM` deleted. + +Example: + +* `deleteGrade 1 Y1819S1_Mid` + +Deletes grade record named "Y1819S1_Mid" for the first person in the display panel. + +// end::deleteGrade[] + + +// tag::find[] === Locating persons by name: `find` Finds persons whose names contain any of the given keywords. + -Format: `find KEYWORD [MORE_KEYWORDS]` +Format: `find KEYWORD [MORE_KEYWORDS]...` **** -* The search is case insensitive. e.g `hans` will match `Hans` -* The order of the keywords does not matter. e.g. `Hans Bo` will match `Bo Hans` +* The search is case insensitive. + +e.g. `hans` will match `Hans` +* The search allows fuzzy matching when the length of the keyword is greater than 3 (with Levenshtein Distance < 3). + +e.g. `challotto` will match `Charlotte` +* If the length of the keyword you type in is smaller or equal to 3, the keyword must be exactly the same to expected (but still case insensitive). + +e.g. `Lo` will not match `Li` +* The order of the keywords does not matter. + +e.g. `Hans Bo` will match `Bo Hans` * Only the name is searched. -* Only full words will be matched e.g. `Han` will not match `Hans` -* Persons matching at least one keyword will be returned (i.e. `OR` search). e.g. `Hans Bo` will return `Hans Gruber`, `Bo Yang` +* Persons matching at least one keyword will be returned (i.e. `OR` search). + +e.g. `Hans Bo` will return `Hans Gruber`, `Bo Yang` **** Examples: * `find John` + Returns `john` and `John Doe` -* `find Betsy Tim John` + -Returns any person having names `Betsy`, `Tim`, or `John` +* `find challotto` + +Returns `Charlotte Oliveiro` +* `find David Roy John` + +Returns any person having names `David`, `Roy`, or `John` +// end::find[] + +// tag::find/a[] +=== Locating persons by address: `find/a` + +Finds persons whose addresses contain all the given keywords. + +Format: `find/a KEYWORD [MORE_KEYWORDS]...` + +**** +* The search will search for persons whose addresses contain all the keywords. + +e.g. `Clementi` will find person `John Doe` whose address is `311, Clementi Ave 2, #02-25` +* If the keywords match more than one person, all of these person will be returned. + +e.g. `Serangoon` will return the persons whose addresses contain `Serangoon`, who are `Bernice Yu` and `David Li` +* The search is case insensitive. + +e.g `cLeMenTi` is same as `Clementi`, and `cLeMenTi` can also be used to find person `John Doe` whose address is `311, Clementi Ave 2, #02-25` +* The search allows fuzzy matching on long keywords (long keyword means the keyword whose length is greater than 3). + +e.g. `clenti` will be fuzzy matched with `Clementi`, and will find the person `John Doe` whose address is `311, Clementi Ave 2, #02-25` +* The search will not support fuzzy matching when the keywords are too short (≤ 3) or contain numbers. + +e.g. `Clementi Avo` does not match `Clementi Ave` because keyword `Avo` is short and will not be allowed to use fuzzy matching, therefore, no person will be found +* The order of the keywords does not matter. + +e.g. `Ave Clementi 2, 311, #02-25` will match `311, Clementi Ave 2, #02-25`, and will find the person `John Doe` whose address is `311, Clementi Ave 2, #02-25` +* Only the address is searched. +**** + +Examples: + +* `find/a B311, Clementi Ave 2, #02-25` + +Returns `John Doe` +* `find/a B311, CLEMENTI Ave 2, #02-25` + +Returns `John Doe` (case insensitive) +* `find/a #02-25, Ave 2 Clementi, B311` + +Returns `John Doe` (the order of the keywords does not matter) +* `find/a serangoon` + +Returns person whose addresses containing the keyword `Serangoon`, i.e. `Bernice Yu` and `David Li` +* `find/a srangon` + +Returns persons whose addresses containing the keyword `Serangoon`, i.e. `Bernice Yu` and `David Li` (fuzzy matching) +// end::find/a[] + +// tag::find/e[] +=== Locating persons by email address: `find/e` + +Finds a person through his/her email address. + +Format: `find/e EMAIL [MORE_EMAILS]...` + +**** +* The search is case insensitive. + +e.g `LIDaVid@example.com` will match `lidavid@example.com`, and will find person `David Li` whose email is `lidavid@example.com` +* The search allows fuzzy matching (with Levenshtein Distance < 4). + +e.g.`lidavd@exmple.com` will match `lidavid@example.com`, and will find person `David Li` whose email is `lidavid@example.com` +* Only the email is searched. +* Person matching the email will be returned. +**** + +Examples: + +* `find/e John@example.com` + +Returns `John Doe` whose email address is `John@example.com` +* `find/e LIDavd@example.com` + +Returns `David Li` whose email address is `lidavid@example.com` (case insensitive) +* `find/e lidavd@exmple.com` + +Returns `David Li` whose email address is `lidavid@example.com` (fuzzy matching) +// end::find/e[] + +// tag::find/p[] +=== Locating persons by phone number: `find/p` + +Finds a person through his/her phone number. + +Format: `find/p PHONE_NUMBER [MORE_PHONE_NUMBER]...` + +**** +* Only the phone number is searched. +* The search allows fuzzy matching (with Levenshtein Distance < 3). + +e.g. `123456` will match `12345678`, `12435678` will match `12345678` +* Person matching the phone number will be returned. +**** + +Examples: + +* `find/p 98765432` + +Returns `John Doe` whose phone number is `98765432` +* `find/p 9876543` + +Returns `John Doe` whose phone number is `98765432` (fuzzy matching) +* `find/p 98765433` + +Returns `John Doe` whose phone number is `98765432` (fuzzy matching) +// end::find/p[] === Deleting a person : `delete` -Deletes the specified person from the address book. + +Deletes the specified person from the student list. + Format: `delete INDEX` **** @@ -129,7 +352,7 @@ Examples: * `list` + `delete 2` + -Deletes the 2nd person in the address book. +Deletes the 2nd person in the student list. * `find Betsy` + `delete 1` + Deletes the 1st person in the results of the `find` command. @@ -149,11 +372,161 @@ Examples: * `list` + `select 2` + -Selects the 2nd person in the address book. +Selects the 2nd person in the student list. * `find Betsy` + `select 1` + Selects the 1st person in the results of the `find` command. +// tag::filter1[] +=== Filter students by tuition fee: `filterByFee` + +List all the students whose tuition fee is greater or equal to the input fee. + +Format: `filterByFee FEE` + +**** +* filter result: list all the students whose tuition fee is greater or equal to the input fee. +**** + +Examples: + +* `filterByFee 24` +returns a list of students whose tuition fee is greater or equals to $24/hour. + +[NOTE] +==== +If no students qualify the filter criteria, an empty list is returned along with +a system message which says that no such students can be found. +==== + +image::Fee.png[width="790"] + +// end::filter1[] + +// tag::filter2[] +=== Filter students by educational level: `filterByEducation` + +List all the students with given educational level + +Format: `filterByEducation EDUCATIONAL_LEVEL` + +**** +* filter result: list all the students whose education level is the same as input. +**** + +Examples: + +* `filterByEducation Secondary` + +returns a list of students whose Education level is Secondary.(no matter which year he or she is in) + +* `filterByEducation JC` + +returns a list of students whose Education level is JC.(no matter which year he or she is in) + +[NOTE] +==== +If no students qualify the filter criteria, an empty list is returned along with a system message which says that no such students can be found. + +The input of the education level must be "JC" "Secondary" or "Primary". Other input will be considered invalid input. +==== + +image::Education.png[width="790"] + +// end::filter2[] + +// tag::filter3[] +=== Filter students by grade: `filterByGrade` + +List all the students whose grades fall between the minimum and maximum grade(both inclusive). + +Format: `filterByGrade MINIMUM_GRADE MAXIMUM_GRADE` + +**** +* filter result: A list containing students with grades which fall between the minimum and maximum grade. +**** + +Examples: + +* `filterByGrade 50 100` + +returns a list of students whose has grade within 50 and 100 (both 50 and 100 are inclusive). + +[NOTE] +==== +If the input minimal grade is larger than maximal grade, then it will be regarded as the range between maximal and minimal grade. + +If no students qualify the filter criteria, an empty list is returned along with a system message which says that no such students can be found. +==== + +image::Grade.png[width="790"] + +// end::filter3[] + +// tag::filter4[] +=== Filter students by time slot: `filterByTime` + +List the student who has class at the given time. + +Format: `filterByTime ts/TIME_SLOT` + +**** +* filter result: A student who has a lesson at the given time slot. +**** + +Examples: + +* `filterByTime ts/mon 1300 1400` + +returns the student whose has tuition time in monday 1300-1400. + +[NOTE] +==== +The time must be followed as format like "mon 1300 1400" and only "mon" "tue" "wed" "thu" "fri" "sun" "sat" are considered valid date. + +If no students qualify the filter criteria, an empty list is returned along with a system message which says that no such students can be found. +==== + +image::Time.png[width="790"] + +// end::filter4[] + +// tag::suggest1[] +=== Give Suggestions to students: `suggestion` + +Give Suggestions to students + +Format: `suggestion NAME` + +**** +* result: show the suggestions. +**** + +Examples: + +* `suggestion Alice` +Show the suggestion to Alice according to her performance. + +[NOTE] +==== +If the student has not taken any exam before +No suggestion gonna be shown. +==== +// end::suggest1[] + +// tag::suggest2[] +=== Give Suggestions to students: `suggestionByIndex` + +Give Suggestions to students + +Format: `suggestion index (base 1)` + +**** +* result: show the suggestions. +**** + +Examples: + +* `suggestion 1` +Show the suggestion to the first student in the list according to his or her performance. + +[NOTE] +==== +If the student has not taken any exam before +No suggestion gonna be shown. +==== +// end::suggest2[] + === Listing entered commands : `history` Lists all the commands that you have entered in reverse chronological order. + @@ -164,6 +537,129 @@ Format: `history` Pressing the kbd:[↑] and kbd:[↓] arrows will display the previous and next input respectively in the command box. ==== +// tag::grade[] +[[grade]] +=== Grades attribute + +Grade attribute consists of two parts, exam name and exam score. + +[NOTE] +==== +* The name and grade should be separated by space. + +* Score should be between 0 and 100. + +* Considering the grades are just some records, the APP didn't implement the delete function temporarily. If you input a wrong exam name, use undo to fix it. +==== + +Add grade: + +You can add some grades record for a student, both using add command and edit command. + +Example + +`add g/mid-test 100 [other part]` + +`edit 1 g/mid-test 100` + +[NOTE] +==== +Edit grade will not delete the previous grades as tap attribute. +==== + +Change grade: + +if you need to change the score of a exam, you can use edit as well. +// end::grade[] + +// tag::promote[] +=== Promote students stored in TutorPal : `promote` + +Promotes educational grade of the selected student(s) + +Format: `promote [INDEX]...` + +* Promotes the educational grade of the students specified by their index. +* There can be more than one INDEX provided. + +[NOTE] +==== +Multiple indexes should be separated by a space. +==== + +Format: `promote all` + +* Promotes all students stored in TutorPal, including those who are not +displayed on the panel. + +Examples + +* `promote 1 2 4 12` + +Promotes the first, second, fourth and twelfth student. +* `promote all` + +Promotes all students in TutorPal. + + +**** +* The promote function does not promote students across educational levels + +i.e. from Primary to Secondary. For such changes, kindly refer to <>. +* For students advancing to Secondary 5, please also refer to <>. +* For students in their final year (Primary 6, Secondary 4/5, JC 2), + +the promote function automatically adds a tag "Graduated" to indicate that +the student has graduated. +* The "Graduated" tag is automatically removed when command: edit is used to + +edit the student's educational level and/or grade. +* Users can choose to delete graduated students or edit their educational level/grade + +according to their needs. +**** +// end::promote[] + +=== Analyzing grades commands `[coming in v2.0]` + +Analyze the grades of students + +Format: `grades ACTION [parameters]` + +**** +* grades sort: list the details of students sorting by grades. +**** + +[NOTE] +==== +Regard the mark of the student who doesn't have a grade as 0. +==== + +// tag::earnings[] +=== Retrieving earnings + +Retrieve the total earnings from tuition fees from all students between a range of date in the current year. + +Format: `earnings START_DATE END_DATE` + +* `START_DATE` and `END_DATE` should be given in the format of DDMM. +* The beginning and ending dates are included in the calculation of tuition fees. +* The year field is not required as TutorPal assumes current calender year by default. +* To calculate the amount of money earned within a day, input the same `START_DATE` and `END_DATE`. +* Graduated students and students without tuition time slot(s) are ignored by the earnings function. +* Due to the lack of built-in attendance taking capability in TutorPal, the earnings function: + +. Follows a standard one lesson per week schedule and does not account for cancelled or ad-hoc lessons. +. Should only be used to calculate tuition fees that will be earned in the future. +. Does not account for the tuition fees of graduated students. + +[NOTE] +==== +While the use of earnings command for dates before the current date is not prohibited, it is not +encouraged as the values calculated will be inaccurate if tutorPal contains either *graduated students* and/or +*students whom had their time slot(s) changed before*. +==== + +Example: + +* `earnings 0204 2506` + +This command returns the total amount of tuition fees earned between 2 April 2018 to 25 June 2018 inclusive. +A warning message will be displayed to remind the user on the useage of past dates. + +* `earnings 1212 1212` + +This command will return the total amount of tuition fees to be earned on 12 December. +// end::earnings[] + // tag::undoredo[] === Undoing previous command : `undo` @@ -238,23 +734,51 @@ _{explain how the user can enable/disable data encryption}_ == FAQ *Q*: How do I transfer my data to another Computer? + -*A*: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous Address Book folder. +*A*: Install the app in the other computer and overwrite the empty data file it creates with the file that contains the data of your previous Tutor Pal folder. == Command Summary -* *Add* `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]...` + -e.g. `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 t/friend t/colleague` +* *Add* : `add n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS el/EDUCATIONAL_LEVEL [g/GRADE]... [t/TAG]...` + +e.g. `add n/James Ho p/22224444 e/jamesho@example.com a/123, Clementi Rd, 1234665 el/JC 1 g/FinalExam 85` +* *Add time* : `addTime INDEX ts/TIME` + +e.g. `addTime 1 ts/mon 1300 1500` * *Clear* : `clear` * *Delete* : `delete INDEX` + e.g. `delete 3` -* *Edit* : `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]...` + -e.g. `edit 2 n/James Lee e/jameslee@example.com` +* *Delete time* : `deleteTime INDEX ts/TIME` + +e.g. `deleteTime 1 ts/mon 1300 1500` +* *Earnings* : `earnings START_DATE END_DATE` +* *Promote* : `promote all` +* *Promote* : `promote INDEX...` + +e.g. `promote 1 2 5 13` +* *Edit* : `edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [el/EDUCATIONAL_LEVEL] [a/ADDRESS] [t/TAG]...` + +e.g. `edit 2 n/James Lee e/jameslee@example.com el/JC 1` +* *Edit time* : `editTime n/NAME ts/OLD_TIME_SLOT ts/NEW_TIME_SLOT` + +e.g. `editTime n/Alice ts/mon 1300 1400 ts/tue 1300 1400` +* *Exchange time* : `exchangeTime NAME_A A_TIME_SLOT_ORDINAL_NUMBER NAME_B B_TIME_SLOT_ORDINAL_NUMBER` + +e.g. `ExchangeTime Alice 0 Bob 0` +* *Filter by fee* : `filterByFee FEE` + +e.g. `filterByFee 24` +* *Filter by educational level* : `filterByEducation EDUCATIONAL_LEVEL` + +e.g. `filterByEducation Secondary` +* *Filter by grade* : `filterByGrade MINIMUM_GRADE MAXIMUM_GRADE` + +e.g. `filterByGrade 50 100` +* *Filter by time* : `filterByFee TIME_SLOT` + +e.g. `filterByTime mon 1300 1400` * *Find* : `find KEYWORD [MORE_KEYWORDS]` + e.g. `find James Jake` -* *List* : `list` +* *Find by address* : `find/a ADDRESS` + +e.g `find/a serangoon` +* *Find by phone number* : `find/p PHONE` + +e.g `find/p 12345678` +* *Find by email* : `find/e EMAIL` + +e.g `find/e lidavid@example.com` * *Help* : `help` +* *History* : `history` +* *List* : `list` +* *Redo* : `redo` * *Select* : `select INDEX` + e.g.`select 2` -* *History* : `history` +* *Suggestion* : `suggestion NAME` + +e.g.`suggestion Alice` * *Undo* : `undo` -* *Redo* : `redo` diff --git a/docs/images/AddTimeSequenceDiagram.png b/docs/images/AddTimeSequenceDiagram.png new file mode 100644 index 000000000000..5bb825dd013a Binary files /dev/null and b/docs/images/AddTimeSequenceDiagram.png differ diff --git a/docs/images/DeleteGradeDiagram.png b/docs/images/DeleteGradeDiagram.png new file mode 100644 index 000000000000..3a56bc5f68e5 Binary files /dev/null and b/docs/images/DeleteGradeDiagram.png differ diff --git a/docs/images/DeleteTimeSequenceDiagram.png b/docs/images/DeleteTimeSequenceDiagram.png new file mode 100644 index 000000000000..e5163a509f7b Binary files /dev/null and b/docs/images/DeleteTimeSequenceDiagram.png differ diff --git a/docs/images/EarningsCommandSequenceDiagram.png b/docs/images/EarningsCommandSequenceDiagram.png new file mode 100644 index 000000000000..d89447ed1a04 Binary files /dev/null and b/docs/images/EarningsCommandSequenceDiagram.png differ diff --git a/docs/images/EditDiagram.png b/docs/images/EditDiagram.png new file mode 100644 index 000000000000..631998f5059e Binary files /dev/null and b/docs/images/EditDiagram.png differ diff --git a/docs/images/Education.png b/docs/images/Education.png new file mode 100644 index 000000000000..b4b0276654e1 Binary files /dev/null and b/docs/images/Education.png differ diff --git a/docs/images/Fee.png b/docs/images/Fee.png new file mode 100644 index 000000000000..52f574269bd2 Binary files /dev/null and b/docs/images/Fee.png differ diff --git a/docs/images/FindAddressCommandLogicDiagram.png b/docs/images/FindAddressCommandLogicDiagram.png new file mode 100644 index 000000000000..b44fb234225a Binary files /dev/null and b/docs/images/FindAddressCommandLogicDiagram.png differ diff --git a/docs/images/FindCommandLogicDiagram.png b/docs/images/FindCommandLogicDiagram.png new file mode 100644 index 000000000000..9295dad96f54 Binary files /dev/null and b/docs/images/FindCommandLogicDiagram.png differ diff --git a/docs/images/FindEmailCommandLogicDiagram.png b/docs/images/FindEmailCommandLogicDiagram.png new file mode 100644 index 000000000000..2d4bcb81bcfe Binary files /dev/null and b/docs/images/FindEmailCommandLogicDiagram.png differ diff --git a/docs/images/FindPhoneCommandLogicDiagram-1.png b/docs/images/FindPhoneCommandLogicDiagram-1.png new file mode 100644 index 000000000000..6dcdef68bf89 Binary files /dev/null and b/docs/images/FindPhoneCommandLogicDiagram-1.png differ diff --git a/docs/images/GraduateExample.png b/docs/images/GraduateExample.png new file mode 100644 index 000000000000..56538389bc9f Binary files /dev/null and b/docs/images/GraduateExample.png differ diff --git a/docs/images/ModelForGrade.png b/docs/images/ModelForGrade.png new file mode 100644 index 000000000000..ef17b3f3b887 Binary files /dev/null and b/docs/images/ModelForGrade.png differ diff --git a/docs/images/PersonCardExample.png b/docs/images/PersonCardExample.png new file mode 100644 index 000000000000..e025ce53fe63 Binary files /dev/null and b/docs/images/PersonCardExample.png differ diff --git a/docs/images/StorageForGrade.png b/docs/images/StorageForGrade.png new file mode 100644 index 000000000000..baefde5b4419 Binary files /dev/null and b/docs/images/StorageForGrade.png differ diff --git a/docs/images/Time.png b/docs/images/Time.png new file mode 100644 index 000000000000..84dcc2535f5b Binary files /dev/null and b/docs/images/Time.png differ diff --git a/docs/images/Ui.png b/docs/images/Ui.png index 5ec9c527b49c..01e4628c2058 100644 Binary files a/docs/images/Ui.png and b/docs/images/Ui.png differ diff --git a/docs/images/UiClassDiagram.png b/docs/images/UiClassDiagram.png index 369469ef176e..da9e7478febf 100644 Binary files a/docs/images/UiClassDiagram.png and b/docs/images/UiClassDiagram.png differ diff --git a/docs/images/chenlu-chua.png b/docs/images/chenlu-chua.png new file mode 100644 index 000000000000..33fac7e49989 Binary files /dev/null and b/docs/images/chenlu-chua.png differ diff --git a/docs/images/cjuanvip.png b/docs/images/cjuanvip.png new file mode 100644 index 000000000000..0884ba67e2b7 Binary files /dev/null and b/docs/images/cjuanvip.png differ diff --git a/docs/images/damithc.jpg b/docs/images/damithc.jpg deleted file mode 100644 index 127543883893..000000000000 Binary files a/docs/images/damithc.jpg and /dev/null differ diff --git a/docs/images/hrxiong.png b/docs/images/hrxiong.png new file mode 100644 index 000000000000..419e5ef0fece Binary files /dev/null and b/docs/images/hrxiong.png differ diff --git a/docs/images/junjiee.png b/docs/images/junjiee.png new file mode 100644 index 000000000000..afafb996c15e Binary files /dev/null and b/docs/images/junjiee.png differ diff --git a/docs/images/lejolly.jpg b/docs/images/lejolly.jpg deleted file mode 100644 index 2d1d94e0cf5d..000000000000 Binary files a/docs/images/lejolly.jpg and /dev/null differ diff --git a/docs/images/lzyandy.png b/docs/images/lzyandy.png new file mode 100644 index 000000000000..597a2a3da328 Binary files /dev/null and b/docs/images/lzyandy.png differ diff --git a/docs/images/m133225.jpg b/docs/images/m133225.jpg deleted file mode 100644 index fd14fb94593a..000000000000 Binary files a/docs/images/m133225.jpg and /dev/null differ diff --git a/docs/images/tutor.png b/docs/images/tutor.png new file mode 100644 index 000000000000..a01dd5c8f885 Binary files /dev/null and b/docs/images/tutor.png differ diff --git a/docs/images/tutor1.png b/docs/images/tutor1.png new file mode 100644 index 000000000000..f00033fa31dc Binary files /dev/null and b/docs/images/tutor1.png differ diff --git a/docs/images/tutor2.png b/docs/images/tutor2.png new file mode 100644 index 000000000000..bbeaff195e33 Binary files /dev/null and b/docs/images/tutor2.png differ diff --git a/docs/images/tutor3.png b/docs/images/tutor3.png new file mode 100644 index 000000000000..301a631b78c2 Binary files /dev/null and b/docs/images/tutor3.png differ diff --git a/docs/images/tutorpal.png b/docs/images/tutorpal.png new file mode 100644 index 000000000000..151e42682391 Binary files /dev/null and b/docs/images/tutorpal.png differ diff --git a/docs/images/yijinl.jpg b/docs/images/yijinl.jpg deleted file mode 100644 index adbf62ad9406..000000000000 Binary files a/docs/images/yijinl.jpg and /dev/null differ diff --git a/docs/images/yl_coder.jpg b/docs/images/yl_coder.jpg deleted file mode 100644 index 17b48a732272..000000000000 Binary files a/docs/images/yl_coder.jpg and /dev/null differ diff --git a/docs/team/chenlu-chua.adoc b/docs/team/chenlu-chua.adoc new file mode 100644 index 000000000000..bb0baf2c6169 --- /dev/null +++ b/docs/team/chenlu-chua.adoc @@ -0,0 +1,73 @@ += Chua Chen Lu - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets + +== PROJECT: TutorPal + +--- + +== Overview + +TutorPal is a desktop application used by private home tutors for managing student information. The useage is primarily through CLI. It is written in Java. + +== Summary of contributions + +* *Major enhancement*: implemented the *promote feature* to allow tutor to promote multiple students simultaneously. +** What is does: Allow tutors to raise the educational grade of the students stored in TutorPal. Tutors +can choose to promote all students or selectively. +** Justification: This function is an efficient and yet flexible solution to swiftly increase the +educational grade of students as a year passes. +The decision to *not automate the promotion of students* is deliberate. +This provides the users with a higher level of autonomy when using TutorPal. + +In providing such feature instead of relying on promoting the students stored in TutorPal automatically, +undesirable outcomes like promoting all students when the system time is changed to other years are avoided. +As a private tutor, it is not uncommon to encounter parents who wish for their children to begin tuition lessons +even before the start of an academic year. A situation like this is an example of why greater flexibility is more +beneficial to a user, even if it means taking an additional step to manually promote the students in TutorPal. + +* *Minor enhancement*: implemented the *earnings feature* +** What it does: Allows tutors to calculate the amount of money earned from giving tuition between a range of dates. +** Justification: It is important to calculate and keep track of his/her income. This feature allows tutor to ensure that +future earnings are sufficient, and also assist the tutor in planning and organizing current and future student intakes. + +* *Code contributed*: https://nus-cs2103-ay1819s1.github.io/cs2103-dashboard/#=undefined&search=chenlu-chua + +* *Other contributions*: + +** Project management: +*** Managed releases `v1.2` - `v1.4` (3 releases) on GitHub +*** Setting up of team repository. +*** Setting up of issue tracker. +*** Managed project Milestone. +** Enhancements to existing features: +*** Updated the GUI of "Graduated" Tag to become more prominent to users. +*** Updated the add command to allow adding of educational level and grade. +*** Added an Education field to the person object in TutorPal to +allow users to store the educational level of students. +*** Implemented tuition fees attribute to student. Tuition fees are based on student's +educational level and grade, irrespective of the subject(s) taught to them. +** Documentation: +*** Removed obsolete AB4 information and updated relevant documents with TutorPal project. + +== Contributions to the User Guide + + +|=== +|_Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users._ +|=== + +include::../UserGuide.adoc[tag=promote] + +include::../UserGuide.adoc[tag=earnings] + +== Contributions to the Developer Guide + +|=== +|_Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project._ +|=== + +include::../DeveloperGuide.adoc[tag=promotefeature] + +include::../DeveloperGuide.adoc[tag=earningfeature] + diff --git a/docs/team/cjuanvip.adoc b/docs/team/cjuanvip.adoc new file mode 100644 index 000000000000..4b3d38c59e1e --- /dev/null +++ b/docs/team/cjuanvip.adoc @@ -0,0 +1,92 @@ += Chen Juan - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets + +== PROJECT: TutorPal + +--- + +== Overview + +TutorPal is a desktop application used by private home tutors for managing student information. The useage is primarily through CLI. It is written in Java. + +== Summary of contributions + +* *Major enhancement*: implemented the *Filter command* in aspect of *fee* *grade* *timeslot* *education* +** What it does: +***FilterByFee enable user to read the list of students whose tuition fee is equal or larger than the given minimal limit fee. +***FilterByGrade enable user to read the list of students whose gradeslist include the given grade range from a to b. +***FilterByEducation enable user to read the list of students whose education level is the same. +***FilterByTimeSlot enable user to get the student whose timeslot is the same as input timeslot. +** Justification: Filter is an important command for the user to search according to different features, given the range and +list the qualified students can provide a simple review in aspect to certain features. + +* *Major enhancement*: implemented the *exchange Time command* +** What is does: To exchange the time slot between two students whose education is the same. +** Justification: Since it is not allowed to simply add the new time slot when a time slot is already +be taken, so exchanging Time between two students is different from simply delete and add time slot, +this command allow two student to exchange their time slot without bringing any crush on time slots. + +* *Major enhancement*: implemented the *Suggestion command* +** What is does: To provide suggestion to students according to his or her average grades. +** Justification: This command allow user to clearly see the overall performance of certain students +by analysing the average grades. If the student has not taken any exams yet, there is no suggestion gonna +be provided. + +* *Other contributions*: + +** Project management: +*** Make sure every editing of any features is compatible with current code +*** Improve features added by others in order to match the command request. +*** Initiate the creative thought about the project. +*** Arrange specific work for everyone during meeting. +*** Managed project Milestone. +** Documentation: +*** Add the section on Reporting Module to the UserGuide. +*** Add the use cases of Reporting Module to the Developer Guide. +** Enhancements to others features: +*** Add the predicate for filtering the grade, fee, education and time slot. +*** Improve the time and education features by adding setting method and enums. + +== Contributions to the User Guide + + +|=== +|_Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users._ +|=== + +include::../UserGuide.adoc[tag=filter1] + +include::../UserGuide.adoc[tag=filter2] + +include::../UserGuide.adoc[tag=filter3] + +include::../UserGuide.adoc[tag=filter4] + +include::../UserGuide.adoc[tag=suggest1] + +include::../UserGuide.adoc[tag=suggest2] + +include::../UserGuide.adoc[tag=exchange] + +== Contributions to the Developer Guide + +|=== +|_Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project._ +|=== + +include::../DeveloperGuide.adoc[tag=filter1] + +include::../DeveloperGuide.adoc[tag=filter2] + +include::../DeveloperGuide.adoc[tag=filter3] + +include::../DeveloperGuide.adoc[tag=filter4] + +include::../DeveloperGuide.adoc[tag=suggest1] + +include::../DeveloperGuide.adoc[tag=suggest2] + +include::../DeveloperGuide.adoc[tag=exchange] + diff --git a/docs/team/hrxiong.adoc b/docs/team/hrxiong.adoc new file mode 100644 index 000000000000..83e531ee72cb --- /dev/null +++ b/docs/team/hrxiong.adoc @@ -0,0 +1,86 @@ += XIONG HAORAN - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets + +== PROJECT: TutorPal + +--- + +== Overview + +TutorPal is a desktop application used by private home tutors for managing student information. The useage is primarily through CLI. It is written in Java. + +== Summary of contributions +* *Code Contributed*: +https://nus-cs2103-ay1819s1.github.io/cs2103-dashboard/#=undefined&search=hrxiong[RepoSense] + +* *Major enhancement*: implemented the *add and edit grades feature* +** What it does: Allows tutors to add one or more than one grade records for a student during using editing command or adding a student with the help of add command. +** Justification: As an indicator of the quality of teaching,grades are a very important part of tutoring. +If the exam results can be recorded, the tutor can more easily analyze the student's learning status and reflect his or her own teaching ability as well. + + +* *Minor enhancement*: implemented the *delete grades feature* +** What is does: Allow tutors to delete a grade record of a students stored in TutorPal. +** Justification: Tutor can also use the undo command to delete the wrong records inputted. And this way is more efficient way if the tutor +is good at typing. But if the tutor inputs a wrong name of the exam and then closes the TutorPal unfortunately, the undo command will out of action. +So a deleteGrade command is added to fix this logic bug. + +* *Other contributions*: + +** Project management: +*** Configuring Travis, Coverage and auto-publishing of documentation. +*** Setting up and assigning of the issue tracker. +*** Editing project Milestone. + +** Enhancements to existing features: +*** Added test for grade part. (pull request: https://github.com/CS2103-AY1819S1-T13-1/main/pull/183[#183]) +*** Fixed the bug when the project totally broke down.(pull request: https://github.com/CS2103-AY1819S1-T13-1/main/pull/40[#40], +https://github.com/CS2103-AY1819S1-T13-1/main/pull/61[#61], https://github.com/CS2103-AY1819S1-T13-1/main/pull/95[#95]) +*** Updated the GUI of "grades" to become more tidy. (pull request: https://github.com/CS2103-AY1819S1-T13-1/main/pull/91[#91]) +*** Fixed the logic conflict caused by the education enum. (pull request: https://github.com/CS2103-AY1819S1-T13-1/main/pull/55[#55]) +*** Guaranteed the grades feature working normally without affecting other function +such as storage, undo and redo command. (pull request: https://github.com/CS2103-AY1819S1-T13-1/main/pull/170[#170]) + +** Documentation: +*** Did cosmetic tweaks to existing contents of the AboutUs and README. (pull request: https://github.com/CS2103-AY1819S1-T13-1/main/pull/5[#5], +https://github.com/CS2103-AY1819S1-T13-1/main/pull/6[#6], https://github.com/CS2103-AY1819S1-T13-1/main/pull/26[#26], +https://github.com/CS2103-AY1819S1-T13-1/main/pull/30[#30], https://github.com/CS2103-AY1819S1-T13-1/main/pull/32[#32]) +*** Removed some information about AB4 and updated relevant documents with TutorPal project. (pull request: +https://github.com/CS2103-AY1819S1-T13-1/main/pull/1[#1], https://github.com/CS2103-AY1819S1-T13-1/main/pull/2[#2], +https://github.com/CS2103-AY1819S1-T13-1/main/pull/4[#4]) + +** Community: +*** PRs reviewed (pull request: https://github.com/CS2103-AY1819S1-T13-1/main/pull/60[#60], +https://github.com/CS2103-AY1819S1-T13-1/main/pull/62[#62]) + +== Contributions to the User Guide + + +|=== +|_Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users._ +|=== + +include::../UserGuide.adoc[tag=grade] + +include::../UserGuide.adoc[tag=add] + +include::../UserGuide.adoc[tag=edit] + +include::../UserGuide.adoc[tag=deleteGrade] + + +== Contributions to the Developer Guide + +|=== +|_Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project._ +|=== + +include::../DeveloperGuide.adoc[tag=grades1] + +include::../DeveloperGuide.adoc[tag=grades2] + +include::../DeveloperGuide.adoc[tag=grades3] + +include::../DeveloperGuide.adoc[tag=gradesfeature] diff --git a/docs/team/junjiee.adoc b/docs/team/junjiee.adoc new file mode 100644 index 000000000000..c93c826b5eb1 --- /dev/null +++ b/docs/team/junjiee.adoc @@ -0,0 +1,55 @@ += Ong Jun Jie - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets + +== PROJECT: TutorPal + +--- + +== Overview + +TutorPal is a desktop application used by mainly private home tutors to manage their students and schedules. The usage is primarily through CLI. It is written in Java. + +== Summary of contributions + +* *Major enhancement*: Added *timing attribute* for the Person class +** What it does: It stores the tuition timings of a student in Tutor Pal. +** Justification: In addition to having contact details of their students, allows users to keep track of their students' tuition timings increases our product's relevance to our target users, making Tutor Pal more convenient for our target user. + +* *Major enhancement*: implemented *addTime* / *deleteTime* commands +** What it does: It allows user to add or delete tuition timings of their students in Tutor Pal. +** Justification: The commands enable users to easily manage the tuition timings of their students. If there is a need to change the tuition timings of a student, users do not have to recreate the student entirely in Tutor Pal. Tuition timings of students are one of the details that changes the most in Tutor Pal as the year progresses. This may be due to changes in the student's timetable or additional school commitments. Hence, having *addTime* and *deleteTime* will make our product more convenient for our target users, private tutors, and increase our product's relevance to them. + +* *Code contributed*: [https://nus-cs2103-ay1819s1.github.io/cs2103-dashboard/#=undefined&search=junjiee&sort=displayName&since=2018-09-12&until=2018-11-10&timeframe=day&reverse=false&repoSort=false[Reposense]] + +* *Other contributions*: + +** Project management: +*** Enabling our code to be reposense compatible. +** Enhancements to existing features: +*** Updated the GUI to display tuition time slots of a student. + +== Contributions to the User Guide + + +|=== +|_Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users._ +|=== + +include::../UserGuide.adoc[tag=addtimecommand] + +include::../UserGuide.adoc[tag=deletetimecommand] + +== Contributions to the Developer Guide + +|=== +|_Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project._ +|=== + +include::../DeveloperGuide.adoc[tag=timefeature] + +include::../DeveloperGuide.adoc[tag=addtimecommand] + +include::../DeveloperGuide.adoc[tag=deletetimecommand] + diff --git a/docs/team/lzyandy.adoc b/docs/team/lzyandy.adoc new file mode 100644 index 000000000000..a9417737d250 --- /dev/null +++ b/docs/team/lzyandy.adoc @@ -0,0 +1,67 @@ += Liu Zhaoyu - Project Portfolio +:site-section: AboutUs +:imagesDir: ../images +:stylesDir: ../stylesheets + +== PROJECT: TutorPal + +--- + +== Overview + +TutorPal is a desktop application used by private home tutors for managing student information. The useage is primarily through CLI. It is written in Java. + +== Summary of contributions + +* *Major enhancement*: enhanced *FindCommand* to make it support fuzzy matching +** What it does: allows the user to find Person by name and supports fuzzy matching, which means even if the user has a small typo, it can still find Persons with similar names. +** Justification: This feature enhancement makes this command more practical because sometimes users may type wrongly during searching. However, fuzzy matching allows small mistakes in typing and makes searching much easier. +** Highlights: This search allows fuzzy matching (with Levenshtein Distance < 3) only when the length of the keyword is greater than 3. If the length of the keyword you type in is smaller or equal to 3, the keyword must be exactly the same to expected + +* *Major enhancement*: extended FindCommand to *FindAddressCommand, FindEmailCommand, and FindPhoneCommand* +** What it does: allows the user to find Persons by address, email, and phone number and support fuzzy matching, which means even if the user has a small typo, it can still find Persons with similar address, email, or phone number. +** Justification: These features largely improve the convenience for finding a specific Person or a list of Persons. For instance, a Person now can be found by his or her address, email or phone number, and multiple step of find command can be used to find a person by more than one kind of conditions. +** Highlights: All these commands are case insensitive and support fuzzy matching (however, with some restrictions, which are specified in User Guide). + +* *Minor enhancement*: +** Built tests case for *Find* related commands and UI. + +* *Code contributed*: [https://github.com[Functional code]] [https://github.com[Test code]] _{give links to collated code files}_ + +* *Other contributions*: + +** Project management: +*** Set milestones for `v1.2 - v1.4` on GitHub +*** Opened issues for `v1.2 - v1.4` on GitHub +*** Set up milestone deadlines, close issues accordingly on GitHub +** Enhancements to existing features: +*** Modified the UI and added related test case (Pull requests https://github.com/CS2103-AY1819S1-T13-1/main/pull/169[#169], https://github.com/CS2103-AY1819S1-T13-1/main/pull/178[#178]) +*** Wrote additional tests for existing features to increase coverage (Pull requests https://github.com/CS2103-AY1819S1-T13-1/main/pull/101[#101]) +** Documentation: +*** Modified the format and changed some inaccurate expressions for the whole User Guide: https://github.com/CS2103-AY1819S1-T13-1/main/pull/167[#167] +** Community: +*** PRs reviewed (with non-trivial review comments): https://github.com/CS2103-AY1819S1-T13-1/main/pull/166[#166], https://github.com/CS2103-AY1819S1-T13-1/main/pull/175[#175], https://github.com/CS2103-AY1819S1-T13-1/main/pull/182[#182], https://github.com/CS2103-AY1819S1-T13-1/main/pull/183[#183] +*** Reported bugs and suggestions for other teams in the class (examples: https://github.com/CS2103-AY1819S1-W10-2/main/issues/257[#257]) + +== Contributions to the User Guide + + +|=== +|_Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users._ +|=== + +include::../UserGuide.adoc[tag=find] + +include::../UserGuide.adoc[tag=find/a] + +include::../UserGuide.adoc[tag=find/e] + +include::../UserGuide.adoc[tag=find/p] + +== Contributions to the Developer Guide + +|=== +|_Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project._ +|=== + +include::../DeveloperGuide.adoc[tag=findfeature] diff --git a/src/main/java/seedu/address/MainApp.java b/src/main/java/seedu/address/MainApp.java index ecdd043a4f81..b5cd08e2fd0d 100644 --- a/src/main/java/seedu/address/MainApp.java +++ b/src/main/java/seedu/address/MainApp.java @@ -40,7 +40,7 @@ */ public class MainApp extends Application { - public static final Version VERSION = new Version(0, 6, 0, true); + public static final Version VERSION = new Version(1, 4, 0, true); private static final Logger logger = LogsCenter.getLogger(MainApp.class); diff --git a/src/main/java/seedu/address/commons/core/Config.java b/src/main/java/seedu/address/commons/core/Config.java index e978d621e086..36afe5acf65c 100644 --- a/src/main/java/seedu/address/commons/core/Config.java +++ b/src/main/java/seedu/address/commons/core/Config.java @@ -13,7 +13,7 @@ public class Config { public static final Path DEFAULT_CONFIG_FILE = Paths.get("config.json"); // Config values customizable through config file - private String appTitle = "Address App"; + private String appTitle = "TutorPal"; private Level logLevel = Level.INFO; private Path userPrefsFilePath = Paths.get("preferences.json"); diff --git a/src/main/java/seedu/address/commons/util/StringUtil.java b/src/main/java/seedu/address/commons/util/StringUtil.java index 61cc8c9a1cb8..bbb6e855f988 100644 --- a/src/main/java/seedu/address/commons/util/StringUtil.java +++ b/src/main/java/seedu/address/commons/util/StringUtil.java @@ -12,18 +12,70 @@ */ public class StringUtil { + //@@author LZYAndy /** * Returns true if the {@code sentence} contains the {@code word}. - * Ignores case, but a full word match is required. + * Ignores case, and allow fuzzy matching. + *
examples:
+     *       containsWordIgnoreCaseAndFuzzyName("ABc def", "abc") == true
+     *       containsWordIgnoreCaseAndFuzzyName("ABc def", "DEF") == true
+     *       containsWordIgnoreCaseAndFuzzyName("ABc def", "AB") == true
+     *       
+ * @param sentence cannot be null + * @param word cannot be null, cannot be empty, must be a single word + */ + public static boolean containsWordIgnoreCaseAndFuzzyName(String sentence, String word) { + requireNonNull(sentence); + requireNonNull(word); + + String preppedWord = word.trim().toLowerCase(); + checkArgument(!preppedWord.isEmpty(), "Word parameter cannot be empty"); + checkArgument(preppedWord.split("\\s+").length == 1, "Word parameter should be a single word"); + + String preppedSentence = sentence.toLowerCase(); + String[] wordsInPreppedSentence = preppedSentence.split("\\s+"); + + return Arrays.stream(wordsInPreppedSentence) + .anyMatch(w -> w.length() < 4 ? preppedWord.equals(w) : calculate(preppedWord, w) < 3); + } + + /** + * Returns true if the {@code sentence} contains the {@code word}. + * Ignores case, and allow fuzzy matching. *
examples:
-     *       containsWordIgnoreCase("ABc def", "abc") == true
-     *       containsWordIgnoreCase("ABc def", "DEF") == true
-     *       containsWordIgnoreCase("ABc def", "AB") == false //not a full word match
+     *       containsWordIgnoreCaseAndFuzzyEmail("ABc def", "abc") == true
+     *       containsWordIgnoreCaseAndFuzzyEmail("ABc def", "DEF") == true
+     *       containsWordIgnoreCaseAndFuzzyEmail("ABc def", "AB") == true
      *       
* @param sentence cannot be null * @param word cannot be null, cannot be empty, must be a single word */ - public static boolean containsWordIgnoreCase(String sentence, String word) { + public static boolean containsWordIgnoreCaseAndFuzzyEmail(String sentence, String word) { + requireNonNull(sentence); + requireNonNull(word); + + String preppedWord = word.trim().toLowerCase(); + checkArgument(!preppedWord.isEmpty(), "Word parameter cannot be empty"); + checkArgument(preppedWord.split("\\s+").length == 1, "Word parameter should be a single word"); + + String preppedSentence = sentence.toLowerCase(); + String[] wordsInPreppedSentence = preppedSentence.split("\\s+"); + + return Arrays.stream(wordsInPreppedSentence) + .anyMatch(w -> calculate(preppedWord, w) < 4); + } + + /** + * Returns true if the {@code sentence} contains the {@code word}. + * Ignores case, and allow fuzzy matching. + *
examples:
+     *       containsWordIgnoreCaseAndFuzzyPhone("12345678", "123456") == true
+     *       containsWordIgnoreCaseAndFuzzyPhone("12345678", "123467") == true
+     *       
+ * @param sentence cannot be null + * @param word cannot be null, cannot be empty, must be a single word + */ + public static boolean containsWordIgnoreCaseAndFuzzyPhone(String sentence, String word) { requireNonNull(sentence); requireNonNull(word); @@ -35,8 +87,103 @@ public static boolean containsWordIgnoreCase(String sentence, String word) { String[] wordsInPreppedSentence = preppedSentence.split("\\s+"); return Arrays.stream(wordsInPreppedSentence) - .anyMatch(preppedWord::equalsIgnoreCase); + .anyMatch(w -> calculate(preppedWord, w) < 3); + } + + /** + * Returns true if the {@code sentence} contains the {@code word}. + * Ignores case, but a full word match is required. + *
examples:
+     *       containsWordIgnoreCaseAndFuzzyAddress("ABc def", "abc") == true
+     *       containsWordIgnoreCaseAndFuzzyAddress("ABc def", "DEF") == true
+     *       containsWordIgnoreCaseAndFuzzyAddress("ABc def", "AB") == false //length too short, must be totally match
+     *       containsWordIgnoreCaseAndFuzzyAddress("ABCdefg sdf", "AcDfg") == true
+     *       
+ * @param sentence cannot be null + * @param word cannot be null, cannot be empty, must be a single word + */ + public static boolean containsWordIgnoreCaseAndFuzzyAddress(String sentence, String word) { + requireNonNull(sentence); + requireNonNull(word); + + String preppedWord = word.trim().toLowerCase(); + checkArgument(!preppedWord.isEmpty(), "Word parameter cannot be empty"); + checkArgument(preppedWord.split("\\s+").length == 1, "Word parameter should be a single word"); + + String preppedSentence = sentence.toLowerCase(); + String[] wordsInPreppedSentence = preppedSentence.split("\\s+"); + + return Arrays.stream(wordsInPreppedSentence) + .anyMatch(w -> containsDigit(w) || w.length() < 4 ? preppedWord.equals(w) + : w.length() < 8 ? calculate(preppedWord, w) < 3 : calculate(preppedWord, w) < 4); + } + + /** + * Check whether a string contains digit. + * @param s String + * @return Boolean + */ + public static final boolean containsDigit(String s) { + boolean containsDigit = false; + + if (s != null && !s.isEmpty()) { + for (char c : s.toCharArray()) { + if (containsDigit = Character.isDigit(c)) { + break; + } + } + } + + return containsDigit; + } + + /** + * A function used to support fuzzy matching + * @param x the first string + * @param y the second string + * @return Levenshtein Distance + */ + public static int calculate(String x, String y) { + int[][] dp = new int[x.length() + 1][y.length() + 1]; + + for (int i = 0; i <= x.length(); i++) { + for (int j = 0; j <= y.length(); j++) { + if (i == 0) { + dp[i][j] = j; + } else if (j == 0) { + dp[i][j] = i; + } else { + dp[i][j] = min(dp[i - 1][j - 1] + + costOfSubstitution(x.charAt(i - 1), y.charAt(j - 1)), + dp[i - 1][j] + 1, + dp[i][j - 1] + 1); + } + } + } + + return dp[x.length()][y.length()]; + } + + /** + * Get cost of substitution. + * @param a char + * @param b char + * @return integer + */ + public static int costOfSubstitution(char a, char b) { + return a == b ? 0 : 1; + } + + /** + * Get min. + * @param numbers integer + * @return integer + */ + public static int min(int... numbers) { + return Arrays.stream(numbers) + .min().orElse(Integer.MAX_VALUE); } + //@@author LZYAndy /** * Returns a detailed message of the t, including the stack trace. diff --git a/src/main/java/seedu/address/logic/commands/AddCommand.java b/src/main/java/seedu/address/logic/commands/AddCommand.java index d88e831ff1ce..44de6177b42d 100644 --- a/src/main/java/seedu/address/logic/commands/AddCommand.java +++ b/src/main/java/seedu/address/logic/commands/AddCommand.java @@ -2,7 +2,9 @@ import static java.util.Objects.requireNonNull; import static seedu.address.logic.parser.CliSyntax.PREFIX_ADDRESS; +import static seedu.address.logic.parser.CliSyntax.PREFIX_EDUCATION; import static seedu.address.logic.parser.CliSyntax.PREFIX_EMAIL; +import static seedu.address.logic.parser.CliSyntax.PREFIX_GRADES; import static seedu.address.logic.parser.CliSyntax.PREFIX_NAME; import static seedu.address.logic.parser.CliSyntax.PREFIX_PHONE; import static seedu.address.logic.parser.CliSyntax.PREFIX_TAG; @@ -19,23 +21,27 @@ public class AddCommand extends Command { public static final String COMMAND_WORD = "add"; - public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a person to the address book. " + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a person to the student list. " + "Parameters: " + PREFIX_NAME + "NAME " + PREFIX_PHONE + "PHONE " + PREFIX_EMAIL + "EMAIL " + PREFIX_ADDRESS + "ADDRESS " + + PREFIX_EDUCATION + "EDUCATION " + + PREFIX_GRADES + "EXAM GRADES " + "[" + PREFIX_TAG + "TAG]...\n" + "Example: " + COMMAND_WORD + " " + PREFIX_NAME + "John Doe " + PREFIX_PHONE + "98765432 " + PREFIX_EMAIL + "johnd@example.com " + PREFIX_ADDRESS + "311, Clementi Ave 2, #02-25 " + + PREFIX_EDUCATION + "Primary 4 " + + PREFIX_GRADES + "Y1819S1_Mid 89 " + PREFIX_TAG + "friends " + PREFIX_TAG + "owesMoney"; public static final String MESSAGE_SUCCESS = "New person added: %1$s"; - public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the address book"; + public static final String MESSAGE_DUPLICATE_PERSON = "This person already exists in the student list"; private final Person toAdd; diff --git a/src/main/java/seedu/address/logic/commands/AddTimeCommand.java b/src/main/java/seedu/address/logic/commands/AddTimeCommand.java new file mode 100644 index 000000000000..647b78a005a0 --- /dev/null +++ b/src/main/java/seedu/address/logic/commands/AddTimeCommand.java @@ -0,0 +1,146 @@ +package seedu.address.logic.commands; + +import static java.util.Objects.requireNonNull; +import static seedu.address.logic.parser.CliSyntax.PREFIX_TIME; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Set; + +import seedu.address.commons.core.Messages; +import seedu.address.commons.core.index.Index; +import seedu.address.logic.CommandHistory; +import seedu.address.logic.commands.exceptions.CommandException; +import seedu.address.model.Model; +import seedu.address.model.person.Address; +import seedu.address.model.person.Education; +import seedu.address.model.person.Email; +import seedu.address.model.person.Grades; +import seedu.address.model.person.Name; +import seedu.address.model.person.Person; +import seedu.address.model.person.Phone; +import seedu.address.model.person.Time; +import seedu.address.model.tag.Tag; + +/** + * Adds a time slot of a Person in the address book. + */ +public class AddTimeCommand extends Command { + public static final String COMMAND_WORD = "addTime"; + + public static final String MESSAGE_USAGE = COMMAND_WORD + ": Adds a tutorial time slot of a person. " + + "Parameters: INDEX (must be a positive integer) " + + PREFIX_TIME + "TIME " + + "Example: " + COMMAND_WORD + " 1 " + + PREFIX_TIME + "mon 1300 1500 "; + + public static final String MESSAGE_SUCCESS = "Time slot successfully added"; + public static final String MESSAGE_PERSON_NOT_FOUND = "This person does not exists in the address book"; + public static final String MESSAGE_TIME_IS_NOT_AVAILABLE = "The time has already been taken"; + public static final String MESSAGE_INVALID_START_END_TIME = "Start time must be earlier than end time"; + public static final String MESSAGE_TIME_CLASH = "There is a clash with other tuition timing in the address book"; + + private final Time toAdd; + + private final Index index; + + /** + * Creates a AddTimeCommand to add the specified {@code Time} + */ + public AddTimeCommand(Index index, Time time) { + requireNonNull(index); + requireNonNull(time); + toAdd = time; + this.index = index; + } + + @Override + public CommandResult execute(Model model, CommandHistory history) throws CommandException { + requireNonNull(model); + List lastShownList = model.getFilteredPersonList(); + if (index.getZeroBased() >= lastShownList.size()) { + throw new CommandException(Messages.MESSAGE_INVALID_PERSON_DISPLAYED_INDEX); + } + + ArrayList