overhauled histograms

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2026-03-10 11:34:52 +01:00
parent 577e99d840
commit 2cd99f362b
13 changed files with 144 additions and 24 deletions

View File

@@ -144,6 +144,7 @@ public class Field {
public static final String START_DATE = "start_date";
public static final String START_TIME = "start_time";
public static final String STATE = "state";
public static final String STATS = "stats";
public static final String STATUS = "status";
public static final String STATUS_CODE = "code";
public static final String SUBJECT = "subject";

View File

@@ -107,18 +107,79 @@ public class Poll implements Mappable {
}
public static class Evaluation {
// Map<Option → Map<Weight → Count>>
private HashMap<Integer,Map<Integer,Integer>> selections = new HashMap<>();
public void count(ResultSet rs) throws SQLException {
var optionId = rs.getInt(OPTION_ID);
var userId = rs.getObject(USER);
var weight = rs.getInt(WEIGHT);
var optionStats = selections.computeIfAbsent(optionId, k -> new HashMap<>());
optionStats.compute(weight, (k, sum) -> sum == null ? 1 : sum + 1);
private static class Histogram extends HashMap<Integer,Integer>{
public Double average() {
var sum = 0;
var count = 0;
for (var entry : entrySet()){
var weight = entry.getKey();
var votes = entry.getValue();
count += votes;
sum += weight * votes;
}
if (count < 1) return null;
return sum/(double) count;
}
}
private static class OptionStats extends HashMap<Integer,Histogram>{}
private static class Stats extends HashMap<Double,OptionStats>{
public Stats(OptionStats optionStats) {
for (var entry : optionStats.entrySet()){
var optionId = entry.getKey();
var histo = entry.getValue();
var average = histo.average();
var os = get(average);
if (os == null) put(average,os = new OptionStats());
os.put(optionId,histo);
}
}
}
/*
{
options : {
1: option 1
2: option 2
},
stat : {
0.571 : { // average
1 : { // option
-2 : 0, // weight → selections
-1 : 1,
0 : 2
1 : 3
2 : 1
}
2 :
}
}
}
public HashMap<Integer, Map<Integer, Integer>> toMap() {
return selections;
*/
private final Map<Integer, Option> options = new HashMap<>();
private final OptionStats optionStats = new OptionStats();
public Evaluation(Poll poll) {
for (var option : poll.options){
options.put(option.id,option);
var histo = new Histogram();
for (var w : poll.weights.keySet()) histo.put(w,0);
optionStats.put(option.id,histo);
}
}
public void count(ResultSet rs) throws SQLException {
var optionId = rs.getInt(OPTION_ID);
//var userId = rs.getObject(USER);
var weight = rs.getInt(WEIGHT);
var histogram = optionStats.get(optionId);
histogram.put(weight,histogram.get(weight)+1);
}
public Map<Double,?> toMap() {
return new Stats(optionStats);
}
}