瀏覽代碼

Merge 4d91dc0b7cdd85ead5165de44538537c18d43060 into 23c2c01bf07b924ac9b860fa2771bf6ceb246ad5

gjarant 6 年之前
父節點
當前提交
5bc526bdbb
沒有帳戶連結到提交者的電子郵件

+ 1
- 0
src/main/java/io/zipcoder/ItemParseException.java 查看文件

@@ -1,4 +1,5 @@
1 1
 package io.zipcoder;
2 2
 
3 3
 public class ItemParseException extends Exception {
4
+
4 5
 }

+ 209
- 12
src/main/java/io/zipcoder/ItemParser.java 查看文件

@@ -1,31 +1,228 @@
1 1
 package io.zipcoder;
2 2
 
3
-import java.util.ArrayList;
4
-import java.util.Arrays;
3
+import java.util.*;
4
+import java.util.regex.Matcher;
5
+import java.util.regex.Pattern;
5 6
 
6 7
 public class ItemParser {
7 8
 
9
+    private Integer countExceptionsThrown = 0;
10
+    private Integer count = 0;
8 11
 
9
-    public ArrayList<String> parseRawDataIntoStringArray(String rawData){
12
+    private ArrayList<String> splitStringWithRegexPattern(String stringPattern, String inputString) {
13
+        return new ArrayList<String>(Arrays.asList(inputString.split(stringPattern)));
14
+    }
15
+
16
+    public ArrayList<String> parseRawDataIntoStringArray(String rawData) {
10 17
         String stringPattern = "##";
11
-        ArrayList<String> response = splitStringWithRegexPattern(stringPattern , rawData);
18
+        ArrayList<String> response = splitStringWithRegexPattern(stringPattern, rawData);
12 19
         return response;
13 20
     }
14 21
 
15
-    public Item parseStringIntoItem(String rawItem) throws ItemParseException{
16
-        return null;
22
+    public ArrayList<String> findKeyValuePairsInRawItemData(String rawItem) {
23
+        String stringPattern = "[@|^|*|%|!|;]";
24
+        ArrayList<String> response = splitStringWithRegexPattern(stringPattern, rawItem);
25
+        return response;
17 26
     }
18 27
 
19
-    public ArrayList<String> findKeyValuePairsInRawItemData(String rawItem){
20
-        String stringPattern = "[;|^]";
21
-        ArrayList<String> response = splitStringWithRegexPattern(stringPattern , rawItem);
22
-        return response;
28
+    public Item parseStringIntoItem(String rawItem) throws ItemParseException {
29
+            if (checkName(rawItem) == null || checkPrice(rawItem) == null || checkType(rawItem) == null
30
+                    || checkExpiration(rawItem) == null) {
31
+                throw new ItemParseException();
32
+            }
33
+
34
+            String name = checkName(rawItem);
35
+            Double price = Double.valueOf(checkPrice(rawItem));
36
+            String type = checkType(rawItem);
37
+            String expiration = checkExpiration(rawItem);
38
+
39
+            return new Item(name, price, type, expiration);
23 40
     }
24 41
 
25
-    private ArrayList<String> splitStringWithRegexPattern(String stringPattern, String inputString){
26
-        return new ArrayList<String>(Arrays.asList(inputString.split(stringPattern)));
42
+    public ArrayList<Item> createItemArrayList(String rawData) {
43
+        ArrayList<String> temp = parseRawDataIntoStringArray(rawData);
44
+        ArrayList<Item> itemArrayList = new ArrayList<Item>();
45
+
46
+        for (int i = 0; i <temp.size() ; i++) {
47
+            try {
48
+                itemArrayList.add(parseStringIntoItem(temp.get(i)));
49
+            } catch (ItemParseException e) {
50
+                count++;
51
+            }
52
+        }
53
+        return itemArrayList;
54
+    }
55
+
56
+    public ArrayList<Item> filterItemArrayList(ArrayList<Item> input, String filterType){
57
+        ArrayList<Item> filterItemArrayList = new ArrayList<Item>();
58
+        for (int i = 0; i <input.size() ; i++) {
59
+            if(input.get(i).getName().equals(filterType))
60
+            filterItemArrayList.add(input.get(i));
61
+        }
62
+        return filterItemArrayList;
63
+    }
64
+
65
+    public Map<Double, Integer> individualItemCount(ArrayList<Item> filteredArrayList) {
66
+        Map<Double, Integer> priceTotals = new TreeMap<Double, Integer>(Collections.reverseOrder());
67
+        for (int i = 0; i < filteredArrayList.size(); i++) {
68
+            Double key = filteredArrayList.get(i).getPrice();
69
+            Integer count = priceTotals.get(key);
70
+            if (count == null) {
71
+                priceTotals.put(key, 1);
72
+            } else {
73
+                priceTotals.put(key, count + 1);
74
+            }
75
+        }
76
+        return priceTotals;
77
+    }
78
+
79
+    public Map<Double, Integer> itemTypeMapWithCounts(String rawData, String filterType)  {
80
+        ArrayList<Item> itemArrayList = createItemArrayList(rawData);
81
+        ArrayList<Item> filterItemArrayList = filterItemArrayList(itemArrayList, filterType);
82
+        Map<Double, Integer> priceTotals = individualItemCount(filterItemArrayList);
83
+        return priceTotals;
84
+    }
85
+
86
+    public Integer totalTimesItemSeen(String rawData, String filterType)  {
87
+        ArrayList<Item> itemArrayList = createItemArrayList(rawData);
88
+        ArrayList<Item> filterItemArrayList = filterItemArrayList(itemArrayList, filterType);
89
+        return filterItemArrayList.size();
90
+    }
91
+
92
+    public ArrayList<String> filterTypeArrayList(String rawData)  {
93
+        ArrayList<Item> itemArrayList = createItemArrayList(rawData);
94
+        ArrayList<String> filterType = new ArrayList<String>();
95
+
96
+        for(int i = 0; i < itemArrayList.size(); i++) {
97
+            if (!filterType.contains(itemArrayList.get(i).getName())) {
98
+                filterType.add(itemArrayList.get(i).getName());
99
+            }
100
+        }
101
+        return filterType;
102
+    }
103
+
104
+    public String formatText(String rawData) throws ItemParseException {
105
+        ArrayList<String> filterType = filterTypeArrayList(rawData);
106
+        StringBuilder sb = new StringBuilder();
107
+
108
+            for (int i = 0; i < filterType.size(); i++) {
109
+                String name = filterType.get(i);
110
+                Integer total = totalTimesItemSeen(rawData, filterType.get(i));
111
+                String priceFormated = formatPriceField(rawData, filterType.get(i));
112
+                sb.append("name: ");
113
+                sb.append(String.format("%7s", name.substring(0, 1).toUpperCase() + name.substring(1)));
114
+                sb.append("\t \t");
115
+                sb.append(" seen: " + total + " times\n");
116
+                sb.append("============= \t \t =============\n");
117
+                sb.append(priceFormated + "\n");
118
+            }
119
+
120
+        sb.append("Errors              " + " seen: " + getExceptionsThrown(rawData) + " times");
121
+
122
+        return sb.toString();
123
+    }
124
+
125
+    public String formatPriceField(String rawData, String filterType)  {
126
+        Map<Double, Integer> priceTotals = itemTypeMapWithCounts(rawData, filterType);
127
+        StringBuilder sb = new StringBuilder();
128
+        Set mapSet = (Set) priceTotals.entrySet();
129
+        Iterator mapIterator = mapSet.iterator();
130
+        while (mapIterator.hasNext()) {
131
+            Map.Entry mapEntry = (Map.Entry) mapIterator.next();
132
+            // getKey Method of HashMap access a key of map
133
+            Object keyValue = mapEntry.getKey();
134
+            //getValue method returns corresponding key's value
135
+            Object value = mapEntry.getValue();
136
+            String time = (1 < (Integer)value) ?  " times": " time";
137
+            sb.append("Price:   " + keyValue + "\t\t seen: " + value + time + "\n");
138
+            if (mapIterator.hasNext()) sb.append(String.format("-------------        -------------\n"));
139
+            if(priceTotals.size() < 2) sb.append(String.format("-------------        -------------\n"));
140
+
141
+        }
142
+        return sb.toString();
143
+    }
144
+
145
+    public String checkName(String input) {
146
+        String newInput = fixCookie(input);
147
+        Pattern patternName = Pattern.compile("([Nn]..[Ee]:)(\\w+)");
148
+        Matcher matcherName= patternName.matcher(newInput);
149
+
150
+        if (matcherName.find())
151
+            return matcherName.group(2).toLowerCase();
152
+        else return null;
153
+    }
154
+
155
+    public String fixCookie(String input){
156
+        Pattern patternCookies = Pattern.compile("([Cc][0Oo][0Oo][Kk][Ii][Ee][Ss])");
157
+        Matcher matcherCookie= patternCookies.matcher(input);
158
+        return matcherCookie.replaceAll("cookies");
27 159
     }
28 160
 
161
+    public String checkPrice(String input) {
162
+        Pattern patternPrice = Pattern.compile("([Pp]...[Ee]:)(\\d\\.\\d{2})");
163
+        Matcher matcherPrice= patternPrice.matcher(input);
29 164
 
165
+        if (matcherPrice.find())
166
+            return matcherPrice.group(2);
167
+        else return null;
168
+    }
169
+
170
+    public String checkType(String input) {
171
+        Pattern patternType = Pattern.compile("([Tt]..[Ee]:)(\\w+)");
172
+        Matcher matcherType = patternType.matcher(input);
173
+
174
+        if (matcherType.find())
175
+            return matcherType.group(2).toLowerCase();
176
+        else return null;
177
+    }
178
+
179
+    public String checkExpiration(String input) {
180
+        Pattern patternExpiration = Pattern.compile("([Ee]........[Nn]:)(\\d\\/\\d{2}\\/\\d{4})");
181
+        Matcher matcherExpiration = patternExpiration.matcher(input);
30 182
 
183
+        if (matcherExpiration.find())
184
+            return matcherExpiration.group(2);
185
+        else return null;
186
+    }
187
+
188
+    public Integer getExceptionsThrown(String rawData)  {
189
+        ArrayList<String> parsedRawData = parseRawDataIntoStringArray(rawData);
190
+        for (int i = 0; i < parsedRawData.size(); i++)
191
+            try {
192
+                parseStringIntoItem(parsedRawData.get(i));
193
+            } catch (ItemParseException e){
194
+                countExceptionsThrown++;
195
+            }
196
+        return this.countExceptionsThrown;
197
+    }
31 198
 }
199
+
200
+
201
+//    public String checkName(String input) throws ItemParseException{
202
+//        Pattern patternName = Pattern.compile("([Nn]..[Ee]:)(\\w+)");
203
+//        Matcher matcherName= patternName.matcher(input);
204
+//
205
+//        if (matcherName.find())
206
+//            return matcherName.group(2).toLowerCase();
207
+//        else throw new ItemParseException();
208
+//    }
209
+
210
+//    Pattern[] patternName = new Pattern[4];
211
+//        patternName[0] = Pattern.compile("([Nn]..[Ee]:)([Mm]..[Kk])");
212
+//                patternName[1] = Pattern.compile("([Nn]..[Ee]:)([Bb]...[Dd])");
213
+//                patternName[2] = Pattern.compile("([Nn]..[Ee]:)([Cc].....[Ss])");
214
+//                patternName[3] = Pattern.compile("([Nn]..[Ee]:)([Aa]....[Ss])");
215
+//
216
+//                for (int i = 0; i < patternName.length; i++) {
217
+//        Matcher nameMatcher = patternName[i].matcher(input);
218
+//        if (nameMatcher.find()) {
219
+//        return "milk";
220
+//        } else if (nameMatcher.find()) {
221
+//        return "bread";
222
+//        } else if (nameMatcher.find()) {
223
+//        return "cookies";
224
+//        } else if (nameMatcher.find()) {
225
+//        return "apples";
226
+//        }
227
+//        }
228
+//        throw new ItemParseException();

+ 3
- 1
src/main/java/io/zipcoder/Main.java 查看文件

@@ -13,7 +13,9 @@ public class Main {
13 13
 
14 14
     public static void main(String[] args) throws Exception{
15 15
         String output = (new Main()).readRawDataToString();
16
-        System.out.println(output);
16
+        ItemParser item = new ItemParser();
17
+        ItemParseException itemParseException = new ItemParseException();
18
+        System.out.println(item.formatText(output));
17 19
         // TODO: parse the data in output into items, and display to console.
18 20
     }
19 21
 }

+ 147
- 1
src/test/java/io/zipcoder/ItemParserTest.java 查看文件

@@ -14,11 +14,25 @@ public class ItemParserTest {
14 14
 
15 15
     private String rawSingleItemIrregularSeperatorSample = "naMe:MiLK;price:3.23;type:Food^expiration:1/11/2016##";
16 16
 
17
-    private String rawBrokenSingleItem =    "naMe:Milk;price:3.23;type:Food;expiration:1/25/2016##";
17
+    private String rawBrokenSingleItem =    "naMe:;price:3.23;type:Food;expiration:1/25/2016##";
18 18
 
19 19
     private String rawMultipleItems = "naMe:Milk;price:3.23;type:Food;expiration:1/25/2016##"
20 20
                                       +"naME:BreaD;price:1.23;type:Food;expiration:1/02/2016##"
21 21
                                       +"NAMe:BrEAD;price:1.23;type:Food;expiration:2/25/2016##";
22
+    private String rawMultipleItems2 = "naMe:Milk;price:3.23;type:Food;expiration:1/25/2016##"
23
+                                    +"naME:BreaD;price:1.23;type:Food;expiration:1/02/2016##"
24
+                                    +"NAMe:BrEAD;price:3.23;type:Food;expiration:2/25/2016##"
25
+                                    +"NAMe:BrEAD;price:3.23;type:Food;expiration:2/25/2016##"
26
+                                    +"NAMe:BrEAD;price:1.23;type:Food;expiration:2/25/2016##"
27
+                                    +"NAMe:BrEAD;price:2.23;type:Food;expiration:2/25/2016##";
28
+
29
+    private String rawMultipleItemsBroken = "naMe:Milk;price:3.23;type:Food;expiration:1/25/2016##"
30
+            +"naME:;price:1.23;type:Food;expiration:1/02/2016##"
31
+            +"NAMe:BrEAD;price:3.23;type:Food;expiration:2/25/2016##"
32
+            +"NAMe:BrEAD;price:;type:Food;expiration:2/25/2016##"
33
+            +"NAMe:BrEAD;price:1.23;type:Food;expiration:2/25/2016##"
34
+            +"NAMe:BrEAD;price:2.23;type:Food;expiration:##";
35
+
22 36
     private ItemParser itemParser;
23 37
 
24 38
     @Before
@@ -59,4 +73,136 @@ public class ItemParserTest {
59 73
         Integer actual = itemParser.findKeyValuePairsInRawItemData(rawSingleItemIrregularSeperatorSample).size();
60 74
         assertEquals(expected, actual);
61 75
     }
76
+
77
+    @Test
78
+    public void createItemArrayListTest() {
79
+        String expected ="name:milk price:3.23 type:food expiration:1/25/2016";
80
+        String actual  = itemParser.createItemArrayList(rawMultipleItems).get(0).toString();
81
+        assertEquals(expected, actual);
82
+    }
83
+
84
+    @Test
85
+    public void filterItemArrayListTest() {
86
+        ArrayList<Item> filterItemArrayListTester = itemParser.createItemArrayList(rawMultipleItems);
87
+        String expected ="[name:bread price:1.23 type:food expiration:1/02/2016, name:bread price:1.23 type:food expiration:2/25/2016]";
88
+        String actual  = itemParser.filterItemArrayList(filterItemArrayListTester,"bread").toString();
89
+
90
+        assertEquals(expected, actual);
91
+    }
92
+
93
+    @Test
94
+    public void individualItemCountTest1() {
95
+        ArrayList<Item> individualItemCountTester = itemParser.filterItemArrayList(itemParser.createItemArrayList(rawMultipleItems),"bread");
96
+        String expected ="{1.23=2}";
97
+        String actual  = itemParser.individualItemCount(individualItemCountTester).toString();
98
+
99
+        assertEquals(expected, actual);
100
+    }
101
+
102
+    @Test
103
+    public void individualItemCountTest2()  {
104
+        ArrayList<Item> individualItemCountTester = itemParser.filterItemArrayList(itemParser.createItemArrayList(rawMultipleItems2),"bread");
105
+        String expected ="{3.23=2, 2.23=1, 1.23=2}";
106
+        String actual  = itemParser.individualItemCount(individualItemCountTester).toString();
107
+        assertEquals(expected, actual);
108
+    }
109
+
110
+    @Test
111
+    public void itemTypeMapWithCountsTest() throws ItemParseException {
112
+        String expected ="{3.23=2, 2.23=1, 1.23=2}";
113
+        String actual  = itemParser.itemTypeMapWithCounts(rawMultipleItems2,"bread").toString();
114
+        assertEquals(expected, actual);
115
+    }
116
+
117
+    @Test
118
+    public void totalTimesItemSeen() throws ItemParseException {
119
+        Integer expected = 5;
120
+        Integer actual  = itemParser.totalTimesItemSeen(rawMultipleItems2, "bread");
121
+        assertEquals(expected, actual);
122
+    }
123
+
124
+    @Test
125
+    public void filterTypeArrayListTest() throws ItemParseException {
126
+        String expected = "[milk, bread]";
127
+        String actual = itemParser.filterTypeArrayList(rawMultipleItems2).toString();
128
+        assertEquals(expected, actual);
129
+    }
130
+
131
+    @Test
132
+    public void formatTextTest() throws ItemParseException {
133
+        String expected = "name:    Milk\t \t seen: 1 times\n" +
134
+                "============= \t \t =============\n" +
135
+                "Price:   3.23\t\t seen: 1 time\n" +
136
+                "-------------        -------------\n" +
137
+                "\n" +
138
+                "name:   Bread\t \t seen: 5 times\n" +
139
+                "============= \t \t =============\n" +
140
+                "Price:   3.23\t\t seen: 2 times\n" +
141
+                "-------------        -------------\n" +
142
+                "Price:   2.23\t\t seen: 1 time\n" +
143
+                "-------------        -------------\n" +
144
+                "Price:   1.23\t\t seen: 2 times\n" +
145
+                "\n" +
146
+                "Errors               seen: 0 times";
147
+        String actual = itemParser.formatText(rawMultipleItems2).toString();
148
+        assertEquals(expected, actual);
149
+    }
150
+
151
+    @Test
152
+    public void formatPriceFieldTest() throws ItemParseException {
153
+        String expected = "Price:   3.23\t\t seen: 2 times\n" +
154
+                "-------------        -------------\n" +
155
+                "Price:   2.23\t\t seen: 1 time\n" +
156
+                "-------------        -------------\n" +
157
+                "Price:   1.23\t\t seen: 2 times\n";
158
+        String actual = itemParser.formatPriceField(rawMultipleItems2, "bread").toString();
159
+        assertEquals(expected, actual);
160
+    }
161
+
162
+    @Test
163
+    public void checkNameTest1() {
164
+        String rawItemTest = "naMe:c00kies;price:3.23;type:Food;expiration:1/25/2016##";
165
+        String expected = "cookies";
166
+        String  actual = itemParser.checkName(rawItemTest);
167
+        assertEquals(expected, actual);
168
+    }
169
+
170
+    @Test
171
+    public void checkNameTest2() {
172
+        String rawItemTest = "naMe:mIlk;price:3.23;type:Food;expiration:1/25/2016##";
173
+        String expected = "milk";
174
+        String  actual = itemParser.checkName(rawItemTest);
175
+        assertEquals(expected, actual);
176
+    }
177
+
178
+    @Test
179
+    public void checkPriceTest() throws ItemParseException{
180
+        String rawItemTest = "naMe:Milk;price:3.23;type:Food;expiration:1/25/2016##";
181
+        String expected = "3.23";
182
+        String  actual = itemParser.checkPrice(rawItemTest);
183
+        assertEquals(expected, actual);
184
+    }
185
+
186
+    @Test
187
+    public void checkTypeTest() throws ItemParseException{
188
+        String rawItemTest = "naMe:Milk;price:3.23;type:Food;expiration:1/25/2016##";
189
+        String expected = "food";
190
+        String  actual = itemParser.checkType(rawItemTest);
191
+        assertEquals(expected, actual);
192
+    }
193
+
194
+    @Test
195
+    public void checkExpirationTest() throws ItemParseException{
196
+        String rawItemTest = "naMe:Milk;price:3.23;type:Food;expiration:1/25/2016##";
197
+        String expected = "1/25/2016";
198
+        String  actual = itemParser.checkExpiration(rawItemTest);
199
+        assertEquals(expected, actual);
200
+    }
201
+
202
+    @Test
203
+    public void getExceptionsThrownTest() {
204
+        Integer expected = 3;
205
+        Integer  actual = itemParser.getExceptionsThrown(rawMultipleItemsBroken);
206
+        assertEquals(expected, actual);
207
+    }
62 208
 }