Description:
shows test pair download and grade sample test cases
Commit status:
[Not Reviewed]
References:
Diff options:
Comments:
0 Commit comments
0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
r381:abc583474e72 - - 9 files changed: 201 inserted, 11 deleted
@@ -0,0 +1,9 | |||||
|
|
1 | + class TestPairAssignment < ActiveRecord::Base | ||
|
|
2 | + belongs_to :problem | ||
|
|
3 | + belongs_to :test_pair | ||
|
|
4 | + belongs_to :user | ||
|
|
5 | + | ||
|
|
6 | + def expired? | ||
|
|
7 | + return created_at + TEST_ASSIGNMENT_EXPIRATION_DURATION < Time.new.gmtime | ||
|
|
8 | + end | ||
|
|
9 | + end |
@@ -0,0 +1,5 | |||||
|
|
1 | + class AddIsPrivateToTestPairs < ActiveRecord::Migration | ||
|
|
2 | + def change | ||
|
|
3 | + add_column :test_pairs, :is_private, :boolean | ||
|
|
4 | + end | ||
|
|
5 | + end |
@@ -0,0 +1,16 | |||||
|
|
1 | + class CreateTestPairAssignments < ActiveRecord::Migration | ||
|
|
2 | + def up | ||
|
|
3 | + create_table :test_pair_assignments do |t| | ||
|
|
4 | + t.integer "user_id" | ||
|
|
5 | + t.integer "problem_id" | ||
|
|
6 | + t.integer "test_pair_id" | ||
|
|
7 | + t.integer "request_number" | ||
|
|
8 | + t.boolean "submitted" | ||
|
|
9 | + t.timestamps | ||
|
|
10 | + end | ||
|
|
11 | + end | ||
|
|
12 | + | ||
|
|
13 | + def down | ||
|
|
14 | + drop_table :test_pair_assignments | ||
|
|
15 | + end | ||
|
|
16 | + end |
@@ -200,9 +200,88 | |||||
|
200 | @user = user |
|
200 | @user = user |
|
201 | end |
|
201 | end |
|
202 | end |
|
202 | end |
|
|
203 | + | ||
|
|
204 | + # thailandoi contests | ||
|
|
205 | + | ||
|
|
206 | + def verifying_testcase | ||
|
|
207 | + problem = Problem.find(params[:id]) | ||
|
|
208 | + if !problem.available | ||
|
|
209 | + flash[:notice] = 'Error: problem is not available' | ||
|
|
210 | + redirect_to :action => 'list' | ||
|
|
211 | + else | ||
|
|
212 | + test_pair = TestPair.get_for(problem, false) | ||
|
|
213 | + send_data(test_pair.input, | ||
|
|
214 | + {:filename => problem.name + '-verifying-input.txt', | ||
|
|
215 | + :type => 'text/plain'}) | ||
|
|
216 | + end | ||
|
|
217 | + end | ||
|
203 |
|
218 | ||
|
|
219 | + def testcase | ||
|
|
220 | + problem = Problem.find(params[:id]) | ||
|
|
221 | + if !problem.available | ||
|
|
222 | + flash[:notice] = 'Error: problem is not available' | ||
|
|
223 | + redirect_to :action => 'list' | ||
|
|
224 | + else | ||
|
|
225 | + test_pair = TestPair.get_for(problem, true) | ||
|
|
226 | + | ||
|
|
227 | + user = User.find(session[:user_id]) | ||
|
|
228 | + assignent = user.get_test_pair_assignment_for(problem) | ||
|
|
229 | + | ||
|
|
230 | + if !assignent | ||
|
|
231 | + assignent = TestPairAssignment.new | ||
|
|
232 | + assignent.user = user | ||
|
|
233 | + assignent.problem = problem | ||
|
|
234 | + assignent.test_pair = test_pair | ||
|
|
235 | + assignent.submitted = false | ||
|
|
236 | + assignent.save | ||
|
|
237 | + end | ||
|
|
238 | + | ||
|
|
239 | + send_data(test_pair.input, | ||
|
|
240 | + {:filename => problem.name + '-input.txt', | ||
|
|
241 | + :type => 'text/plain'}) | ||
|
|
242 | + end | ||
|
|
243 | + end | ||
|
|
244 | + | ||
|
|
245 | + def verifying_submit | ||
|
|
246 | + user = User.find(session[:user_id]) | ||
|
|
247 | + problem_id = params[:id] | ||
|
|
248 | + problem = Problem.find(problem_id) | ||
|
|
249 | + | ||
|
|
250 | + if !problem or !problem.available | ||
|
|
251 | + flash[:notice] = 'Error: problem is not available' | ||
|
|
252 | + redirect_to :action => 'list' and return | ||
|
|
253 | + end | ||
|
|
254 | + | ||
|
|
255 | + test_pair = TestPair.get_for(problem, false) | ||
|
|
256 | + if (params['output_file']) and (params['output_file']!='') | ||
|
|
257 | + output = params['output_file'].read | ||
|
|
258 | + | ||
|
|
259 | + @current_problem = problem | ||
|
|
260 | + @grading_result = grade(output, test_pair.solution) | ||
|
|
261 | + prepare_list_information | ||
|
|
262 | + render :action => 'list' and return | ||
|
|
263 | + else | ||
|
|
264 | + flash[:notice] = 'Error: output file errors' | ||
|
|
265 | + redirect_to :action => 'list' | ||
|
|
266 | + end | ||
|
|
267 | + end | ||
|
|
268 | + | ||
|
204 | protected |
|
269 | protected |
|
205 |
|
270 | ||
|
|
271 | + def grade(output, solution) | ||
|
|
272 | + out_items = output.split | ||
|
|
273 | + sol_items = solution.split | ||
|
|
274 | + res = '' | ||
|
|
275 | + sol_items.length.times do |i| | ||
|
|
276 | + if out_items[i] == sol_items[i] | ||
|
|
277 | + res = res + 'P' | ||
|
|
278 | + else | ||
|
|
279 | + res = res + '-' | ||
|
|
280 | + end | ||
|
|
281 | + end | ||
|
|
282 | + return res | ||
|
|
283 | + end | ||
|
|
284 | + | ||
|
206 | def prepare_announcements(recent=nil) |
|
285 | def prepare_announcements(recent=nil) |
|
207 | if GraderConfiguration.show_tasks_to?(@user) |
|
286 | if GraderConfiguration.show_tasks_to?(@user) |
|
208 | @announcements = Announcement.find_published(true) |
|
287 | @announcements = Announcement.find_published(true) |
@@ -215,6 +294,23 | |||||
|
215 | end |
|
294 | end |
|
216 | end |
|
295 | end |
|
217 |
|
296 | ||
|
|
297 | + def prepare_timeout_information(problems) | ||
|
|
298 | + @submission_timeouts = {} | ||
|
|
299 | + problems.each do |problem| | ||
|
|
300 | + assignment = @user.get_test_pair_assignment_for(problem) | ||
|
|
301 | + if assignment == nil | ||
|
|
302 | + timeout = nil | ||
|
|
303 | + else | ||
|
|
304 | + if (assignment.expired?) or (assignment.submitted) | ||
|
|
305 | + timeout = 0 | ||
|
|
306 | + else | ||
|
|
307 | + timeout = assignment.created_at + TEST_ASSIGNMENT_EXPIRATION_DURATION - Time.new.gmtime | ||
|
|
308 | + end | ||
|
|
309 | + end | ||
|
|
310 | + @submission_timeouts[problem.id] = timeout | ||
|
|
311 | + end | ||
|
|
312 | + end | ||
|
|
313 | + | ||
|
218 | def prepare_list_information |
|
314 | def prepare_list_information |
|
219 | @user = User.find(session[:user_id]) |
|
315 | @user = User.find(session[:user_id]) |
|
220 | if not GraderConfiguration.multicontests? |
|
316 | if not GraderConfiguration.multicontests? |
@@ -233,6 +329,7 | |||||
|
233 | end |
|
329 | end |
|
234 | end |
|
330 | end |
|
235 | prepare_announcements |
|
331 | prepare_announcements |
|
|
332 | + prepare_timeout_information(@problems) | ||
|
236 | end |
|
333 | end |
|
237 |
|
334 | ||
|
238 | def check_viewability |
|
335 | def check_viewability |
@@ -1,3 +1,8 | |||||
|
1 | class TestPair < ActiveRecord::Base |
|
1 | class TestPair < ActiveRecord::Base |
|
2 | belongs_to :problem |
|
2 | belongs_to :problem |
|
|
3 | + | ||
|
|
4 | + def self.get_for(problem, is_private) | ||
|
|
5 | + return TestPair.where(:problem_id => problem.id, | ||
|
|
6 | + :is_private => is_private).first | ||
|
|
7 | + end | ||
|
3 | end |
|
8 | end |
@@ -254,6 +254,11 | |||||
|
254 | end |
|
254 | end |
|
255 | end |
|
255 | end |
|
256 |
|
256 | ||
|
|
257 | + def get_test_pair_assignment_for(problem) | ||
|
|
258 | + return TestPairAssignment.where(:problem_id => problem.id, | ||
|
|
259 | + :user_id => id).first | ||
|
|
260 | + end | ||
|
|
261 | + | ||
|
257 | protected |
|
262 | protected |
|
258 | def encrypt_new_password |
|
263 | def encrypt_new_password |
|
259 | return if password.blank? |
|
264 | return if password.blank? |
@@ -1,8 +1,51 | |||||
|
1 | - <%= form_tag({:action => 'submit'}, :multipart => true) do %> |
|
1 | + <div class="submitbox"> |
|
2 | - <b>Problem:</b> <%= select 'submission', 'problem_id', |
|
2 | + <b>Problem:</b> <%= select 'submission', 'problem_id', |
|
3 | - [[(t 'main.specified_in_header'),'-1']] + |
|
3 | + [['กรุณาเลือกข้อที่ต้องการส่งหรือทดสอบ','-1']] + |
|
4 | - @problems.collect {|p| [p.full_name, p.id]}, |
|
4 | + @problems.collect {|p| [p.full_name, p.id]}, |
|
5 |
- :selected => '-1' |
|
5 | + { :selected => '-1' }, |
|
6 | - <b>File:</b> <%= file_field_tag 'file' %> |
|
6 | + { :onchange => 'select_click()' } %> |
|
7 | - <%= submit_tag 'Submit' %> |
|
7 | + </div> |
|
|
8 | + | ||
|
|
9 | + <% @problems.each do |problem| %> | ||
|
|
10 | + <div class="submission-submit-divs" id="submission_submit_div_<%= problem.id %>_id" style="displanny: none;"> | ||
|
|
11 | + <div style="border: 1px solid #c0c0c0; padding: 5px; margin: 5px 0 5px 0;"> | ||
|
|
12 | + <b><%= problem.full_name %>: ข้อมูลสำหรับตรวจสอบ</b> (สามารถดาวน์โหลดและส่งกี่ครั้งก็ได้): | ||
|
|
13 | + <%= link_to 'ดาวน์โหลด input', :action => 'verifying_testcase', :id => problem.id %> | ||
|
|
14 | + <% if @current_problem.id == problem.id %> | ||
|
|
15 | + <% if @grading_result %> | ||
|
|
16 | + | <b>ผลการตรวจ:</b> <%= @grading_result %> | ||
|
|
17 | + <% end %> | ||
|
|
18 | + <% end %> | ||
|
|
19 | + <%= form_tag({:controller => 'main', :action => 'verifying_submit', :id => problem.id}, {:method => 'post', :multipart => true}) do %> | ||
|
|
20 | + ส่งคำตอบของข้อมูลสำหรับตรวจสอบ: | ||
|
|
21 | + <%= file_field_tag 'output_file' %> | ||
|
|
22 | + <%= submit_tag 'Submit' %> | ||
|
|
23 | + <% end %> | ||
|
|
24 | + </div> | ||
|
|
25 | + <div style="border: 1px solid #c0c0c0; padding: 5px; margin: 5px 0 5px 0;"> | ||
|
|
26 | + <b><%= problem.full_name %>: ข้อมูลทดสอบจริง</b> (ส่งกี่ครั้งก็ได้ภายในเวลา 5 นาทีหลังดาวน์โหลด): | ||
|
|
27 | + <%= link_to 'ดาวน์โหลด input และเริ่มจับเวลา', { :action => 'testcase', :id => problem.id}, { :onclick => 'return confirm_download()' } %> | ||
|
|
28 | + <span id="submission_time_left_<%= problem.id %>_id"></span> | ||
|
|
29 | + <%= form_tag do %> | ||
|
|
30 | + ข้อมูลส่งออก: <%= file_field_tag 'output_file' %> | ||
|
|
31 | + โปรแกรมคำตอบ: <%= file_field_tag 'source_file' %> | ||
|
|
32 | + <%= submit_tag 'Submit' %> | ||
|
|
33 | + <% end %> | ||
|
|
34 | + </div> | ||
|
|
35 | + </div> | ||
|
8 | <% end %> |
|
36 | <% end %> |
|
|
37 | + <script> | ||
|
|
38 | + function select_click() { | ||
|
|
39 | + $$(".submission-submit-divs").each(function(item) { | ||
|
|
40 | + item.hide(); | ||
|
|
41 | + }); | ||
|
|
42 | + var problem_id = $('submission_problem_id').value; | ||
|
|
43 | + if ( problem_id < 0 ) { | ||
|
|
44 | + return; | ||
|
|
45 | + } | ||
|
|
46 | + $("submission_submit_div_" + problem_id + "_id").show(); | ||
|
|
47 | + } | ||
|
|
48 | + function confirm_download() { | ||
|
|
49 | + return confirm("แน่ใจ?"); | ||
|
|
50 | + } | ||
|
|
51 | + </script> |
@@ -10,9 +10,8 | |||||
|
10 | = render :partial => 'announcement', :collection => @announcements |
|
10 | = render :partial => 'announcement', :collection => @announcements |
|
11 |
|
11 | ||
|
12 | - if GraderConfiguration.show_submitbox_to?(@user) |
|
12 | - if GraderConfiguration.show_submitbox_to?(@user) |
|
13 | - .submitbox |
|
13 | + = error_messages_for 'submission' |
|
14 | - = error_messages_for 'submission' |
|
14 | + = render :partial => 'submission_box' |
|
15 | - = render :partial => 'submission_box' |
|
||
|
16 |
|
15 | ||
|
17 |
|
16 | ||
|
18 | %hr/ |
|
17 | %hr/ |
@@ -11,7 +11,7 | |||||
|
11 | # |
|
11 | # |
|
12 | # It's strongly recommended to check this file into your version control system. |
|
12 | # It's strongly recommended to check this file into your version control system. |
|
13 |
|
13 | ||
|
14 |
- ActiveRecord::Schema.define(:version => 201 |
|
14 | + ActiveRecord::Schema.define(:version => 20150128165518) do |
|
15 |
|
15 | ||
|
16 | create_table "announcements", :force => true do |t| |
|
16 | create_table "announcements", :force => true do |t| |
|
17 | t.string "author" |
|
17 | t.string "author" |
@@ -178,12 +178,23 | |||||
|
178 | t.datetime "updated_at" |
|
178 | t.datetime "updated_at" |
|
179 | end |
|
179 | end |
|
180 |
|
180 | ||
|
|
181 | + create_table "test_pair_assignments", :force => true do |t| | ||
|
|
182 | + t.integer "user_id" | ||
|
|
183 | + t.integer "problem_id" | ||
|
|
184 | + t.integer "test_pair_id" | ||
|
|
185 | + t.integer "request_number" | ||
|
|
186 | + t.boolean "submitted" | ||
|
|
187 | + t.datetime "created_at", :null => false | ||
|
|
188 | + t.datetime "updated_at", :null => false | ||
|
|
189 | + end | ||
|
|
190 | + | ||
|
181 | create_table "test_pairs", :force => true do |t| |
|
191 | create_table "test_pairs", :force => true do |t| |
|
182 | t.integer "problem_id" |
|
192 | t.integer "problem_id" |
|
183 | t.text "input", :limit => 16777215 |
|
193 | t.text "input", :limit => 16777215 |
|
184 | t.text "solution", :limit => 16777215 |
|
194 | t.text "solution", :limit => 16777215 |
|
185 | t.datetime "created_at", :null => false |
|
195 | t.datetime "created_at", :null => false |
|
186 | t.datetime "updated_at", :null => false |
|
196 | t.datetime "updated_at", :null => false |
|
|
197 | + t.boolean "is_private" | ||
|
187 | end |
|
198 | end |
|
188 |
|
199 | ||
|
189 | create_table "test_requests", :force => true do |t| |
|
200 | create_table "test_requests", :force => true do |t| |
You need to be logged in to leave comments.
Login now