From d204876fa142fe5a7035f3125823a16b561f6c5c Mon Sep 17 00:00:00 2001 From: Jeffinson Darmawan Date: Mon, 15 Apr 2024 04:35:56 +0800 Subject: [PATCH] ASCII Table & User Guide Update & PPP Update --- docs/UserGuide.md | 222 +++++++++++------- docs/team/jeffinsondarmawan.md | 42 +++- .../java/florizz/command/CompareCommand.java | 17 ++ .../java/florizz/command/InfoCommand.java | 1 - .../java/florizz/core/FlowerDictionary.java | 30 +-- src/main/java/florizz/core/FuzzyLogic.java | 164 ++++++------- src/main/java/florizz/core/Parser.java | 7 +- src/main/java/florizz/core/Ui.java | 97 ++++++-- src/main/java/florizz/objects/Flower.java | 4 + src/main/java/florizz/objects/TableData.java | 32 ++- 10 files changed, 397 insertions(+), 219 deletions(-) diff --git a/docs/UserGuide.md b/docs/UserGuide.md index fe66c2d870..17f5160616 100644 --- a/docs/UserGuide.md +++ b/docs/UserGuide.md @@ -11,19 +11,44 @@ Format: `help` Expected output: ``` -Here are the list of commands you can use: -1. new - Add a bouquet -2. delete - Delete a bouquets -3. mybouquets - List current saved bouquets -4. info - Provide information on chosen flower -5. add /q /to - add flower to a bouquet -6. remove /q /from - remove flower from a bouquet -7. flowers - Shows a list of flowers that can be added into mybouquets -8. flowers - Shows a list of flowers associated with said occasion -9. occasion - Shows a list of occasions associated with available flowers -10. save - Saves a bouquet to an external .txt file -11. recommend - Recommends a bouquet based on the chosen occasion and colour -12. bye - Exits the programme +Here is the table showing a list of commands you can use: ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ +| No. | Command | Explanation | Example | ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ +| 1 | new | Add a bouquet | new Birthday Bouquet | ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ +| 2 | delete | Delete a bouquets | delete Birthday Bouquet | ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ +| 3 | mybouquets | List current saved bouquets | mybouquets | ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ +| 4 | info | Provide information on chosen flower | info Rose | ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ +| 5 | add /c (optional) /q | Add flower to a bouquet | add Rose /c Red /q 5 /to Birthday Bouquet | +| | /to | | | ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ +| 6 | remove /c (optional) /q | Remove flower from a bouquet | remove Rose /c Red /q 5 /from Birthday Bouquet | +| | /from | | | ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ +| 7 | flowers | Shows a list of flowers that can be | flowers | +| | | added into mybouquets | | ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ +| 8 | flowers | Shows a list of flowers associated | flowers Valentines | +| | | with said occasion | | ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ +| 9 | occasion | Shows a list of occasions associated | occasion | +| | | with available flowers | | ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ +| 10 | save | Saves a bouquet to an external | save Birthday Bouquet | +| | | .txt file | | ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ +| 11 | recommend | Recommends a bouquet based on the | recommend | +| | | chosen occasion and colour | | ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ +| 12 | compare <1st flowerName> /vs/ <2nd flowerName> | Show information regarding two flowers | compare Rose /vs/ Lily | +| | | side-by-side for comparison | | ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ +| 13 | bye | Exits the programme | bye | ++-----+----------------------------------------------------------+----------------------------------------+------------------------------------------------+ ``` ### Create a new bouquet: `new` @@ -118,12 +143,14 @@ Example: `info Lily` Expected Output: ``` -Here is page 1/1 of info regarding flowers whose name contains Lily: -1. Name: Lily -Colour: White -Occasions: Funeral, Wedding -Price: $2.50 -Meanings: Innocence +Here is a table of information about the flower Lily: ++-----+-------------+--------+--------------------+-------------+--------+-----------+ +| No. | Flower Name | Colour | Occasion | Meaning | Type | Price ($) | ++-----+-------------+--------+--------------------+-------------+--------+-----------+ +| 1 | Lily | White | [FUNERAL, WEDDING] | [Innocence] | FLOWER | 2.50 | ++-----+-------------+--------+--------------------+-------------+--------+-----------+ +| 2 | Lily | Orange | [] | [Hatred] | FLOWER | 2.50 | ++-----+-------------+--------+--------------------+-------------+--------+-----------+ ____________________________________________________________ ``` @@ -199,46 +226,46 @@ Recommends a bouquet based on the occasion and the recipient's preference Steps: 1. Type command: `recommend` -Expected output: -``` -For what occasion are you buying flowers for? -Here is the list of our available occasion: -Here are all the occasions associated with the available flowers: -- Funeral -- Wedding -- Valentines -- Mothers day -____________________________________________________________ -``` + Expected output: + ``` + For what occasion are you buying flowers for? + Here is the list of our available occasion: + Here are all the occasions associated with the available flowers: + - Funeral + - Wedding + - Valentines + - Mothers day + ____________________________________________________________ + ``` 2. Type occasion: `Funeral` - -Expected output: -``` -What colour would you like your bouquets to be? -Here is the list of colours available for the occasion: -- DARK_CRIMSON -- WHITE -``` + + Expected output: + ``` + What colour would you like your bouquets to be? + Here is the list of colours available for the occasion: + - DARK_CRIMSON + - WHITE + ``` 3. Select colour of bouquet: `WHITE` -Expected output: - -``` -Would you like to save this bouquet to your list? -Here is the full list of flowers in Recommended Bouquet: - - 3 x Lily - - 2 x Chrysanthemum -____________________________________________________________ -Type 'yes' to save, 'no' to discard -``` + Expected output: + + ``` + Would you like to save this bouquet to your list? + Here is the full list of flowers in Recommended Bouquet: + - 3 x Lily + - 2 x Chrysanthemum + ____________________________________________________________ + Type 'yes' to save, 'no' to discard + ``` 4. Confirm whether you want to add the recommended bouquet to your mybouquets list: `yes` - -``` -Added new bouquet to list: -Recommended Bouquet -____________________________________________________________ -``` + + ``` + Added new bouquet to list: + Recommended Bouquet + ____________________________________________________________ + ``` ### Save a bouquet to device: `save` Saves chosen bouquet, if it exists, locally to the users device @@ -255,6 +282,34 @@ Expected Output: Successfully saved moms bouquet. You can find it at 'florizz-out/saved/moms bouquet.txt' ``` +### Compare two flowers: `compare` +Compares the colour, occasion, meaning, type and price of flowers based on flower names + +Format: `compare /vs/ ` + +- Both flowers must exist in the database + +Examples: +- `compare Rose /vs/ Lily` + +Expected output: +``` +Here is a table of comparison between the two flowers: ++-----+-------------+--------------+------------------------------------+------------------------------------------+--------+-----------+ +| No. | Flower Name | Colour | Occasion | Meaning | Type | Price ($) | ++-----+-------------+--------------+------------------------------------+------------------------------------------+--------+-----------+ +| 1 | Rose | Dark crimson | [FUNERAL] | [Mourning] | FLOWER | 2.00 | ++-----+-------------+--------------+------------------------------------+------------------------------------------+--------+-----------+ +| 2 | Rose | Red | [VALENTINES, WEDDING, MOTHERS_DAY] | [Love] | FLOWER | 2.00 | ++-----+-------------+--------------+------------------------------------+------------------------------------------+--------+-----------+ +| 3 | Rose | Yellow | [] | [Jealousy, Decrease of love, Infidelity] | FLOWER | 2.00 | ++-----+-------------+--------------+------------------------------------+------------------------------------------+--------+-----------+ +| 4 | Lily | White | [FUNERAL, WEDDING] | [Innocence] | FLOWER | 2.50 | ++-----+-------------+--------------+------------------------------------+------------------------------------------+--------+-----------+ +| 5 | Lily | Orange | [] | [Hatred] | FLOWER | 2.50 | ++-----+-------------+--------------+------------------------------------+------------------------------------------+--------+-----------+ +``` + ### Exit programme: `bye` Exits the program. @@ -268,50 +323,49 @@ Enjoy your bouquet! Thank you for using Florizz! ### Fuzzy Logic -Florizz uses a type of fuzzy logic to rectifies typos in user input by utilising the Damerau-Levenshtein Distance -to measure the similarity between the user input and a valid command/item/occasion. +Florizz uses a type of fuzzy logic that rectifies typos in user input by utilising the Damerau-Levenshtein Distance +to measure the similarity between the user input and a valid command/flower/colour/occasion. The Damerau-Levenshtein distance measures the minimum number of single-character edits required to change one string into another. These edits can be insertions, deletions, substitutions and transpositions of individual characters. -When a typo is detected, Florizz will make a calculated guess as to the valid commands that a user is actually calling. +When a typo is detected, Florizz will make a calculated guess as to the valid command that a user is actually referring to. -Examples: -- `newq mybouquet1` -- `adds Chysanthenum /q 10 /to mybouquet1` -- `delate mybouquet1` +Examples of typos that Florizz can rectify include: + +1. Typo in spelling + - `flowerz Vlentine` + - `ads Ross /c ret /q 10 /to mybouquet1` +2. Incorrect placements of whitespaces + - `c o m p are R ose /v s/ L i ly` + - `m y b ouq ue ts` +3. Absence of whitespaces + - `flowersmothersday` + - `infoDaisy` Expected output: ``` -newq mybouquet1 ---> Your input is [newq] but I am guessing you mean [new] -Added new bouquet to list: -mybouquet1 -____________________________________________________________ -What can I do for you? +flowerz Vlentine +--> Your input is [flowerz] but I am guessing you mean [flowers] +--> Your input is [Vlentine] but I am guessing you mean [Valentines] ``` + ``` -adds Chysanthenum /q 10 /to mybouquet1 ---> Your input is [adds] but I am guessing you mean [add] ---> Your input is [Chysanthenum] but I am guessing you mean [Chrysanthemum] -You have successfully added the following: - - 10 x chrysanthemum -> Bouquet: mybouquet1 -Here is the list of your saved bouquets: -1. mybouquet1 : - - 10 x Chrysanthemum - Total estimated price = $10.00 -____________________________________________________________ -What can I do for you? +ads Ross /c ret /q 10 /to mybouquet1 +--> Your input is [ads] but I am guessing you mean [add] +--> Your input is [Ross] but I am guessing you mean [Rose] +--> Your input is [ret] but I am guessing you mean [Red] ``` ``` -delate mybouquet1 ---> Your input is [delate] but I am guessing you mean [delete] -Deleted bouquet: -mybouquet1 -____________________________________________________________ -What can I do for you? +c o m p are R ose /v s/ L i ly +--> Your input is [c o m p are R ose /v s/ L i ly] but I am guessing you mean [compare Rose /vs/ Lily] +``` + +``` +flowersmothersday +--> Your input is [flowersmothersday] but I am guessing you mean [flowers Mothers Day] ``` ### Autosave diff --git a/docs/team/jeffinsondarmawan.md b/docs/team/jeffinsondarmawan.md index 5602e1dc26..8ddebf4289 100644 --- a/docs/team/jeffinsondarmawan.md +++ b/docs/team/jeffinsondarmawan.md @@ -24,12 +24,14 @@ Code Contribution: [Jeffinson Darmawan RepoSense Report](https://nus-cs2113-ay23 `info Rose` where Florizz will show information regarding that flower. Suppose that a user mistakenly input `invo Ross` and another user mistakenly input `zjgh bfre`. Without Fuzzy Logic, both `invo Ross` and `zjgh bfre` will be regarded as equaly invalid commands and the programme will throw an exception. However, one can make a - strong case that `invo Ross` is definitely closer to `info Rose` compared to `zjgh bfre`. Thus, Fuzzy Logic helps - users by correcting their typos due to accidental human errors and increase the overall convenience of using the - programme. Imagine having to retype `adds Rose /q 1 /to Bouquet for My 3th Anniversary with My Girlfriend` because - of a small mistake of having an "s" after "add" and repeating this over and over again! - - + strong case that `invo Ross` is definitely closer to `info Rose` compared to `zjgh bfre`. + - Justification: + Fuzzy Logic helps + users by correcting their typos due to accidental human errors and increase the overall convenience of using the + programme. This feature is especially useful for users who are prone to making typos in their inputs. By implementing + Fuzzy Logic, Florizz is able to correct these typos and provide the user with the intended output thereby reducing + the effect of human errors.Imagine having to retype `adds Rose /q 1 /to Bouquet for My 3th Anniversary with My Girlfriend` + because of a small mistake of having an "s" after "add" and repeating this over and over again! - How it works: Fuzzy Logic in Florizz works primarily in 3 ways. Firstly, applying @@ -46,13 +48,29 @@ Code Contribution: [Jeffinson Darmawan RepoSense Report](https://nus-cs2113-ay23 2. Listing Available Occasion (Pull Request [#26](https://github.com/AY2324S2-CS2113-T11-3/tp/pull/26)) - What it is: - `Occasion` lists out all the occasions which are associated will all flowers in our database. This + `occasion` lists out all the occasions which are associated will all flowers in our database. This allows users to have a quick look at what occasions they can choose for their flowers. Once users know what occasion they can input `flowers ` to see all the flowers associated with the occasion of choosing. - + - Justification: + This feature is especially useful for users who are unsure of what flowers to choose for a specific occasion. 3. Help Command (Pull Request [#16](https://github.com/AY2324S2-CS2113-T11-3/tp/pull/16)) - What it is: `help` assists users in using Florizz by showing a quick list of commands that users can use. + - Justification: + This feature is especially useful for new users who are unfamiliar with the commands available in Florizz. + - Highlights: + This feature uses an ASCII table to increase readability of the list of available commands. +4. Compare Command + - What it is: + `compare` allows users to compare the colour, occasion, meaning, type and price of two flowers. + - Justification: + When deciding which flowers to add to a bouquet, users might find it difficult to compare between different flowers + as they need to separately call the `info` command for each flower. + Thus, this feature is especially useful for users who are deciding between two flowers and want to know the + differences between them. + - Highlights: + This feature required the implementation of a new command and the creation of a new class to handle the comparison of two flowers. + It also uses an ASCII table to increase readability of the comparison results. **Enhancements:** 1. Applying appropriate exceptions to ensure valid integer inputs in all commands involving integers @@ -70,5 +88,9 @@ Code Contribution: [Jeffinson Darmawan RepoSense Report](https://nus-cs2113-ay23 - Added UML diagrams and implementation details for `remove` and `help` 2. User Guide (Pull Request [#106](https://github.com/AY2324S2-CS2113-T11-3/tp/pull/106)) - - Added documentation on Fuzzy Logic - - Updated documentation on `help`, `new`, `add` and `remove` \ No newline at end of file + - Added documentation on `compare` and Fuzzy Logic + - Updated documentation on `help`, `new`, `add` and `remove` + +**Tools** +1. Integrated a third party JTextUtil library called "freva ascii-table" to create ASCII tables for the `help` +and `compare` commands. (Link to Github Page: [Freva ASCII Table](https://github.com/freva/ascii-table)) \ No newline at end of file diff --git a/src/main/java/florizz/command/CompareCommand.java b/src/main/java/florizz/command/CompareCommand.java index 098500161e..4ba9b06af4 100644 --- a/src/main/java/florizz/command/CompareCommand.java +++ b/src/main/java/florizz/command/CompareCommand.java @@ -13,12 +13,29 @@ public class CompareCommand extends Command { private String firstFlowerName; private String secondFlowerName; + /** + * Constructor for the CompareCommand class. + * + * @param firstFlowerName The name of the first flower to compare + * @param secondFlowerName The name of the second flower to compare + */ public CompareCommand(String firstFlowerName, String secondFlowerName) { this.firstFlowerName = firstFlowerName; this.secondFlowerName = secondFlowerName; } + /** + * Executes the CompareCommand by comparing two flowers. + * + * @param bouquetList The list of bouquets to search for the specified bouquet + * @param ui The user interface to interact with the user + * @return True if the command is executed successfully, false otherwise + */ public boolean execute(ArrayList bouquetList, Ui ui) throws FlorizzException { + if (firstFlowerName.equals(secondFlowerName)) { + throw new FlorizzException("Unable to compare a flower with itself. Please input different flowers"); + } + ArrayList firstFilteredFlowers = FlowerDictionary.filterByName(firstFlowerName); ArrayList secondFilteredFlowers = FlowerDictionary.filterByName(secondFlowerName); diff --git a/src/main/java/florizz/command/InfoCommand.java b/src/main/java/florizz/command/InfoCommand.java index 4ab73b90be..7bde343326 100644 --- a/src/main/java/florizz/command/InfoCommand.java +++ b/src/main/java/florizz/command/InfoCommand.java @@ -30,7 +30,6 @@ public boolean execute(ArrayList bouquetList, Ui ui) throws FlorizzExce } else{ ui.printFlowerInfo(filteredFlowers, flowerName, 1); } - return true; } } diff --git a/src/main/java/florizz/core/FlowerDictionary.java b/src/main/java/florizz/core/FlowerDictionary.java index b41b02dc0f..ade46cdbd3 100644 --- a/src/main/java/florizz/core/FlowerDictionary.java +++ b/src/main/java/florizz/core/FlowerDictionary.java @@ -60,21 +60,21 @@ public static void startup() { // [Fillers have yet to be implemented] add("Baby Breath", "White", new String[]{"Wedding", "Valentines", "Mothers Day"}, 1.00, new String[]{"Innocence", "Kindness", "Care", "Humble"}, Flower.Type.FLOWER); - add("Eucalyptus", "Green", new String[]{"Wedding"}, 1.5, new String[]{"Love", "Kindness"}, Flower.Type.FLOWER); - add("Dusty Miller", "Green", new String[]{}, 1.5, new String[]{}, Flower.Type.FILLER); - add("Pistacia", "Green", new String[]{}, 1.5, new String[]{}, Flower.Type.FILLER); - add("Pittosporum", "Green", new String[]{}, 1.5, new String[]{}, Flower.Type.FILLER); - add("Chamomile", "White", new String[]{}, 1.9, new String[]{}, Flower.Type.FILLER); - add("Astilbe", "Pink", new String[]{}, 2.8, new String[]{}, Flower.Type.FILLER); - add("Hypericum", "Red", new String[]{}, 2.0, new String[]{}, Flower.Type.FILLER); - add("Freesia", "White", new String[]{}, 1.9, new String[]{}, Flower.Type.FILLER); - add("Helichrysum", "Yellow", new String[]{}, 1.5, new String[]{}, Flower.Type.FILLER); - add("Limonium", "Red", new String[]{}, 1.8, new String[]{}, Flower.Type.FILLER); - add("Limonium", "Dark Crimson", new String[]{}, 1.8, new String[]{}, Flower.Type.FILLER); - add("Limonium Perezii", "Purple", new String[]{}, 1.8, new String[]{}, Flower.Type.FILLER); - add("Statice", "Blue", new String[]{}, 1.5, new String[]{}, Flower.Type.FILLER); - add("Statice", "Purple", new String[]{}, 1.5, new String[]{}, Flower.Type.FILLER); - add("Rice Flower", "Pink", new String[]{}, 1.8, new String[]{}, Flower.Type.FILLER); + add("Eucalyptus", "Green", new String[]{"Wedding"}, 1.50, new String[]{"Love", "Kindness"}, Flower.Type.FLOWER); + add("Dusty Miller", "Green", new String[]{}, 1.50, new String[]{}, Flower.Type.FILLER); + add("Pistacia", "Green", new String[]{}, 1.50, new String[]{}, Flower.Type.FILLER); + add("Pittosporum", "Green", new String[]{}, 1.50, new String[]{}, Flower.Type.FILLER); + add("Chamomile", "White", new String[]{}, 1.90, new String[]{}, Flower.Type.FILLER); + add("Astilbe", "Pink", new String[]{}, 2.80, new String[]{}, Flower.Type.FILLER); + add("Hypericum", "Red", new String[]{}, 2.00, new String[]{}, Flower.Type.FILLER); + add("Freesia", "White", new String[]{}, 1.90, new String[]{}, Flower.Type.FILLER); + add("Helichrysum", "Yellow", new String[]{}, 1.50, new String[]{}, Flower.Type.FILLER); + add("Limonium", "Red", new String[]{}, 1.80, new String[]{}, Flower.Type.FILLER); + add("Limonium", "Dark Crimson", new String[]{}, 1.80, new String[]{}, Flower.Type.FILLER); + add("Limonium Perezii", "Purple", new String[]{}, 1.80, new String[]{}, Flower.Type.FILLER); + add("Statice", "Blue", new String[]{}, 1.50, new String[]{}, Flower.Type.FILLER); + add("Statice", "Purple", new String[]{}, 1.50, new String[]{}, Flower.Type.FILLER); + add("Rice Flower", "Pink", new String[]{}, 1.80, new String[]{}, Flower.Type.FILLER); } /** diff --git a/src/main/java/florizz/core/FuzzyLogic.java b/src/main/java/florizz/core/FuzzyLogic.java index 44ef0fa2d1..c46ad7277d 100644 --- a/src/main/java/florizz/core/FuzzyLogic.java +++ b/src/main/java/florizz/core/FuzzyLogic.java @@ -60,6 +60,14 @@ public class FuzzyLogic { ITEMS.put("Limonium Perezii", "Flower"); ITEMS.put("Statice", "Flower"); ITEMS.put("Rice Flower", "Flower"); + ITEMS.put("Red", "Colour"); + ITEMS.put("Yellow", "Colour"); + ITEMS.put("White", "Colour"); + ITEMS.put("Blue", "Colour"); + ITEMS.put("Pink", "Colour"); + ITEMS.put("Green", "Colour"); + ITEMS.put("Purple", "Colour"); + ITEMS.put("Dark Crimson", "Colour"); } /** @@ -75,7 +83,7 @@ protected static String detectItem(String userInput) throws FlorizzException { } if (userInput.length() == 1) { - throw new FlorizzException("No matching command/item/occasion found for input: " + userInput); + throw new FlorizzException("No matching command/flower/occasion/colour match the input: " + userInput); } String bestMatch = null; @@ -175,6 +183,7 @@ protected static String processCommand(String userInput) throws FlorizzException } String correctedInput; String trimmedInput = userInput.trim(); + String[] words = trimmedInput.split(" "); int firstWhitespace = trimmedInput.indexOf(" "); if ((firstWhitespace != -1) && (userInput.startsWith("delete") @@ -183,7 +192,7 @@ protected static String processCommand(String userInput) throws FlorizzException || userInput.startsWith("remove") || userInput.startsWith("add") || userInput.startsWith("info") - || userInput.startsWith("compare") + || (userInput.startsWith("compare") && words.length == 4 || words.length == 5) || userInput.startsWith("flowers"))) { String[] arguments = new String[2]; arguments[0] = userInput.substring(0,firstWhitespace).toLowerCase(); @@ -213,87 +222,82 @@ protected static String processCommand(String userInput) throws FlorizzException * @throws FlorizzException if there is an issue processing the input. */ protected static String splitAndMergeInput(String userInput) throws FlorizzException { - try { - String correctedInput; - String mergedInput = mergeInput(userInput); - String splitMergedInput = splitInput(mergedInput); - String[] arguments = splitMergedInput.split(" "); - String bouquetName; - String removeArgument; - String addArgument; - Ui uiFuzzy = new Ui(); + String correctedInput; + String mergedInput = mergeInput(userInput); + String splitMergedInput = splitInput(mergedInput); + String[] arguments = splitMergedInput.split(" "); + String bouquetName; + String removeArgument; + String addArgument; + Ui uiFuzzy = new Ui(); - if (arguments.length == 1 && arguments[0] - .matches("(mybouquets|flowers|occasion|recommend|bye|help|back|next)")) { - correctedInput = arguments[0]; - uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); - } else if (arguments[0].matches("(info|flowers)")) { - if (Objects.equals(arguments[1].toLowerCase(), "mothersday")) { - arguments[1] = "Mothers Day"; - } - correctedInput = arguments[0] + " " + arguments[1]; - uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); - } else if (arguments[0].matches("(new)")) { - bouquetName = userInput.replaceFirst("n", "") - .replaceFirst("e", "") - .replaceFirst("w", "") - .strip(); - correctedInput = "new " + bouquetName; - uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); - } else if (arguments[0].matches("(delete)")) { - bouquetName = userInput.replaceFirst("d", "") - .replaceFirst("e", "") - .replaceFirst("l", "") - .replaceFirst("e", "") - .replaceFirst("t", "") - .replaceFirst("e", "") - .strip(); - correctedInput = "delete " + bouquetName; - uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); - } else if (arguments[0].matches("(save)")) { - bouquetName = userInput.replaceFirst("s", "") - .replaceFirst("a", "") - .replaceFirst("v", "") - .replaceFirst("e", "") - .strip(); - correctedInput = "save " + bouquetName; - uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); - } else if (arguments[0].matches("(remove)")) { - removeArgument = userInput.replaceFirst("r", "") - .replaceFirst("e", "") - .replaceFirst("m", "") - .replaceFirst("o", "") - .replaceFirst("v", "") - .replaceFirst("e", "") - .strip(); - correctedInput = "remove " + removeArgument; - uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); - } else if (arguments[0].matches("(add)")) { - addArgument = userInput.replaceFirst("a", "") - .replaceFirst("d", "") - .replaceFirst("d", "") - .strip(); - correctedInput = "add " + addArgument; - uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); - } else if (arguments[0].matches("(compare)")) { - String argument = userInput.replaceFirst("c", "") - .replaceFirst("o", "") - .replaceFirst("m", "") - .replaceFirst("p", "") - .replaceFirst("a", "") - .replaceFirst("r", "") - .replaceFirst("e", "") - .strip(); - String[] flowerNames = argument.split("/vs/"); - correctedInput = "compare " + flowerNames[0] + " /vs/ " + flowerNames[1]; - uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); - } else { - correctedInput = userInput; + if (arguments[0] == null) { + throw new FlorizzException("Input cannot be empty."); + } + + if (arguments.length == 1 && arguments[0] + .matches("(mybouquets|flowers|occasion|recommend|bye|help|back|next)")) { + correctedInput = arguments[0]; + uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); + } else if (arguments[0].matches("(info|flowers)")) { + if (Objects.equals(arguments[1].toLowerCase(), "mothersday")) { + arguments[1] = "Mothers Day"; + } + correctedInput = arguments[0] + " " + arguments[1]; + uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); + } else if (arguments[0].matches("(new)")) { + bouquetName = userInput.replaceFirst("n", "") + .replaceFirst("e", "") + .replaceFirst("w", "") + .strip(); + correctedInput = "new " + bouquetName; + uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); + } else if (arguments[0].matches("(delete)")) { + bouquetName = userInput.replaceFirst("d", "") + .replaceFirst("e", "") + .replaceFirst("l", "") + .replaceFirst("e", "") + .replaceFirst("t", "") + .replaceFirst("e", "") + .strip(); + correctedInput = "delete " + bouquetName; + uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); + } else if (arguments[0].matches("(save)")) { + bouquetName = userInput.replaceFirst("s", "") + .replaceFirst("a", "") + .replaceFirst("v", "") + .replaceFirst("e", "") + .strip(); + correctedInput = "save " + bouquetName; + uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); + } else if (arguments[0].matches("(remove)")) { + removeArgument = userInput.replaceFirst("r", "") + .replaceFirst("e", "") + .replaceFirst("m", "") + .replaceFirst("o", "") + .replaceFirst("v", "") + .replaceFirst("e", "") + .strip(); + correctedInput = "remove " + removeArgument; + uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); + } else if (arguments[0].matches("(add)")) { + addArgument = userInput.replaceFirst("a", "") + .replaceFirst("d", "") + .replaceFirst("d", "") + .strip(); + correctedInput = "add " + addArgument; + uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); + } else if (arguments[0].matches("(compare)")) { + String[] flowerNames = arguments[1].split("/vs/"); + if (flowerNames.length != 2 || flowerNames[0].length() <= 2 || flowerNames[1].length() <= 2) { + throw new FlorizzException("Please input 2 flowers to compare."); } - return correctedInput; - } catch (Exception e) { - throw new FlorizzException("Error processing input: " + e.getMessage()); + correctedInput = "compare " + flowerNames[0].strip() + " /vs/ " + flowerNames[1].strip(); + uiFuzzy.printFuzzyInputDetection(userInput, correctedInput); + } else { + correctedInput = userInput; } + return correctedInput; } /** diff --git a/src/main/java/florizz/core/Parser.java b/src/main/java/florizz/core/Parser.java index d860470bdb..29b1f2470b 100644 --- a/src/main/java/florizz/core/Parser.java +++ b/src/main/java/florizz/core/Parser.java @@ -283,12 +283,13 @@ private static AddFlowerCommand handleAddFlower(String argument, boolean enableU String bouquetName = removePrefix(argument.substring(prefixIndex), ADD_FLOWER_PREFIX).trim(); if (includeColour) { int colourIndex = argument.indexOf(COLOUR); - try{ + try { flowerName = argument.substring(0,colourIndex).trim(); - String colourString = removePrefix(argument.substring(colourIndex, quantityIndex), COLOUR).trim(); + String colourString = FuzzyLogic.detectItem( + removePrefix(argument.substring(colourIndex, quantityIndex), COLOUR).trim()); Flower.Colour colourToAdd = Flower.stringToColour(colourString); return new AddFlowerCommand(flowerName, colourToAdd, quantity, bouquetName, enableUi); - } catch( IllegalArgumentException error){ + } catch ( IllegalArgumentException error) { throw new FlorizzException("Tried to add a non recognised colour" + "Type 'flowers' to view all the currently available flowers and their colours."); } diff --git a/src/main/java/florizz/core/Ui.java b/src/main/java/florizz/core/Ui.java index e459cbcff0..d9ebac3759 100644 --- a/src/main/java/florizz/core/Ui.java +++ b/src/main/java/florizz/core/Ui.java @@ -129,7 +129,7 @@ public void printFullBouquet(Bouquet bouquet) { */ public void printHelpMessage() { lastCommand = "OTHERS"; - System.out.println("Here is the table of commands you can use:"); + System.out.println("Here is the table showing a list of commands you can use:"); List tableData = Arrays.asList( new TableData(1, "new " , "Add a bouquet" @@ -144,7 +144,7 @@ public void printHelpMessage() { , "Provide information on chosen flower" , "info Rose"), new TableData(5, "add /c (optional) /q /to " - , "Sdd flower to a bouquet" + , "Add flower to a bouquet" , "add Rose /c Red /q 5 /to Birthday Bouquet"), new TableData(6, "remove /c (optional) /q /from " , "Remove flower from a bouquet" @@ -166,7 +166,7 @@ public void printHelpMessage() { , "recommend"), new TableData(12, "compare <1st flowerName> /vs/ <2nd flowerName>" , "Show information regarding two flowers side-by-side for comparison" - , "compare Rose vs Lily"), + , "compare Rose /vs/ Lily"), new TableData(13, "bye" , "Exits the programme" , "bye") @@ -201,9 +201,6 @@ public void printExitMessage() { printBreakLine(); } - private static void printNextOrBack(int pageNo, int maxPages){ - - } /** * Prints a list of flowers with optional additional information. * @@ -260,14 +257,23 @@ public void printFilteredFlowers(ArrayList flowers, String filter, int p * @param targetFlower The name of the flower the user searched for. * @param flowers The list of flowers that contain that name. */ - public void printFlowerInfo(ArrayList flowers, String targetFlower, int pageNo) { - lastShownList = flowers; - lastPageNo = pageNo; - lastCommand = "INFO_FLOWERS " + targetFlower; - int maxPages = (int) Math.ceil((double)lastShownList.size() / PAGE_SIZE); - System.out.println("Here is page " + lastPageNo + "/" + maxPages + - " of info regarding flowers whose name contains " + targetFlower + ":"); - printFlowerList(true); + public void printFlowerInfo(ArrayList flowers, String targetFlower, int pageNo) throws FlorizzException { + List tableData = new ArrayList<>(List.of()); + int id = 1; + + for (Flower flower : flowers) { + tableData.add(new TableData(id, flower.getFlowerName(), flower.getColour(), flower.getOccasion().toString(), + flower.getMeanings().toString(), String.format("%.2f", flower.getPrice()) + , flower.getType().toString())); + id++; + } + System.out.println("Here is a table of information about the flower " + targetFlower + ":"); + try { + printFlowersTable(tableData); + printBreakLine(); + } catch (FlorizzException error){ + printError(error); + } } /** @@ -479,7 +485,7 @@ public void printSaveSuccess(String bouquetName) { * @param flowerName The name of the flower that the user is trying to choose its colour from * @return Flower the specific Flower with the correct colour. Is blank if user chose to cancel the command instead */ - public Flower chooseColour(ArrayList flowers, String flowerName){ + public Flower chooseColour(ArrayList flowers, String flowerName) throws FlorizzException { printGetFlowerColour(flowers, flowerName); while (true){ @@ -522,22 +528,67 @@ public Flower chooseColour(ArrayList flowers, String flowerName){ * @param flowers The list of flowers containing the flower with multiple colors * @param flowerName The name of the flower with multiple colors */ - public void printGetFlowerColour(ArrayList flowers, String flowerName){ + public void printGetFlowerColour(ArrayList flowers, String flowerName) throws FlorizzException { System.out.println("The flower you're looking for has more than one colour available, " + - "each with their own vastly different meanings. Here's some info:"); + "each with their own vastly different meanings."); printFlowerInfo(flowers, flowerName, 1); System.out.println("Type the colour you want to add into the bouquet, or 'cancel' to return to the main menu."); } - public void printCompareFlowers(ArrayList firstFilteredFlowers, ArrayList secondFilteredFlowers) { - System.out.println("Here is the comparison between the two flowers:"); - System.out.println("First flower: " + firstFilteredFlowers.get(0).getNameAndColour()); - System.out.println("Second flower: " + secondFilteredFlowers.get(0).getNameAndColour()); - System.out.println("Price: $" + firstFilteredFlowers.get(0).getPrice() + " vs $" + secondFilteredFlowers.get(0).getPrice()); - System.out.println("Meanings: " + firstFilteredFlowers.get(0).getMeanings() + " vs " + secondFilteredFlowers.get(0).getMeanings()); + + /** + * Prints a table comparing two flowers. + */ + public void printCompareFlowers(ArrayList firstFilteredFlowers, ArrayList secondFilteredFlowers) + throws FlorizzException { + List tableData = new ArrayList<>(List.of()); + int id = 1; + + for (Flower flower : firstFilteredFlowers) { + tableData.add(new TableData(id, flower.getFlowerName(), flower.getColour(), flower.getOccasion().toString(), + flower.getMeanings().toString(), String.format("%.2f", flower.getPrice()) + , flower.getType().toString())); + id++; + } + for (Flower flower : secondFilteredFlowers) { + tableData.add(new TableData(id, flower.getFlowerName(), flower.getColour(), flower.getOccasion().toString(), + flower.getMeanings().toString(), String.format("%.2f", flower.getPrice()) + , flower.getType().toString())); + id++; + } + printBreakLine(); + System.out.println("Here is a table of comparison between the two flowers:"); + printFlowersTable(tableData); printBreakLine(); } + /** + * Prints a table of flowers. + * + * @param tableData The list of flowers to be printed in a table + * @throws FlorizzException If there are no flowers to display + */ + protected void printFlowersTable(List tableData) throws FlorizzException{ + if (tableData.isEmpty()){ + throw new FlorizzException("No flowers to display."); + } + System.out.println(AsciiTable.getTable(tableData, Arrays.asList( + new Column().header("No.").dataAlign(HorizontalAlign.CENTER) + .with((TableData data) -> Integer.toString(data.getId())), + new Column().header("Flower Name").dataAlign(HorizontalAlign.LEFT) + .with(TableData::getFlowerName), + new Column().header("Colour").dataAlign(HorizontalAlign.LEFT) + .with(TableData::getFlowerColor), + new Column().header("Occasion").dataAlign(HorizontalAlign.LEFT) + .with(TableData::getFlowerOccasion), + new Column().header("Meaning").dataAlign(HorizontalAlign.LEFT) + .with(TableData::getFlowerMeaning), + new Column().header("Type").dataAlign(HorizontalAlign.LEFT) + .with(TableData::getType), + new Column().header("Price ($)").dataAlign(HorizontalAlign.RIGHT) + .with(TableData::getFlowerPrice)))); + } + /** * Prints a message indicating that the command has been canceled and the user is returning to the main menu. */ diff --git a/src/main/java/florizz/objects/Flower.java b/src/main/java/florizz/objects/Flower.java index b647bba6aa..37436265fd 100644 --- a/src/main/java/florizz/objects/Flower.java +++ b/src/main/java/florizz/objects/Flower.java @@ -236,6 +236,10 @@ public String toString() { finalMeaning); } + public Type getType() { + return type; + } + @Override public boolean equals(Object obj) { if (obj == this) { diff --git a/src/main/java/florizz/objects/TableData.java b/src/main/java/florizz/objects/TableData.java index 6ac105def7..ad1f824441 100644 --- a/src/main/java/florizz/objects/TableData.java +++ b/src/main/java/florizz/objects/TableData.java @@ -10,6 +10,7 @@ public class TableData { private String flowerPrice; private String flowerColor; private String flowerMeaning; + private String type; public TableData(int id, String command, String explanation, String example) { this.id = id; @@ -18,13 +19,15 @@ public TableData(int id, String command, String explanation, String example) { this.example = example; } - public TableData(String flowerName, String flowerOccasion, String flowerPrice - , String flowerColor, String flowerMeaning) { + public TableData(int id, String flowerName, String flowerColor, String flowerOccasion, + String flowerMeaning, String flowerPrice, String type) { + this.id = id; this.flowerName = flowerName; this.flowerOccasion = flowerOccasion; - this.flowerPrice = flowerPrice; this.flowerColor = flowerColor; this.flowerMeaning = flowerMeaning; + this.flowerPrice = flowerPrice; + this.type = type; } public int getId() { @@ -42,4 +45,27 @@ public String getExplanation() { public String getExample() { return example; } + + public String getFlowerName() { + return flowerName; + } + + public String getFlowerOccasion() { + return flowerOccasion; + } + + public String getFlowerPrice() { + return flowerPrice; + } + + public String getFlowerColor() { + return flowerColor; + } + + public String getFlowerMeaning() { + return flowerMeaning; + } + public String getType() { + return type; + } }