asker-tool 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/README.md +53 -0
- data/bin/asker +4 -0
- data/docs/changelog/v2.1.md +99 -0
- data/docs/commands.md +15 -0
- data/docs/contributions.md +18 -0
- data/docs/history.md +40 -0
- data/docs/idea.md +44 -0
- data/docs/inputs/README.md +39 -0
- data/docs/inputs/code.md +69 -0
- data/docs/inputs/concepts.md +142 -0
- data/docs/inputs/jedi.md +68 -0
- data/docs/inputs/tables.md +112 -0
- data/docs/inputs/templates.md +87 -0
- data/docs/install/README.md +38 -0
- data/docs/install/manual.md +26 -0
- data/docs/install/scripts.md +26 -0
- data/docs/revise/asker-file.md +41 -0
- data/docs/revise/buenas-practicas/01-convocatoria.md +30 -0
- data/docs/revise/buenas-practicas/02-formulario.md +35 -0
- data/docs/revise/buenas-practicas/03-descripcion.md +63 -0
- data/docs/revise/buenas-practicas/04-resultados.md +17 -0
- data/docs/revise/buenas-practicas/05-reproducir.md +10 -0
- data/docs/revise/ejemplos/01/README.md +27 -0
- data/docs/revise/ejemplos/02/README.md +31 -0
- data/docs/revise/ejemplos/03/README.md +31 -0
- data/docs/revise/ejemplos/04/README.md +37 -0
- data/docs/revise/ejemplos/05/README.md +25 -0
- data/docs/revise/ejemplos/06/README.md +43 -0
- data/docs/revise/ejemplos/README.md +11 -0
- data/docs/revise/projects.md +74 -0
- data/lib/asker.rb +103 -0
- data/lib/asker/ai/ai.rb +70 -0
- data/lib/asker/ai/ai_calculate.rb +55 -0
- data/lib/asker/ai/concept_ai.rb +49 -0
- data/lib/asker/ai/question.rb +58 -0
- data/lib/asker/ai/stages/base_stage.rb +16 -0
- data/lib/asker/ai/stages/main.rb +8 -0
- data/lib/asker/ai/stages/stage_b.rb +87 -0
- data/lib/asker/ai/stages/stage_d.rb +160 -0
- data/lib/asker/ai/stages/stage_f.rb +156 -0
- data/lib/asker/ai/stages/stage_i.rb +140 -0
- data/lib/asker/ai/stages/stage_s.rb +52 -0
- data/lib/asker/ai/stages/stage_t.rb +170 -0
- data/lib/asker/application.rb +30 -0
- data/lib/asker/checker.rb +356 -0
- data/lib/asker/cli.rb +85 -0
- data/lib/asker/code/ai/base_code_ai.rb +48 -0
- data/lib/asker/code/ai/code_ai_factory.rb +26 -0
- data/lib/asker/code/ai/javascript_code_ai.rb +167 -0
- data/lib/asker/code/ai/python_code_ai.rb +167 -0
- data/lib/asker/code/ai/ruby_code_ai.rb +169 -0
- data/lib/asker/code/ai/sql_code_ai.rb +69 -0
- data/lib/asker/code/code.rb +53 -0
- data/lib/asker/data/column.rb +62 -0
- data/lib/asker/data/concept.rb +183 -0
- data/lib/asker/data/data_field.rb +87 -0
- data/lib/asker/data/row.rb +93 -0
- data/lib/asker/data/table.rb +96 -0
- data/lib/asker/data/template.rb +65 -0
- data/lib/asker/data/world.rb +53 -0
- data/lib/asker/exporter/code_gift_exporter.rb +35 -0
- data/lib/asker/exporter/code_screen_exporter.rb +45 -0
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +33 -0
- data/lib/asker/exporter/concept_ai_screen_exporter.rb +115 -0
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +33 -0
- data/lib/asker/exporter/concept_doc_exporter.rb +21 -0
- data/lib/asker/exporter/concept_screen_exporter.rb +25 -0
- data/lib/asker/exporter/main.rb +9 -0
- data/lib/asker/files/config.ini +40 -0
- data/lib/asker/formatter/code_string_formatter.rb +16 -0
- data/lib/asker/formatter/concept_doc_formatter.rb +37 -0
- data/lib/asker/formatter/concept_string_formatter.rb +66 -0
- data/lib/asker/formatter/question_gift_formatter.rb +65 -0
- data/lib/asker/formatter/question_hash_formatter.rb +40 -0
- data/lib/asker/formatter/question_moodlexml_formatter.rb +71 -0
- data/lib/asker/formatter/rb2haml_formatter.rb +26 -0
- data/lib/asker/lang/lang.rb +42 -0
- data/lib/asker/lang/lang_factory.rb +19 -0
- data/lib/asker/lang/text_actions.rb +150 -0
- data/lib/asker/loader/code_loader.rb +53 -0
- data/lib/asker/loader/content_loader.rb +101 -0
- data/lib/asker/loader/directory_loader.rb +58 -0
- data/lib/asker/loader/file_loader.rb +33 -0
- data/lib/asker/loader/image_url_loader.rb +61 -0
- data/lib/asker/loader/input_loader.rb +24 -0
- data/lib/asker/loader/project_loader.rb +71 -0
- data/lib/asker/logger.rb +21 -0
- data/lib/asker/project.rb +170 -0
- metadata +261 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
require_relative '../../lang/lang_factory'
|
3
|
+
require_relative '../../ai/question'
|
4
|
+
|
5
|
+
class BaseCodeAI
|
6
|
+
def name
|
7
|
+
File.basename(@data_object.filename)
|
8
|
+
end
|
9
|
+
|
10
|
+
def num
|
11
|
+
@num += 1
|
12
|
+
end
|
13
|
+
|
14
|
+
def clone_array(array)
|
15
|
+
out = []
|
16
|
+
array.each { |item| out << item.dup }
|
17
|
+
out
|
18
|
+
end
|
19
|
+
|
20
|
+
def lines_to_s(lines)
|
21
|
+
out = ''
|
22
|
+
lines.each_with_index do |line,index|
|
23
|
+
out << "%2d: #{line}\n"%(index+1)
|
24
|
+
end
|
25
|
+
out
|
26
|
+
end
|
27
|
+
|
28
|
+
def lines_to_html(lines)
|
29
|
+
out = ''
|
30
|
+
lines.each_with_index do |line,index|
|
31
|
+
out << "%2d: #{line}</br>"%(index+1)
|
32
|
+
end
|
33
|
+
out
|
34
|
+
end
|
35
|
+
|
36
|
+
def find_make_methods
|
37
|
+
list = self.public_methods.sort
|
38
|
+
list.select! { |name| name.to_s.start_with? 'make_'}
|
39
|
+
list.delete(:make_questions)
|
40
|
+
list
|
41
|
+
end
|
42
|
+
|
43
|
+
def make_questions
|
44
|
+
list = find_make_methods
|
45
|
+
list.each { |m| @questions += self.send m }
|
46
|
+
@questions
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
require_relative 'javascript_code_ai'
|
3
|
+
require_relative 'python_code_ai'
|
4
|
+
require_relative 'ruby_code_ai'
|
5
|
+
require_relative 'sql_code_ai'
|
6
|
+
|
7
|
+
module CodeAIFactory
|
8
|
+
def self.get(code)
|
9
|
+
type = code.type
|
10
|
+
case type
|
11
|
+
when :javascript
|
12
|
+
return JavascriptCodeAI.new(code)
|
13
|
+
when :python
|
14
|
+
return PythonCodeAI.new(code)
|
15
|
+
when :ruby
|
16
|
+
return RubyCodeAI.new(code)
|
17
|
+
when :sql
|
18
|
+
return SQLCodeAI.new(code)
|
19
|
+
when :vagrantfile
|
20
|
+
return RubyCodeAI.new(code)
|
21
|
+
else
|
22
|
+
puts "[ERROR] <#{type}> is not valid type"
|
23
|
+
end
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
|
2
|
+
require_relative '../../lang/lang_factory'
|
3
|
+
require_relative '../../ai/question'
|
4
|
+
require_relative 'base_code_ai'
|
5
|
+
|
6
|
+
class JavascriptCodeAI < BaseCodeAI
|
7
|
+
def initialize(data_object)
|
8
|
+
@data_object = data_object
|
9
|
+
@lines = data_object.lines
|
10
|
+
@lang = LangFactory.instance.get('javascript')
|
11
|
+
@num = 0
|
12
|
+
@questions = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def make_comment_error
|
16
|
+
questions = []
|
17
|
+
error_lines = []
|
18
|
+
@lines.each_with_index do |line,index|
|
19
|
+
if line.strip.start_with?('//')
|
20
|
+
lines = clone_array @lines
|
21
|
+
lines[index].sub!('//','').strip!
|
22
|
+
|
23
|
+
q = Question.new(:short)
|
24
|
+
q.name = "#{name}-#{num}-uncomment"
|
25
|
+
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
26
|
+
q.shorts << (index+1)
|
27
|
+
q.feedback = 'Comment symbol removed'
|
28
|
+
questions << q
|
29
|
+
elsif line.strip.size>0
|
30
|
+
lines = clone_array @lines
|
31
|
+
lines[index]='// ' + lines[index]
|
32
|
+
|
33
|
+
q = Question.new(:short)
|
34
|
+
q.name = "#{name}-#{num}-comment"
|
35
|
+
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
36
|
+
q.shorts << (index+1)
|
37
|
+
q.feedback = 'Comment symbol added'
|
38
|
+
questions << q
|
39
|
+
end
|
40
|
+
end
|
41
|
+
questions
|
42
|
+
end
|
43
|
+
|
44
|
+
def make_no_error_changes
|
45
|
+
questions = []
|
46
|
+
empty_lines = []
|
47
|
+
used_lines = []
|
48
|
+
@lines.each_with_index do |line,index|
|
49
|
+
if line.strip.size.zero?
|
50
|
+
empty_lines << index
|
51
|
+
else
|
52
|
+
used_lines << index
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
used_lines.each do |index|
|
57
|
+
lines = clone_array(@lines)
|
58
|
+
lines.insert(index, ' ' * (rand(4).to_i + 1))
|
59
|
+
if @lines.size < 4 || rand(2) == 0
|
60
|
+
q = Question.new(:short)
|
61
|
+
q.name = "#{name}-#{num}-codeok"
|
62
|
+
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
63
|
+
q.shorts << '0'
|
64
|
+
q.feedback = 'Code is OK'
|
65
|
+
questions << q
|
66
|
+
else
|
67
|
+
q = Question.new(:choice)
|
68
|
+
q.name = "#{name}-#{num}-codeok"
|
69
|
+
q.text = @lang.text_for(:code2,lines_to_html(lines))
|
70
|
+
others = (1..@lines.size).to_a.shuffle!
|
71
|
+
q.good = '0'
|
72
|
+
q.bads << others[0].to_s
|
73
|
+
q.bads << others[1].to_s
|
74
|
+
q.bads << others[2].to_s
|
75
|
+
q.feedback = 'Code is OK'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
questions
|
80
|
+
end
|
81
|
+
|
82
|
+
def make_syntax_error
|
83
|
+
questions = []
|
84
|
+
|
85
|
+
@lang.mistakes.each_pair do |key,values|
|
86
|
+
error_lines = []
|
87
|
+
@lines.each_with_index do |line,index|
|
88
|
+
error_lines << index if line.include?(key.to_s)
|
89
|
+
end
|
90
|
+
|
91
|
+
v = values.split(',')
|
92
|
+
v.each do |value|
|
93
|
+
error_lines.each do |index|
|
94
|
+
lines = clone_array(@lines)
|
95
|
+
lines[index].sub!(key.to_s, value)
|
96
|
+
if @lines.size < 4 || rand(2) == 0
|
97
|
+
q = Question.new(:short)
|
98
|
+
q.name = "#{name}-#{num}-syntaxerror"
|
99
|
+
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
100
|
+
q.shorts << (index+1)
|
101
|
+
q.feedback = "Syntax error: '#{value}' must be '#{key}'"
|
102
|
+
else
|
103
|
+
q = Question.new(:choice)
|
104
|
+
q.name = "#{name}-#{num}-syntaxerror"
|
105
|
+
q.text = @lang.text_for(:code2,lines_to_html(lines))
|
106
|
+
others = (1..@lines.size).to_a.shuffle!
|
107
|
+
others.delete(index+1)
|
108
|
+
q.good = (index + 1).to_s
|
109
|
+
q.bads << others[0].to_s
|
110
|
+
q.bads << others[1].to_s
|
111
|
+
q.bads << others[2].to_s
|
112
|
+
q.feedback = "Syntax error: '#{value}' must be '#{key}'"
|
113
|
+
end
|
114
|
+
questions << q
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
questions
|
119
|
+
end
|
120
|
+
|
121
|
+
def make_variable_error
|
122
|
+
questions = []
|
123
|
+
error_lines = []
|
124
|
+
@lines.each_with_index do |line, index|
|
125
|
+
# Search Variable assignment
|
126
|
+
m = /var\s*(\w*);\s*\w*/.match(line)
|
127
|
+
i = []
|
128
|
+
unless m.nil?
|
129
|
+
varname = (m.values_at 1)[0]
|
130
|
+
# Search used Variable
|
131
|
+
@lines.each_with_index do |line2, index2|
|
132
|
+
next if index >= index2
|
133
|
+
i << index2 if line2.include?(varname)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
next if i.size == 0
|
137
|
+
i.shuffle!
|
138
|
+
i.each do |k|
|
139
|
+
lines = clone_array @lines
|
140
|
+
temp = lines[index]
|
141
|
+
lines[index] = lines[k]
|
142
|
+
lines[k] = temp
|
143
|
+
|
144
|
+
if rand(2) == 0
|
145
|
+
q = Question.new(:short)
|
146
|
+
q.name = "#{name}-#{num}-variable"
|
147
|
+
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
148
|
+
q.shorts << (index + 1)
|
149
|
+
q.feedback = "Variable error! Swapped lines #{(index+1)} with #{(k+1)}"
|
150
|
+
else
|
151
|
+
q = Question.new(:choice)
|
152
|
+
q.name = "#{name}-#{num}-variable"
|
153
|
+
q.text = @lang.text_for(:code2,lines_to_html(lines))
|
154
|
+
others = (1..@lines.size).to_a.shuffle!
|
155
|
+
others.delete(index+1)
|
156
|
+
q.good = (index + 1).to_s
|
157
|
+
q.bads << others[0].to_s
|
158
|
+
q.bads << others[1].to_s
|
159
|
+
q.bads << others[2].to_s
|
160
|
+
q.feedback = "Variable error! Swapped lines #{(index+1)} with #{(k+1)}"
|
161
|
+
end
|
162
|
+
questions << q
|
163
|
+
end
|
164
|
+
end
|
165
|
+
questions
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
|
2
|
+
require_relative '../../lang/lang_factory'
|
3
|
+
require_relative '../../ai/question'
|
4
|
+
require_relative 'base_code_ai'
|
5
|
+
|
6
|
+
class PythonCodeAI < BaseCodeAI
|
7
|
+
def initialize(data_object)
|
8
|
+
@data_object = data_object
|
9
|
+
@lines = data_object.lines
|
10
|
+
@lang = LangFactory.instance.get('python')
|
11
|
+
@num = 0
|
12
|
+
@questions = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def make_comment_error
|
16
|
+
questions = []
|
17
|
+
error_lines = []
|
18
|
+
@lines.each_with_index do |line,index|
|
19
|
+
if line.strip.start_with?('#')
|
20
|
+
lines = clone_array @lines
|
21
|
+
lines[index].sub!('#','').strip!
|
22
|
+
|
23
|
+
q = Question.new(:short)
|
24
|
+
q.name = "#{name}-#{num}-uncomment"
|
25
|
+
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
26
|
+
q.shorts << (index+1)
|
27
|
+
q.feedback = 'Comment symbol removed'
|
28
|
+
questions << q
|
29
|
+
elsif line.strip.size>0
|
30
|
+
lines = clone_array @lines
|
31
|
+
lines[index]='# ' + lines[index]
|
32
|
+
|
33
|
+
q = Question.new(:short)
|
34
|
+
q.name = "#{name}-#{num}-comment"
|
35
|
+
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
36
|
+
q.shorts << (index+1)
|
37
|
+
q.feedback = 'Comment symbol added'
|
38
|
+
questions << q
|
39
|
+
end
|
40
|
+
end
|
41
|
+
questions
|
42
|
+
end
|
43
|
+
|
44
|
+
def make_no_error_changes
|
45
|
+
questions = []
|
46
|
+
empty_lines = []
|
47
|
+
used_lines = []
|
48
|
+
@lines.each_with_index do |line,index|
|
49
|
+
if line.strip.size.zero?
|
50
|
+
empty_lines << index
|
51
|
+
else
|
52
|
+
used_lines << index
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
used_lines.each do |index|
|
57
|
+
lines = clone_array(@lines)
|
58
|
+
lines.insert(index, ' ' * (rand(4).to_i + 1))
|
59
|
+
if @lines.size < 4 || rand(2) == 0
|
60
|
+
q = Question.new(:short)
|
61
|
+
q.name = "#{name}-#{num}-codeok"
|
62
|
+
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
63
|
+
q.shorts << '0'
|
64
|
+
q.feedback = 'Code is OK'
|
65
|
+
questions << q
|
66
|
+
else
|
67
|
+
q = Question.new(:choice)
|
68
|
+
q.name = "#{name}-#{num}-codeok"
|
69
|
+
q.text = @lang.text_for(:code2,lines_to_html(lines))
|
70
|
+
others = (1..@lines.size).to_a.shuffle!
|
71
|
+
q.good = '0'
|
72
|
+
q.bads << others[0].to_s
|
73
|
+
q.bads << others[1].to_s
|
74
|
+
q.bads << others[2].to_s
|
75
|
+
q.feedback = 'Code is OK'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
questions
|
80
|
+
end
|
81
|
+
|
82
|
+
def make_syntax_error
|
83
|
+
questions = []
|
84
|
+
|
85
|
+
@lang.mistakes.each_pair do |key,values|
|
86
|
+
error_lines = []
|
87
|
+
@lines.each_with_index do |line,index|
|
88
|
+
error_lines << index if line.include?(key.to_s)
|
89
|
+
end
|
90
|
+
|
91
|
+
v = values.split(',')
|
92
|
+
v.each do |value|
|
93
|
+
error_lines.each do |index|
|
94
|
+
lines = clone_array(@lines)
|
95
|
+
lines[index].sub!(key.to_s, value)
|
96
|
+
if @lines.size < 4 || rand(2) == 0
|
97
|
+
q = Question.new(:short)
|
98
|
+
q.name = "#{name}-#{num}-syntaxerror"
|
99
|
+
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
100
|
+
q.shorts << (index+1)
|
101
|
+
q.feedback = "Syntax error: '#{value}' must be '#{key}'"
|
102
|
+
else
|
103
|
+
q = Question.new(:choice)
|
104
|
+
q.name = "#{name}-#{num}-syntaxerror"
|
105
|
+
q.text = @lang.text_for(:code2,lines_to_html(lines))
|
106
|
+
others = (1..@lines.size).to_a.shuffle!
|
107
|
+
others.delete(index+1)
|
108
|
+
q.good = (index + 1).to_s
|
109
|
+
q.bads << others[0].to_s
|
110
|
+
q.bads << others[1].to_s
|
111
|
+
q.bads << others[2].to_s
|
112
|
+
q.feedback = "Syntax error: '#{value}' must be '#{key}'"
|
113
|
+
end
|
114
|
+
questions << q
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
questions
|
119
|
+
end
|
120
|
+
|
121
|
+
def make_variable_error
|
122
|
+
questions = []
|
123
|
+
error_lines = []
|
124
|
+
@lines.each_with_index do |line, index|
|
125
|
+
# Search Variable assignment
|
126
|
+
m = /\s*(\w*)\s*\=\w*/.match(line)
|
127
|
+
i = []
|
128
|
+
unless m.nil?
|
129
|
+
varname = (m.values_at 1)[0]
|
130
|
+
# Search used Variable
|
131
|
+
@lines.each_with_index do |line2, index2|
|
132
|
+
next if index >= index2
|
133
|
+
i << index2 if line2.include?(varname)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
next if i.size == 0
|
137
|
+
i.shuffle!
|
138
|
+
i.each do |k|
|
139
|
+
lines = clone_array @lines
|
140
|
+
temp = lines[index]
|
141
|
+
lines[index] = lines[k]
|
142
|
+
lines[k] = temp
|
143
|
+
|
144
|
+
if rand(2) == 0
|
145
|
+
q = Question.new(:short)
|
146
|
+
q.name = "#{name}-#{num}-variable"
|
147
|
+
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
148
|
+
q.shorts << (index + 1)
|
149
|
+
q.feedback = "Variable error! Swapped lines #{(index+1)} with #{(k+1)}"
|
150
|
+
else
|
151
|
+
q = Question.new(:choice)
|
152
|
+
q.name = "#{name}-#{num}-variable"
|
153
|
+
q.text = @lang.text_for(:code2,lines_to_html(lines))
|
154
|
+
others = (1..@lines.size).to_a.shuffle!
|
155
|
+
others.delete(index+1)
|
156
|
+
q.good = (index + 1).to_s
|
157
|
+
q.bads << others[0].to_s
|
158
|
+
q.bads << others[1].to_s
|
159
|
+
q.bads << others[2].to_s
|
160
|
+
q.feedback = "Variable error! Swapped lines #{(index+1)} with #{(k+1)}"
|
161
|
+
end
|
162
|
+
questions << q
|
163
|
+
end
|
164
|
+
end
|
165
|
+
questions
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
|
2
|
+
require_relative '../../lang/lang_factory'
|
3
|
+
require_relative '../../ai/question'
|
4
|
+
require_relative 'base_code_ai'
|
5
|
+
|
6
|
+
class RubyCodeAI < BaseCodeAI
|
7
|
+
def initialize(data_object)
|
8
|
+
@data_object = data_object
|
9
|
+
@lines = data_object.lines
|
10
|
+
@lang = LangFactory.instance.get('ruby')
|
11
|
+
@num = 0
|
12
|
+
@questions = []
|
13
|
+
@reduce = 1
|
14
|
+
@reduce = 4 if @lines.size > 25
|
15
|
+
end
|
16
|
+
|
17
|
+
def make_comment_error
|
18
|
+
questions = []
|
19
|
+
error_lines = []
|
20
|
+
@lines.each_with_index do |line,index|
|
21
|
+
if line.strip.start_with?('#')
|
22
|
+
lines = clone_array @lines
|
23
|
+
lines[index].sub!('#','').strip!
|
24
|
+
|
25
|
+
q = Question.new(:short)
|
26
|
+
q.name = "#{name}-#{num}-uncomment"
|
27
|
+
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
28
|
+
q.shorts << (index+1)
|
29
|
+
q.feedback = 'Comment symbol removed'
|
30
|
+
questions << q
|
31
|
+
elsif line.strip.size>0
|
32
|
+
lines = clone_array @lines
|
33
|
+
lines[index]='# ' + lines[index]
|
34
|
+
|
35
|
+
q = Question.new(:short)
|
36
|
+
q.name = "#{name}-#{num}-comment"
|
37
|
+
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
38
|
+
q.shorts << (index+1)
|
39
|
+
q.feedback = 'Comment symbol added'
|
40
|
+
questions << q
|
41
|
+
end
|
42
|
+
end
|
43
|
+
questions.shuffle[0,@lines.size/@reduce]
|
44
|
+
end
|
45
|
+
|
46
|
+
def make_no_error_changes
|
47
|
+
questions = []
|
48
|
+
empty_lines = []
|
49
|
+
used_lines = []
|
50
|
+
@lines.each_with_index do |line,index|
|
51
|
+
if line.strip.size.zero?
|
52
|
+
empty_lines << index
|
53
|
+
else
|
54
|
+
used_lines << index
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
used_lines.each do |index|
|
59
|
+
lines = clone_array(@lines)
|
60
|
+
lines.insert(index, ' ' * (rand(4).to_i + 1))
|
61
|
+
if @lines.size < 4 || rand(2) == 0
|
62
|
+
q = Question.new(:short)
|
63
|
+
q.name = "#{name}-#{num}-codeok"
|
64
|
+
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
65
|
+
q.shorts << '0'
|
66
|
+
q.feedback = 'Code is OK'
|
67
|
+
questions << q
|
68
|
+
else
|
69
|
+
q = Question.new(:choice)
|
70
|
+
q.name = "#{name}-#{num}-codeok"
|
71
|
+
q.text = @lang.text_for(:code2,lines_to_html(lines))
|
72
|
+
others = (1..@lines.size).to_a.shuffle!
|
73
|
+
q.good = '0'
|
74
|
+
q.bads << others[0].to_s
|
75
|
+
q.bads << others[1].to_s
|
76
|
+
q.bads << others[2].to_s
|
77
|
+
q.feedback = 'Code is OK'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
questions.shuffle[0,@lines.size/@reduce]
|
82
|
+
end
|
83
|
+
|
84
|
+
def make_syntax_error
|
85
|
+
questions = []
|
86
|
+
|
87
|
+
@lang.mistakes.each_pair do |key,values|
|
88
|
+
error_lines = []
|
89
|
+
@lines.each_with_index do |line,index|
|
90
|
+
error_lines << index if line.include?(key.to_s)
|
91
|
+
end
|
92
|
+
|
93
|
+
v = values.split(',')
|
94
|
+
v.each do |value|
|
95
|
+
error_lines.each do |index|
|
96
|
+
lines = clone_array(@lines)
|
97
|
+
lines[index].sub!(key.to_s, value)
|
98
|
+
if @lines.size < 4 || rand(2) == 0
|
99
|
+
q = Question.new(:short)
|
100
|
+
q.name = "#{name}-#{num}-syntaxerror"
|
101
|
+
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
102
|
+
q.shorts << (index+1)
|
103
|
+
q.feedback = "Syntax error: '#{value}' must be '#{key}'"
|
104
|
+
else
|
105
|
+
q = Question.new(:choice)
|
106
|
+
q.name = "#{name}-#{num}-syntaxerror"
|
107
|
+
q.text = @lang.text_for(:code2,lines_to_html(lines))
|
108
|
+
others = (1..@lines.size).to_a.shuffle!
|
109
|
+
others.delete(index+1)
|
110
|
+
q.good = (index + 1).to_s
|
111
|
+
q.bads << others[0].to_s
|
112
|
+
q.bads << others[1].to_s
|
113
|
+
q.bads << others[2].to_s
|
114
|
+
q.feedback = "Syntax error: '#{value}' must be '#{key}'"
|
115
|
+
end
|
116
|
+
questions << q
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
questions.shuffle[0,@lines.size/@reduce]
|
121
|
+
end
|
122
|
+
|
123
|
+
def make_variable_error
|
124
|
+
questions = []
|
125
|
+
error_lines = []
|
126
|
+
@lines.each_with_index do |line, index|
|
127
|
+
# Search Variable assignment
|
128
|
+
m = /\s*(\w*)\s*\=\w*/.match(line)
|
129
|
+
i = []
|
130
|
+
unless m.nil?
|
131
|
+
varname = (m.values_at 1)[0]
|
132
|
+
# Search used Variable
|
133
|
+
@lines.each_with_index do |line2, index2|
|
134
|
+
next if index >= index2
|
135
|
+
i << index2 if line2.include?(varname)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
next if i.size == 0
|
139
|
+
i.shuffle!
|
140
|
+
i.each do |k|
|
141
|
+
lines = clone_array @lines
|
142
|
+
temp = lines[index]
|
143
|
+
lines[index] = lines[k]
|
144
|
+
lines[k] = temp
|
145
|
+
|
146
|
+
if rand(2) == 0
|
147
|
+
q = Question.new(:short)
|
148
|
+
q.name = "#{name}-#{num}-variable"
|
149
|
+
q.text = @lang.text_for(:code1, lines_to_html(lines))
|
150
|
+
q.shorts << (index + 1)
|
151
|
+
q.feedback = "Variable error! Swapped lines #{(index+1)} with #{(k+1)}"
|
152
|
+
else
|
153
|
+
q = Question.new(:choice)
|
154
|
+
q.name = "#{name}-#{num}-variable"
|
155
|
+
q.text = @lang.text_for(:code2, lines_to_html(lines))
|
156
|
+
others = (1..@lines.size).to_a.shuffle!
|
157
|
+
others.delete(index+1)
|
158
|
+
q.good = (index + 1).to_s
|
159
|
+
q.bads << others[0].to_s
|
160
|
+
q.bads << others[1].to_s
|
161
|
+
q.bads << others[2].to_s
|
162
|
+
q.feedback = "Variable error! Swapped lines #{(index+1)} with #{(k+1)}"
|
163
|
+
end
|
164
|
+
questions << q
|
165
|
+
end
|
166
|
+
end
|
167
|
+
questions.shuffle[0,@lines.size/@reduce]
|
168
|
+
end
|
169
|
+
end
|