Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a5acd69
i_1006 Add initial code changes for scoring problems
johnbrvc Sep 18, 2024
994a00d
i_1006 Added junit for ContestImportUtilities
johnbrvc Sep 19, 2024
f9644a9
i_1006 Fix JUnit tests and rebase errors
johnbrvc Jun 23, 2025
c4e49fa
i_1006 Rework for legacy TestDataGroup specification
johnbrvc Jul 5, 2025
c0bf453
i_1006 Remove debug prints from JUnit test
johnbrvc Jul 5, 2025
2e5986d
i_1006 Read problem test data using new TestDataGroup
johnbrvc Jul 6, 2025
a800aee
i_1006 Add Legacy Default Grader with JUnits
johnbrvc Jul 7, 2025
53d0cf7
i_1006 Fix bugs found by JUnit
johnbrvc Jul 8, 2025
c3f775b
i_1006 Adjust JUnits for new TestDataGroups
johnbrvc Jul 9, 2025
e1e622a
i1006: add "pointscoring" sample contest (v.1)
Jul 10, 2025
1d6262c
i1006 Fix JUnits to include ensureStaticLog()
johnbrvc Jul 10, 2025
5717d21
i_1006 Fix JUnit issues
johnbrvc Jul 10, 2025
8b22eb6
i1006: update "pointscoring" contest.yaml to specify "scoreboard-type"
Jul 10, 2025
5c17389
Merge pull request #1142 from johnbrvc/i1006_scoring_algorithm_changes
johnbrvc Jul 10, 2025
7f776b4
Merge pull request #1143 from clevengr/i1006_point_scoring_add_sample…
johnbrvc Jul 11, 2025
c69e128
i_1006 Remember scoreboard type in ContestInformation
johnbrvc Jul 11, 2025
449576c
i1006 Fix JUnits to include ensureStaticLog()
johnbrvc Jul 10, 2025
ed62158
i_1006 JUnit fixes
johnbrvc Jul 11, 2025
ec76b81
i_1006 Implement point scoring in DSA
johnbrvc Jul 13, 2025
f785e0c
i_1006 PR change requests to comments
johnbrvc Jul 16, 2025
6ff085e
i_1006 Add comment explaining comparision logic
johnbrvc Jul 16, 2025
dc2ae23
i_1006 Fix event feed for point scoring
johnbrvc Jul 18, 2025
b50c961
i_1006 allow LegacyGrader to accept list of judgments
johnbrvc Jul 18, 2025
253fdfd
i_1006 Add ignore_sample option to LegacyGrader
johnbrvc Jul 27, 2025
e3e8ae8
i_1006 use test data groups for validateCDP
johnbrvc Jul 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions src/edu/csus/ecs/pc2/clics/API202306/CLICSJudgement.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@

import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

import edu.csus.ecs.pc2.core.IInternalController;
import edu.csus.ecs.pc2.core.Utilities;
Expand All @@ -17,6 +22,7 @@
import edu.csus.ecs.pc2.core.model.JudgementRecord;
import edu.csus.ecs.pc2.core.model.Run;
import edu.csus.ecs.pc2.core.util.IJSONTool;
import edu.csus.ecs.pc2.services.core.JSONUtilities;

