Description:
fix display bugs in corrent score
Commit status:
[Not Reviewed]
References:
Diff options:
Comments:
0 Commit comments
0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
r782:97cd56a5f1d8 - - 3 files changed: 5 inserted, 4 deleted
@@ -276,251 +276,252 | |||
|
276 | 276 | @summary[:attempt] = user.count |
|
277 | 277 | user.each_value { |v| @summary[:solve] += 1 if v == 1 } |
|
278 | 278 | end |
|
279 | 279 | |
|
280 | 280 | def stuck #report struggling user,problem |
|
281 | 281 | # init |
|
282 | 282 | user,problem = nil |
|
283 | 283 | solve = true |
|
284 | 284 | tries = 0 |
|
285 | 285 | @struggle = Array.new |
|
286 | 286 | record = {} |
|
287 | 287 | Submission.includes(:problem,:user).order(:problem_id,:user_id).find_each do |sub| |
|
288 | 288 | next unless sub.problem and sub.user |
|
289 | 289 | if user != sub.user_id or problem != sub.problem_id |
|
290 | 290 | @struggle << { user: record[:user], problem: record[:problem], tries: tries } unless solve |
|
291 | 291 | record = {user: sub.user, problem: sub.problem} |
|
292 | 292 | user,problem = sub.user_id, sub.problem_id |
|
293 | 293 | solve = false |
|
294 | 294 | tries = 0 |
|
295 | 295 | end |
|
296 | 296 | if sub.points >= sub.problem.full_score |
|
297 | 297 | solve = true |
|
298 | 298 | else |
|
299 | 299 | tries += 1 |
|
300 | 300 | end |
|
301 | 301 | end |
|
302 | 302 | @struggle.sort!{|a,b| b[:tries] <=> a[:tries] } |
|
303 | 303 | @struggle = @struggle[0..50] |
|
304 | 304 | end |
|
305 | 305 | |
|
306 | 306 | |
|
307 | 307 | def multiple_login |
|
308 | 308 | #user with multiple IP |
|
309 | 309 | raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:login) |
|
310 | 310 | last,count = 0,0 |
|
311 | 311 | first = 0 |
|
312 | 312 | @users = [] |
|
313 | 313 | raw.each do |r| |
|
314 | 314 | if last != r.user.login |
|
315 | 315 | count = 1 |
|
316 | 316 | last = r.user.login |
|
317 | 317 | first = r |
|
318 | 318 | else |
|
319 | 319 | @users << first if count == 1 |
|
320 | 320 | @users << r |
|
321 | 321 | count += 1 |
|
322 | 322 | end |
|
323 | 323 | end |
|
324 | 324 | |
|
325 | 325 | #IP with multiple user |
|
326 | 326 | raw = Submission.joins(:user).joins(:problem).where("problems.available != 0").group("login,ip_address").order(:ip_address) |
|
327 | 327 | last,count = 0,0 |
|
328 | 328 | first = 0 |
|
329 | 329 | @ip = [] |
|
330 | 330 | raw.each do |r| |
|
331 | 331 | if last != r.ip_address |
|
332 | 332 | count = 1 |
|
333 | 333 | last = r.ip_address |
|
334 | 334 | first = r |
|
335 | 335 | else |
|
336 | 336 | @ip << first if count == 1 |
|
337 | 337 | @ip << r |
|
338 | 338 | count += 1 |
|
339 | 339 | end |
|
340 | 340 | end |
|
341 | 341 | end |
|
342 | 342 | |
|
343 | 343 | def cheat_report |
|
344 | 344 | date_and_time = '%Y-%m-%d %H:%M' |
|
345 | 345 | begin |
|
346 | 346 | md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/) |
|
347 | 347 | @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i) |
|
348 | 348 | rescue |
|
349 | 349 | @since_time = Time.zone.now.ago( 90.minutes) |
|
350 | 350 | end |
|
351 | 351 | begin |
|
352 | 352 | md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/) |
|
353 | 353 | @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i) |
|
354 | 354 | rescue |
|
355 | 355 | @until_time = Time.zone.now |
|
356 | 356 | end |
|
357 | 357 | |
|
358 | 358 | #multi login |
|
359 | 359 | @ml = Login.joins(:user).where("logins.created_at >= ? and logins.created_at <= ?",@since_time,@until_time).select('users.login,count(distinct ip_address) as count,users.full_name').group("users.id").having("count > 1") |
|
360 | 360 | |
|
361 | 361 | st = <<-SQL |
|
362 | 362 | SELECT l2.* |
|
363 | 363 | FROM logins l2 INNER JOIN |
|
364 | 364 | (SELECT u.id,COUNT(DISTINCT ip_address) as count,u.login,u.full_name |
|
365 | 365 | FROM logins l |
|
366 | 366 | INNER JOIN users u ON l.user_id = u.id |
|
367 | 367 | WHERE l.created_at >= '#{@since_time.in_time_zone("UTC")}' and l.created_at <= '#{@until_time.in_time_zone("UTC")}' |
|
368 | 368 | GROUP BY u.id |
|
369 | 369 | HAVING count > 1 |
|
370 | 370 | ) ml ON l2.user_id = ml.id |
|
371 | 371 | WHERE l2.created_at >= '#{@since_time.in_time_zone("UTC")}' and l2.created_at <= '#{@until_time.in_time_zone("UTC")}' |
|
372 | 372 | UNION |
|
373 | 373 | SELECT l2.* |
|
374 | 374 | FROM logins l2 INNER JOIN |
|
375 | 375 | (SELECT l.ip_address,COUNT(DISTINCT u.id) as count |
|
376 | 376 | FROM logins l |
|
377 | 377 | INNER JOIN users u ON l.user_id = u.id |
|
378 | 378 | WHERE l.created_at >= '#{@since_time.in_time_zone("UTC")}' and l.created_at <= '#{@until_time.in_time_zone("UTC")}' |
|
379 | 379 | GROUP BY l.ip_address |
|
380 | 380 | HAVING count > 1 |
|
381 | 381 | ) ml on ml.ip_address = l2.ip_address |
|
382 | 382 | INNER JOIN users u ON l2.user_id = u.id |
|
383 | 383 | WHERE l2.created_at >= '#{@since_time.in_time_zone("UTC")}' and l2.created_at <= '#{@until_time.in_time_zone("UTC")}' |
|
384 | 384 | ORDER BY ip_address,created_at |
|
385 | 385 | SQL |
|
386 | 386 | @mld = Login.find_by_sql(st) |
|
387 | 387 | |
|
388 | 388 | st = <<-SQL |
|
389 | 389 | SELECT s.id,s.user_id,s.ip_address,s.submitted_at,s.problem_id |
|
390 | 390 | FROM submissions s INNER JOIN |
|
391 | 391 | (SELECT u.id,COUNT(DISTINCT ip_address) as count,u.login,u.full_name |
|
392 | 392 | FROM logins l |
|
393 | 393 | INNER JOIN users u ON l.user_id = u.id |
|
394 | 394 | WHERE l.created_at >= ? and l.created_at <= ? |
|
395 | 395 | GROUP BY u.id |
|
396 | 396 | HAVING count > 1 |
|
397 | 397 | ) ml ON s.user_id = ml.id |
|
398 | 398 | WHERE s.submitted_at >= ? and s.submitted_at <= ? |
|
399 | 399 | UNION |
|
400 | 400 | SELECT s.id,s.user_id,s.ip_address,s.submitted_at,s.problem_id |
|
401 | 401 | FROM submissions s INNER JOIN |
|
402 | 402 | (SELECT l.ip_address,COUNT(DISTINCT u.id) as count |
|
403 | 403 | FROM logins l |
|
404 | 404 | INNER JOIN users u ON l.user_id = u.id |
|
405 | 405 | WHERE l.created_at >= ? and l.created_at <= ? |
|
406 | 406 | GROUP BY l.ip_address |
|
407 | 407 | HAVING count > 1 |
|
408 | 408 | ) ml on ml.ip_address = s.ip_address |
|
409 | 409 | WHERE s.submitted_at >= ? and s.submitted_at <= ? |
|
410 | 410 | ORDER BY ip_address,submitted_at |
|
411 | 411 | SQL |
|
412 | 412 | @subs = Submission.joins(:problem).find_by_sql([st,@since_time,@until_time, |
|
413 | 413 | @since_time,@until_time, |
|
414 | 414 | @since_time,@until_time, |
|
415 | 415 | @since_time,@until_time]) |
|
416 | 416 | |
|
417 | 417 | end |
|
418 | 418 | |
|
419 | 419 | def cheat_scruntinize |
|
420 | 420 | #convert date & time |
|
421 | 421 | date_and_time = '%Y-%m-%d %H:%M' |
|
422 | 422 | begin |
|
423 | 423 | md = params[:since_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/) |
|
424 | 424 | @since_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i) |
|
425 | 425 | rescue |
|
426 | 426 | @since_time = Time.zone.now.ago( 90.minutes) |
|
427 | 427 | end |
|
428 | 428 | begin |
|
429 | 429 | md = params[:until_datetime].match(/(\d+)-(\d+)-(\d+) (\d+):(\d+)/) |
|
430 | 430 | @until_time = Time.zone.local(md[1].to_i,md[2].to_i,md[3].to_i,md[4].to_i,md[5].to_i) |
|
431 | 431 | rescue |
|
432 | 432 | @until_time = Time.zone.now |
|
433 | 433 | end |
|
434 | 434 | |
|
435 | 435 | #convert sid |
|
436 | 436 | @sid = params[:SID].split(/[,\s]/) if params[:SID] |
|
437 | 437 | unless @sid and @sid.size > 0 |
|
438 | 438 | return |
|
439 | 439 | redirect_to actoin: :cheat_scruntinize |
|
440 | 440 | flash[:notice] = 'Please enter at least 1 student id' |
|
441 | 441 | end |
|
442 | 442 | mark = Array.new(@sid.size,'?') |
|
443 | 443 | condition = "(u.login = " + mark.join(' OR u.login = ') + ')' |
|
444 | 444 | |
|
445 | 445 | @st = <<-SQL |
|
446 | 446 | SELECT l.created_at as submitted_at ,-1 as id,u.login,u.full_name,l.ip_address,"" as problem_id,"" as points,l.user_id |
|
447 | 447 | FROM logins l INNER JOIN users u on l.user_id = u.id |
|
448 | 448 | WHERE l.created_at >= ? AND l.created_at <= ? AND #{condition} |
|
449 | 449 | UNION |
|
450 | 450 | SELECT s.submitted_at,s.id,u.login,u.full_name,s.ip_address,s.problem_id,s.points,s.user_id |
|
451 | 451 | FROM submissions s INNER JOIN users u ON s.user_id = u.id |
|
452 | 452 | WHERE s.submitted_at >= ? AND s.submitted_at <= ? AND #{condition} |
|
453 | 453 | ORDER BY submitted_at |
|
454 | 454 | SQL |
|
455 | 455 | |
|
456 | 456 | p = [@st,@since_time,@until_time] + @sid + [@since_time,@until_time] + @sid |
|
457 | 457 | @logs = Submission.joins(:problem).find_by_sql(p) |
|
458 | 458 | |
|
459 | 459 | |
|
460 | 460 | |
|
461 | 461 | |
|
462 | 462 | |
|
463 | 463 | end |
|
464 | 464 | |
|
465 | 465 | protected |
|
466 | 466 | |
|
467 | 467 | def calculate_max_score(problems, users,since_id,until_id, get_last_score = false) |
|
468 | + #score[i] = user #i's user stat where i is the index (not id) | |
|
468 | 469 | scorearray = Array.new |
|
469 | 470 | users.each do |u| |
|
470 | 471 | ustat = Array.new |
|
471 | 472 | ustat[0] = u |
|
472 | 473 | problems.each do |p| |
|
473 | 474 | unless get_last_score |
|
474 | 475 | #get max score |
|
475 | 476 | max_points = 0 |
|
476 | 477 | Submission.find_in_range_by_user_and_problem(u.id,p.id,since_id,until_id).each do |sub| |
|
477 | 478 | max_points = sub.points if sub and sub.points and (sub.points > max_points) |
|
478 | 479 | end |
|
479 | 480 | ustat << [(max_points.to_f*100/p.full_score).round, (max_points>=p.full_score)] |
|
480 | 481 | else |
|
481 | 482 | #get latest score |
|
482 | 483 | sub = Submission.find_last_by_user_and_problem(u.id,p.id) |
|
483 | 484 | if (sub!=nil) and (sub.points!=nil) and p and p.full_score |
|
484 | 485 | ustat << [(sub.points.to_f*100/p.full_score).round, (sub.points>=p.full_score)] |
|
485 | 486 | else |
|
486 | 487 | ustat << [0,false] |
|
487 | 488 | end |
|
488 | 489 | end |
|
489 | 490 | end |
|
490 | 491 | scorearray << ustat |
|
491 | 492 | end |
|
492 | 493 | return scorearray |
|
493 | 494 | end |
|
494 | 495 | |
|
495 | 496 | def gen_csv_from_scorearray(scorearray,problem) |
|
496 | 497 | CSV.generate do |csv| |
|
497 | 498 | #add header |
|
498 | 499 | header = ['User','Name', 'Activated?', 'Logged in', 'Contest'] |
|
499 | 500 | problem.each { |p| header << p.name } |
|
500 | 501 | header += ['Total','Passed'] |
|
501 | 502 | csv << header |
|
502 | 503 | #add data |
|
503 | 504 | scorearray.each do |sc| |
|
504 | 505 | total = num_passed = 0 |
|
505 | 506 | row = Array.new |
|
506 | 507 | sc.each_index do |i| |
|
507 | 508 | if i == 0 |
|
508 | 509 | row << sc[i].login |
|
509 | 510 | row << sc[i].full_name |
|
510 | 511 | row << sc[i].activated |
|
511 | 512 | row << (sc[i].try(:contest_stat).try(:started_at)!=nil ? 'yes' : 'no') |
|
512 | 513 | row << sc[i].contests.collect {|c| c.name}.join(', ') |
|
513 | 514 | else |
|
514 | 515 | row << sc[i][0] |
|
515 | 516 | total += sc[i][0] |
|
516 | 517 | num_passed += 1 if sc[i][1] |
|
517 | 518 | end |
|
518 | 519 | end |
|
519 | 520 | row << total |
|
520 | 521 | row << num_passed |
|
521 | 522 | csv << row |
|
522 | 523 | end |
|
523 | 524 | end |
|
524 | 525 | end |
|
525 | 526 | |
|
526 | 527 | end |
@@ -1,69 +1,69 | |||
|
1 | 1 | %table.table.sortable.table-striped.table-bordered.table-condensed |
|
2 | 2 | %thead |
|
3 | 3 | %tr |
|
4 | 4 | %th Login |
|
5 | 5 | %th Name |
|
6 | 6 | / %th Activated? |
|
7 | 7 | / %th Logged_in |
|
8 | 8 | / %th Contest(s) |
|
9 | 9 | %th Remark |
|
10 | 10 | - @problems.each do |p| |
|
11 | 11 | %th.text-right= p.name.gsub('_',' ') |
|
12 | 12 | %th.text-right Total |
|
13 | 13 | %th.text-right Passed |
|
14 | 14 | %tbody |
|
15 |
- - sum = Array.new(@ |
|
|
16 |
- - nonzero = Array.new(@ |
|
|
17 |
- - full = Array.new(@ |
|
|
15 | + - sum = Array.new(@problems.count,0) | |
|
16 | + - nonzero = Array.new(@problems.count,0) | |
|
17 | + - full = Array.new(@problems.count,0) | |
|
18 | 18 | - @scorearray.each do |sc| |
|
19 | 19 | %tr |
|
20 | 20 | - total,num_passed = 0,0 |
|
21 | 21 | - sc.each_index do |i| |
|
22 | 22 | - if i == 0 |
|
23 | 23 | %td= link_to sc[i].login, stat_user_path(sc[i]) |
|
24 | 24 | %td= sc[i].full_name |
|
25 | 25 | / %td= sc[i].activated |
|
26 | 26 | / %td= sc[i].try(:contest_stat).try(:started_at) ? 'yes' : 'no' |
|
27 | 27 | / %td= sc[i].contests.collect {|c| c.name}.join(', ') |
|
28 | 28 | %td= sc[i].remark |
|
29 | 29 | - else |
|
30 | 30 | %td.text-right= sc[i][0] |
|
31 | 31 | - total += sc[i][0] |
|
32 | 32 | - num_passed += 1 if sc[i][1] |
|
33 | 33 | - sum[i] += sc[i][0] |
|
34 | 34 | - nonzero[i] += 1 if sc[i][0] > 0 |
|
35 | 35 | - full[i] += 1 if sc[i][1] |
|
36 | 36 | %td.text-right= total |
|
37 | 37 | %td.text-right= num_passed |
|
38 | 38 | %tfoot |
|
39 | 39 | %tr |
|
40 | 40 | %td Summation |
|
41 | 41 | %td |
|
42 | 42 | %td |
|
43 | 43 | - sum.each.with_index do |s,i| |
|
44 | 44 | - next if i == 0 |
|
45 | 45 | %td.text-right= number_with_delimiter(s) |
|
46 | 46 | %td |
|
47 | 47 | %td |
|
48 | 48 | %tr |
|
49 | 49 | %td partial solver |
|
50 | 50 | %td |
|
51 | 51 | %td |
|
52 | 52 | - nonzero.each.with_index do |s,i| |
|
53 | 53 | - next if i == 0 |
|
54 | 54 | %td.text-right= number_with_delimiter(s) |
|
55 | 55 | %td |
|
56 | 56 | %td |
|
57 | 57 | %tr |
|
58 | 58 | %td Full solver |
|
59 | 59 | %td |
|
60 | 60 | %td |
|
61 | 61 | - full.each.with_index do |s,i| |
|
62 | 62 | - next if i == 0 |
|
63 | 63 | %td.text-right= number_with_delimiter(s) |
|
64 | 64 | %td |
|
65 | 65 | %td |
|
66 | 66 | |
|
67 | 67 | |
|
68 | 68 | :javascript |
|
69 | 69 | $.bootstrapSortable(true,'reversed') |
@@ -1,11 +1,11 | |||
|
1 | 1 | .container-fluid |
|
2 | 2 | %h1 Current Score |
|
3 | 3 | = form_tag current_score_report_path, method: 'get' do |
|
4 | 4 | Show only users from this group |
|
5 |
- = select_tag "group_id", options_from_collection_for_select( Group.all, 'id','name',params[:group_ |
|
|
5 | + = select_tag "group_id", options_from_collection_for_select( Group.all, 'id','name',params[:group_id]), id: 'group_name',class: 'select2', style: 'width: 20em'; | |
|
6 | 6 | = submit_tag 'Apply',class: 'btn btn-default' |
|
7 | 7 | |
|
8 | 8 | %br |
|
9 | 9 | |
|
10 | 10 | |
|
11 | 11 | = render "score_table" |
You need to be logged in to leave comments.
Login now