Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add token divider field to contest voting XML file #1034

Merged
merged 47 commits into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
7fc0f4c
Add files via upload
kjw142857 Sep 14, 2023
cf813e1
Add files via upload
kjw142857 Sep 14, 2023
dd00f88
Add files via upload
kjw142857 Sep 14, 2023
4420b05
Add files via upload
kjw142857 Sep 15, 2023
bc05fa9
Add files via upload
kjw142857 Sep 15, 2023
3c1d314
Add files via upload
kjw142857 Sep 15, 2023
d39f5d9
Merge branch 'master' of https://github.com/kjw142857/backend-Contest…
kjw142857 Sep 15, 2023
3248a3c
1
kjw142857 Sep 15, 2023
8565013
commit
kjw142857 Sep 16, 2023
289b9db
commit
kjw142857 Sep 16, 2023
5c97c1e
Update config.exs
kjw142857 Sep 17, 2023
6057cfd
Update assessments.ex
kjw142857 Sep 17, 2023
46649b8
commit
kjw142857 Sep 18, 2023
902cd80
commit
kjw142857 Sep 18, 2023
df7d66d
commit
kjw142857 Sep 19, 2023
a5069fc
Add files via upload
kjw142857 Sep 20, 2023
cd858eb
Update assessments_test.exs
kjw142857 Sep 20, 2023
b8f14d0
Merge branch 'master' of https://github.com/kjw142857/backend-Contest…
kjw142857 Sep 20, 2023
ebe71d9
Merge branch 'source-academy:master' into master
kjw142857 Oct 1, 2023
3475d0b
Change modifier to 70 for Game of Tones contest
kjw142857 Oct 1, 2023
76d4108
Update assessments_test.exs
kjw142857 Oct 1, 2023
bda994a
Fix incorrect denominator to 80
RichDom2185 Oct 1, 2023
1dac5a3
Merge branch 'source-academy:master' into master
kjw142857 Nov 7, 2023
934c7f1
commit
kjw142857 Nov 7, 2023
67710dc
Update assessments.ex
kjw142857 Nov 7, 2023
a733e87
Update voting_question.ex
kjw142857 Nov 7, 2023
5d402a8
Update xml_parser.ex
kjw142857 Nov 7, 2023
c5ded99
Add files via upload
kjw142857 Nov 7, 2023
2c3c64b
Add files via upload
kjw142857 Nov 7, 2023
6471b68
Add files via upload
kjw142857 Nov 7, 2023
a26b4b3
Add files via upload
kjw142857 Nov 7, 2023
d60ac12
Add files via upload
kjw142857 Nov 7, 2023
a0bf48a
Add files via upload
kjw142857 Nov 7, 2023
eaaee94
Add files via upload
kjw142857 Nov 7, 2023
6508bbf
Add files via upload
kjw142857 Nov 7, 2023
a465e8a
Add files via upload
kjw142857 Nov 7, 2023
5f2df96
Add files via upload
kjw142857 Nov 7, 2023
2cb1b2e
Add files via upload
kjw142857 Nov 7, 2023
ddc874c
Add files via upload
kjw142857 Nov 7, 2023
02410e0
Update voting_question.ex
kjw142857 Nov 7, 2023
a9cac0d
Merge branch 'master' of https://github.com/kjw142857/backend-Contest…
kjw142857 Nov 8, 2023
f61a358
Add files via upload
kjw142857 Nov 8, 2023
d1412cc
Add files via upload
kjw142857 Nov 8, 2023
e6dc124
Update mix.lock
kjw142857 Nov 8, 2023
2b648c3
Revert "Update mix.lock"
kjw142857 Nov 8, 2023
4537fc0
Insert validation that token divider must be > 0
kjw142857 Nov 16, 2023
744afd4
Merge branch 'master' into master
RichDom2185 Dec 8, 2023
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
18 changes: 11 additions & 7 deletions lib/cadet/assessments/assessments.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1175,7 +1175,12 @@ defmodule Cadet.Assessments do
)
|> Repo.all()

