![JAR search and dependency download from the Maven repository](/logo.png)
io.github.oliviercailloux.javagrade.graders.PersonsManagerGrader Maven / Gradle / Ivy
The newest version!
package io.github.oliviercailloux.javagrade.graders;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultiset;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators;
import com.google.common.collect.Maps;
import com.google.common.collect.Streams;
import com.google.common.util.concurrent.SimpleTimeLimiter;
import io.github.oliviercailloux.grade.Criterion;
import io.github.oliviercailloux.grade.CriterionGradeWeight;
import io.github.oliviercailloux.grade.DeadlineGrader;
import io.github.oliviercailloux.grade.GitGeneralGrader;
import io.github.oliviercailloux.grade.IGrade;
import io.github.oliviercailloux.grade.RepositoryFetcher;
import io.github.oliviercailloux.grade.WeightingGrade;
import io.github.oliviercailloux.grade.old.Mark;
import io.github.oliviercailloux.jaris.exceptions.TryCatchAll;
import io.github.oliviercailloux.jaris.exceptions.TryCatchAllVoid;
import io.github.oliviercailloux.jaris.throwing.TSupplier;
import io.github.oliviercailloux.javagrade.bytecode.Instanciator;
import io.github.oliviercailloux.javagrade.utils.StdOutErrLogger;
import io.github.oliviercailloux.javagrade.utils.Summarizer;
import io.github.oliviercailloux.personsmanager.Person;
import io.github.oliviercailloux.personsmanager.PersonsManager;
import io.github.oliviercailloux.personsmanager.RedundancyCounter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Supplier;
import java.util.stream.IntStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PersonsManagerGrader {
public static Supplier> wrap(TSupplier supplier) {
return () -> {
try {
return Optional.of(supplier.get());
} catch (@SuppressWarnings("unused") Exception e) {
return Optional.empty();
}
};
}
private static class MyInputStream extends InputStream {
private final ByteArrayInputStream delegate;
private boolean wasClosed;
private MyInputStream(String content) {
delegate = new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8));
wasClosed = false;
}
public boolean wasClosed() {
return wasClosed;
}
@Override
public int read() throws IOException {
return delegate.read();
}
@Override
public void close() throws IOException {
wasClosed = true;
delegate.close();
}
}
@SuppressWarnings("unused")
private static final Logger LOGGER = LoggerFactory.getLogger(PersonsManagerGrader.class);
public static final String PREFIX = "persons-manager";
public static final ZonedDateTime DEADLINE =
ZonedDateTime.parse("2021-03-31T23:59:59+01:00[Europe/Paris]");
public static void main(String[] args) throws Exception {
/* Nb should give 0.5/20 pts for user.grade. */
final RepositoryFetcher fetcher = RepositoryFetcher.withPrefix(PREFIX)
.setRepositoriesFilter(r -> r.getUsername().equals("Student"));
final GitGeneralGrader grader =
GitGeneralGrader
.using(fetcher,
DeadlineGrader.usingInstantiatorGrader(PersonsManagerGrader::grade, DEADLINE)
.setPenalizer(DeadlineGrader.LinearPenalizer
.proportionalToLateness(Duration.ofSeconds(300))))
.setExcludeCommitsByAuthors(
ImmutableSet.of("Olivier Cailloux", "github-classroom[bot]"));
grader.grade();
Summarizer.create().setPrefix(PREFIX)
.setDissolveCriteria(ImmutableSet.of(Criterion.given("Warnings"))).summarize();
}
public static IGrade grade(Instanciator instanciator) {
return new PersonsManagerGrader(instanciator).grade();
}
private final Instanciator instanciator;
private final ExecutorService executors;
private PersonsManagerGrader(Instanciator instanciator) {
this.instanciator = checkNotNull(instanciator);
executors = Executors.newCachedThreadPool();
}
public IGrade grade() {
final ImmutableSet.Builder gradeBuilder = ImmutableSet.builder();
/* TODO redirect logger seems to also redirect info logs! */
try (StdOutErrLogger redirecter = StdOutErrLogger.redirect()) {
LOGGER.info("Grading");
gradeBuilder.add(CriterionGradeWeight.from(Criterion.given("Size and static factories"),
sizeAndStaticFactories(), 2.5d));
gradeBuilder.add(CriterionGradeWeight.from(Criterion.given("Task force"), taskForce(), 2d));
gradeBuilder.add(CriterionGradeWeight.from(Criterion.given("Contains"), contains(), 2d));
gradeBuilder.add(
CriterionGradeWeight.from(Criterion.given("Contains stream"), containsStream(), 2.5d));
gradeBuilder.add(CriterionGradeWeight.from(Criterion.given("Map"), map(), 2d));
gradeBuilder.add(CriterionGradeWeight.from(Criterion.given("Iterator"), iterator(), 2d));
gradeBuilder.add(CriterionGradeWeight.from(Criterion.given("Id iterator"), idIterator(), 2d));
gradeBuilder.add(CriterionGradeWeight.from(Criterion.given("Counter"), counter(), 2.5d));
gradeBuilder
.add(CriterionGradeWeight.from(Criterion.given("To string"), toStringGrade(), 2d));
}
executors.shutdownNow();
return WeightingGrade.from(gradeBuilder.build());
}
private TryCatchAll getManager() {
final TryCatchAll tryTarget = TryCatchAll.get(
() -> instanciator.getInstanceOrThrow(PersonsManager.class, "empty", ImmutableList.of()))
.or(() -> instanciator.getInstanceOrThrow(PersonsManager.class), (e1, e2) -> e1);
return tryTarget.andApply(target -> SimpleTimeLimiter.create(executors).newProxy(target,
PersonsManager.class, Duration.ofSeconds(5)));
}
private TryCatchAll getManagerGiven(Iterable arg) {
return TryCatchAll.get(() -> instanciator.getInstanceOrThrow(PersonsManager.class, "given",
ImmutableList.of(arg)));
}
private TryCatchAll getManagerWith(List persons) {
return getManager().andConsume(m -> m.setPersons(persons));
}
TryCatchAll getManagerWithTaskForce(Person... persons) {
return getManager().andConsume(m -> m.setTaskForce(persons));
}
private WeightingGrade sizeAndStaticFactories() {
final ImmutableSet.Builder gradeBuilder = ImmutableSet.builder();
{
final TryCatchAll manager = TryCatchAll.get(
() -> instanciator.getInstanceOrThrow(PersonsManager.class, "empty", ImmutableList.of()));
final TryCatchAll size = manager.andApply(PersonsManager::size);
final Mark mark = size.map(s -> Mark.binary(s == 0), PersonsManagerGrader::exc);
gradeBuilder.add(CriterionGradeWeight.from(Criterion.given("Empty"), mark, 1d));
}
{
final TryCatchAll sizeList =
getManagerGiven(ImmutableList.of()).andApply(PersonsManager::size);
final TryCatchAll sizeSet =
getManagerGiven(ImmutableMultiset.of()).andApply(PersonsManager::size);
final Mark mark = sizeList.and(sizeSet, (sL, sS) -> Mark.binary(sL == 0 && sS == 0))
.orMapCause(PersonsManagerGrader::exc);
gradeBuilder.add(CriterionGradeWeight.from(Criterion.given("Given empty coll"), mark, 0.5d));
}
{
final ImmutableList persons = IntStream.range(1000, 1100).boxed()
.map(PersonsManagerGrader::personWithId).collect(ImmutableList.toImmutableList());
final TryCatchAll size =
getManagerGiven(ImmutableMultiset.copyOf(persons)).andApply(PersonsManager::size);
final Mark mark = size.map(s -> Mark.binary(s == 100), PersonsManagerGrader::exc);
gradeBuilder.add(
CriterionGradeWeight.from(Criterion.given("Given 100 distinct persons"), mark, 0.5d));
}
{
final TryCatchAll manager = getManagerWith(ImmutableList.of());
final TryCatchAll size = manager.andApply(PersonsManager::size);
final Mark mark = size.map(s -> Mark.binary(s == 0), PersonsManagerGrader::exc);
gradeBuilder.add(CriterionGradeWeight.from(Criterion.given("Set to empty"), mark, 0.5d));
}
{
final ImmutableList persons = IntStream.range(1000, 1100).boxed()
.map(i -> Person.given(i, "The person " + i)).collect(ImmutableList.toImmutableList());
final TryCatchAll manager = getManagerWith(persons);
final TryCatchAll size = manager.andApply(PersonsManager::size);
final Mark mark = size.map(s -> Mark.binary(s == 100), PersonsManagerGrader::exc);
gradeBuilder.add(CriterionGradeWeight.from(Criterion.given("Set 100 persons"), mark, 1d));
}
{
final ImmutableList persons =
Streams
.concat(
IntStream.range(1000, 1100).boxed()
.map(i -> Person.given(455, "The person " + i)),
IntStream.range(1200, 1300).boxed().map(i -> Person.given(81, "The person " + i)))
.collect(ImmutableList.toImmutableList());
final TryCatchAll manager = getManagerWith(persons);
final TryCatchAll size = manager.andApply(PersonsManager::size);
final Mark mark = size.map(s -> Mark.binary(s == 200), PersonsManagerGrader::exc);
gradeBuilder.add(CriterionGradeWeight
.from(Criterion.given("Set 200 persons with some duplicate ids"), mark, 1d));
}
{
final ImmutableList persons = Streams
.concat(
IntStream.range(1000, 1100).boxed().map(i -> Person.given(455, "The person " + i)),
IntStream.range(1000, 1100).boxed().map(i -> Person.given(455, "The person " + i)),
IntStream.range(1000, 1100).boxed().map(i -> Person.given(455, "The person " + i)))
.collect(ImmutableList.toImmutableList());
final TryCatchAll manager = getManagerWith(persons);
final TryCatchAll size = manager.andApply(PersonsManager::size);
final Mark mark = size.map(s -> Mark.binary(s == 100), PersonsManagerGrader::exc);
gradeBuilder.add(CriterionGradeWeight.from(
Criterion.given("Set 100 unique persons with some duplicates and duplicate ids"), mark,
0.5d));
}
return WeightingGrade.from(gradeBuilder.build());
}
private WeightingGrade taskForce() {
final ImmutableSet.Builder gradeBuilder = ImmutableSet.builder();
{
final TryCatchAll managerSetMarked = getManager().andApply(m -> TryCatchAllVoid
.run(m::setTaskForce).map(() -> Mark.zero("Set succeeded but shouldn’t have."),
t -> Mark.binary(t instanceof IllegalArgumentException, "",
"Incorrect exception when set: " + t)));
final Mark mark = managerSetMarked.orMapCause(t1 -> Mark.zero("Got init exception: " + t1));
// final TryCatchAll> managerSet = getManager()
// .flatMap(m -> TryCatchAllVoid.run(m::setTaskForce).map(Optional::empty, Optional::of));
// final Mark mark = managerSet.map(
// o -> o.map(t -> Mark.binary(t instanceof IllegalArgumentException, "",
// "Incorrect exception when set: " + t))
// .orElse(Mark.zero("Set succeeded but shouldn’t have.")),
// t1 -> Mark.zero("Got init exception: " + t1));
// final Try managerSet = manager.and(m -> m.setTaskForce());
// final Mark setMark = managerSet.map(m2 -> Mark.zero("Set succeeded."),
// t2 -> Mark.binary(t2 instanceof IllegalArgumentException));
// final Mark mark = manager.map(m1 -> setMark, t1 -> Mark.zero("Got init exception: " + t1));
// final boolean setFailed = manager.isSuccess() && managerSet.isFailure();
// final boolean rightExc = setFailed && isIllegalArgumentFailure(managerSet);
// final String comment = setFailed ? (rightExc ? "" : "Got exception: " +
// managerSet.getCause()) : "";
// final Mark mark = Mark.binary(setFailed && rightExc, "", comment);
gradeBuilder.add(CriterionGradeWeight.from(
Criterion.given("Set empty task force, thrown IllegalArgumentException"), mark, 1d));
}
{
final TryCatchAll manager = getManager();
final TryCatchAll> managerSet = manager.andApply(m -> TryCatchAllVoid
.run(() -> m.setTaskForce(personWithId(416), personWithId(417), personWithId(418)))
.map(Optional::empty, Optional::of));
final Mark mark = managerSet.map(
o -> o
.map(t -> Mark.binary(t instanceof IllegalArgumentException, "",
"Incorrect exception when set: " + t))
.orElse(Mark.zero("Set succeeded but shouldn’t have.")),
t1 -> Mark.zero("Got init exception: " + t1));
gradeBuilder.add(CriterionGradeWeight.from(
Criterion.given("Set triple task force, thrown IllegalArgumentException"), mark, 1d));
}
{
final TryCatchAll manager = getManager();
final TryCatchAll sizeStart = manager.andApply(PersonsManager::size);
final TryCatchAll managerSet =
manager.andConsume(m -> m.setTaskForce(personWithId(416)));
final TryCatchAll size = managerSet.andApply(PersonsManager::size);
final Mark mark = sizeStart.and(size, (sS, s) -> Mark.binary(sS == 0 && s == 1))
.orMapCause(PersonsManagerGrader::exc);
gradeBuilder.add(
CriterionGradeWeight.from(Criterion.given("Set singleton task force, size 1"), mark, 1d));
}
{
final TryCatchAll manager = getManager();
final TryCatchAll sizeStart = manager.andApply(PersonsManager::size);
final TryCatchAll managerSet =
manager.andConsume(m -> m.setTaskForce(personWithId(416), personWithId(41)));
final TryCatchAll size = managerSet.andApply(PersonsManager::size);
final Mark mark = sizeStart.and(size, (sS, s) -> Mark.binary(sS == 0 && s == 2))
.orMapCause(PersonsManagerGrader::exc);
gradeBuilder
.add(CriterionGradeWeight.from(Criterion.given("Set dual task force, size 2"), mark, 1d));
}
return WeightingGrade.from(gradeBuilder.build());
}
private WeightingGrade contains() {
final ImmutableSet.Builder gradeBuilder = ImmutableSet.builder();
// {
// final Try managerSet = getManagerWith(ImmutableList.of());
// final Try containsEmptyName = managerSet.flatMap(m -> m.contains(""));
// final Mark mark = containsEmptyName.map(b -> Mark.binary(!b), PersonsManagerGrader::exc);
// gradeBuilder
// .add(CriterionGradeWeight.from(Criterion.given("Set to empty, does not contain empty name"),
// mark, 0.5d));
// }
{
final ImmutableList persons = IntStream.range(1000, 1100).boxed()
.map(i -> Person.given(i, "The person " + i)).collect(ImmutableList.toImmutableList());
final TryCatchAll managerSet = getManagerWith(persons);
final TryCatchAll containsRight100 =
managerSet.andApply(m -> !m.contains("The person 100"));
final TryCatchAll containsRight1000 =
managerSet.andApply(m -> m.contains("The person 1000"));
final TryCatchAll containsRight =
containsRight100.and(containsRight1000, (r100, r1000) -> r100 && r1000);
final Mark mark =
containsRight.map(c -> Mark.binary(c, "", "Invalid contains"), PersonsManagerGrader::exc);
gradeBuilder.add(CriterionGradeWeight.from(Criterion.given("Set 100 persons"), mark, 1d));
}
{
final ImmutableList persons = Streams
.concat(
IntStream.range(1000, 1100).boxed().map(i -> Person.given(455, "The person " + i)),
IntStream.range(1000, 1100).boxed().map(i -> Person.given(455, "The person " + i)),
IntStream.range(1000, 1100).boxed().map(i -> Person.given(455, "The person " + i)))
.collect(ImmutableList.toImmutableList());
final TryCatchAll managerSet = getManagerWith(persons);
final TryCatchAll containsRight100 =
managerSet.andApply(m -> !m.contains("The person 100"));
final TryCatchAll containsRight1000 =
managerSet.andApply(m -> m.contains("The person 1000"));
final TryCatchAll containsRight =
containsRight100.and(containsRight1000, (r100, r1000) -> r100 && r1000);
final Mark mark =
containsRight.map(c -> Mark.binary(c, "", "Invalid contains"), PersonsManagerGrader::exc);
gradeBuilder.add(CriterionGradeWeight.from(
Criterion.given("Set 100 unique persons with some duplicates and duplicate ids"), mark,
1d));
}
return WeightingGrade.from(gradeBuilder.build());
}
private WeightingGrade containsStream() {
final ImmutableSet.Builder gradeBuilder = ImmutableSet.builder();
{
final ImmutableList persons = IntStream.range(1000, 1100).boxed()
.map(i -> Person.given(i, "The person " + i)).collect(ImmutableList.toImmutableList());
final TryCatchAll managerSet = getManagerWith(persons);
final TryCatchAll containsRight1 =
managerSet.andApply(m -> !m.contains(new MyInputStream("")));
managerSet.andConsume(m -> m.setPersons(ImmutableList.of(Person.given(21, ""))));
final TryCatchAll containsRight2 =
managerSet.andApply(m -> m.contains(new MyInputStream("")));
final TryCatchAll containsRight =
containsRight1.and(containsRight2, (b1, b2) -> b1 && b2);
final Mark mark =
containsRight.map(c -> Mark.binary(c, "", "Invalid contains"), PersonsManagerGrader::exc);
gradeBuilder
.add(CriterionGradeWeight.from(Criterion.given("Contains stream empty name"), mark, 1d));
}
{
final ImmutableList persons1 = Streams
.concat(
IntStream.range(1000, 1100).boxed().map(i -> Person.given(455, "The person " + i)),
IntStream.range(1000, 1100).boxed().map(i -> Person.given(455, "The person " + i)),
IntStream.range(1000, 1100).boxed().map(i -> Person.given(455, "The person " + i)))
.collect(ImmutableList.toImmutableList());
final TryCatchAll managerSet = getManagerWith(persons1);
/** Thanks to https://www.babygaga.com/25-names-that-have-more-than-letters/. */
@SuppressWarnings("resource")
final MyInputStream stream1 = new MyInputStream("Asbjørn Nuñez");
@SuppressWarnings("resource")
final MyInputStream stream2 = new MyInputStream("Asbjørn Nuñez");
final ImmutableList persons2 =
Streams
.concat(
IntStream.range(1000, 1100).boxed()
.map(i -> Person.given(455, "The person " + i)),
IntStream.range(1000, 1100).boxed().map(i -> Person.given(455, "Asbjørn Nuñez")),
IntStream.range(1000, 1100).boxed()
.map(i -> Person.given(455, "The person " + i)))
.collect(ImmutableList.toImmutableList());
final TryCatchAll containsRight = managerSet.andApply(m -> {
final boolean contains1 = m.contains(stream1);
m.setPersons(persons2);
final boolean contains2 = m.contains(stream2);
return !contains1 && contains2;
});
final Mark markContains =
containsRight.map(c -> Mark.binary(c, "", "Invalid contains"), PersonsManagerGrader::exc);
final Mark markAll =
containsRight.map(c -> Mark.binary(c && !stream1.wasClosed() && !stream2.wasClosed()),
PersonsManagerGrader::exc);
gradeBuilder.add(CriterionGradeWeight.from(Criterion.given("Contains stream Asbjørn Nuñez"),
WeightingGrade.from(ImmutableSet.of(
CriterionGradeWeight.from(Criterion.given("Contains"), markContains, 0.75d),
CriterionGradeWeight.from(Criterion.given("Contains and not closed"), markAll,
0.5d))),
1d));
}
return WeightingGrade.from(gradeBuilder.build());
}
private WeightingGrade map() {
final ImmutableSet.Builder gradeBuilder = ImmutableSet.builder();
{
// Unique names but one dupl id.
final ImmutableList persons = Streams
.concat(IntStream.range(1000, 1100).boxed().map(i -> Person.given(i, "The person " + i)),
IntStream.range(1099, 1200).boxed().map(i -> Person.given(i, "The person " + i * 10)))
.collect(ImmutableList.toImmutableList());
final TryCatchAll managerSet = getManagerWith(persons);
final TryCatchAll managerSetMarked = managerSet.andApply(m -> TryCatchAllVoid
.run(m::toMap).map(() -> Mark.zero("toMap succeeded but shouldn’t have."),
t -> Mark.binary(
(t instanceof IllegalArgumentException) || (t instanceof IllegalStateException),
"", "Incorrect toMap exception: " + t)));
final Mark mark = managerSetMarked.orMapCause(t1 -> Mark.zero("Got init exception: " + t1));
gradeBuilder.add(CriterionGradeWeight
.from(Criterion.given("Set a duplicate id, toMap throwing"), mark, 1d));
}
{
final ImmutableList persons = IntStream.range(1000, 1100).boxed()
.map(PersonsManagerGrader::personWithId).collect(ImmutableList.toImmutableList());
final TryCatchAll managerSet = getManagerWith(persons);
final TryCatchAll
© 2015 - 2025 Weber Informatics LLC | Privacy Policy