package tudelft.mentalhealth.motivatepersisting; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.Random; import tudelft.utilities.statistic.WeightedSet; /** * contains Table 1/ Statements-nl-NL.csv or Statements=en.csv: the Statements * table with all available statements. The .csv files contain rows with 4 * columns of data: *
    *
  1. New Category *
  2. New subcat *
  3. Count *
  4. Statement (correct language) *
*/ class Statements { // contains for each Category and Subcategory a set of statements. private final Map>> statements; private static final Random random = new Random(); public Statements(Locale locale) { statements = readTable(locale); } /** * * @param cat required {@link Category} * @param subcat required {@link Subcategory} * @return all statements for given category and subcategory. */ public WeightedSet getStatements(Category cat, Subcategory subcat) { return statements.get(cat).get(subcat); } /** * read in the CSV table * * @return map containing the CSV file contents. * @throws IOException */ private Map>> readTable( Locale locale) { Map>> table = new HashMap<>(); String filename = "Statements-" + locale.toLanguageTag() + ".csv"; InputStream is = getClass().getResourceAsStream(filename); if (is == null) { throw new IllegalStateException("Resource not found: " + filename); } BufferedReader reader = new BufferedReader(new InputStreamReader(is)); reader.lines().forEach(line -> addLine(line, table)); return table; } /** * Add one line of comma-separated text (typically from csv file) to given * table. * * @param line the line of text, containing Category, Subcategory, text. * @param table the table to add the info in the line to */ private void addLine(String line, Map>> table) { String[] values = line.split(",", 4); Category cat = Category.valueOf(values[0]); Subcategory subcat; if (values[1].isEmpty()) { subcat = Subcategory.ALL; if (!cat.getSubCategories().isEmpty()) { throw new IllegalArgumentException("Category " + cat + " has subcategories, so ALL is not allowed in this table here:" + line); } } else { subcat = Subcategory.valueOf(values[1]); if (!cat.isSubcategoryAllowed(subcat)) { throw new IllegalArgumentException( "" + subcat + " is not allowed as subcategory of " + cat + " here :" + line); } } if (!table.containsKey(cat)) { table.put(cat, new HashMap<>()); } WeightedSet map = table.get(cat).get(subcat); Double count; try { count = Double.valueOf(values[2]); } catch (NumberFormatException e) { throw new IllegalArgumentException("'" + values[2] + "' is not a good line count value here :" + line); } if (map != null) { map = map.add(values[3].trim(), count); } else { Map first = new HashMap<>(); first.put(values[3].trim(), count); map = new WeightedSet(first); } table.get(cat).put(subcat, map); } /** * @param category the {@link Category} required * @param subcategory the subcategory, or {@link Subcategory#ALL} if the * category has no subcategory. * @return text string that matches the Category and Subcategory as * specified. Thee chosen text is weighted according to the count * field of the text lines. Subsequent calls may return different * results. */ public String getText(Category category, Subcategory subcategory) { return getStatements(category, subcategory).getRandom(); } }