/**
* Contains the judgment for a submission (Accepted, Wrong Answer, etc).
Expand All @@ -38,9 +44,8 @@ public class CLICSJudgement {
@JsonProperty
private String judgement_type_id;

// Only for "score" type contests, N/A for ICPC pass/fail
// @JsonProperty
// private String score;
@JsonProperty
private double score;

@JsonProperty
private String start_time;
Expand All @@ -57,6 +62,8 @@ public class CLICSJudgement {
@JsonProperty
private double max_run_time;

private boolean isPointScoring = false;

/**
* Fill in properties for a judgment description.
*
Expand All @@ -71,6 +78,9 @@ public CLICSJudgement(IInternalContest model, IInternalController controller, Ru
id = submission.getElementId().toString();
submission_id = IJSONTool.getSubmissionId(submission);

// Remember this for serialization
isPointScoring = model.getContestInformation().isScoreboardTypeScore();

Date startJudgeDate = submission.getJudgeStartDate();
if(startJudgeDate == null) {
// Yikes! Using submission time since there is no judge start date... Something is amiss, but this is a last ditch guess
Expand Down Expand Up @@ -130,4 +140,33 @@ public CLICSJudgement(IInternalContest model, IInternalController controller, Ru
}
// else not much to do here if no start date.
}

public String toJSON() {
Set<String> exceptProps = new HashSet<String>();

getExceptProps(exceptProps);
try {
ObjectMapper mapper = JSONUtilities.getObjectMapper();
// for this judgment, create filter to omit inappropriate properties,
// 'score' in this case if not Point Scoring contest
SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.serializeAllExcept(exceptProps);
FilterProvider fp = new SimpleFilterProvider().addFilter("rtFilter", filter).setFailOnUnknownId(false);
mapper.setFilters(fp);
return mapper.writeValueAsString(this);
} catch (Exception e) {
return "Error creating JSON for judgment " + e.getMessage();
}
}

/**
* Get set of properties for which we do not want to serialize into JSON.
* This is so we don't serialize score for pass-fail contests
*
* @param exceptProps Set to fill in with property names to omit
*/
public void getExceptProps(Set<String> exceptProps) {
if(!isPointScoring){
exceptProps.add("score");
}
}
}
49 changes: 45 additions & 4 deletions src/edu/csus/ecs/pc2/clics/API202306/CLICSProblem.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
// Copyright (C) 1989-2025 PC2 Development Team: John Clevenger, Douglas Lane, Samir Ashoo, and Troy Boudreau.
package edu.csus.ecs.pc2.clics.API202306;

import java.util.HashSet;
import java.util.Set;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

import edu.csus.ecs.pc2.core.StringUtilities;
import edu.csus.ecs.pc2.core.model.IInternalContest;
import edu.csus.ecs.pc2.core.model.Problem;
import edu.csus.ecs.pc2.core.model.ProblemDataFiles;
import edu.csus.ecs.pc2.core.util.IJSONTool;
import edu.csus.ecs.pc2.imports.ccs.TestDataGroup;
import edu.csus.ecs.pc2.services.core.JSONUtilities;

/**
Expand All @@ -19,6 +28,7 @@
*
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonFilter("rtFilter")
public class CLICSProblem {

@JsonProperty
Expand Down Expand Up @@ -48,9 +58,8 @@ public class CLICSProblem {
@JsonProperty
private int test_data_count;

// only for "score" type contests, N/A for pc2/wf pass-fail type contests
// @JsonProperty
// private int max_score;
@JsonProperty
private double max_score;

// The next two will be 'null' for now until we implement the new json CPF
@JsonProperty("package")
Expand All @@ -59,6 +68,8 @@ public class CLICSProblem {
@JsonProperty
private CLICSFileReference [] statement;

private boolean isPointScoring = false;

/**
* Fill in properties for a Problem description.
*
Expand All @@ -82,15 +93,45 @@ public CLICSProblem(IInternalContest model, Problem problem, int ordinal) {
}
test_data_count = problem.getNumberTestCases();
time_limit = problem.getTimeOutInSeconds();
if(model.getContestInformation().isScoreboardTypeScore()) {
isPointScoring = true;
ProblemDataFiles problemDataFiles = model.getProblemDataFile(problem);
if(problemDataFiles != null) {
TestDataGroup [] testDataGroups = problemDataFiles.getJudgesDataGroups();
// Really, there's only 1 top level TestDataGruop
Comment thread
clevengr marked this conversation as resolved.
Outdated
if(testDataGroups != null && testDataGroups.length > 0) {
max_score = testDataGroups[0].getRangeMax();
}
}
}
}

public String toJSON() {
Set<String> exceptProps = new HashSet<String>();

getExceptProps(exceptProps);
try {
ObjectMapper mapper = JSONUtilities.getObjectMapper();
// for this problem, create filter to omit inappropriate properties,
// 'max_score' in this case if not Point Scoring contest
SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.serializeAllExcept(exceptProps);
FilterProvider fp = new SimpleFilterProvider().addFilter("rtFilter", filter).setFailOnUnknownId(false);
mapper.setFilters(fp);
return mapper.writeValueAsString(this);
} catch (Exception e) {
return "Error creating JSON for CLICS problem info " + e.getMessage();
return "Error creating JSON for CLICSProblem " + e.getMessage();
}
}

/**
* Get set of properties for which we do not want to serialize into JSON.
* This is so we don't serialize max_score for pass-fail contests
*
* @param exceptProps Set to fill in with property names to omit
*/
public void getExceptProps(Set<String> exceptProps) {
if(!isPointScoring){
exceptProps.add("max_score");
}
}
}
51 changes: 47 additions & 4 deletions src/edu/csus/ecs/pc2/clics/API202306/CLICSProblemScore.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,22 @@
package edu.csus.ecs.pc2.clics.API202306;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

