From 495e474d6790a9a133b0812820c7e3022a3c457f Mon Sep 17 00:00:00 2001
From: Pedro Cardona <pedropca@stud.ntnu.no>
Date: Thu, 4 May 2023 10:35:14 +0200
Subject: [PATCH] All the bugs related to the alogrithms was fixed

---
 .../v233/SmartMat/util/ProductUtil.java       | 56 ++++++++++++-------
 .../v233/SmartMat/util/StatisticUtil.java     |  2 +-
 .../v233/SmartMat/util/ProductUtilTest.java   | 54 +++++++++---------
 3 files changed, 65 insertions(+), 47 deletions(-)

diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/util/ProductUtil.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/util/ProductUtil.java
index 40ba1f50..d83bf6cf 100644
--- a/src/main/java/ntnu/idatt2016/v233/SmartMat/util/ProductUtil.java
+++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/util/ProductUtil.java
@@ -17,34 +17,50 @@ import java.util.regex.Pattern;
  */
 public class ProductUtil {
 
+    public static Optional<List<String>> getVolumeFromProduct(Product product) {
+        String total = product.getName() + " " + product.getDescription();
+        double amount = parseAmount(total);
+        String unit = parseUnit(total);
+        if (unit.equals("STK") && total.matches(".*\\d+x\\d+.*")) {
+            // If no unit was found but the description matches "number x number", assume a multiplication and calculate the result
+            Pattern pattern = Pattern.compile("(\\d+)x(\\d+)");
+            Matcher matcher = pattern.matcher(total);
+            if (matcher.find()) {
+                amount = Integer.parseInt(matcher.group(1)) * Integer.parseInt(matcher.group(2));
+            }
+        }
+        return Optional.of(List.of(amount + "", unit));
+    }
 
-    private static final String VOLUME_REGEX = "(\\d+(\\.\\d+)?)\\s*(mls?|centiliters?|deciliters?|liters?|grams?|kilograms?)";
-    private static final Map<String, List<String>> VOLUME_UNIT_VARIATIONS = Map.of(
-            "ml", List.of("ml", "milliliters", "millilitres"),
-            "cl", List.of("cl", "centiliters", "centilitres"),
-            "dl", List.of("dl", "deciliters", "decilitres"),
-            "l", List.of("l", "liters", "litres"),
-            "g", List.of("g", "grams"),
-            "kg", List.of("kg", "kilograms")
-    );
+    private static String parseUnit(String input) {
+        Pattern pattern = Pattern.compile("(\\d+(\\.\\d+)?)\\s*(g|kg|l|ml|dl|cl|Kg|L|STK)\\b", Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(input);
+        if (matcher.find()) {
+            String unit = matcher.group(3).toLowerCase();
+            if (!unit.equals("stk")) {
+                return unit;
+            }
+        }
+        return "STK";
+    }
 
-    public static Optional<List<String>> getVolumeFromProduct(Product product) {
-        String desc = product.getName() + " " + product.getDescription();
-        Matcher matcher = Pattern.compile(VOLUME_REGEX).matcher(desc);
+    private static double parseAmount(String input) {
+        Pattern pattern = Pattern.compile("(\\d+(\\.\\d+)?)\\s*(g|kg|l|ml|dl|cl|Kg|L|STK)\\b", Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(input);
         if (matcher.find()) {
-            String volumeString = matcher.group(1);
-            double volume = Double.parseDouble(volumeString);
-            String unitString = matcher.group(3);
-            for (Map.Entry<String, List<String>> entry : VOLUME_UNIT_VARIATIONS.entrySet()) {
-                if (entry.getValue().contains(unitString)) {
-                    return Optional.of(List.of(String.valueOf(volume), entry.getKey()));
-                }
+            double amount = Double.parseDouble(matcher.group(1));
+            Pattern multiplicationPattern = Pattern.compile("(\\d+)x(\\d+)");
+            Matcher multiplicationMatcher = multiplicationPattern.matcher(input);
+            if (multiplicationMatcher.find()) {
+                amount *= Integer.parseInt(multiplicationMatcher.group(1));
             }
+            return amount;
         }
-        return Optional.empty();
+        return 1.0;
     }
 
 
+
     /**
      * Checks if a string contains any numbers
      * @param s The string to check
diff --git a/src/main/java/ntnu/idatt2016/v233/SmartMat/util/StatisticUtil.java b/src/main/java/ntnu/idatt2016/v233/SmartMat/util/StatisticUtil.java
index b0ba2dc9..10fc2557 100644
--- a/src/main/java/ntnu/idatt2016/v233/SmartMat/util/StatisticUtil.java
+++ b/src/main/java/ntnu/idatt2016/v233/SmartMat/util/StatisticUtil.java
@@ -116,7 +116,7 @@ public class StatisticUtil {
         if(diffInDays >= 365){
             return co2Sum / (((double) (diffInDays +1) / 365.0) * (double) numberOfPerson);
         }else {
-            return (118.0/diffInDays) + (( co2Sum / (((double) (diffInDays +1) / 365.0) * (double) numberOfPerson))/(365.0-(double) diffInDays));
+            return (118.0/((double) diffInDays +1.0)) + (( co2Sum / (((double) (diffInDays +1) / 365.0) * (double) numberOfPerson))/(365.0-(double) diffInDays));
         }
     }
 
diff --git a/src/test/java/ntnu/idatt2016/v233/SmartMat/util/ProductUtilTest.java b/src/test/java/ntnu/idatt2016/v233/SmartMat/util/ProductUtilTest.java
index 2ee4467a..5524c72c 100644
--- a/src/test/java/ntnu/idatt2016/v233/SmartMat/util/ProductUtilTest.java
+++ b/src/test/java/ntnu/idatt2016/v233/SmartMat/util/ProductUtilTest.java
@@ -1,53 +1,55 @@
 package ntnu.idatt2016.v233.SmartMat.util;
 
 import ntnu.idatt2016.v233.SmartMat.entity.product.Product;
-import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
 
 import java.util.List;
+import java.util.Optional;
 
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
 class ProductUtilTest {
 
-    Product product;
-    @BeforeEach
-    void setUp() {
-        this.product = Product.builder()
-                .ean(123456789)
-                .name("Pepsi Original 24x500 ml")
-                .description("Pepsi Original 24x500 ml")
-                .build();
-    }
+    private Product product;
 
-    @Test
+    @Test @Order(1)
     void getVolumeFromProduct() {
-        assertEquals(List.of("500.0", "ml"), ProductUtil.getVolumeFromProduct(product).get());
-
-        this.product = Product.builder()
+        product = Product.builder()
                 .ean(123456789)
-                .name("test")
-                .description("Pepsi Original 24x500 ml")
+                .name("Pepsi Original")
+                .description("500 ml")
                 .build();
-
         assertEquals(List.of("500.0", "ml"), ProductUtil.getVolumeFromProduct(product).get());
+    }
 
-        this.product = Product.builder()
+    @Test @Order(2)
+    void getVolumeFromProductMultipleUnits() {
+        product = Product.builder()
                 .ean(123456789)
                 .name("Pepsi Original 24x500ml")
                 .description("test")
                 .build();
+        assertEquals(List.of("12000.0", "ml"), ProductUtil.getVolumeFromProduct(product).get());
+    }
 
+    @Test @Order(3)
+    void getVolumeFromProductCombined() {
+        product = Product.builder()
+                .ean(123456789)
+                .name("test")
+                .description("Pepsi Original 24x500 ml")
+                .build();
+        assertEquals(List.of("12000.0", "ml"), ProductUtil.getVolumeFromProduct(product).get());
 
-        assertEquals(List.of("500.0", "ml"), ProductUtil.getVolumeFromProduct(product).get());
-
-        this.product = Product.builder()
+        product = Product.builder()
                 .ean(123456789)
                 .name("test")
                 .description("Pepsi Original 24x500ml")
                 .build();
-
-
-        assertEquals(List.of("500.0", "ml"), ProductUtil.getVolumeFromProduct(product).get());
+        assertEquals(List.of("12000.0", "ml"), ProductUtil.getVolumeFromProduct(product).get());
     }
-}
\ No newline at end of file
+}
-- 
GitLab