sclass Scorer {
double score, total;
L successes, errors; // set to non-null if you want them filled
bool verboseFailures, verboseAll;
void addZeroToOne(double score) {
++total;
this.score += clamp(score, 0, 1);
}
void addZeroToOneError(double error) {
addZeroToOne(1-error);
}
void addError { add(false); }
void addOK { add(true); }
bool add(bool correct) {
++total;
if (correct) ++score;
ret correct;
}
bool add(bool correct, A info) {
main.add(correct ? successes : errors, info);
if (verboseAll || verboseFailures && !correct)
print((correct ? "[GOOD] " : "[BAD] ") + info);
ret add(correct);
}
// works if you use Scorer or Scorer
void eq(O a, O b) {
if (_eq(a, b))
add(true);
else
add(false, (A) (a + " != " + b));
}
void print() {
main.print(toString());
}
toString {
ret formatDouble(ratioToPercent(score, total), 1) + "% correct (n=" + total + ")";
}
double get() {
ret ratioToPercent(score, total);
}
double percentScore() { ret get(); }
bool allCorrect() {
ret score == total;
}
void add(Scorer scorer) {
if (scorer == null) ret;
total += scorer.total;
score += scorer.score;
addAll(successes, scorer.successes);
addAll(errors, scorer.errors);
}
}