Skip to content

Commit 1c7d012

Browse files
lizchowchowncesYaleChen299
authored
Remove rank from contest voting (#1959)
* Remove rank from contest voting * Rename relative_score to final_score Co-authored-by: En Rong <53928333+chownces@users.noreply.github.com> Co-authored-by: Chen Yanyu <39845424+YaleChen299@users.noreply.github.com>
1 parent 691baa2 commit 1c7d012

8 files changed

+67
-44
lines changed

src/commons/assessment/AssessmentTypes.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ export type Testcase = {
172172
export type ContestEntry = {
173173
submission_id: number;
174174
answer: ContestEntryCodeAnswer; //contest entry program to be input into editor
175-
rank?: number;
176175
score?: number;
176+
final_score?: number;
177177
student_name?: string;
178178
};
179179

src/commons/sideContent/SideContentContestEntryCard.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ type StateProps = {
1616
isValid: boolean;
1717
contestEntry: ContestEntry;
1818
entryNumber: number;
19-
maxRank: number;
19+
minScore: number;
20+
maxScore: number;
2021
};
2122

2223
/**
@@ -33,7 +34,8 @@ const SideContentContestEntryCard: React.FunctionComponent<SideContentConstestEn
3334
handleVotingSubmissionChange,
3435
contestEntry,
3536
entryNumber,
36-
maxRank
37+
minScore,
38+
maxScore
3739
} = props;
3840

3941
return (
@@ -49,13 +51,13 @@ const SideContentContestEntryCard: React.FunctionComponent<SideContentConstestEn
4951
<Pre className="contestentry-rank">
5052
<NumericInput
5153
disabled={!canSave}
52-
value={contestEntry.rank}
53-
onValueChange={(rank: number) =>
54-
handleVotingSubmissionChange(contestEntry.submission_id, rank)
54+
value={contestEntry.score}
55+
onValueChange={(score: number) =>
56+
handleVotingSubmissionChange(contestEntry.submission_id, score)
5557
}
56-
placeholder={`Enter rank for entry ${entryNumber}`}
57-
min={1}
58-
max={maxRank}
58+
placeholder={`Enter score for entry ${entryNumber}`}
59+
min={minScore}
60+
max={maxScore}
5961
allowNumericCharactersOnly
6062
fill
6163
minorStepSize={null} // limits input to integers

src/commons/sideContent/SideContentContestVoting.tsx

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ type DispatchProps = {
1515
type StateProps = {
1616
canSave: boolean;
1717
isValid: boolean;
18-
handleVotingSubmissionChange: (entryId: number, rank: number) => void;
18+
handleVotingSubmissionChange: (entryId: number, score: number) => void;
1919
contestEntries: ContestEntry[];
20+
minScore: number;
21+
maxScore: number;
2022
};
2123

2224
/*
@@ -32,14 +34,10 @@ const columnHeader = (colClass: string, colTitle: string) => (
3234
const contestEntryHeader = (
3335
<div className="contestentries-header">
3436
{columnHeader('header-entryid', 'Entry Id')}
35-
{columnHeader('header-entryrank', 'Rank')}
37+
{columnHeader('header-entryrank', 'Score')}
3638
</div>
3739
);
3840

39-
const contestEntryTooltipContent = (numOfEntries: number) => (
40-
<span>Rank your favourite contest entries from 1 (best) to {numOfEntries} (worst)!</span>
41-
);
42-
4341
/**
4442
* Main contest voting tab
4543
* @param props contestEntries for student to vote for : ContestEntry[],
@@ -51,7 +49,9 @@ const SideContentContestVoting: React.FunctionComponent<SideContentContestVoting
5149
canSave,
5250
isValid,
5351
handleContestEntryClick,
54-
handleVotingSubmissionChange
52+
handleVotingSubmissionChange,
53+
maxScore,
54+
minScore
5555
} = props;
5656
const [showContestEntries, setShowContestEntries] = useState<boolean>(true);
5757

@@ -69,7 +69,8 @@ const SideContentContestVoting: React.FunctionComponent<SideContentContestVoting
6969
handleContestEntryClick={handleContestEntryClick}
7070
handleVotingSubmissionChange={handleVotingSubmissionChange}
7171
contestEntry={contestEntry}
72-
maxRank={contestEntries.length}
72+
minScore={minScore}
73+
maxScore={maxScore}
7374
/>
7475
))
7576
) : (
@@ -78,7 +79,15 @@ const SideContentContestVoting: React.FunctionComponent<SideContentContestVoting
7879
</div>
7980
),
8081
// determines when to re-render
81-
[isValid, canSave, contestEntries, handleContestEntryClick, handleVotingSubmissionChange]
82+
[
83+
isValid,
84+
canSave,
85+
contestEntries,
86+
handleContestEntryClick,
87+
handleVotingSubmissionChange,
88+
maxScore,
89+
minScore
90+
]
8291
);
8392

8493
return (
@@ -90,7 +99,13 @@ const SideContentContestVoting: React.FunctionComponent<SideContentContestVoting
9099
onClick={() => setShowContestEntries(!showContestEntries)}
91100
>
92101
<span>Contest Voting</span>
93-
<Tooltip2 content={contestEntryTooltipContent(contestEntries.length)}>
102+
<Tooltip2
103+
content={
104+
<span>
105+
Score your favourite contest entries from {minScore} (worst) to {maxScore} (best)!
106+
</span>
107+
}
108+
>
94109
<Icon icon={IconNames.HELP} />
95110
</Tooltip2>
96111
</Button>

src/commons/sideContent/SideContentContestVotingContainer.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ const SideContentContestVotingContainer: React.FunctionComponent<SideContentCont
2525
const { canSave, contestEntries, handleSave, handleContestEntryClick } = props;
2626
const [isValid, setIsValid] = useState<boolean>(true);
2727
const [votingSubmission, setVotingSubmission] = useState<ContestEntry[]>([]);
28+
const minScore = 11 - contestEntries.length;
29+
const maxScore = 10;
2830

2931
useEffect(() => {
3032
setVotingSubmission(contestEntries);
@@ -37,25 +39,25 @@ const SideContentContestVotingContainer: React.FunctionComponent<SideContentCont
3739
*/
3840
const isSubmissionValid = (votingSubmission: ContestEntry[]) => {
3941
return votingSubmission.reduce((isValid, vote) => {
40-
const rank = vote.rank!;
41-
return isValid && rank >= 1 && rank <= contestEntries.length;
42+
const score = vote.score!;
43+
return isValid && score >= minScore && score <= maxScore;
4244
}, true);
4345
};
4446

4547
const submissionHasNoNull = (votingSubmission: ContestEntry[]) => {
4648
return votingSubmission.reduce((noNull, vote) => {
47-
return noNull && vote.rank !== undefined && vote.rank !== null;
49+
return noNull && vote.score !== undefined && vote.score !== null;
4850
}, true);
4951
};
5052

51-
const handleVotingSubmissionChange = (submissionId: number, rank: number): void => {
53+
const handleVotingSubmissionChange = (submissionId: number, score: number): void => {
5254
// update the votes
5355
const updatedSubmission = votingSubmission.map(vote =>
54-
vote.submission_id === submissionId ? { ...vote, rank: rank } : vote
56+
vote.submission_id === submissionId ? { ...vote, score: score } : vote
5557
);
5658
setVotingSubmission(updatedSubmission);
5759
const noDuplicates =
58-
new Set(updatedSubmission.map(vote => vote.rank)).size === updatedSubmission.length;
60+
new Set(updatedSubmission.map(vote => vote.score)).size === updatedSubmission.length;
5961
// validate that scores are unique
6062
const noNull = submissionHasNoNull(updatedSubmission);
6163
if (noDuplicates && noNull && isSubmissionValid(updatedSubmission)) {
@@ -64,7 +66,7 @@ const SideContentContestVotingContainer: React.FunctionComponent<SideContentCont
6466
setIsValid(true);
6567
} else if (noDuplicates && noNull) {
6668
showWarningMessage(
67-
`Vote rankings invalid. Please input rankings between 1 - ${contestEntries.length}.`
69+
`Vote rankings invalid. Please input scores between ${minScore} - ${maxScore}.`
6870
);
6971
setIsValid(false);
7072
} else if (!noDuplicates && noNull) {
@@ -82,6 +84,8 @@ const SideContentContestVotingContainer: React.FunctionComponent<SideContentCont
8284
handleContestEntryClick={handleContestEntryClick}
8385
handleVotingSubmissionChange={handleVotingSubmissionChange}
8486
contestEntries={votingSubmission}
87+
minScore={minScore}
88+
maxScore={maxScore}
8589
/>
8690
);
8791
};

src/commons/sideContent/SideContentLeaderboardCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const SideContentLeaderboardCard: React.FunctionComponent<SideContentLeaderboard
3030
>
3131
<Pre className="contestentry-entryid">{contestEntry.student_name}</Pre>
3232
<Pre className="contestentry-rank">{rank}</Pre>
33-
<Pre className="contestentry-score">{contestEntry.score}</Pre>
33+
<Pre className="contestentry-score">{contestEntry.final_score}</Pre>
3434
</Card>
3535
</div>
3636
);

src/commons/sideContent/__tests__/SideContentContestLeaderboard.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@ const mockLeaderboardEntries = [
88
{
99
submission_id: 1,
1010
answer: { code: "display('hello world')" },
11-
score: 100,
11+
final_score: 100,
1212
student_name: 'student_1'
1313
},
1414
{
1515
submission_id: 2,
1616
answer: { code: 'function test() { return 1; }' },
17-
score: 90,
17+
final_score: 90,
1818
student_name: 'student_2'
1919
},
2020
{
2121
submission_id: 3,
2222
answer: { code: 'function test() { return 1; }' },
23-
score: 80,
23+
final_score: 80,
2424
student_name: 'student_3'
2525
}
2626
];

src/commons/sideContent/__tests__/SideContentContestVoting.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,18 +78,20 @@ test('SideContentVotingContainer only updates when ranks assigned to entries are
7878
const contestVotingCard = contestVotingContainerRender.find('input');
7979

8080
// simulate change to duplicate
81-
contestVotingCard.map(card => card.simulate('change', { target: { value: 1 } }));
81+
contestVotingCard.map(card => card.simulate('change', { target: { value: 10 } }));
8282
expect(mockedHandleSave).toHaveBeenCalledTimes(0);
8383

8484
// to avoid warning messages from blueprint.js due to testing invalid input during tests
8585
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
8686

87-
// simulate change to exceed rank limit (ie. if 2 entries can only rank [1, 2])
88-
contestVotingCard.map(card => card.simulate('change', { target: { value: 3 } }));
87+
// simulate change to exceed score limit (ie. if 2 entries can only rank [9, 10])
88+
contestVotingCard.map(card => card.simulate('change', { target: { value: 11 } }));
8989
expect(mockedHandleSave).toHaveBeenCalledTimes(0);
9090

9191
// simulate appropriate ranking for entries
92-
contestVotingCard.map((card, index) => card.simulate('change', { target: { value: index + 1 } }));
92+
contestVotingCard.map((card, index) =>
93+
card.simulate('change', { target: { value: 10 - index } })
94+
);
9395
expect(mockedHandleSave).toHaveBeenCalledTimes(1);
9496

9597
consoleWarnSpy.mockRestore();

0 commit comments

Comments
 (0)