1 | package tudelft.mentalhealth.motivatepersisting;
|
---|
2 |
|
---|
3 | import java.io.BufferedReader;
|
---|
4 | import java.io.IOException;
|
---|
5 | import java.io.InputStream;
|
---|
6 | import java.io.InputStreamReader;
|
---|
7 | import java.util.HashMap;
|
---|
8 | import java.util.Locale;
|
---|
9 | import java.util.Map;
|
---|
10 | import java.util.Random;
|
---|
11 |
|
---|
12 | import tudelft.utilities.statistic.WeightedSet;
|
---|
13 |
|
---|
14 | /**
|
---|
15 | * contains Table 1/ Statements-nl-NL.csv or Statements=en.csv: the Statements
|
---|
16 | * table with all available statements. The .csv files contain rows with 4
|
---|
17 | * columns of data:
|
---|
18 | * <ol>
|
---|
19 | * <li>New Category
|
---|
20 | * <li>New subcat
|
---|
21 | * <li>Count
|
---|
22 | * <li>Statement (correct language)
|
---|
23 | * </ol>
|
---|
24 | */
|
---|
25 | class Statements {
|
---|
26 |
|
---|
27 | // contains for each Category and Subcategory a set of statements.
|
---|
28 | private final Map<Category, Map<Subcategory, WeightedSet<String>>> statements;
|
---|
29 | private static final Random random = new Random();
|
---|
30 |
|
---|
31 | public Statements(Locale locale) {
|
---|
32 | statements = readTable(locale);
|
---|
33 | }
|
---|
34 |
|
---|
35 | /**
|
---|
36 | *
|
---|
37 | * @param cat required {@link Category}
|
---|
38 | * @param subcat required {@link Subcategory}
|
---|
39 | * @return all statements for given category and subcategory.
|
---|
40 | */
|
---|
41 | public WeightedSet<String> getStatements(Category cat, Subcategory subcat) {
|
---|
42 | return statements.get(cat).get(subcat);
|
---|
43 | }
|
---|
44 |
|
---|
45 | /**
|
---|
46 | * read in the CSV table
|
---|
47 | *
|
---|
48 | * @return map containing the CSV file contents.
|
---|
49 | * @throws IOException
|
---|
50 | */
|
---|
51 | private Map<Category, Map<Subcategory, WeightedSet<String>>> readTable(
|
---|
52 | Locale locale) {
|
---|
53 | Map<Category, Map<Subcategory, WeightedSet<String>>> table = new HashMap<>();
|
---|
54 | String filename = "Statements-" + locale.toLanguageTag() + ".csv";
|
---|
55 | InputStream is = getClass().getResourceAsStream(filename);
|
---|
56 | if (is == null) {
|
---|
57 | throw new IllegalStateException("Resource not found: " + filename);
|
---|
58 | }
|
---|
59 |
|
---|
60 | BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
---|
61 | reader.lines().forEach(line -> addLine(line, table));
|
---|
62 | return table;
|
---|
63 |
|
---|
64 | }
|
---|
65 |
|
---|
66 | /**
|
---|
67 | * Add one line of comma-separated text (typically from csv file) to given
|
---|
68 | * table.
|
---|
69 | *
|
---|
70 | * @param line the line of text, containing Category, Subcategory, text.
|
---|
71 | * @param table the table to add the info in the line to
|
---|
72 | */
|
---|
73 | private void addLine(String line,
|
---|
74 | Map<Category, Map<Subcategory, WeightedSet<String>>> table) {
|
---|
75 | String[] values = line.split(",", 4);
|
---|
76 | Category cat = Category.valueOf(values[0]);
|
---|
77 |
|
---|
78 | Subcategory subcat;
|
---|
79 | if (values[1].isEmpty()) {
|
---|
80 | subcat = Subcategory.ALL;
|
---|
81 | if (!cat.getSubCategories().isEmpty()) {
|
---|
82 | throw new IllegalArgumentException("Category " + cat
|
---|
83 | + " has subcategories, so ALL is not allowed in this table here:"
|
---|
84 | + line);
|
---|
85 | }
|
---|
86 | } else {
|
---|
87 | subcat = Subcategory.valueOf(values[1]);
|
---|
88 | if (!cat.isSubcategoryAllowed(subcat)) {
|
---|
89 | throw new IllegalArgumentException(
|
---|
90 | "" + subcat + " is not allowed as subcategory of " + cat
|
---|
91 | + " here :" + line);
|
---|
92 | }
|
---|
93 | }
|
---|
94 |
|
---|
95 | if (!table.containsKey(cat)) {
|
---|
96 | table.put(cat, new HashMap<>());
|
---|
97 | }
|
---|
98 | WeightedSet<String> map = table.get(cat).get(subcat);
|
---|
99 | Double count;
|
---|
100 | try {
|
---|
101 | count = Double.valueOf(values[2]);
|
---|
102 | } catch (NumberFormatException e) {
|
---|
103 | throw new IllegalArgumentException("'" + values[2]
|
---|
104 | + "' is not a good line count value here :" + line);
|
---|
105 |
|
---|
106 | }
|
---|
107 |
|
---|
108 | if (map != null) {
|
---|
109 | map = map.add(values[3].trim(), count);
|
---|
110 | } else {
|
---|
111 | Map<String, Double> first = new HashMap<>();
|
---|
112 | first.put(values[3].trim(), count);
|
---|
113 | map = new WeightedSet<String>(first);
|
---|
114 | }
|
---|
115 | table.get(cat).put(subcat, map);
|
---|
116 | }
|
---|
117 |
|
---|
118 | /**
|
---|
119 | * @param category the {@link Category} required
|
---|
120 | * @param subcategory the subcategory, or {@link Subcategory#ALL} if the
|
---|
121 | * category has no subcategory.
|
---|
122 | * @return text string that matches the Category and Subcategory as
|
---|
123 | * specified. Thee chosen text is weighted according to the count
|
---|
124 | * field of the text lines. Subsequent calls may return different
|
---|
125 | * results.
|
---|
126 | */
|
---|
127 | public String getText(Category category, Subcategory subcategory) {
|
---|
128 | return getStatements(category, subcategory).getRandom();
|
---|
129 | }
|
---|
130 |
|
---|
131 | }
|
---|