[5] | 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 | }
|
---|