Description:
add selectable checker (for now, only 'text' and 'float') in the problem import
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r402:7f3e18dca393 - - 4 files changed: 25 inserted, 3 deleted

@@ -22,93 +22,100
22 import_params, problem = Problem.extract_params_and_check(params,
22 import_params, problem = Problem.extract_params_and_check(params,
23 org_problem)
23 org_problem)
24
24
25 if !problem.errors.empty?
25 if !problem.errors.empty?
26 return problem, 'Error importing'
26 return problem, 'Error importing'
27 end
27 end
28
28
29 problem.full_score = 100
29 problem.full_score = 100
30 problem.date_added = Time.new
30 problem.date_added = Time.new
31 problem.test_allowed = true
31 problem.test_allowed = true
32 problem.output_only = false
32 problem.output_only = false
33 problem.available = false
33 problem.available = false
34
34
35 if not problem.save
35 if not problem.save
36 return problem, 'Error importing'
36 return problem, 'Error importing'
37 end
37 end
38
38
39 import_to_db = params.has_key? :import_to_db
39 import_to_db = params.has_key? :import_to_db
40
40
41 importer = TestdataImporter.new(problem)
41 importer = TestdataImporter.new(problem)
42
42
43 if not importer.import_from_file(import_params[:file],
43 if not importer.import_from_file(import_params[:file],
44 import_params[:time_limit],
44 import_params[:time_limit],
45 import_params[:memory_limit],
45 import_params[:memory_limit],
46 + import_params[:checker_name],
46 import_to_db)
47 import_to_db)
47 problem.errors.add_to_base('Import error.')
48 problem.errors.add_to_base('Import error.')
48 end
49 end
49
50
50 return problem, importer.log_msg
51 return problem, importer.log_msg
51 end
52 end
52
53
53 def self.download_file_basedir
54 def self.download_file_basedir
54 return "#{Rails.root}/data/tasks"
55 return "#{Rails.root}/data/tasks"
55 end
56 end
56
57
57 protected
58 protected
58
59
59 def self.to_i_or_default(st, default)
60 def self.to_i_or_default(st, default)
60 if st!=''
61 if st!=''
61 result = st.to_i
62 result = st.to_i
62 end
63 end
63 result ||= default
64 result ||= default
64 end
65 end
65
66
66 def self.to_f_or_default(st, default)
67 def self.to_f_or_default(st, default)
67 if st!=''
68 if st!=''
68 result = st.to_f
69 result = st.to_f
69 end
70 end
70 result ||= default
71 result ||= default
71 end
72 end
72
73
73 def self.extract_params_and_check(params, problem)
74 def self.extract_params_and_check(params, problem)
74 time_limit = Problem.to_f_or_default(params[:time_limit],
75 time_limit = Problem.to_f_or_default(params[:time_limit],
75 DEFAULT_TIME_LIMIT)
76 DEFAULT_TIME_LIMIT)
76 memory_limit = Problem.to_i_or_default(params[:memory_limit],
77 memory_limit = Problem.to_i_or_default(params[:memory_limit],
77 DEFAULT_MEMORY_LIMIT)
78 DEFAULT_MEMORY_LIMIT)
78
79
79 if time_limit<=0 or time_limit >60
80 if time_limit<=0 or time_limit >60
80 problem.errors.add_to_base('Time limit out of range.')
81 problem.errors.add_to_base('Time limit out of range.')
81 end
82 end
82
83
83 if memory_limit==0 and params[:memory_limit]!='0'
84 if memory_limit==0 and params[:memory_limit]!='0'
84 problem.errors.add_to_base('Memory limit format errors.')
85 problem.errors.add_to_base('Memory limit format errors.')
85 elsif memory_limit<=0 or memory_limit >512
86 elsif memory_limit<=0 or memory_limit >512
86 problem.errors.add_to_base('Memory limit out of range.')
87 problem.errors.add_to_base('Memory limit out of range.')
87 end
88 end
88
89
89 if params[:file]==nil or params[:file]==''
90 if params[:file]==nil or params[:file]==''
90 problem.errors.add_to_base('No testdata file.')
91 problem.errors.add_to_base('No testdata file.')
91 end
92 end
92
93
94 + checker_name = 'text'
95 + if ['text','float'].include? params[:checker]
96 + checker_name = params[:checker]
97 + end
98 +
93 file = params[:file]
99 file = params[:file]
94
100
95 if !problem.errors.empty?
101 if !problem.errors.empty?
96 return nil, problem
102 return nil, problem
97 end
103 end
98
104
99 problem.name = params[:name]
105 problem.name = params[:name]
100 if params[:full_name]!=''
106 if params[:full_name]!=''
101 problem.full_name = params[:full_name]
107 problem.full_name = params[:full_name]
102 else
108 else
103 problem.full_name = params[:name]
109 problem.full_name = params[:name]
104 end
110 end
105
111
106 return [{
112 return [{
107 :time_limit => time_limit,
113 :time_limit => time_limit,
108 :memory_limit => memory_limit,
114 :memory_limit => memory_limit,
109 - :file => file
115 + :file => file,
116 + :checker_name => checker_name
110 },
117 },
111 problem]
118 problem]
112 end
119 end
113
120
114 end
121 end
@@ -11,48 +11,61
11 = form_tag({:action => 'do_import'}, :multipart => true) do
11 = form_tag({:action => 'do_import'}, :multipart => true) do
12 .submitbox
12 .submitbox
13 %table
13 %table
14 %tr
14 %tr
15 %td Name:
15 %td Name:
16 %td= text_field_tag 'name'
16 %td= text_field_tag 'name'
17 %tr
17 %tr
18 %td Full name:
18 %td Full name:
19 %td
19 %td
20 = text_field_tag 'full_name'
20 = text_field_tag 'full_name'
21 %span{:class => 'help'} Leave blank to use the same value as the name above.
21 %span{:class => 'help'} Leave blank to use the same value as the name above.
22 %tr
22 %tr
23 %td Testdata file:
23 %td Testdata file:
24 %td= file_field_tag 'file'
24 %td= file_field_tag 'file'
25 %tr
25 %tr
26 %td
26 %td
27 %td
27 %td
28 %span{:class => 'help'}
28 %span{:class => 'help'}
29 In .zip, .tgz, tar.gz, .tar format.
29 In .zip, .tgz, tar.gz, .tar format.
30 It should includes inputs (e.g., 1.in, 2a.in, 2b.in)
30 It should includes inputs (e.g., 1.in, 2a.in, 2b.in)
31 and solutions (e.g., 1.sol, 2a.sol, 2b.sol).
31 and solutions (e.g., 1.sol, 2a.sol, 2b.sol).
32 %br/
32 %br/
33 You may put task description in *.html for raw html
33 You may put task description in *.html for raw html
34 and *.md or *.markdown for markdown.
34 and *.md or *.markdown for markdown.
35 + %br/
36 + You may also put a pdf file for the task description
37 + %tr
38 + %td Checker:
39 + %td= select_tag 'checker', options_for_select([['Text checker','text'],['Float checker','float']], 'text')
40 + %tr
41 + %td
42 + %td
43 + %span{:class => 'help'}
44 + "Text" checker checks if the text (including numbers) is the same, ignoring any whitespace
45 + %br/
46 + "Float" checker checks if all numbers is within EPSILON error using formula |a-b| < EPSILON * max(|a|,|b|)
47 +
35 - if @allow_test_pair_import
48 - if @allow_test_pair_import
36 %tr
49 %tr
37 %td
50 %td
38 %td
51 %td
39 = check_box_tag 'import_to_db'
52 = check_box_tag 'import_to_db'
40 Import test data to database (for a test-pair task)
53 Import test data to database (for a test-pair task)
41 %tr
54 %tr
42 %td Time limit:
55 %td Time limit:
43 %td
56 %td
44 = text_field_tag 'time_limit'
57 = text_field_tag 'time_limit'
45 %span{:class => 'help'} In seconds. Leave blank to use 1 sec.
58 %span{:class => 'help'} In seconds. Leave blank to use 1 sec.
46 %tr
59 %tr
47 %td Memory limit:
60 %td Memory limit:
48 %td
61 %td
49 = text_field_tag 'memory_limit'
62 = text_field_tag 'memory_limit'
50 %span{:class => 'help'} In MB. Leave blank to use 32MB.
63 %span{:class => 'help'} In MB. Leave blank to use 32MB.
51 %tr
64 %tr
52 %td
65 %td
53 %td= submit_tag 'Import problem'
66 %td= submit_tag 'Import problem'
54
67
55 - if @log
68 - if @log
56 %h3 Import log
69 %h3 Import log
57 %pre.import-log
70 %pre.import-log
58 = @log
71 = @log
@@ -29,30 +29,30
29 end
29 end
30
30
31 def self.start_grader(env)
31 def self.start_grader(env)
32 GraderScript.call_grader "#{env} queue &"
32 GraderScript.call_grader "#{env} queue &"
33 GraderScript.call_grader "#{env} test_request &"
33 GraderScript.call_grader "#{env} test_request &"
34 end
34 end
35
35
36 def self.call_import_problem(problem_name,
36 def self.call_import_problem(problem_name,
37 problem_dir,
37 problem_dir,
38 time_limit=1,
38 time_limit=1,
39 memory_limit=32,
39 memory_limit=32,
40 checker_name='text')
40 checker_name='text')
41 if GraderScript.grader_control_enabled?
41 if GraderScript.grader_control_enabled?
42 cur_dir = `pwd`.chomp
42 cur_dir = `pwd`.chomp
43 Dir.chdir(GRADER_ROOT_DIR)
43 Dir.chdir(GRADER_ROOT_DIR)
44
44
45 script_name = File.join(GRADER_ROOT_DIR, "scripts/import_problem")
45 script_name = File.join(GRADER_ROOT_DIR, "scripts/import_problem")
46 cmd = "#{script_name} #{problem_name} #{problem_dir} #{checker_name}" +
46 cmd = "#{script_name} #{problem_name} #{problem_dir} #{checker_name}" +
47 " -t #{time_limit} -m #{memory_limit}"
47 " -t #{time_limit} -m #{memory_limit}"
48
48
49 output = `#{cmd}`
49 output = `#{cmd}`
50
50
51 Dir.chdir(cur_dir)
51 Dir.chdir(cur_dir)
52
52
53 - return output
53 + return "import CMD: #{cmd}\n" + output
54 end
54 end
55 return ''
55 return ''
56 end
56 end
57
57
58 end
58 end
@@ -1,46 +1,48
1 require 'tmpdir'
1 require 'tmpdir'
2
2
3 class TestdataImporter
3 class TestdataImporter
4
4
5 attr :log_msg
5 attr :log_msg
6
6
7 def initialize(problem)
7 def initialize(problem)
8 @problem = problem
8 @problem = problem
9 end
9 end
10
10
11 def import_from_file(tempfile,
11 def import_from_file(tempfile,
12 time_limit,
12 time_limit,
13 memory_limit,
13 memory_limit,
14 + checker_name='text',
14 import_to_db=false)
15 import_to_db=false)
15
16
16 dirname = extract(tempfile)
17 dirname = extract(tempfile)
17 return false if not dirname
18 return false if not dirname
18 if not import_to_db
19 if not import_to_db
19 @log_msg = GraderScript.call_import_problem(@problem.name,
20 @log_msg = GraderScript.call_import_problem(@problem.name,
20 dirname,
21 dirname,
21 time_limit,
22 time_limit,
22 - memory_limit)
23 + memory_limit,
24 + checker_name)
23 else
25 else
24 # Import test data to test pairs.
26 # Import test data to test pairs.
25
27
26 @problem.test_pairs.clear
28 @problem.test_pairs.clear
27 if import_test_pairs(dirname)
29 if import_test_pairs(dirname)
28 test_pair_count = TestPair.count :conditions => "problem_id = #{@problem.id}"
30 test_pair_count = TestPair.count :conditions => "problem_id = #{@problem.id}"
29 @log_msg = "Importing test pair successful. (#{test_pair_count} test pairs imported)"
31 @log_msg = "Importing test pair successful. (#{test_pair_count} test pairs imported)"
30 else
32 else
31 @log_msg = "Importing test pair failed. (0 test pairs imported)"
33 @log_msg = "Importing test pair failed. (0 test pairs imported)"
32 end
34 end
33 end
35 end
34
36
35 @log_msg << import_problem_description(dirname)
37 @log_msg << import_problem_description(dirname)
36 @log_msg << import_problem_pdf(dirname)
38 @log_msg << import_problem_pdf(dirname)
37 @log_msg << import_full_score(dirname)
39 @log_msg << import_full_score(dirname)
38
40
39 return true
41 return true
40 end
42 end
41
43
42 protected
44 protected
43
45
44 def self.long_ext(filename)
46 def self.long_ext(filename)
45 i = filename.index('.')
47 i = filename.index('.')
46 len = filename.length
48 len = filename.length
You need to be logged in to leave comments. Login now