entry_scores = map_eligible_votes_to_entry_score(eligible_votes)
token_divider =
Question
|> select([q], q.question["token_divider"])
|> Repo.get_by(id: contest_voting_question_id)

entry_scores = map_eligible_votes_to_entry_score(eligible_votes, token_divider)

entry_scores
|> Enum.map(fn {ans_id, relative_score} ->
Expand All @@ -1192,7 +1197,7 @@ defmodule Cadet.Assessments do
|> Repo.transaction()
end

defp map_eligible_votes_to_entry_score(eligible_votes) do
defp map_eligible_votes_to_entry_score(eligible_votes, token_divider) do
# converts eligible votes to the {total cumulative score, number of votes, tokens}
entry_vote_data =
Enum.reduce(eligible_votes, %{}, fn %{ans_id: ans_id, score: score, ans: ans}, tracker ->
Expand All @@ -1210,18 +1215,17 @@ defmodule Cadet.Assessments do
Enum.map(
entry_vote_data,
fn {ans_id, {sum_of_scores, number_of_voters, tokens}} ->
{ans_id, calculate_formula_score(sum_of_scores, number_of_voters, tokens)}
{ans_id, calculate_formula_score(sum_of_scores, number_of_voters, tokens, token_divider)}
end
)
end

# Calculate the score based on formula
# score(v,t) = v - 2^(t/n) where v is the normalized_voting_score and n is the modifier
# n = 50 for C3 & C4, n = 80 for C6
# score(v,t) = v - 2^(t/token_divider) where v is the normalized_voting_score
# normalized_voting_score = sum_of_scores / number_of_voters / 10 * 100
defp calculate_formula_score(sum_of_scores, number_of_voters, tokens) do
defp calculate_formula_score(sum_of_scores, number_of_voters, tokens, token_divider) do
normalized_voting_score = sum_of_scores / number_of_voters / 10 * 100
normalized_voting_score - :math.pow(2, min(1023.5, tokens / 80))
normalized_voting_score - :math.pow(2, min(1023.5, tokens / token_divider))
end

@doc """
Expand Down
4 changes: 3 additions & 1 deletion lib/cadet/assessments/question_types/voting_question.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ defmodule Cadet.Assessments.QuestionTypes.VotingQuestion do
field(:template, :string)
field(:contest_number, :string)
field(:reveal_hours, :integer)
field(:token_divider, :integer)
end

@required_fields ~w(content contest_number reveal_hours)a
@required_fields ~w(content contest_number reveal_hours token_divider)a
@optional_fields ~w(prepend template)a

def changeset(question, params \\ %{}) do
question
|> cast(params, @required_fields ++ @optional_fields)
|> validate_required(@required_fields)
|> validate_number(:token_divider, greater_than: 0)
end
end
3 changes: 2 additions & 1 deletion lib/cadet/jobs/xml_parser.ex
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,8 @@ defmodule Cadet.Updater.XMLParser do
|> xpath(
~x"./VOTING"e,
contest_number: ~x"./@assessment_number"s,
reveal_hours: ~x"./@reveal_hours"i
reveal_hours: ~x"./@reveal_hours"i,
token_divider: ~x"./@token_divider"i
)
)
end
Expand Down
16 changes: 8 additions & 8 deletions test/cadet/assessments/assessments_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ defmodule Cadet.AssessmentsTest do
question: %{
content: Faker.Pokemon.name(),
contest_number: assessment.number,
reveal_hours: 48
reveal_hours: 48,
token_divider: 50
}
},
assessment.id
Expand Down Expand Up @@ -646,13 +647,13 @@ defmodule Cadet.AssessmentsTest do

top_x_ans = Assessments.fetch_top_relative_score_answers(question_id, 5)

assert get_answer_relative_scores(top_x_ans) == expected_top_relative_scores(5)
assert get_answer_relative_scores(top_x_ans) == expected_top_relative_scores(5, 50)

x = 3
top_x_ans = Assessments.fetch_top_relative_score_answers(question_id, x)

# verify that top x ans are queried correctly
assert get_answer_relative_scores(top_x_ans) == expected_top_relative_scores(3)
assert get_answer_relative_scores(top_x_ans) == expected_top_relative_scores(3, 50)
end
end

Expand Down Expand Up @@ -886,7 +887,7 @@ defmodule Cadet.AssessmentsTest do

assert get_answer_relative_scores(
Assessments.fetch_top_relative_score_answers(yesterday_question.id, 5)
) == expected_top_relative_scores(5)
) == expected_top_relative_scores(5, 50)
end

test "update_rolling_contest_leaderboards correcly updates leaderboards which voting is active",
Expand All @@ -908,7 +909,7 @@ defmodule Cadet.AssessmentsTest do

assert get_answer_relative_scores(
Assessments.fetch_top_relative_score_answers(current_question.id, 5)
) == expected_top_relative_scores(5)
) == expected_top_relative_scores(5, 50)
end
end

Expand Down Expand Up @@ -1707,12 +1708,11 @@ defmodule Cadet.AssessmentsTest do
questions |> Enum.map(fn q -> q.id end) |> Enum.sort()
end

defp expected_top_relative_scores(top_x) do
# test with token penalty of 80
defp expected_top_relative_scores(top_x, token_divider) do
# "return 0;" in the factory has 3 token
10..0
|> Enum.to_list()
|> Enum.map(fn score -> 10 * score - :math.pow(2, 3 / 80) end)
|> Enum.map(fn score -> 10 * score - :math.pow(2, 3 / token_divider) end)
|> Enum.take(top_x)
end
end
3 changes: 2 additions & 1 deletion test/cadet/assessments/question_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ defmodule Cadet.Assessments.QuestionTest do
question: %{
content: Faker.Pokemon.name(),
contest_number: assessment.number,
reveal_hours: 48
reveal_hours: 48,
token_divider: 50
}
}

Expand Down
23 changes: 22 additions & 1 deletion test/cadet/assessments/question_types/voting_question_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ defmodule Cadet.Assessments.QuestionTypes.VotingQuestionTest do
%{
content: "content",
contest_number: "C4",
reveal_hours: 48
reveal_hours: 48,
token_divider: 50
},
:valid
)
Expand All @@ -22,6 +23,26 @@ defmodule Cadet.Assessments.QuestionTypes.VotingQuestionTest do
},
:invalid
)

assert_changeset(
%{
content: "content",
contest_number: "C3",
reveal_hours: 48,
token_divider: -1
},
:invalid
)

assert_changeset(
%{
content: "content",
contest_number: "C6",
reveal_hours: 48,
token_divider: 0
},
:invalid
)
end
end
end
6 changes: 4 additions & 2 deletions test/factories/assessments/question_factory.ex
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ defmodule Cadet.Assessments.QuestionFactory do
prepend: Faker.Pokemon.location(),
template: Faker.Lorem.Shakespeare.as_you_like_it(),
contest_number: contest_assessment.number,
reveal_hours: 48
reveal_hours: 48,
token_divider: 50
}
}
end
Expand All @@ -106,7 +107,8 @@ defmodule Cadet.Assessments.QuestionFactory do
prepend: Faker.Pokemon.location(),
template: Faker.Lorem.Shakespeare.as_you_like_it(),
contest_number: contest_assessment.number,
reveal_hours: 48
reveal_hours: 48,
token_divider: 50
}
end
end
Expand Down
5 changes: 3 additions & 2 deletions test/support/xml_generator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ defmodule Cadet.Test.XMLGenerator do
voting_field =
voting(%{
reveal_hours: question.question.reveal_hours,
assessment_number: question.question.contest_number
assessment_number: question.question.contest_number,
token_divider: question.question.token_divider
})

[
Expand All @@ -167,7 +168,7 @@ defmodule Cadet.Test.XMLGenerator do
end

defp voting(raw_attr) do
{"VOTING", map_permit_keys(raw_attr, ~w(assessment_number reveal_hours)a)}
{"VOTING", map_permit_keys(raw_attr, ~w(assessment_number reveal_hours token_divider)a)}
end

defp deployment(raw_attrs, children) do
Expand Down
Loading