asker-tool 2.6.0 → 2.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/lib/asker/ai/ai.rb +6 -6
- data/lib/asker/ai/ai_calculate.rb +3 -3
- data/lib/asker/ai/code/base_code_ai.rb +5 -30
- data/lib/asker/ai/code/code_ai_factory.rb +6 -12
- data/lib/asker/ai/code/javascript_code_ai.rb +33 -34
- data/lib/asker/ai/code/python_code_ai.rb +35 -36
- data/lib/asker/ai/code/ruby_code_ai.rb +33 -33
- data/lib/asker/ai/code/sql_code_ai.rb +20 -21
- data/lib/asker/ai/concept_ai.rb +12 -22
- data/lib/asker/ai/problem/problem_ai.rb +226 -0
- data/lib/asker/ai/question.rb +34 -45
- data/lib/asker/ai/stages/base_stage.rb +7 -7
- data/lib/asker/ai/stages/stage_b.rb +62 -28
- data/lib/asker/ai/stages/stage_d.rb +10 -10
- data/lib/asker/ai/stages/stage_f.rb +17 -17
- data/lib/asker/ai/stages/stage_i.rb +8 -18
- data/lib/asker/ai/stages/stage_s.rb +28 -26
- data/lib/asker/ai/stages/stage_t.rb +40 -51
- data/lib/asker/application.rb +15 -14
- data/lib/asker/check_input/check_haml_data.rb +52 -51
- data/lib/asker/check_input/check_table.rb +17 -20
- data/lib/asker/check_input.rb +10 -23
- data/lib/asker/cli.rb +43 -24
- data/lib/asker/data/code.rb +10 -9
- data/lib/asker/data/column.rb +21 -17
- data/lib/asker/data/concept.rb +24 -37
- data/lib/asker/data/data_field.rb +2 -2
- data/lib/asker/data/problem.rb +112 -0
- data/lib/asker/data/project_data.rb +11 -15
- data/lib/asker/data/row.rb +25 -23
- data/lib/asker/data/table.rb +25 -46
- data/lib/asker/data/template.rb +7 -7
- data/lib/asker/data/world.rb +3 -3
- data/lib/asker/{formatter → deprecated}/question_moodlexml_formatter.rb +19 -21
- data/lib/asker/displayer/code_displayer.rb +10 -10
- data/lib/asker/displayer/concept_ai_displayer.erb +1 -1
- data/lib/asker/displayer/concept_ai_displayer.rb +17 -17
- data/lib/asker/displayer/concept_displayer.rb +4 -2
- data/lib/asker/displayer/problem_displayer.rb +45 -0
- data/lib/asker/displayer/stats_displayer.rb +7 -12
- data/lib/asker/exporter/code_gift_exporter.rb +2 -2
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +4 -4
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +7 -7
- data/lib/asker/exporter/concept_doc_exporter.rb +5 -5
- data/lib/asker/exporter/data_gift_exporter.rb +14 -15
- data/lib/asker/exporter/data_moodle_exporter.rb +51 -20
- data/lib/asker/exporter/output_file_exporter.rb +9 -8
- data/lib/asker/exporter/problem_gift_exporter.rb +30 -0
- data/lib/asker/files/language/ca/templates.yaml +6 -0
- data/lib/asker/files/language/du/templates.yaml +6 -0
- data/lib/asker/files/language/en/templates.yaml +7 -1
- data/lib/asker/files/language/es/templates.yaml +6 -0
- data/lib/asker/files/language/fr/templates.yaml +6 -0
- data/lib/asker/formatter/code_string_formatter.rb +5 -5
- data/lib/asker/formatter/concept_doc_formatter.rb +3 -3
- data/lib/asker/formatter/concept_string_formatter.rb +6 -6
- data/lib/asker/formatter/moodle/ddmatch.erb +40 -0
- data/lib/asker/formatter/moodle/gapfill.erb +57 -0
- data/lib/asker/formatter/moodle/ordering.erb +41 -0
- data/lib/asker/formatter/question_gift_formatter.rb +41 -14
- data/lib/asker/formatter/question_hash_formatter.rb +5 -6
- data/lib/asker/formatter/question_moodle_formatter.rb +14 -7
- data/lib/asker/formatter/rb2haml_formatter.rb +8 -7
- data/lib/asker/lang/lang.rb +16 -16
- data/lib/asker/lang/lang_factory.rb +13 -16
- data/lib/asker/lang/text_actions.rb +20 -18
- data/lib/asker/loader/code_loader.rb +10 -22
- data/lib/asker/loader/content_loader.rb +42 -49
- data/lib/asker/loader/directory_loader.rb +13 -16
- data/lib/asker/loader/embedded_file.rb +14 -14
- data/lib/asker/loader/file_loader.rb +5 -4
- data/lib/asker/loader/haml_loader.rb +4 -3
- data/lib/asker/loader/image_url_loader.rb +6 -5
- data/lib/asker/loader/input_loader.rb +24 -10
- data/lib/asker/loader/problem_loader.rb +88 -0
- data/lib/asker/loader/project_loader.rb +5 -12
- data/lib/asker/logger.rb +19 -10
- data/lib/asker/skeleton.rb +19 -35
- data/lib/asker/start.rb +44 -0
- data/lib/asker/version.rb +1 -1
- data/lib/asker.rb +7 -52
- metadata +12 -6
- data/lib/asker/ai/code/problem_code_ai.rb +0 -176
- data/lib/asker/exporter/code_moodle_exporter.rb +0 -15
- data/lib/asker/exporter/concept_ai_moodle_exporter.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e5cbcd35b27392a56444a2bdae4036445ac8b7b8404c6601e006764fbe0dae8
|
4
|
+
data.tar.gz: 04de6c0757edfba5abf31744d53844fd51f766c5287413d387c309fa3c95131e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0305dfd9e98c0f92cf05cf567f1ab71b2522db32f930865e623dadc84fa9601623269a095fe590e4d7be9cc77c842590fd03848ad961c9047be786bfae6c7d6
|
7
|
+
data.tar.gz: 833a34e6159b81f68919944a9fbc412c6870634d3d5eb6614e23c470c9d1bea5d4bf4a2c57bc70c836b06a75ad914f411710200cc2bde8070e5c8d32f04cb745
|
data/README.md
CHANGED
@@ -34,10 +34,10 @@ Let's see an example creating questions from ACDC input example file:
|
|
34
34
|
+--------------------+-----------+---------+---------+---+---+----+---+---+----+
|
35
35
|
| Concept | Questions | Entries | xFactor | d | b | f | i | s | t |
|
36
36
|
+--------------------+-----------+---------+---------+---+---+----+---+---+----+
|
37
|
-
| AC/DC |
|
37
|
+
| AC/DC | 46 | 18 | 2.5 | 7 | 0 | 15 | 0 | 4 | 20 |
|
38
38
|
| Excluded questions | 0 | - | - | 0 | 0 | 0 | 0 | 0 | 0 |
|
39
39
|
+--------------------+-----------+---------+---------+---+---+----+---+---+----+
|
40
|
-
| 1 concept/s |
|
40
|
+
| 1 concept/s | 46 | 18 | 2.5 | 7 | 0 | 15 | 0 | 4 | 20 |
|
41
41
|
+--------------------+-----------+---------+---------+---+---+----+---+---+----+
|
42
42
|
```
|
43
43
|
|
@@ -46,15 +46,15 @@ Let's see an example creating questions from ACDC input example file:
|
|
46
46
|
* [Free Software License](LICENSE).
|
47
47
|
* Multiplatform.
|
48
48
|
* Input files formats: XML, HAML.
|
49
|
-
* Output formats: GIFT, Moodle XML.
|
50
|
-
* Question types: true/false, multiple choice, short answer, matching.
|
49
|
+
* Output formats: GIFT, Moodle XML, YAML.
|
50
|
+
* Question types: true/false, multiple choice, short answer, matching and ordering.
|
51
51
|
* Embeded files: mp3, ogg, wav, jpg, jpeg, png, mp4, ogv and plain text files.
|
52
52
|
|
53
53
|
# Documentation
|
54
54
|
|
55
55
|
* [Installation](docs/install/README.md)
|
56
56
|
* [Videos](docs/videos.md)
|
57
|
-
* [
|
57
|
+
* [Get started](docs/inputs/README.md)
|
58
58
|
* [Usage](docs/usage.md)
|
59
59
|
* [Reference](docs/reference.md)
|
60
60
|
* [Contributions](docs/contributions.md)
|
data/lib/asker/ai/ai.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative
|
4
|
-
require_relative
|
3
|
+
require_relative "stages/main"
|
4
|
+
require_relative "ai_calculate"
|
5
5
|
|
6
6
|
# Description: Method to be included into every ConceptAI instance.
|
7
7
|
# * make_questions: use AI to fill @questions Array
|
@@ -49,12 +49,12 @@ module AI
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def exclude_questions
|
52
|
-
param = Application.instance.config[
|
52
|
+
param = Application.instance.config["questions"]["exclude"]
|
53
53
|
return if param.nil?
|
54
54
|
|
55
|
-
tags = param.split(
|
56
|
-
input = {
|
57
|
-
output = {
|
55
|
+
tags = param.split(",").each(&:strip!)
|
56
|
+
input = {d: [], b: [], f: [], i: [], s: [], t: []}
|
57
|
+
output = {d: [], b: [], f: [], i: [], s: [], t: []}
|
58
58
|
|
59
59
|
@questions.each_pair do |key, qlist|
|
60
60
|
output[key] = qlist.select { |q| string_has_this_tags?(q.name, tags) }
|
@@ -12,7 +12,7 @@ module AICalculate
|
|
12
12
|
list1 = []
|
13
13
|
count = 1
|
14
14
|
p_table.rows.each do |i|
|
15
|
-
list1 << {
|
15
|
+
list1 << {id: count, weight: 0, data: i}
|
16
16
|
count += 1
|
17
17
|
end
|
18
18
|
|
@@ -23,7 +23,7 @@ module AICalculate
|
|
23
23
|
next if t2.name != p_table.name
|
24
24
|
|
25
25
|
t2.rows.each do |i|
|
26
|
-
list2 << {
|
26
|
+
list2 << {id: count, weight: 0, data: i}
|
27
27
|
count += 1
|
28
28
|
end
|
29
29
|
end
|
@@ -34,7 +34,7 @@ module AICalculate
|
|
34
34
|
def calculate_nearness_between_texts(text1, text2)
|
35
35
|
return 0.0 if text2.nil? || text2.empty?
|
36
36
|
|
37
|
-
words = text1.split(
|
37
|
+
words = text1.split(" ")
|
38
38
|
count = 0
|
39
39
|
words.each { |w| count += 1 if text2.include?(w) }
|
40
40
|
(count * 100 / words.count)
|
@@ -1,16 +1,13 @@
|
|
1
1
|
# frozen_string_literal: false
|
2
2
|
|
3
|
-
require_relative
|
4
|
-
require_relative
|
3
|
+
require_relative "../../lang/lang_factory"
|
4
|
+
require_relative "../../ai/question"
|
5
5
|
|
6
6
|
##
|
7
7
|
# BaseCodeAI class
|
8
8
|
class BaseCodeAI
|
9
9
|
attr_reader :questions
|
10
10
|
|
11
|
-
##
|
12
|
-
# Create CodeAI object from Code data
|
13
|
-
# @param code (Code)
|
14
11
|
def initialize(code)
|
15
12
|
@code = code
|
16
13
|
@lines = code.lines
|
@@ -19,9 +16,6 @@ class BaseCodeAI
|
|
19
16
|
make_questions
|
20
17
|
end
|
21
18
|
|
22
|
-
##
|
23
|
-
# Return the name of code
|
24
|
-
# @return String
|
25
19
|
def name
|
26
20
|
File.basename(@code.filename)
|
27
21
|
end
|
@@ -42,51 +36,32 @@ class BaseCodeAI
|
|
42
36
|
@code.lines
|
43
37
|
end
|
44
38
|
|
45
|
-
##
|
46
|
-
# Counter
|
47
|
-
# @return count
|
48
39
|
def num
|
49
40
|
@num += 1
|
50
41
|
end
|
51
42
|
|
52
|
-
##
|
53
|
-
# Clone array
|
54
|
-
# @param array (Array)
|
55
|
-
# @return Array
|
56
43
|
def clone_array(array)
|
57
44
|
out = []
|
58
45
|
array.each { |item| out << item.dup }
|
59
46
|
out
|
60
47
|
end
|
61
48
|
|
62
|
-
##
|
63
|
-
# Convert an array of lines into one String
|
64
|
-
# @param lines (Array)
|
65
|
-
# @return String
|
66
|
-
# rubocop:disable Style/FormatString
|
67
49
|
def lines_to_s(lines)
|
68
|
-
out =
|
50
|
+
out = ""
|
69
51
|
lines.each_with_index do |line, index|
|
70
52
|
out << "%2d: #{line}\n" % (index + 1)
|
71
53
|
end
|
72
54
|
out
|
73
55
|
end
|
74
56
|
|
75
|
-
##
|
76
|
-
# Convert an array of lines into one HTML String
|
77
|
-
# @param lines (Array)
|
78
|
-
# @return String
|
79
57
|
def lines_to_html(lines)
|
80
|
-
out =
|
58
|
+
out = ""
|
81
59
|
lines.each_with_index do |line, index|
|
82
60
|
out << "%2d: #{line}</br>" % (index + 1)
|
83
61
|
end
|
84
62
|
out
|
85
63
|
end
|
86
|
-
# rubocop:enable Style/FormatString
|
87
64
|
|
88
|
-
##
|
89
|
-
# Make questions
|
90
65
|
def make_questions
|
91
66
|
list = find_make_methods
|
92
67
|
list.each { |m| @questions += send m }
|
@@ -97,7 +72,7 @@ class BaseCodeAI
|
|
97
72
|
|
98
73
|
def find_make_methods
|
99
74
|
list = public_methods.sort
|
100
|
-
list.select! { |name| name.to_s.start_with?
|
75
|
+
list.select! { |name| name.to_s.start_with? "make_" }
|
101
76
|
list.delete(:make_questions)
|
102
77
|
list
|
103
78
|
end
|
@@ -1,13 +1,9 @@
|
|
1
|
+
require_relative "javascript_code_ai"
|
2
|
+
require_relative "python_code_ai"
|
3
|
+
require_relative "ruby_code_ai"
|
4
|
+
require_relative "sql_code_ai"
|
5
|
+
require_relative "../../logger"
|
1
6
|
|
2
|
-
require 'rainbow'
|
3
|
-
require_relative 'javascript_code_ai'
|
4
|
-
require_relative 'problem_code_ai'
|
5
|
-
require_relative 'python_code_ai'
|
6
|
-
require_relative 'ruby_code_ai'
|
7
|
-
require_relative 'sql_code_ai'
|
8
|
-
|
9
|
-
##
|
10
|
-
# CodeAI factory
|
11
7
|
module CodeAIFactory
|
12
8
|
##
|
13
9
|
# Return CodeAI associated to Code.type
|
@@ -18,8 +14,6 @@ module CodeAIFactory
|
|
18
14
|
case type
|
19
15
|
when :javascript
|
20
16
|
return JavascriptCodeAI.new(code)
|
21
|
-
when :problem
|
22
|
-
return ProblemCodeAI.new(code)
|
23
17
|
when :python
|
24
18
|
return PythonCodeAI.new(code)
|
25
19
|
when :ruby
|
@@ -29,7 +23,7 @@ module CodeAIFactory
|
|
29
23
|
when :vagrantfile
|
30
24
|
return RubyCodeAI.new(code)
|
31
25
|
else
|
32
|
-
|
26
|
+
Logger.warn "CodeAIFactory: Invalid type (#{type})"
|
33
27
|
end
|
34
28
|
nil
|
35
29
|
end
|
@@ -1,7 +1,6 @@
|
|
1
|
-
|
2
|
-
require_relative
|
3
|
-
require_relative
|
4
|
-
require_relative 'base_code_ai'
|
1
|
+
require_relative "../../lang/lang_factory"
|
2
|
+
require_relative "../../ai/question"
|
3
|
+
require_relative "base_code_ai"
|
5
4
|
|
6
5
|
class JavascriptCodeAI < BaseCodeAI
|
7
6
|
def initialize(code)
|
@@ -13,25 +12,25 @@ class JavascriptCodeAI < BaseCodeAI
|
|
13
12
|
questions = []
|
14
13
|
# error_lines = []
|
15
14
|
@lines.each_with_index do |line, index|
|
16
|
-
if line.strip.start_with?(
|
15
|
+
if line.strip.start_with?("//")
|
17
16
|
lines = clone_array @lines
|
18
|
-
lines[index].sub!(
|
17
|
+
lines[index].sub!("//", "").strip!
|
19
18
|
|
20
19
|
q = Question.new(:short)
|
21
20
|
q.name = "#{name}-#{num}-uncomment"
|
22
|
-
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
23
|
-
q.shorts << (index+1)
|
24
|
-
q.feedback =
|
21
|
+
q.text = @lang.text_for(:code1, lines_to_html(lines))
|
22
|
+
q.shorts << (index + 1)
|
23
|
+
q.feedback = "Comment symbol removed"
|
25
24
|
questions << q
|
26
|
-
elsif line.strip.size>0
|
25
|
+
elsif line.strip.size > 0
|
27
26
|
lines = clone_array @lines
|
28
|
-
lines[index]=
|
27
|
+
lines[index] = "// " + lines[index]
|
29
28
|
|
30
29
|
q = Question.new(:short)
|
31
30
|
q.name = "#{name}-#{num}-comment"
|
32
|
-
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
33
|
-
q.shorts << (index+1)
|
34
|
-
q.feedback =
|
31
|
+
q.text = @lang.text_for(:code1, lines_to_html(lines))
|
32
|
+
q.shorts << (index + 1)
|
33
|
+
q.feedback = "Comment symbol added"
|
35
34
|
questions << q
|
36
35
|
end
|
37
36
|
end
|
@@ -42,7 +41,7 @@ class JavascriptCodeAI < BaseCodeAI
|
|
42
41
|
questions = []
|
43
42
|
empty_lines = []
|
44
43
|
used_lines = []
|
45
|
-
@lines.each_with_index do |line,index|
|
44
|
+
@lines.each_with_index do |line, index|
|
46
45
|
if line.strip.size.zero?
|
47
46
|
empty_lines << index
|
48
47
|
else
|
@@ -52,24 +51,24 @@ class JavascriptCodeAI < BaseCodeAI
|
|
52
51
|
|
53
52
|
used_lines.each do |index|
|
54
53
|
lines = clone_array(@lines)
|
55
|
-
lines.insert(index,
|
54
|
+
lines.insert(index, " " * (rand(4).to_i + 1))
|
56
55
|
if @lines.size < 4 || rand(2) == 0
|
57
56
|
q = Question.new(:short)
|
58
57
|
q.name = "#{name}-#{num}-codeok"
|
59
|
-
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
60
|
-
q.shorts <<
|
61
|
-
q.feedback =
|
58
|
+
q.text = @lang.text_for(:code1, lines_to_html(lines))
|
59
|
+
q.shorts << "0"
|
60
|
+
q.feedback = "Code is OK"
|
62
61
|
questions << q
|
63
62
|
else
|
64
63
|
q = Question.new(:choice)
|
65
64
|
q.name = "#{name}-#{num}-codeok"
|
66
|
-
q.text = @lang.text_for(:code2,lines_to_html(lines))
|
65
|
+
q.text = @lang.text_for(:code2, lines_to_html(lines))
|
67
66
|
others = (1..@lines.size).to_a.shuffle!
|
68
|
-
q.good =
|
67
|
+
q.good = "0"
|
69
68
|
q.bads << others[0].to_s
|
70
69
|
q.bads << others[1].to_s
|
71
70
|
q.bads << others[2].to_s
|
72
|
-
q.feedback =
|
71
|
+
q.feedback = "Code is OK"
|
73
72
|
end
|
74
73
|
end
|
75
74
|
|
@@ -79,13 +78,13 @@ class JavascriptCodeAI < BaseCodeAI
|
|
79
78
|
def make_syntax_error
|
80
79
|
questions = []
|
81
80
|
|
82
|
-
@lang.mistakes.each_pair do |key,values|
|
81
|
+
@lang.mistakes.each_pair do |key, values|
|
83
82
|
error_lines = []
|
84
|
-
@lines.each_with_index do |line,index|
|
83
|
+
@lines.each_with_index do |line, index|
|
85
84
|
error_lines << index if line.include?(key.to_s)
|
86
85
|
end
|
87
86
|
|
88
|
-
v = values.split(
|
87
|
+
v = values.split(",")
|
89
88
|
v.each do |value|
|
90
89
|
error_lines.each do |index|
|
91
90
|
lines = clone_array(@lines)
|
@@ -93,15 +92,15 @@ class JavascriptCodeAI < BaseCodeAI
|
|
93
92
|
if @lines.size < 4 || rand(2) == 0
|
94
93
|
q = Question.new(:short)
|
95
94
|
q.name = "#{name}-#{num}-syntaxerror"
|
96
|
-
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
97
|
-
q.shorts << (index+1)
|
95
|
+
q.text = @lang.text_for(:code1, lines_to_html(lines))
|
96
|
+
q.shorts << (index + 1)
|
98
97
|
q.feedback = "Syntax error: '#{value}' must be '#{key}'"
|
99
98
|
else
|
100
99
|
q = Question.new(:choice)
|
101
100
|
q.name = "#{name}-#{num}-syntaxerror"
|
102
|
-
q.text = @lang.text_for(:code2,lines_to_html(lines))
|
101
|
+
q.text = @lang.text_for(:code2, lines_to_html(lines))
|
103
102
|
others = (1..@lines.size).to_a.shuffle!
|
104
|
-
others.delete(index+1)
|
103
|
+
others.delete(index + 1)
|
105
104
|
q.good = (index + 1).to_s
|
106
105
|
q.bads << others[0].to_s
|
107
106
|
q.bads << others[1].to_s
|
@@ -141,20 +140,20 @@ class JavascriptCodeAI < BaseCodeAI
|
|
141
140
|
if rand(2) == 0
|
142
141
|
q = Question.new(:short)
|
143
142
|
q.name = "#{name}-#{num}-variable"
|
144
|
-
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
143
|
+
q.text = @lang.text_for(:code1, lines_to_html(lines))
|
145
144
|
q.shorts << (index + 1)
|
146
|
-
q.feedback = "Variable error! Swapped lines #{
|
145
|
+
q.feedback = "Variable error! Swapped lines #{index + 1} with #{k + 1}"
|
147
146
|
else
|
148
147
|
q = Question.new(:choice)
|
149
148
|
q.name = "#{name}-#{num}-variable"
|
150
|
-
q.text = @lang.text_for(:code2,lines_to_html(lines))
|
149
|
+
q.text = @lang.text_for(:code2, lines_to_html(lines))
|
151
150
|
others = (1..@lines.size).to_a.shuffle!
|
152
|
-
others.delete(index+1)
|
151
|
+
others.delete(index + 1)
|
153
152
|
q.good = (index + 1).to_s
|
154
153
|
q.bads << others[0].to_s
|
155
154
|
q.bads << others[1].to_s
|
156
155
|
q.bads << others[2].to_s
|
157
|
-
q.feedback = "Variable error! Swapped lines #{
|
156
|
+
q.feedback = "Variable error! Swapped lines #{index + 1} with #{k + 1}"
|
158
157
|
end
|
159
158
|
questions << q
|
160
159
|
end
|
@@ -1,11 +1,10 @@
|
|
1
|
-
|
2
|
-
require_relative
|
3
|
-
require_relative
|
4
|
-
require_relative 'base_code_ai'
|
1
|
+
require_relative "../../lang/lang_factory"
|
2
|
+
require_relative "../../ai/question"
|
3
|
+
require_relative "base_code_ai"
|
5
4
|
|
6
5
|
class PythonCodeAI < BaseCodeAI
|
7
6
|
def initialize(code)
|
8
|
-
@lang = LangFactory.instance.get(
|
7
|
+
@lang = LangFactory.instance.get("python")
|
9
8
|
super code
|
10
9
|
end
|
11
10
|
|
@@ -13,25 +12,25 @@ class PythonCodeAI < BaseCodeAI
|
|
13
12
|
questions = []
|
14
13
|
# error_lines = []
|
15
14
|
@lines.each_with_index do |line, index|
|
16
|
-
if line.strip.start_with?(
|
15
|
+
if line.strip.start_with?("#")
|
17
16
|
lines = clone_array @lines
|
18
|
-
lines[index].sub!(
|
17
|
+
lines[index].sub!("#", "").strip!
|
19
18
|
|
20
19
|
q = Question.new(:short)
|
21
20
|
q.name = "#{name}-#{num}-uncomment"
|
22
|
-
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
23
|
-
q.shorts << (index+1)
|
24
|
-
q.feedback =
|
21
|
+
q.text = @lang.text_for(:code1, lines_to_html(lines))
|
22
|
+
q.shorts << (index + 1)
|
23
|
+
q.feedback = "Comment symbol removed"
|
25
24
|
questions << q
|
26
|
-
elsif line.strip.size>0
|
25
|
+
elsif line.strip.size > 0
|
27
26
|
lines = clone_array @lines
|
28
|
-
lines[index]=
|
27
|
+
lines[index] = "# " + lines[index]
|
29
28
|
|
30
29
|
q = Question.new(:short)
|
31
30
|
q.name = "#{name}-#{num}-comment"
|
32
|
-
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
33
|
-
q.shorts << (index+1)
|
34
|
-
q.feedback =
|
31
|
+
q.text = @lang.text_for(:code1, lines_to_html(lines))
|
32
|
+
q.shorts << (index + 1)
|
33
|
+
q.feedback = "Comment symbol added"
|
35
34
|
questions << q
|
36
35
|
end
|
37
36
|
end
|
@@ -42,7 +41,7 @@ class PythonCodeAI < BaseCodeAI
|
|
42
41
|
questions = []
|
43
42
|
empty_lines = []
|
44
43
|
used_lines = []
|
45
|
-
@lines.each_with_index do |line,index|
|
44
|
+
@lines.each_with_index do |line, index|
|
46
45
|
if line.strip.size.zero?
|
47
46
|
empty_lines << index
|
48
47
|
else
|
@@ -52,24 +51,24 @@ class PythonCodeAI < BaseCodeAI
|
|
52
51
|
|
53
52
|
used_lines.each do |index|
|
54
53
|
lines = clone_array(@lines)
|
55
|
-
lines.insert(index,
|
54
|
+
lines.insert(index, " " * (rand(4).to_i + 1))
|
56
55
|
if @lines.size < 4 || rand(2) == 0
|
57
56
|
q = Question.new(:short)
|
58
57
|
q.name = "#{name}-#{num}-codeok"
|
59
|
-
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
60
|
-
q.shorts <<
|
61
|
-
q.feedback =
|
58
|
+
q.text = @lang.text_for(:code1, lines_to_html(lines))
|
59
|
+
q.shorts << "0"
|
60
|
+
q.feedback = "Code is OK"
|
62
61
|
questions << q
|
63
62
|
else
|
64
63
|
q = Question.new(:choice)
|
65
64
|
q.name = "#{name}-#{num}-codeok"
|
66
|
-
q.text = @lang.text_for(:code2,lines_to_html(lines))
|
65
|
+
q.text = @lang.text_for(:code2, lines_to_html(lines))
|
67
66
|
others = (1..@lines.size).to_a.shuffle!
|
68
|
-
q.good =
|
67
|
+
q.good = "0"
|
69
68
|
q.bads << others[0].to_s
|
70
69
|
q.bads << others[1].to_s
|
71
70
|
q.bads << others[2].to_s
|
72
|
-
q.feedback =
|
71
|
+
q.feedback = "Code is OK"
|
73
72
|
end
|
74
73
|
end
|
75
74
|
|
@@ -79,13 +78,13 @@ class PythonCodeAI < BaseCodeAI
|
|
79
78
|
def make_syntax_error
|
80
79
|
questions = []
|
81
80
|
|
82
|
-
@lang.mistakes.each_pair do |key,values|
|
81
|
+
@lang.mistakes.each_pair do |key, values|
|
83
82
|
error_lines = []
|
84
|
-
@lines.each_with_index do |line,index|
|
83
|
+
@lines.each_with_index do |line, index|
|
85
84
|
error_lines << index if line.include?(key.to_s)
|
86
85
|
end
|
87
86
|
|
88
|
-
v = values.split(
|
87
|
+
v = values.split(",")
|
89
88
|
v.each do |value|
|
90
89
|
error_lines.each do |index|
|
91
90
|
lines = clone_array(@lines)
|
@@ -93,15 +92,15 @@ class PythonCodeAI < BaseCodeAI
|
|
93
92
|
if @lines.size < 4 || rand(2) == 0
|
94
93
|
q = Question.new(:short)
|
95
94
|
q.name = "#{name}-#{num}-syntaxerror"
|
96
|
-
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
97
|
-
q.shorts << (index+1)
|
95
|
+
q.text = @lang.text_for(:code1, lines_to_html(lines))
|
96
|
+
q.shorts << (index + 1)
|
98
97
|
q.feedback = "Syntax error: '#{value}' must be '#{key}'"
|
99
98
|
else
|
100
99
|
q = Question.new(:choice)
|
101
100
|
q.name = "#{name}-#{num}-syntaxerror"
|
102
|
-
q.text = @lang.text_for(:code2,lines_to_html(lines))
|
101
|
+
q.text = @lang.text_for(:code2, lines_to_html(lines))
|
103
102
|
others = (1..@lines.size).to_a.shuffle!
|
104
|
-
others.delete(index+1)
|
103
|
+
others.delete(index + 1)
|
105
104
|
q.good = (index + 1).to_s
|
106
105
|
q.bads << others[0].to_s
|
107
106
|
q.bads << others[1].to_s
|
@@ -120,7 +119,7 @@ class PythonCodeAI < BaseCodeAI
|
|
120
119
|
# error_lines = []
|
121
120
|
@lines.each_with_index do |line, index|
|
122
121
|
# Search Variable assignment
|
123
|
-
m = /\s*(\w*)\s
|
122
|
+
m = /\s*(\w*)\s*=\w*/.match(line)
|
124
123
|
i = []
|
125
124
|
unless m.nil?
|
126
125
|
varname = (m.values_at 1)[0]
|
@@ -141,20 +140,20 @@ class PythonCodeAI < BaseCodeAI
|
|
141
140
|
if rand(2) == 0
|
142
141
|
q = Question.new(:short)
|
143
142
|
q.name = "#{name}-#{num}-variable"
|
144
|
-
q.text = @lang.text_for(:code1,lines_to_html(lines))
|
143
|
+
q.text = @lang.text_for(:code1, lines_to_html(lines))
|
145
144
|
q.shorts << (index + 1)
|
146
|
-
q.feedback = "Variable error! Swapped lines #{
|
145
|
+
q.feedback = "Variable error! Swapped lines #{index + 1} with #{k + 1}"
|
147
146
|
else
|
148
147
|
q = Question.new(:choice)
|
149
148
|
q.name = "#{name}-#{num}-variable"
|
150
|
-
q.text = @lang.text_for(:code2,lines_to_html(lines))
|
149
|
+
q.text = @lang.text_for(:code2, lines_to_html(lines))
|
151
150
|
others = (1..@lines.size).to_a.shuffle!
|
152
|
-
others.delete(index+1)
|
151
|
+
others.delete(index + 1)
|
153
152
|
q.good = (index + 1).to_s
|
154
153
|
q.bads << others[0].to_s
|
155
154
|
q.bads << others[1].to_s
|
156
155
|
q.bads << others[2].to_s
|
157
|
-
q.feedback = "Variable error! Swapped lines #{
|
156
|
+
q.feedback = "Variable error! Swapped lines #{index + 1} with #{k + 1}"
|
158
157
|
end
|
159
158
|
questions << q
|
160
159
|
end
|