![JAR search and dependency download from the Maven repository](/logo.png)
io.github.oliviercailloux.grade.WeightingGrader Maven / Gradle / Ivy
package io.github.oliviercailloux.grade;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.ImmutableSet;
import io.github.oliviercailloux.grade.old.Mark;
import io.github.oliviercailloux.jaris.throwing.TFunction;
import io.github.oliviercailloux.jaris.throwing.TPredicate;
import java.io.IOException;
import java.util.List;
import java.util.Optional;
import java.util.Set;
/**
* Could consider a WeightingGraderBuilder.
* Add (c1, predicate1, w1).
* Add (c2, p2, w2)
* Add c3, w3), then on the returned object:
*
* - Add f1, then on the returned object:
*
*
* - Add c1, p1 (over the output of f1), w1
*
- Add c2, p2 (f1), w2
*
- end f1
*
- f2
*
- Add c3, p3(f2), w3
*
- end f2
*
- end c3
*
- Add (c4, w4), …
*
*
* One important advantage to lambdas here is that the intermediate objects need not exist for this
* to make sense: if no pathroot, the corresponding structure may be empty; if the function does not
* work, it may avoid applying the remaining predicates, … Some of these functions may return
* {@code Optional} to indicate conditional continuation (or even
* {@code Optional}).
*
* @param the input type to the grader
*/
public class WeightingGrader {
public static class CriterionGraderWeight {
public static CriterionGraderWeight given(Criterion criterion,
TPredicate predicate, double weight) {
return new CriterionGraderWeight<>(criterion,
(Optional o) -> Mark.binary(o.isPresent() && predicate.test(o.get())), weight);
}
public static CriterionGraderWeight given(Criterion criterion,
TFunction, IGrade, IOException> grader, double weight) {
return new CriterionGraderWeight<>(criterion, grader, weight);
}
private final Criterion criterion;
private final TFunction, IGrade, IOException> grader;
private final double weight;
private CriterionGraderWeight(Criterion criterion,
TFunction, IGrade, IOException> grader, double weight) {
this.criterion = checkNotNull(criterion);
this.grader = checkNotNull(grader);
this.weight = weight;
}
public CriterionGradeWeight grade(Optional path) throws IOException {
return CriterionGradeWeight.from(criterion, grader.apply(path), weight);
}
}
public static WeightingGrader getGrader(List> cs) {
final ImmutableSet, CriterionGradeWeight, IOException>> graders =
cs.stream().map(c -> ((TFunction, CriterionGradeWeight, IOException>) c::grade))
.collect(ImmutableSet.toImmutableSet());
return new WeightingGrader<>(graders);
}
private final ImmutableSet, CriterionGradeWeight, IOException>> subGraders;
private WeightingGrader(
Set, CriterionGradeWeight, IOException>> subGraders) {
checkArgument(!subGraders.isEmpty());
this.subGraders = ImmutableSet.copyOf(subGraders);
}
public WeightingGrade getGrade(Optional source) throws IOException {
final ImmutableSet.Builder builder = ImmutableSet.builder();
for (TFunction, CriterionGradeWeight, IOException> subGrader : subGraders) {
final CriterionGradeWeight grade = subGrader.apply(source);
builder.add(grade);
}
return WeightingGrade.from(builder.build());
}
}