import edu.csus.ecs.pc2.core.StringUtilities;
import edu.csus.ecs.pc2.core.Utilities;
import edu.csus.ecs.pc2.core.model.IInternalContest;
import edu.csus.ecs.pc2.core.standings.ProblemSummaryInfo;
import edu.csus.ecs.pc2.services.core.JSONUtilities;

/**
* Contains information about the score a team received for a single problem.
Expand All @@ -19,6 +28,7 @@
*
*/

@JsonFilter("rtFilter")
public class CLICSProblemScore {

@JsonProperty
Expand All @@ -33,13 +43,14 @@ public class CLICSProblemScore {
@JsonProperty
private boolean solved;

// Not needed for pass-fail contest
// @JsonProperty
// private double score;
@JsonProperty
private double score;

@JsonProperty
private int time;

private boolean isPointScoring = false;

/**
* Provide empty constructor for Jackson deserialization
*/
Expand All @@ -54,7 +65,7 @@ public CLICSProblemScore() {
* @param probEleToShort hashmap for mapping problem elementid to shortname
* @param versionInfo
*/
public CLICSProblemScore(HashMap<String, String> probEleToShort, ProblemSummaryInfo psi) {
public CLICSProblemScore(IInternalContest model, HashMap<String, String> probEleToShort, ProblemSummaryInfo psi) {
num_judged = Utilities.nullSafeToInt(psi.getAttempts(), 0);
num_pending = Utilities.nullSafeToInt(psi.getIsPending(), 0);
problem_id = psi.getProblemId();
Expand All @@ -67,6 +78,38 @@ public CLICSProblemScore(HashMap<String, String> probEleToShort, ProblemSummaryI
// Problem solution time is in minutes
time = StringUtilities.getIntegerValue(psi.getSolutionTime(), 0);
}
if(model != null) {
isPointScoring = model.getContestInformation().isScoreboardTypeScore();
}
}

public String toJSON() {
Set<String> exceptProps = new HashSet<String>();

getExceptProps(exceptProps);
try {
ObjectMapper mapper = JSONUtilities.getObjectMapper();
// for this problem's score, create filter to omit inappropriate properties,
// 'score' in this case if not Point Scoring contest
SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.serializeAllExcept(exceptProps);
FilterProvider fp = new SimpleFilterProvider().addFilter("rtFilter", filter).setFailOnUnknownId(false);
mapper.setFilters(fp);
return mapper.writeValueAsString(this);
} catch (Exception e) {
return "Error creating JSON for CLICSProblemScore " + e.getMessage();
}
}

/**
* Get set of properties for which we do not want to serialize into JSON.
* This is so we don't serialize score for pass-fail contests
*
* @param exceptProps Set to fill in with property names to omit
*/
public void getExceptProps(Set<String> exceptProps) {
if(!isPointScoring){
exceptProps.add("score");
}
}

/**
Expand Down
Loading