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

Show all results publicly #103

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions app/assets/stylesheets/main_table.css
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,6 @@ table.main_table > thead > tr > th {
font-weight: bold;
}

.unofficial > td {
opacity: 0.4;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline

13 changes: 2 additions & 11 deletions app/controllers/contests_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class ContestsController < ApplicationController
def permitted_params
@_permitted_params ||= begin
permitted_attributes = [:name, :start_time, :end_time, :duration, :problem_set_id, :startcode, :observation]
permitted_attributes = [:name, :start_time, :end_time, :duration, :problem_set_id, :startcode, :observation, :live_scoreboard, :show_unofficial_competitors]
permitted_attributes << :owner_id if policy(@contest || Contest).transfer?
params.require(:contest).permit(*permitted_attributes)
end
Expand Down Expand Up @@ -49,7 +49,7 @@ def browse
def show
@contest = Contest.find(params[:id])
if !policy(@contest).overview?
redirect_to info_contest_path(@contest)
redirect_to scoreboard_contest_path(@contest)
return
end
@problem_associations = @contest.problem_set.problem_associations.includes(:problem)
Expand All @@ -64,15 +64,6 @@ def show
render :layout => 'contest'
end

def info
@contest = Contest.find(params[:id])
authorize @contest, :show?
@groups = Group.all
@contest_relation = @contest.get_relation(current_user.id) if user_signed_in?

render :layout => 'contest'
end

def scoreboard
@contest = Contest.find(params[:id])
authorize @contest, :scoreboard?
Expand Down
4 changes: 4 additions & 0 deletions app/views/contests/_admin.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@
<% end %>
</ul>

<p>
<b> Problem set: </b>
<%= link_to @contest.problem_set.name, @contest.problem_set %>
</p>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline

21 changes: 18 additions & 3 deletions app/views/contests/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,18 @@
</div>
<div class="field">
<%= f.label :duration %><br />
<%= f.text_field :duration %>
<%= f.text_field :duration, :value=>3.0 %> hours
</div>
<div class="field">
<%= f.label :observation %><br />
<%= f.select :observation, Contest::OBSERVATION.entries.invert %>
<%= f.select :observation, Contest::OBSERVATION.entries.invert %><br />
Students can only join a contest if they belong to a group that the contest also belongs to.
<ul>
<li> Public: Anyone can see the contest. </li>
<li> Protected: Only those in one of the contest's groups can see the contest. </li>
<li> Private: Only those explicitly added as competitors can see the contest. </li>
</ul>

</div>
<div class="field">
<%= f.label :startcode %><br />
Expand All @@ -46,8 +53,16 @@
<% else %>
<%= handle(@contest.owner) %>
<% end %>

</div>
<div class="field">
<%= f.label :live_scoreboard %> - If true, individual problem scores are shown on the live scoreboard. Otherwise, only total scores are shown.<br />
<%= f.check_box :live_scoreboard %>
<div>
<div class="field">
<%= f.label :show_unofficial_competitors %> - If true, unofficial competitors are greyed out. An offical competitor is any student enrolled in school.<br />
<%= f.check_box :show_unofficial_competitors %>
<div>
<br>
<div class="actions">
<%= f.submit %>
</div>
Expand Down
4 changes: 1 addition & 3 deletions app/views/contests/_index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
<th>Start time</th>
<th>End time</th>
<th>Duration</th>
<th>User</th>
<th>Score</th>
<th></th>
<% if policy(Contest).update? %>
Expand All @@ -27,8 +26,7 @@
<td><%= contest.name %></td>
<td><%= contest.start_time.strftime("%b %d, %H:%M") unless contest.start_time.nil? %></td>
<td><%= contest.end_time.strftime("%b %d, %H:%M") unless contest.end_time.nil? %></td>
<td><%= contest.duration %></td>
<td><%= contest.owner_id %></td>
<td><%= contest.duration %> hours</td>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self reminder to correctly pluralise this

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is fine actually, "1.0 hours" sounds more correct than "1.0 hour".
https://english.stackexchange.com/questions/44489/is-1-0-singular-or-plural

<td><%= contest.get_score(current_user.id) if user_signed_in? %></td>
<td>
<% if contest.is_running? && (policy(contest).start?) %>
Expand Down
11 changes: 1 addition & 10 deletions app/views/contests/edit.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,4 @@

<p>
<%= render 'form' %>
</p>
<% if false # COMMENTED %>
<p>
<b> Problems: </b>
<% @problems.each do |problem| %>
<%= link_to problem.name, problem_path(problem) %>
(<%= link_to "remove", :controller => "problem_contest", :action => "remove", :method => "post", :problem_id => problem, :contest_id => @contest %>)
<% end %>
</p>
<% end %>
</p>
Copy link
Member Author

@puqeko puqeko Apr 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline

20 changes: 0 additions & 20 deletions app/views/contests/info.html.erb

This file was deleted.

100 changes: 60 additions & 40 deletions app/views/contests/scoreboard.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,63 +14,83 @@
<% else %>
<h2><%= @contest.finalized? ? "Final Results" : "Preliminary Results" %></h2>

<table class="main_table" >
<table class="main_table">
<thead>
<tr>
<th style="min-width: 25%;"> User </th>
<% @contest.problem_set.problems.each_with_index do |problem, prob_num|%>
<th style="min-width: 6em;">
<% if policy(@contest).show_details? %>
<%= link_to problem.name, problem_path(problem) %>
<% else %>
<% prob_num += 1 %>
Problem <% while !prob_num.zero? %><% prob_num, rem = (prob_num - 1).divmod(26) %><%= ('A'..'Z').to_a[rem] %><% end %>
<% end %>
(<%= @weighting[problem.id] %>)
</th>
<th style="width:1%"> # </th>
<th style="padding-left:0;padding-right:0;border-right:0"></th>
<th style="">Username</th>
<% if @contest.live_scoreboard %>
<% @contest.problem_set.problems.each_with_index do |problem, prob_num|%>
<th >
<% if policy(@contest).show_details? %>
<%= link_to problem.name, problem_path(problem) %>
<% else %>
<% prob_num += 1 %>
Problem <% while !prob_num.zero? %><% prob_num, rem = (prob_num - 1).divmod(26) %><%= ('A'..'Z').to_a[rem] %><% end %>
<% end %>
(<%= @weighting[problem.id] %>)
</th>
<% end %>
<% end %>
<th style="text-align: right"> Score </th>
<th> Time </th>
<th> Rank </th>
<th style="width:1%; text-align: right"> Score </th>
<th style="width:1%"> Time </th>
</tr>
</thead>
<tbody>
<% median = @scoreboard[@scoreboard.length/2-1] %>
<% rank = 1 %>
<% num_unofficial = 0 %>
<% previous_record = @scoreboard.first %>
<% @scoreboard.each_with_index do |record,index| %>
<% if !user_signed_in? or record.user && record.user.id != current_user.id && !policy(@contest).inspect? %>
<% next if record.score < median.score || (record.score == median.score && record.time_taken > median.time_taken) # no permission to view %>
<% is_official = true %>
<% if @contest.show_unofficial_competitors and record.user %>
<% is_official = record.user.estimated_year_level(@contest.end_time) %>
<% end %>
<tr <% if user_signed_in? && record.id==current_user.id %> class="emphasized"<% end %>>
<td>
<% if record.user %>
<% num_unofficial = num_unofficial + 1 unless is_official %>
<tr class="<% if user_signed_in? && record.id==current_user.id %>emphasized<% end %><% if !is_official%> unofficial <%end%>">
<% rank = index + 1 unless previous_record.score == record.score and previous_record.time_taken == record.time_taken%>
<% previous_record = record %>
<td align="right"> <%= rank - (is_official ? num_unofficial : 0)%> </td>
<% if record.user %>
<td style="width:1%;text-align:left;padding-left:0;padding-right:0;">
<%= flag_list(24){ flag(record.user.country_code.downcase, record.user.country_name, title: true) } if record.user.country_code %>
</td>
<td style="">
<%= link_to handle(record.user), record.user %>
<% else %>
<%= "Deleted User ID #{record[:user_id]}" %>
<% end %>
</td>
<% link_to_submissions = user_signed_in? && (record.id == current_user.id || current_user.is_admin?) %>
<% @problems.each do |prob|%>
<td style="min-width: 5em;">
<span style="float: left; width: 2em; text-align: right;">
<%= record["score_#{prob.id}"].nil? ? "-":link_to_if(link_to_submissions, record["score_#{prob.id}"], submission_path(record["sub_#{prob.id}"])) %>
</span>
<span style="float: left; width: 2.5em; text-align: right; font-size: 75%; line-height: 90%;">
<%= raw record["score_#{prob.id}"].nil? ? "&nbsp;":"#{record["attempt_#{prob.id}"].to_i.ordinalize}&nbsp;<br />try" %>
</span>
<span style="float: left; width: 2.5em; text-align: right;">
(<%= link_to_if link_to_submissions, (record["attempts_#{prob.id}"] || 0), :controller => "submissions", :by_user => record[:user_id], :by_problem => prob.id %>)
</span>
</td>

<% else %>
<td style="border-right:0;padding-right:0"><%= "Deleted User ID #{record[:user_id]}" %></td>
<td style="border-left:0;padding-left:1em"></td>
<% end %>
<% link_to_submissions = user_signed_in? && (record.id == current_user.id || current_user.is_admin?) %>
<% if @contest.live_scoreboard %>
<% @problems.each do |prob|%>
<td>
<span style="float: left; width: 2em; text-align: right;">
<%= record["score_#{prob.id}"].nil? ? "-":link_to_if(link_to_submissions, record["score_#{prob.id}"], submission_path(record["sub_#{prob.id}"])) %>
</span>
<span style="float: left; width: 2.5em; text-align: right; font-size: 75%; line-height: 90%;">
<%= raw record["score_#{prob.id}"].nil? ? "&nbsp;":"#{record["attempt_#{prob.id}"].to_i.ordinalize}&nbsp;<br />try" %>
</span>
<span style="float: left; width: 2.5em; text-align: right;">
(<%= link_to_if link_to_submissions, (record["attempts_#{prob.id}"] || 0), :controller => "submissions", :by_user => record[:user_id], :by_problem => prob.id %>)
</span>
</td>
<% end %>
<% end %>
<td style="text-align: right"> <%= record.score %> </td>
<td> <%= format("%d:%02d:%02d",record.time_taken.to_i/3600,record.time_taken.to_i/60%60,record.time_taken.to_i%60) %> </td>
<% rank = index + 1 unless previous_record.score == record.score and previous_record.time_taken == record.time_taken %>
<% previous_record = record %>
<td align="right"> <%= rank %> </td>
</tr>
<% end %>
</tbody>
</table>
<br>
<b> Key </b>
<table class="main_table">
<tbody>
<tr><td>Official competitor</td></tr>
<tr class="unofficial"><td>Unofficial competitor</td></tr>
</tbody>
<table>
<% end %>
4 changes: 1 addition & 3 deletions app/views/layouts/contest.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@
<p>
<b>Start time:</b> <%= @contest.start_time %><br>
<b>End time:</b> <%= @contest.end_time %><br>
<b>Duration:</b> <%= @contest.duration %><br>
<b>Owner:</b> <%= @contest.owner_id %><br>
<b>Duration:</b> <%= @contest.duration %> <%= @contest.duration == 1.0 ? "hour" : "hours"%><br>
</p>
<% if @contest.ended? and @contest.finalized_at.nil? and policy(@contest).update? %>
<%= link_to "Finalize results", finalize_contest_path(@contest), :data => { :confirm => 'Are you sure?' }, :method => :put %>
Expand All @@ -85,7 +84,6 @@
# SimpleNavigation::ItemContainer.new do |menu|
render_navigation do |menu|
menu.dom_class = :tab_menu
menu.item :info, "info", info_contest_path(@contest) if policy(@contest).show?
menu.item :problems, "problems", contest_path(@contest) if policy(@contest).overview?
menu.item :contestants, "contestants", contestants_contest_path(@contest) if policy(@contest).contestants?
menu.item :supervisors, "supervisors", supervisors_contest_path(@contest) if policy(@contest).manage?
Expand Down
23 changes: 13 additions & 10 deletions db/languages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
# database stores the variants and their language group
# programs will reference a language variant, and will be upgraded if their behaviour is the same across multiple versions

# compiler_command is a shell command executed using bash (see Language#compile)
# interpreter_command is executed directly using 'isolate' (so the first argument must be the full path to the interpreter)

c++:
:name: "C++"
:lexer: c++
Expand All @@ -15,19 +18,19 @@ c++:
:variants:
c++03: # deprecated
:name: "C++03"
:compiler: /usr/bin/g++
:compiler: g++
:compiler_command: "%{compiler} --version | head -n 1 1>&2 && %{compiler} -std=gnu++03 -O2 -o %{output} %{source} -lm"
c++11:
:name: "C++11"
:compiler: /usr/bin/g++
:compiler: g++
:compiler_command: "%{compiler} --version | head -n 1 1>&2 && %{compiler} -std=gnu++11 -O2 -o %{output} %{source} -lm"
c++14: # Changes since C++11: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1319r0.html
:name: "C++14"
:compiler: /usr/bin/g++
:compiler: g++
:compiler_command: "%{compiler} --version | head -n 1 1>&2 && %{compiler} -std=gnu++14 -O2 -o %{output} %{source} -lm"
c++17: # Changes since C++14: https://isocpp.org/files/papers/p0636r0.html
:name: "C++17"
:compiler: /usr/bin/g++
:compiler: g++
:compiler_command: "%{compiler} --version | head -n 1 1>&2 && %{compiler} -std=gnu++17 -O2 -o %{output} %{source} -lm"
c:
:name: "C"
Expand All @@ -42,11 +45,11 @@ c:
:variants:
c99: # deprecated
:name: C99
:compiler: /usr/bin/gcc
:compiler: gcc
:compiler_command: "%{compiler} --version | head -n 1 1>&2 && %{compiler} -std=gnu99 -O2 -o %{output} %{source} -lm"
c11: # Changes since c99: https://en.wikipedia.org/wiki/C11_(C_standard_revision)
:name: C11
:compiler: /usr/bin/gcc
:compiler: gcc
:compiler_command: "%{compiler} --version | head -n 1 1>&2 && %{compiler} -std=gnu11 -O2 -o %{output} %{source} -lm"

java:
Expand All @@ -62,13 +65,13 @@ java:
:variants:
java6:
:name: Java 1.6 # deprecated (note: uses '-source 1.6', which will be removed in a future JDK release)
:compiler: /usr/bin/javac;/usr/bin/jar
:compiler: javac;jar
:compiler_command: '%{compiler[0]} -version | head -n 1 1>&2 && %{compiler[0]} -O -source 1.6 -J-Xms16m -J-Xmx256m %{source} && %{compiler[1]} cfe %{output} Main -C %{source_dir} .'
:interpreter: /usr/bin/java
:interpreter_command: '%{interpreter} -jar %{source}'
java11:
:name: Java 11
:compiler: /usr/bin/javac;/usr/bin/jar
:compiler: javac;jar
:compiler_command: '%{compiler[0]} -version | head -n 1 1>&2 && %{compiler[0]} -O -source 11 -J-Xms16m -J-Xmx256m %{source} && %{compiler[1]} cfe %{output} Main -C %{source_dir} .'
:interpreter: /usr/bin/java
:interpreter_command: '%{interpreter} -jar %{source}'
Expand All @@ -85,7 +88,7 @@ haskell:
:variants:
haskell2010:
:name: "Haskell 2010"
:compiler: /usr/bin/ghc
:compiler: ghc
:compiler_command: '%{compiler} --version 1>&2 && %{compiler} --make -O2 -o %{output} %{source} -lm'
python:
:name: Python
Expand Down Expand Up @@ -168,6 +171,6 @@ csharp:
:variants:
csharp8:
:name: "C# 8.0"
:compiler: /usr/local/bin/dotnet-csc # custom shell script (also prints SDK version number)
:compiler: dotnet-csc # custom shell script (also prints SDK version number)
:compiler_command: '%{compiler} %{source} -optimize+ -out:%{output} -langversion:8.0 -nologo'
:interpreter_command: '%{interpreter} %{source}'
5 changes: 5 additions & 0 deletions db/migrate/20200418113600_add_live_scoreboard_field.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddLiveScoreboardField < ActiveRecord::Migration
def change
add_column :contests, :live_scoreboard, :boolean, :default => true
end
end
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline

5 changes: 5 additions & 0 deletions db/migrate/20200418113601_add_offical_competitors.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddOfficalCompetitors < ActiveRecord::Migration
def change
add_column :contests, :show_unofficial_competitors, :boolean, :default => false
end
end
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline

Loading