Skip to content

Commit

Permalink
Allow scorer to output percentage of subtask points
Browse files Browse the repository at this point in the history
  • Loading branch information
fushar committed Aug 12, 2024
1 parent 6a4faf9 commit e49924b
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 17 deletions.
8 changes: 7 additions & 1 deletion include/tcframe/runner/aggregator/MinAggregator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,13 @@ class MinAggregator : public TestCaseAggregator {
aggregatedVerdict = max(aggregatedVerdict, testCaseVerdict.verdict());

if (testCaseVerdict.verdict() == Verdict::ok()) {
aggregatedPoints = min(aggregatedPoints, testCaseVerdict.points().value());
double points = 0.0;
if (testCaseVerdict.percentage()) {
points = testCaseVerdict.percentage().value() * subtaskPoints / 100.0;
} else if (testCaseVerdict.points()) {
points = testCaseVerdict.points().value();
}
aggregatedPoints = min(aggregatedPoints, points);
} else if (!(testCaseVerdict.verdict() == Verdict::ac())) {
aggregatedPoints = 0;
}
Expand Down
33 changes: 23 additions & 10 deletions include/tcframe/runner/verdict/TestCaseVerdict.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ struct TestCaseVerdict {
private:
Verdict verdict_;
optional<double> points_;
optional<int> percentage_;

public:
TestCaseVerdict()
Expand All @@ -29,6 +30,11 @@ struct TestCaseVerdict {
: verdict_(move(status))
, points_(optional<double>(points)) {}

TestCaseVerdict(Verdict status, optional<double> points, optional<int> percentage)
: verdict_(move(status))
, points_(move(points))
, percentage_(move(percentage)) {}

const Verdict& verdict() const {
return verdict_;
}
Expand All @@ -37,8 +43,12 @@ struct TestCaseVerdict {
return points_;
}

const optional<int>& percentage() const {
return percentage_;
}

bool operator==(const TestCaseVerdict& o) const {
return tie(verdict_, points_) == tie(o.verdict_, o.points_);
return tie(verdict_, points_, percentage_) == tie(o.verdict_, o.points_, percentage_);
}

string toBriefString() const {
Expand All @@ -59,17 +69,20 @@ struct TestCaseVerdict {

private:
string pointsToString() const {
if (!points_) {
return "";
}
string points = StringUtils::toString(points_.value(), 2);
while (points.back() == '0') {
points.pop_back();
if (points_) {
string points = StringUtils::toString(points_.value(), 2);
while (points.back() == '0') {
points.pop_back();
}
if (points.back() == '.') {
points.pop_back();
}
return points;
}
if (points.back() == '.') {
points.pop_back();
if (percentage_) {
return "" + StringUtils::toString(percentage_);
}
return points;
return "";
}
};

Expand Down
18 changes: 14 additions & 4 deletions include/tcframe/runner/verdict/TestCaseVerdictParser.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <istream>
#include <iostream>
#include <stdexcept>
#include <string>
#include <sys/signal.h>
Expand Down Expand Up @@ -35,12 +36,21 @@ class TestCaseVerdictParser {
if (!getline(*in, secondLine)) {
throw runtime_error("Expected: <points> on the second line");
}
string pointsString = StringUtils::split(secondLine, ' ')[0];
optional<double> points = StringUtils::toNumber<double>(pointsString);
if (points) {
string result = StringUtils::split(secondLine, ' ')[0];

if (!result.empty() && result.back() == '%') {
optional<int> percentage = StringUtils::toNumber<int>(result.substr(0, result.size() - 1));
if (!percentage) {
throw runtime_error("Unknown percentage format: " + result);
}
return {Verdict::ok(), optional<double>(), percentage};
} else {
optional<double> points = StringUtils::toNumber<double>(result);
if (!points) {
throw runtime_error("Unknown points format: " + result);
}
return {Verdict::ok(), points.value()};
}
throw runtime_error("Unknown points format: " + pointsString);
}

throw runtime_error("Unknown verdict: " + verdictCode);
Expand Down
9 changes: 9 additions & 0 deletions test/unit/tcframe/runner/aggregator/MinAggregatorTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,13 @@ TEST_F(MinAggregatorTests, Aggregate_MinOKPoints) {
EXPECT_THAT(aggregator.aggregate(verdicts, 70), Eq(SubtaskVerdict(Verdict::ok(), 20)));
}

TEST_F(MinAggregatorTests, Aggregate_MinOKPercentage) {
vector<TestCaseVerdict> verdicts = {
TestCaseVerdict(Verdict::ac()),
TestCaseVerdict(Verdict::ok(), optional<double>(), optional<int>(25)),
TestCaseVerdict(Verdict::ok(), optional<double>(), optional<int>(50))};

EXPECT_THAT(aggregator.aggregate(verdicts, 70), Eq(SubtaskVerdict(Verdict::ok(), 17.5)));
}

}
12 changes: 10 additions & 2 deletions test/unit/tcframe/runner/verdict/TestCaseVerdictParserTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,22 @@ TEST_F(TestCaseVerdictParserTests, ParseStream_WA) {
EXPECT_THAT(parser.parseStream(new istringstream("WA\n")), Eq(TestCaseVerdict(Verdict::wa())));
}

TEST_F(TestCaseVerdictParserTests, ParseStream_OK) {
TEST_F(TestCaseVerdictParserTests, ParseStream_OK_Points) {
EXPECT_THAT(parser.parseStream(new istringstream("OK\n70\n")), Eq(TestCaseVerdict(Verdict::ok(), 70)));
}

TEST_F(TestCaseVerdictParserTests, ParseStream_OK_WithFeedback) {
TEST_F(TestCaseVerdictParserTests, ParseStream_OK_Points_WithFeedback) {
EXPECT_THAT(parser.parseStream(new istringstream("OK\n70 text\n")), Eq(TestCaseVerdict(Verdict::ok(), 70)));
}

TEST_F(TestCaseVerdictParserTests, ParseStream_OK_Percentage) {
EXPECT_THAT(parser.parseStream(new istringstream("OK\n25%\n")), Eq(TestCaseVerdict(Verdict::ok(), optional<double>(), optional<int>(25))));
}

TEST_F(TestCaseVerdictParserTests, ParseStream_OK_Percentage_WithFeedback) {
EXPECT_THAT(parser.parseStream(new istringstream("OK\n25% text\n")), Eq(TestCaseVerdict(Verdict::ok(), optional<double>(), optional<int>(25))));
}

TEST_F(TestCaseVerdictParserTests, ParseStream_OK_Failed_EmptySecondLine) {
try {
parser.parseStream(new istringstream("OK\n"));
Expand Down

0 comments on commit e49924b

Please sign in to comment.