From 1566961fed1a694b9ac7d861a6106dea7c58a1d2 Mon Sep 17 00:00:00 2001 From: Jeffinson Darmawan Date: Tue, 9 Apr 2024 02:10:34 +0800 Subject: [PATCH 1/5] Fuzzy Logic Improvement --- .../florizz/command/RecommendCommand.java | 2 +- src/main/java/florizz/core/FuzzyLogic.java | 52 ++++++++++++++++++- src/main/java/florizz/core/Parser.java | 23 ++++---- 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/main/java/florizz/command/RecommendCommand.java b/src/main/java/florizz/command/RecommendCommand.java index 13354636b3..6f422cc47d 100644 --- a/src/main/java/florizz/command/RecommendCommand.java +++ b/src/main/java/florizz/command/RecommendCommand.java @@ -91,7 +91,7 @@ private void addRandomFlowers(ArrayList eligibleFlowers, Bouquet recomme * Asks user for occasion * @return Occasion enum */ - private Flower.Occasion askOccasion(Ui ui) { + private Flower.Occasion askOccasion(Ui ui) throws FlorizzException { logger.entering(RecommendCommand.class.getName(), "askOccasion"); boolean isValidFormat = false; boolean isValidOccasion = false; diff --git a/src/main/java/florizz/core/FuzzyLogic.java b/src/main/java/florizz/core/FuzzyLogic.java index 5ccf1ed86d..292de26e03 100644 --- a/src/main/java/florizz/core/FuzzyLogic.java +++ b/src/main/java/florizz/core/FuzzyLogic.java @@ -51,11 +51,15 @@ public class FuzzyLogic { * @return The closest matching command/item/occasion. * @throws FlorizzException if the input is null or no matching command/item/occasion is found. */ - public static String detectItem(String userInput) throws FlorizzException { + protected static String detectItem(String userInput) throws FlorizzException { if (userInput == null) { throw new FlorizzException("Input cannot be null"); } + if (userInput.length() == 1) { + throw new FlorizzException("No matching command/item/occasion found for input: " + userInput); + } + String bestMatch = null; int bestDistance = Integer.MAX_VALUE; Ui uiFuzzy = new Ui(); @@ -133,4 +137,50 @@ private static int computeDLDistance(String item, String userInput) { assert previousRow[n] >= 0 : "Levenshtein distance cannot be negative"; return previousRow[n]; } + + /** + * Separates the input string into a command and an argument. + * If the input string matches a predefined command pattern, it corrects the input by adding a space between the + * command and the argument. + * Supported commands include: info, delete, flowers, new, add, remove, save. + * If the input does not match any predefined command pattern, it returns the original input string unchanged. + * + * @param userInput The input string to be separated and corrected. + * @return correctedInput The input with a space between the command and the argument if applicable. + * @throws FlorizzException if the input string is null. + */ + protected static String separateInput(String userInput) throws FlorizzException { + if (userInput == null) { + throw new FlorizzException("Input cannot be empty."); + } + + String correctedInput = ""; + if (userInput.matches("(info)[a-zA-Z].*")) { + String argumentInfo = userInput.replaceAll("(info)", ""); + correctedInput = "info " + argumentInfo; + } else if (userInput.matches("(delete)[a-zA-Z].*")) { + String argumentDelete = userInput.replaceAll("(delete)", ""); + correctedInput = "delete " + argumentDelete; + } else if (userInput.matches("(flowers)[a-zA-Z].*")) { + String argumentFlowers = userInput.replaceAll("(flowers)", ""); + correctedInput = "flowers " + argumentFlowers; + } else if (userInput.matches("(new)[a-zA-Z].*")) { + String argumentNew = userInput.replaceAll("(new)", ""); + correctedInput = "new " + argumentNew; + } else if (userInput.matches("(add)[a-zA-Z].*")) { + String argumentAdd = userInput.replaceAll("(add)", ""); + correctedInput = "add " + argumentAdd; + } else if (userInput.matches("(remove)[a-zA-Z].*")) { + String argumentRemove = userInput.replaceAll("(remove)", ""); + correctedInput = "remove " + argumentRemove; + } else if (userInput.matches("(save)[a-zA-Z].*")) { + String argumentSave = userInput.replaceAll("(save)", ""); + correctedInput = "save " + argumentSave; + } + + if (correctedInput.isEmpty()) { + correctedInput = userInput; + } + return correctedInput; + } } diff --git a/src/main/java/florizz/core/Parser.java b/src/main/java/florizz/core/Parser.java index e707c65cf0..435de5adc2 100644 --- a/src/main/java/florizz/core/Parser.java +++ b/src/main/java/florizz/core/Parser.java @@ -50,10 +50,10 @@ public static Command parse (String input, boolean enableUi) throws FlorizzExcep command = new ListBouquetCommand(); break; case ("new"): - command = handleAddBouquet(input, enableUi); + command = handleAddBouquet(decodedInput[1], enableUi); break; case ("delete"): - command = handleDeleteBouquet(input); + command = handleDeleteBouquet(decodedInput[1]); break; case ("bye"): command = new ExitCommand(); @@ -105,13 +105,14 @@ public static Command parse (String input, boolean enableUi) throws FlorizzExcep /** * Splits input into command and arguments (if any). Handles capitalisation, whitespaces and small typos. * - * @param input + * @param input The user input where command is to be extracted * @return String[] output; output[0] = item ; output[1] = argument(s) */ public static String[] commandHandler(String input) throws FlorizzException { String[] outputs = new String[2]; String trimmedInput = input.trim(); - int firstWhitespace = trimmedInput.indexOf(" "); + String separatedInput = FuzzyLogic.separateInput(trimmedInput); + int firstWhitespace = separatedInput.indexOf(" "); if (firstWhitespace != -1) { outputs[0] = FuzzyLogic.detectItem(trimmedInput.substring(0,firstWhitespace).toLowerCase()); @@ -156,8 +157,8 @@ public static String[] commandHandler(String input) throws FlorizzException { * remove prefix from an input string * e.g. "/to For Mom" -> " For Mom" * - * @param input - * @param prefix + * @param input The argument + * @param prefix The keyword that identifies the argument * @return input with prefix removed */ public static String removePrefix(String input, String prefix) { @@ -171,10 +172,10 @@ public static String removePrefix(String input, String prefix) { * @throws FlorizzException If the input does not contain the required bouquet information. */ private static AddBouquetCommand handleAddBouquet(String input, boolean enableUi) throws FlorizzException{ - if (!input.contains(" ")){ + if (input == null){ throw new FlorizzException("Did not include bouquet to add"); } - String newBouquetName = input.substring(input.indexOf(" ") + 1).trim(); + String newBouquetName = input.trim(); return new AddBouquetCommand(new Bouquet(newBouquetName), enableUi); } @@ -185,11 +186,10 @@ private static AddBouquetCommand handleAddBouquet(String input, boolean enableUi * @throws FlorizzException If the input does not contain the required bouquet information. */ private static DeleteBouquetCommand handleDeleteBouquet(String input) throws FlorizzException{ - if (!input.contains(" ")){ + if (input == null){ throw new FlorizzException("Did not include bouquet to delete"); } - String bouquetToDelete = input.substring(input.indexOf(" ") + 1).trim(); - + String bouquetToDelete = input.trim(); return new DeleteBouquetCommand(new Bouquet(bouquetToDelete)); } @@ -281,7 +281,6 @@ private static InfoCommand handleInfoCommand(String flowerName) throws FlorizzEx * Parses the occasion from the user input. * @param argument The user input to be parsed. * @return The parsed occasion. - * @throws FlorizzException If the input does not match the required format. */ public static boolean parseOccasion(String argument) { if (argument == null) { From bc23e3d8c42379f4f722f4e4c38e1560aed8de07 Mon Sep 17 00:00:00 2001 From: Jeffinson Darmawan Date: Wed, 10 Apr 2024 02:23:47 +0800 Subject: [PATCH 2/5] fuzzy logic enhancement --- src/main/java/florizz/core/FuzzyLogic.java | 123 +++++++++++++++++---- src/main/java/florizz/core/Parser.java | 17 ++- src/main/java/florizz/core/Ui.java | 30 +++-- 3 files changed, 128 insertions(+), 42 deletions(-) diff --git a/src/main/java/florizz/core/FuzzyLogic.java b/src/main/java/florizz/core/FuzzyLogic.java index 292de26e03..3de791d6e9 100644 --- a/src/main/java/florizz/core/FuzzyLogic.java +++ b/src/main/java/florizz/core/FuzzyLogic.java @@ -1,5 +1,6 @@ package florizz.core; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; @@ -81,7 +82,7 @@ protected static String detectItem(String userInput) throws FlorizzException { } else if (bestDistance == 0) { return bestMatch; } else { - logger.log(Level.WARNING, "No matching command/item/occasion found for input: {0}", userInput); + logger.log(Level.SEVERE, "No matching command/item/occasion found for input: {0}", userInput); throw new FlorizzException("No matching command/item/occasion found for input: " + userInput); } } @@ -98,22 +99,22 @@ protected static String detectItem(String userInput) throws FlorizzException { private static int computeDLDistance(String item, String userInput) { assert item != null && userInput != null : "Strings cannot be null"; - int m = item.length(); - int n = userInput.length(); + int itemLength = item.length(); + int inputLength = userInput.length(); - int[] previousRow = new int[n + 1]; - int[] currentRow = new int[n + 1]; + int[] previousRow = new int[inputLength + 1]; + int[] currentRow = new int[inputLength + 1]; // Initialize the first row - for (int j = 0; j <= n; j++) { + for (int j = 0; j <= inputLength; j++) { previousRow[j] = j; } // Calculate the Damerau-Levenshtein distance - for (int i = 1; i <= m; i++) { + for (int i = 1; i <= itemLength; i++) { currentRow[0] = i; - for (int j = 1; j <= n; j++) { + for (int j = 1; j <= inputLength; j++) { int substitutionCost = (item.charAt(i - 1) == userInput.charAt(j - 1)) ? 0 : 1; currentRow[j] = Math.min(Math.min( previousRow[j] + 1, // deletion @@ -134,8 +135,78 @@ private static int computeDLDistance(String item, String userInput) { } // Return the Damerau-Levenshtein distance - assert previousRow[n] >= 0 : "Levenshtein distance cannot be negative"; - return previousRow[n]; + assert previousRow[inputLength] >= 0 : "Levenshtein distance cannot be negative"; + return previousRow[inputLength]; + } + + // doesnt account for deletes abc --> something must be done before split and merge input + // my bouquets + // + + protected static String processCommand(String userInput) throws FlorizzException { + if (userInput == null) { + throw new FlorizzException("Input cannot be empty."); + } + String correctedInput = splitAndMergeInput(userInput); + return correctedInput; + } + + protected static String splitAndMergeInput(String userInput) throws FlorizzException { + String correctedInput = ""; + String mergedInput = mergeInput(userInput); + String splitMergedInput = splitInput(mergedInput); + String[] arguments = splitMergedInput.split(" "); + System.out.println(Arrays.toString(arguments)); + String bouquetName = ""; + String removeArgument = ""; + String addArgument = ""; + + if (arguments.length == 1 && !arguments[0].matches("(mybouquets|flowers|occasion|recommend|bye|help)")) { + correctedInput = userInput; + } else if (arguments[0].matches("(mybouquets|flowers|occasion|recommend|bye|help)")) { + correctedInput = detectItem(mergedInput); + } else if (arguments[0].matches("(info|flowers)")) { + correctedInput = detectItem(arguments[0]) + " " + detectItem(arguments[1]); + } else if (arguments[0].matches("(new)")) { + bouquetName = userInput.replace("n", "") + .replace("e", "") + .replace("w", "") + .strip(); + correctedInput = "new " + bouquetName; + } else if (arguments[0].matches("(delete)")) { + bouquetName = userInput.replace("d", "") + .replace("e", "") + .replace("l", "") + .replace("e", "") + .replace("t", "") + .replace("e", "") + .strip(); + correctedInput = "delete " + bouquetName; + } else if (arguments[0].matches("(save)")) { + bouquetName = userInput.replace("s", "") + .replace("a", "") + .replace("v", "") + .replace("e", "") + .strip(); + correctedInput = "save " + bouquetName; + } else if (arguments[0].matches("(remove)")) { + removeArgument = userInput.replace("r", "") + .replace("e", "") + .replace("m", "") + .replace("o", "") + .replace("v", "") + .replace("e", "") + .strip(); + correctedInput = "remove " + removeArgument; + } else if (arguments[0].matches("(add)")) { + addArgument = userInput.replace("a", "") + .replace("d", "") + .replace("d", "") + .strip(); + correctedInput = "add " + addArgument; + } + System.out.println(correctedInput); + return correctedInput; } /** @@ -149,7 +220,7 @@ private static int computeDLDistance(String item, String userInput) { * @return correctedInput The input with a space between the command and the argument if applicable. * @throws FlorizzException if the input string is null. */ - protected static String separateInput(String userInput) throws FlorizzException { + protected static String splitInput(String userInput) throws FlorizzException { if (userInput == null) { throw new FlorizzException("Input cannot be empty."); } @@ -158,23 +229,25 @@ protected static String separateInput(String userInput) throws FlorizzException if (userInput.matches("(info)[a-zA-Z].*")) { String argumentInfo = userInput.replaceAll("(info)", ""); correctedInput = "info " + argumentInfo; - } else if (userInput.matches("(delete)[a-zA-Z].*")) { - String argumentDelete = userInput.replaceAll("(delete)", ""); + } else if (userInput.matches("(delete).+")) { + String argumentDelete = userInput.replace("delete", ""); correctedInput = "delete " + argumentDelete; } else if (userInput.matches("(flowers)[a-zA-Z].*")) { String argumentFlowers = userInput.replaceAll("(flowers)", ""); correctedInput = "flowers " + argumentFlowers; - } else if (userInput.matches("(new)[a-zA-Z].*")) { - String argumentNew = userInput.replaceAll("(new)", ""); + } else if (userInput.matches("(new).+")) { + String argumentNew = userInput.replace("new", ""); correctedInput = "new " + argumentNew; - } else if (userInput.matches("(add)[a-zA-Z].*")) { - String argumentAdd = userInput.replaceAll("(add)", ""); + } else if (userInput.matches("(add)[a-zA-Z].+")) { + System.out.println(userInput); + String argumentAdd = userInput.replace("add", ""); + System.out.println(argumentAdd); correctedInput = "add " + argumentAdd; - } else if (userInput.matches("(remove)[a-zA-Z].*")) { - String argumentRemove = userInput.replaceAll("(remove)", ""); + } else if (userInput.matches("(remove)[a-zA-Z].+")) { + String argumentRemove = userInput.replace("remove", ""); correctedInput = "remove " + argumentRemove; - } else if (userInput.matches("(save)[a-zA-Z].*")) { - String argumentSave = userInput.replaceAll("(save)", ""); + } else if (userInput.matches("(save)[a-zA-Z].+")) { + String argumentSave = userInput.replace("save", ""); correctedInput = "save " + argumentSave; } @@ -183,4 +256,12 @@ protected static String separateInput(String userInput) throws FlorizzException } return correctedInput; } + + protected static String mergeInput(String userInput) throws FlorizzException { + if (userInput == null) { + throw new FlorizzException("Input cannot be empty."); + } + return userInput.replaceAll("\\s", ""); + } + } diff --git a/src/main/java/florizz/core/Parser.java b/src/main/java/florizz/core/Parser.java index 435de5adc2..2dc3029611 100644 --- a/src/main/java/florizz/core/Parser.java +++ b/src/main/java/florizz/core/Parser.java @@ -111,26 +111,26 @@ public static Command parse (String input, boolean enableUi) throws FlorizzExcep public static String[] commandHandler(String input) throws FlorizzException { String[] outputs = new String[2]; String trimmedInput = input.trim(); - String separatedInput = FuzzyLogic.separateInput(trimmedInput); - int firstWhitespace = separatedInput.indexOf(" "); + String processedInput = FuzzyLogic.processCommand(trimmedInput); + int firstWhitespace = processedInput.indexOf(" "); if (firstWhitespace != -1) { - outputs[0] = FuzzyLogic.detectItem(trimmedInput.substring(0,firstWhitespace).toLowerCase()); + outputs[0] = FuzzyLogic.detectItem(processedInput.substring(0,firstWhitespace).toLowerCase()); switch (outputs[0]) { case ("save"): case ("delete"): // Fallthrough case ("new"): - outputs[1] = trimmedInput.substring(firstWhitespace).trim(); + outputs[1] = processedInput.substring(firstWhitespace).trim(); break; case ("remove"): // Fallthrough case ("add"): String[] arguments = new String[2]; - String trimmedArgument = trimmedInput.substring(firstWhitespace).trim(); + String trimmedArgument = processedInput.substring(firstWhitespace).trim(); int secondWhitespace = trimmedArgument.indexOf(" "); if (secondWhitespace < 0 && outputs[0].equals("remove")){ throw new FlorizzException("Incorrect usage of remove." + " Correct format: remove /q /from "); - } else if (secondWhitespace < 0 && outputs[0].equals("add")) { + } else if (secondWhitespace < 0) { // add throw new FlorizzException("Incorrect usage of add." + " Correct format: add /q /to "); } @@ -139,13 +139,12 @@ public static String[] commandHandler(String input) throws FlorizzException { outputs[1] = arguments[0] + " " + arguments[1]; break; default: - outputs[1] = FuzzyLogic.detectItem(trimmedInput.substring(firstWhitespace).trim()); + outputs[1] = FuzzyLogic.detectItem(processedInput.substring(firstWhitespace).trim()); break; } } else { - outputs[0] = FuzzyLogic.detectItem(trimmedInput.toLowerCase()); + outputs[0] = FuzzyLogic.detectItem(processedInput.toLowerCase()); } - if (firstWhitespace == -1 && (outputs[0].equals("save"))) { throw new FlorizzException("Please specify which bouquet you are saving!"); } diff --git a/src/main/java/florizz/core/Ui.java b/src/main/java/florizz/core/Ui.java index f35f4c6806..24c88bf784 100644 --- a/src/main/java/florizz/core/Ui.java +++ b/src/main/java/florizz/core/Ui.java @@ -139,7 +139,7 @@ public void printHelpMessage() { /** * Prints error message thrown by Florizz Exception. * - * @param error + * @param error Error message */ public void printError(FlorizzException error){ System.out.println(error.errorMessage); @@ -284,10 +284,10 @@ public void printAllOccasions() { /** * print ui if flower added successfully * - * @param bouquetList - * @param flowerName - * @param quantity - * @param bouquetName + * @param bouquetList The list of bouquets. + * @param flowerName The name of the flower added. + * @param quantity The quantity of the flower added. + * @param bouquetName The name of the bouquet to which the flower was added. */ public void printAddFlowerSuccess(ArrayList bouquetList, String flowerName, Integer quantity, String bouquetName) { @@ -300,10 +300,10 @@ public void printAddFlowerSuccess(ArrayList bouquetList, /** * print ui if flower removed successfully * - * @param bouquetList - * @param flowerName - * @param quantity - * @param bouquetName + * @param bouquetList The list of bouquets. + * @param flowerName The name of the flower removed. + * @param quantity The quantity of the flower removed. + * @param bouquetName The name of the bouquet from which the flower was removed. */ public void printRemoveFlowerSuccess(ArrayList bouquetList, String flowerName, Integer quantity, String bouquetName) { @@ -316,9 +316,9 @@ public void printRemoveFlowerSuccess(ArrayList bouquetList, /** * print ui if flower removed can't be found * - * @param bouquetList - * @param flowerName - * @param bouquetName + * @param bouquetList The list of bouquets. + * @param flowerName The name of the flower that couldn't be found. + * @param bouquetName The name of the bouquet in which the flower couldn't be found. */ public void printRemoveFlowerUnsuccessful(ArrayList bouquetList, String flowerName, String bouquetName) { lastCommand = "OTHERS"; @@ -326,6 +326,12 @@ public void printRemoveFlowerUnsuccessful(ArrayList bouquetList, String printAllBouquets(bouquetList); } + /** + * Prints a message to the UI indicating a fuzzy input detection. + * + * @param userInput The user's input. + * @param bestMatch The best matching suggestion for the user's input. + */ public void printFuzzyInputDetection (String userInput, String bestMatch) { System.out.println("--> Your input is [" + userInput + "] but I am guessing you mean [" + bestMatch + "]"); From af18aa466faabb58d319b1b9ca73daa5b311cabb Mon Sep 17 00:00:00 2001 From: Jeffinson Darmawan Date: Wed, 10 Apr 2024 20:38:54 +0800 Subject: [PATCH 3/5] Improvements on Fuzzy Logic --- src/main/java/florizz/core/FuzzyLogic.java | 198 +++++++++++++-------- 1 file changed, 126 insertions(+), 72 deletions(-) diff --git a/src/main/java/florizz/core/FuzzyLogic.java b/src/main/java/florizz/core/FuzzyLogic.java index 3de791d6e9..39da67e67e 100644 --- a/src/main/java/florizz/core/FuzzyLogic.java +++ b/src/main/java/florizz/core/FuzzyLogic.java @@ -1,14 +1,17 @@ package florizz.core; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; /** * Provides functionality for detecting the closest command based on user input, - * and computing Levenshtein Distance between strings. + * by computing Levenshtein Distance between strings; + * removing unnecessary whitespaces within command word (e.g. h e l p, flo wer s); + * and splitting inputs with the correct words but wrong format (e.g. infoRose, deletebouquetname), + * for the purpose of reducing the impact human error and improving programme flow. */ public class FuzzyLogic { @@ -67,7 +70,7 @@ protected static String detectItem(String userInput) throws FlorizzException { // Iterate over predefined commands for (String item : ITEMS.keySet()) { - int distance = computeDLDistance(item, userInput); + int distance = computeDLDistance(item.toLowerCase(), userInput.toLowerCase()); if (distance < bestDistance) { bestDistance = distance; bestMatch = item; @@ -95,8 +98,9 @@ protected static String detectItem(String userInput) throws FlorizzException { * @param item The first string. * @param userInput The second string. * @return The Damerau-Levenshtein distance between the two strings. + * @throws FlorizzException if the loop tries to access elements beyond the array bounds. */ - private static int computeDLDistance(String item, String userInput) { + private static int computeDLDistance(String item, String userInput) throws FlorizzException { assert item != null && userInput != null : "Strings cannot be null"; int itemLength = item.length(); @@ -115,6 +119,10 @@ private static int computeDLDistance(String item, String userInput) { currentRow[0] = i; for (int j = 1; j <= inputLength; j++) { + if (i > itemLength || j > inputLength) { + throw new FlorizzException("Fuzzy Logic: Accessing element outside of array bounds"); + } + int substitutionCost = (item.charAt(i - 1) == userInput.charAt(j - 1)) ? 0 : 1; currentRow[j] = Math.min(Math.min( previousRow[j] + 1, // deletion @@ -139,74 +147,116 @@ private static int computeDLDistance(String item, String userInput) { return previousRow[inputLength]; } - // doesnt account for deletes abc --> something must be done before split and merge input - // my bouquets - // - + /** + * Processes the user input command and returns the input string at the correct format. + * + * + * @param userInput The user input command string. + * @return The corrected input string after processing. + * @throws FlorizzException if the input is null or empty. + */ protected static String processCommand(String userInput) throws FlorizzException { if (userInput == null) { throw new FlorizzException("Input cannot be empty."); } - String correctedInput = splitAndMergeInput(userInput); + String correctedInput; + String trimmedInput = userInput.trim(); + int firstWhitespace = trimmedInput.indexOf(" "); + if ((firstWhitespace != -1) + && (userInput.startsWith("delete") + || userInput.startsWith("save") + || userInput.startsWith("new") + || userInput.startsWith("remove") + || userInput.startsWith("add") + || userInput.startsWith("info") + || userInput.startsWith("flowers"))) { + String[] arguments = new String[2]; + arguments[0] = userInput.substring(0,firstWhitespace).toLowerCase(); + arguments[1] = userInput.substring(firstWhitespace).trim(); + correctedInput = detectItem(arguments[0]) + " " + arguments[1]; + } else { + correctedInput = splitAndMergeInput(userInput); + } return correctedInput; } + /** + * Splits and merges the user input command into an input string with the correct format. + * + * @param userInput The user input command string. + * @return The corrected input string after splitting and merging. + * @throws FlorizzException if there is an issue processing the input. + */ protected static String splitAndMergeInput(String userInput) throws FlorizzException { - String correctedInput = ""; - String mergedInput = mergeInput(userInput); - String splitMergedInput = splitInput(mergedInput); - String[] arguments = splitMergedInput.split(" "); - System.out.println(Arrays.toString(arguments)); - String bouquetName = ""; - String removeArgument = ""; - String addArgument = ""; + 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(); - if (arguments.length == 1 && !arguments[0].matches("(mybouquets|flowers|occasion|recommend|bye|help)")) { - correctedInput = userInput; - } else if (arguments[0].matches("(mybouquets|flowers|occasion|recommend|bye|help)")) { - correctedInput = detectItem(mergedInput); - } else if (arguments[0].matches("(info|flowers)")) { - correctedInput = detectItem(arguments[0]) + " " + detectItem(arguments[1]); - } else if (arguments[0].matches("(new)")) { - bouquetName = userInput.replace("n", "") - .replace("e", "") - .replace("w", "") - .strip(); - correctedInput = "new " + bouquetName; - } else if (arguments[0].matches("(delete)")) { - bouquetName = userInput.replace("d", "") - .replace("e", "") - .replace("l", "") - .replace("e", "") - .replace("t", "") - .replace("e", "") - .strip(); - correctedInput = "delete " + bouquetName; - } else if (arguments[0].matches("(save)")) { - bouquetName = userInput.replace("s", "") - .replace("a", "") - .replace("v", "") - .replace("e", "") - .strip(); - correctedInput = "save " + bouquetName; - } else if (arguments[0].matches("(remove)")) { - removeArgument = userInput.replace("r", "") - .replace("e", "") - .replace("m", "") - .replace("o", "") - .replace("v", "") - .replace("e", "") - .strip(); - correctedInput = "remove " + removeArgument; - } else if (arguments[0].matches("(add)")) { - addArgument = userInput.replace("a", "") - .replace("d", "") - .replace("d", "") - .strip(); - correctedInput = "add " + addArgument; + 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 { + correctedInput = userInput; + } + return correctedInput; + } catch (Exception e) { + throw new FlorizzException("Error processing input: " + e.getMessage()); } - System.out.println(correctedInput); - return correctedInput; } /** @@ -227,27 +277,25 @@ protected static String splitInput(String userInput) throws FlorizzException { String correctedInput = ""; if (userInput.matches("(info)[a-zA-Z].*")) { - String argumentInfo = userInput.replaceAll("(info)", ""); + String argumentInfo = userInput.replaceFirst("(info)", ""); correctedInput = "info " + argumentInfo; } else if (userInput.matches("(delete).+")) { - String argumentDelete = userInput.replace("delete", ""); + String argumentDelete = userInput.replaceFirst("delete", ""); correctedInput = "delete " + argumentDelete; } else if (userInput.matches("(flowers)[a-zA-Z].*")) { - String argumentFlowers = userInput.replaceAll("(flowers)", ""); + String argumentFlowers = userInput.replaceFirst("(flowers)", ""); correctedInput = "flowers " + argumentFlowers; } else if (userInput.matches("(new).+")) { - String argumentNew = userInput.replace("new", ""); + String argumentNew = userInput.replaceFirst("new", ""); correctedInput = "new " + argumentNew; } else if (userInput.matches("(add)[a-zA-Z].+")) { - System.out.println(userInput); - String argumentAdd = userInput.replace("add", ""); - System.out.println(argumentAdd); + String argumentAdd = userInput.replaceFirst("add", ""); correctedInput = "add " + argumentAdd; } else if (userInput.matches("(remove)[a-zA-Z].+")) { - String argumentRemove = userInput.replace("remove", ""); + String argumentRemove = userInput.replaceFirst("remove", ""); correctedInput = "remove " + argumentRemove; } else if (userInput.matches("(save)[a-zA-Z].+")) { - String argumentSave = userInput.replace("save", ""); + String argumentSave = userInput.replaceFirst("save", ""); correctedInput = "save " + argumentSave; } @@ -257,11 +305,17 @@ protected static String splitInput(String userInput) throws FlorizzException { return correctedInput; } + /** + * Merges the user input command by removing all whitespace characters. + * + * @param userInput The user input command string. + * @return The merged input string with whitespace removed. + * @throws FlorizzException if the input is null. + */ protected static String mergeInput(String userInput) throws FlorizzException { if (userInput == null) { throw new FlorizzException("Input cannot be empty."); } return userInput.replaceAll("\\s", ""); } - } From 7bce708f5b8161aaf89581a02548cd730512a03f Mon Sep 17 00:00:00 2001 From: Jeffinson Darmawan Date: Wed, 10 Apr 2024 20:50:54 +0800 Subject: [PATCH 4/5] io redirection --- text-ui-test/ACTUAL.TXT | 13 +++++++++++-- text-ui-test/EXPECTED-UNIX.TXT | 25 ++++++++++++++++++++++++- text-ui-test/EXPECTED.TXT | 15 ++++++++++++--- text-ui-test/input.txt | 2 ++ 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/text-ui-test/ACTUAL.TXT b/text-ui-test/ACTUAL.TXT index bbc30ba059..7dad8f5db0 100644 --- a/text-ui-test/ACTUAL.TXT +++ b/text-ui-test/ACTUAL.TXT @@ -14,8 +14,8 @@ Here are the list of commands you can use: 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 +5. add /c (optional) /q /to - add flower to a bouquet +6. remove /c (optional) /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 @@ -24,5 +24,14 @@ Here are the list of commands you can use: 12. bye - Exits the programme ____________________________________________________________ What can I do for you? +Added new bouquet to list: +test +____________________________________________________________ +What can I do for you? +Here is the list of your saved bouquets: +1. test : + No flowers added so far +____________________________________________________________ +What can I do for you? Enjoy your bouquet! Thank you for using Florizz! ____________________________________________________________ diff --git a/text-ui-test/EXPECTED-UNIX.TXT b/text-ui-test/EXPECTED-UNIX.TXT index 64b4afe24d..7dad8f5db0 100644 --- a/text-ui-test/EXPECTED-UNIX.TXT +++ b/text-ui-test/EXPECTED-UNIX.TXT @@ -8,7 +8,30 @@ Hello from |_| |_|\___/|_| |_/___/___| - +What can I do for you? +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 /c (optional) /q /to - add flower to a bouquet +6. remove /c (optional) /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 +____________________________________________________________ +What can I do for you? +Added new bouquet to list: +test +____________________________________________________________ +What can I do for you? +Here is the list of your saved bouquets: +1. test : + No flowers added so far +____________________________________________________________ What can I do for you? Enjoy your bouquet! Thank you for using Florizz! ____________________________________________________________ diff --git a/text-ui-test/EXPECTED.TXT b/text-ui-test/EXPECTED.TXT index bbc30ba059..68d1a6ee6a 100644 --- a/text-ui-test/EXPECTED.TXT +++ b/text-ui-test/EXPECTED.TXT @@ -14,8 +14,8 @@ Here are the list of commands you can use: 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 +5. add /c (optional) /q /to - add flower to a bouquet +6. remove /c (optional) /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 @@ -24,5 +24,14 @@ Here are the list of commands you can use: 12. bye - Exits the programme ____________________________________________________________ What can I do for you? -Enjoy your bouquet! Thank you for using Florizz! +Added new bouquet to list: +test +____________________________________________________________ +What can I do for you? +Here is the list of your saved bouquets: +1. test : + No flowers added so far ____________________________________________________________ +What can I do for you? +Enjoy your bouquet! Thank you for using Florizz! +____________________________________________________________ \ No newline at end of file diff --git a/text-ui-test/input.txt b/text-ui-test/input.txt index ea20819dd5..468ae301eb 100644 --- a/text-ui-test/input.txt +++ b/text-ui-test/input.txt @@ -1,2 +1,4 @@ help +new test +mybouquets bye \ No newline at end of file From 15f07e504c1114ec439aef1db2032f55a3c92101 Mon Sep 17 00:00:00 2001 From: Jeffinson Darmawan Date: Wed, 10 Apr 2024 21:27:24 +0800 Subject: [PATCH 5/5] Debug --- src/main/java/florizz/core/FuzzyLogic.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/florizz/core/FuzzyLogic.java b/src/main/java/florizz/core/FuzzyLogic.java index 148d73d42b..6f7f842073 100644 --- a/src/main/java/florizz/core/FuzzyLogic.java +++ b/src/main/java/florizz/core/FuzzyLogic.java @@ -187,6 +187,16 @@ protected static String processCommand(String userInput) throws FlorizzException arguments[0] = userInput.substring(0,firstWhitespace).toLowerCase(); arguments[1] = userInput.substring(firstWhitespace).trim(); correctedInput = detectItem(arguments[0]) + " " + arguments[1]; + } else if ((firstWhitespace == -1) + && userInput.equals("help") + || userInput.equals("mybouquets") + || userInput.equals("flowers") + || userInput.equals("recommend") + || userInput.equals("bye") + || userInput.equals("occasion") + || userInput.equals("back") + || userInput.equals("next")) { + correctedInput = userInput; } else { correctedInput = splitAndMergeInput(userInput); }