asker-tool 2.1.5 → 2.2.1
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 +4 -4
- data/README.md +13 -17
- data/bin/asker +2 -1
- data/lib/asker/ai/ai.rb +10 -3
- data/lib/asker/ai/ai_calculate.rb +20 -6
- data/lib/asker/ai/code/base_code_ai.rb +104 -0
- data/lib/asker/{code/ai → ai/code}/code_ai_factory.rb +11 -1
- data/lib/asker/{code/ai → ai/code}/javascript_code_ai.rb +2 -5
- data/lib/asker/ai/code/problem_code_ai.rb +176 -0
- data/lib/asker/{code/ai → ai/code}/python_code_ai.rb +2 -5
- data/lib/asker/{code/ai → ai/code}/ruby_code_ai.rb +14 -7
- data/lib/asker/{code/ai → ai/code}/sql_code_ai.rb +2 -5
- data/lib/asker/ai/concept_ai.rb +13 -3
- data/lib/asker/ai/question.rb +28 -6
- data/lib/asker/ai/stages/base_stage.rb +45 -6
- data/lib/asker/ai/stages/stage_b.rb +100 -50
- data/lib/asker/ai/stages/stage_d.rb +75 -90
- data/lib/asker/ai/stages/stage_f.rb +64 -36
- data/lib/asker/ai/stages/stage_i.rb +79 -92
- data/lib/asker/ai/stages/stage_s.rb +41 -36
- data/lib/asker/ai/stages/stage_t.rb +149 -108
- data/lib/asker/application.rb +19 -11
- data/lib/asker/cli.rb +31 -44
- data/lib/asker/data/code.rb +62 -0
- data/lib/asker/data/column.rb +31 -21
- data/lib/asker/data/concept.rb +109 -65
- data/lib/asker/data/data_field.rb +14 -0
- data/lib/asker/data/project_data.rb +63 -0
- data/lib/asker/data/row.rb +75 -52
- data/lib/asker/data/table.rb +91 -42
- data/lib/asker/data/template.rb +3 -1
- data/lib/asker/data/world.rb +51 -35
- data/lib/asker/displayer/code_displayer.rb +7 -0
- data/lib/asker/displayer/concept_ai_displayer.erb +10 -0
- data/lib/asker/displayer/concept_ai_displayer.rb +74 -53
- data/lib/asker/displayer/concept_displayer.rb +16 -9
- data/lib/asker/displayer/stats_displayer.rb +12 -3
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +19 -11
- data/lib/asker/exporter/concept_ai_moodle_exporter.rb +44 -0
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +13 -6
- data/lib/asker/exporter/concept_doc_exporter.rb +14 -1
- data/lib/asker/exporter/data_gift_exporter.rb +29 -0
- data/lib/asker/exporter/output_file_exporter.rb +9 -6
- data/lib/asker/files/{config.ini → asker.ini} +48 -1
- data/lib/asker/files/example-concept.haml +0 -1
- data/lib/asker/files/language/du/connectors.yaml +81 -0
- data/lib/asker/{lang/locales/fr → files/language/du}/mistakes.yaml +1 -1
- data/lib/asker/files/language/du/templates.yaml +29 -0
- data/lib/asker/{lang/locales → files/language}/en/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/en/mistakes.yaml +0 -0
- data/lib/asker/files/language/en/templates.yaml +29 -0
- data/lib/asker/{lang/locales → files/language}/es/connectors.yaml +0 -0
- data/lib/asker/files/language/es/mistakes.yaml +84 -0
- data/lib/asker/files/language/es/templates.yaml +29 -0
- data/lib/asker/files/language/fr/connectors.yaml +76 -0
- data/lib/asker/{lang/locales/es → files/language/fr}/mistakes.yaml +0 -0
- data/lib/asker/files/language/fr/templates.yaml +29 -0
- data/lib/asker/{lang/locales → files/language}/javascript/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/javascript/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/javascript/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/math/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/math/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/math/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/python/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/python/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/python/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/ruby/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/ruby/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/ruby/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/sql/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/sql/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/sql/templates.yaml +0 -0
- data/lib/asker/formatter/concept_doc_formatter.rb +0 -4
- data/lib/asker/formatter/concept_string_formatter.rb +7 -4
- data/lib/asker/formatter/moodle/matching.erb +38 -0
- data/lib/asker/formatter/moodle/multichoice.erb +49 -0
- data/lib/asker/formatter/moodle/shortanswer.erb +30 -0
- data/lib/asker/formatter/moodle/truefalse.erb +47 -0
- data/lib/asker/formatter/question_gift_formatter.rb +30 -20
- data/lib/asker/formatter/question_moodle_formatter.rb +27 -0
- data/lib/asker/{checker.rb → input_checker.rb} +126 -49
- data/lib/asker/lang/lang.rb +17 -10
- data/lib/asker/lang/lang_factory.rb +32 -5
- data/lib/asker/lang/text_actions.rb +87 -69
- data/lib/asker/loader/code_loader.rb +4 -4
- data/lib/asker/loader/content_loader.rb +21 -19
- data/lib/asker/loader/directory_loader.rb +1 -8
- data/lib/asker/loader/embedded_file.rb +42 -0
- data/lib/asker/loader/file_loader.rb +3 -14
- data/lib/asker/loader/haml_loader.rb +15 -0
- data/lib/asker/loader/image_url_loader.rb +8 -12
- data/lib/asker/loader/input_loader.rb +13 -15
- data/lib/asker/loader/project_loader.rb +25 -15
- data/lib/asker/logger.rb +36 -9
- data/lib/asker/skeleton.rb +23 -13
- data/lib/asker.rb +76 -42
- metadata +53 -54
- data/lib/asker/code/ai/base_code_ai.rb +0 -48
- data/lib/asker/code/code.rb +0 -53
- data/lib/asker/lang/locales/du/templates.yaml +0 -50
- data/lib/asker/lang/locales/en/templates.yaml +0 -29
- data/lib/asker/lang/locales/es/templates.yaml +0 -29
- data/lib/asker/lang/locales/fr/connectors.yaml +0 -92
- data/lib/asker/lang/locales/fr/templates.yaml +0 -29
- data/lib/asker/project.rb +0 -172
|
@@ -1,13 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
|
|
2
3
|
require_relative 'base_stage'
|
|
3
4
|
require_relative '../question'
|
|
4
5
|
|
|
5
6
|
# StageF: process tables with 1 field
|
|
7
|
+
# rubocop:disable Metrics/ClassLength
|
|
6
8
|
class StageF < BaseStage
|
|
9
|
+
##
|
|
10
|
+
# run stage_f: generate guqestion for tables with 1 field
|
|
11
|
+
# @param table (Table)
|
|
12
|
+
# @param list1 (Array) List of Rows from this table
|
|
13
|
+
# @param list2 (Array) List of Row from other tables
|
|
7
14
|
def run(table, list1, list2)
|
|
8
15
|
# process_table1field
|
|
9
16
|
questions = []
|
|
10
|
-
return questions if table.fields.count>1
|
|
17
|
+
return questions if table.fields.count > 1
|
|
11
18
|
|
|
12
19
|
questions += run_only_this_concept(table, list1)
|
|
13
20
|
questions += run_with_other_concepts(table, list1, list2)
|
|
@@ -15,29 +22,32 @@ class StageF < BaseStage
|
|
|
15
22
|
questions
|
|
16
23
|
end
|
|
17
24
|
|
|
18
|
-
private
|
|
25
|
+
private
|
|
19
26
|
|
|
27
|
+
# rubocop:disable Metrics/AbcSize
|
|
28
|
+
# rubocop:disable Metrics/MethodLength
|
|
20
29
|
def run_only_this_concept(table, list1)
|
|
21
30
|
questions = []
|
|
22
|
-
|
|
31
|
+
lang = concept.lang
|
|
32
|
+
s1 = Set.new # Set of rows from this concept
|
|
23
33
|
list1.each { |item| s1 << item[:data][0] }
|
|
24
34
|
a1 = s1.to_a
|
|
25
35
|
a1.shuffle!
|
|
26
36
|
|
|
27
37
|
if a1.size > 3
|
|
28
|
-
a1.each_cons(4) do |e1,e2,e3,e4|
|
|
29
|
-
e = [
|
|
38
|
+
a1.each_cons(4) do |e1, e2, e3, e4|
|
|
39
|
+
e = [e1, e2, e3, e4]
|
|
30
40
|
questions += make_questions_with(e, table)
|
|
31
41
|
|
|
32
|
-
#Question filtered text
|
|
33
|
-
e = [
|
|
42
|
+
# Question filtered text
|
|
43
|
+
e = [e1, e2, e3, e4]
|
|
34
44
|
e.shuffle!
|
|
35
45
|
t = "(a) #{e[0]}, (b) #{e[1]}, (c) #{e[2]}, (d) #{e[3]}"
|
|
36
|
-
filtered=lang.text_with_connectors(t)
|
|
46
|
+
filtered = lang.text_with_connectors(t)
|
|
37
47
|
indexes = filtered[:indexes]
|
|
38
48
|
|
|
39
|
-
groups =
|
|
40
|
-
max = (indexes.size/4).to_i
|
|
49
|
+
groups = indexes.combination(4).to_a.shuffle
|
|
50
|
+
max = (indexes.size / 4).to_i
|
|
41
51
|
groups[0, max].each do |i|
|
|
42
52
|
i.sort!
|
|
43
53
|
q = Question.new(:match)
|
|
@@ -46,9 +56,10 @@ private
|
|
|
46
56
|
s = lang.build_text_from_filtered(filtered, i)
|
|
47
57
|
q.text = random_image_for(name(:raw))
|
|
48
58
|
q.text += lang.text_for(:f3, name(:decorated), table.fields[0].capitalize, s)
|
|
49
|
-
i.each_with_index do |value,index|
|
|
59
|
+
i.each_with_index do |value, index|
|
|
50
60
|
q.matching << [(index + 1).to_s, filtered[:words][value][:word].downcase]
|
|
51
61
|
end
|
|
62
|
+
q.matching << ['', lang.do_mistake_to(filtered[:words][rand(filtered[:words].size)][:word].downcase)]
|
|
52
63
|
questions << q
|
|
53
64
|
end
|
|
54
65
|
end
|
|
@@ -58,59 +69,72 @@ private
|
|
|
58
69
|
end
|
|
59
70
|
questions
|
|
60
71
|
end
|
|
72
|
+
# rubocop:enable Metrics/AbcSize
|
|
73
|
+
# rubocop:enable Metrics/MethodLength
|
|
61
74
|
|
|
62
|
-
|
|
75
|
+
# rubocop:disable Lint/BooleanSymbol
|
|
76
|
+
# rubocop:disable Metrics/MethodLength
|
|
77
|
+
# rubocop:disable Metrics/AbcSize
|
|
78
|
+
def make_questions_with(values, table)
|
|
63
79
|
questions = []
|
|
80
|
+
lang = concept.lang
|
|
64
81
|
|
|
65
|
-
|
|
82
|
+
values.shuffle!
|
|
66
83
|
q = Question.new(:choice)
|
|
67
|
-
q.name = "#{name(:id)}-#{num}-f1true#{
|
|
84
|
+
q.name = "#{name(:id)}-#{num}-f1true#{values.size}-#{table.name}"
|
|
68
85
|
q.text = random_image_for(name(:raw))
|
|
69
|
-
q.text += lang.text_for(:f1, name(:decorated), table.fields[0].capitalize,
|
|
86
|
+
q.text += lang.text_for(:f1, name(:decorated), table.fields[0].capitalize, values.join('</li><li>'))
|
|
70
87
|
q.good = lang.text_for(:true)
|
|
71
88
|
q.bads << lang.text_for(:misspelling)
|
|
72
89
|
q.bads << lang.text_for(:false)
|
|
73
90
|
|
|
74
|
-
if type == 'text'
|
|
75
|
-
|
|
91
|
+
if concept.type == 'text'
|
|
92
|
+
values.shuffle!
|
|
76
93
|
q = Question.new(:short)
|
|
77
|
-
q.name = "#{name(:id)}-#{num}-f1short#{
|
|
94
|
+
q.name = "#{name(:id)}-#{num}-f1short#{values.size}-#{table.name}"
|
|
78
95
|
q.text = random_image_for(name(:raw))
|
|
79
|
-
q.text += lang.text_for(:f1, lang.hide_text(name(:raw)), table.fields[0].capitalize,
|
|
96
|
+
q.text += lang.text_for(:f1, lang.hide_text(name(:raw)), table.fields[0].capitalize, values.join('</li><li>'))
|
|
80
97
|
q.shorts << name(:raw)
|
|
81
98
|
q.shorts << name(:raw).tr('-_', ' ')
|
|
82
99
|
questions << q
|
|
83
100
|
|
|
84
|
-
|
|
85
|
-
save =
|
|
86
|
-
|
|
101
|
+
values.shuffle!
|
|
102
|
+
save = values[0]
|
|
103
|
+
values[0] = lang.do_mistake_to(values[0])
|
|
87
104
|
q = Question.new(:choice)
|
|
88
|
-
q.name = "#{name(:id)}-#{num}-f1name-misspelled#{
|
|
105
|
+
q.name = "#{name(:id)}-#{num}-f1name-misspelled#{values.size}-#{table.name}"
|
|
89
106
|
q.text = random_image_for(name(:raw))
|
|
90
|
-
q.text += lang.text_for(:f1, lang.do_mistake_to(name(:decorated)),
|
|
107
|
+
q.text += lang.text_for(:f1, lang.do_mistake_to(name(:decorated)), \
|
|
108
|
+
table.fields[0].capitalize, values.join('</li><li>'))
|
|
91
109
|
q.good = lang.text_for(:misspelling)
|
|
92
110
|
q.bads << lang.text_for(:true)
|
|
93
111
|
q.bads << lang.text_for(:false)
|
|
94
112
|
q.feedback = "Concept name #{name(:raw)} misspelled!"
|
|
95
|
-
|
|
113
|
+
values[0] = save
|
|
96
114
|
questions << q
|
|
97
115
|
end
|
|
98
116
|
|
|
99
|
-
|
|
100
|
-
save =
|
|
101
|
-
|
|
117
|
+
values.shuffle!
|
|
118
|
+
save = values[0]
|
|
119
|
+
values[0] = lang.do_mistake_to(values[0])
|
|
102
120
|
q = Question.new(:choice)
|
|
103
|
-
q.name = "#{name(:id)}-#{num}-f1true-misspelled#{
|
|
121
|
+
q.name = "#{name(:id)}-#{num}-f1true-misspelled#{values.size}-#{table.name}"
|
|
104
122
|
q.text = random_image_for(name(:raw))
|
|
105
|
-
q.text += lang.text_for(:f1, name(:decorated), table.fields[0].capitalize,
|
|
123
|
+
q.text += lang.text_for(:f1, name(:decorated), table.fields[0].capitalize, values.join('</li><li>'))
|
|
106
124
|
q.good = lang.text_for(:misspelling)
|
|
107
125
|
q.bads << lang.text_for(:true)
|
|
108
126
|
q.bads << lang.text_for(:false)
|
|
109
127
|
q.feedback = "Text #{save} mispelled!"
|
|
110
|
-
|
|
128
|
+
values[0] = save
|
|
111
129
|
questions << q
|
|
112
130
|
end
|
|
131
|
+
# rubocop:enable Lint/BooleanSymbol
|
|
132
|
+
# rubocop:enable Metrics/MethodLength
|
|
133
|
+
# rubocop:enable Metrics/AbcSize
|
|
113
134
|
|
|
135
|
+
# rubocop:disable Lint/BooleanSymbol
|
|
136
|
+
# rubocop:disable Metrics/MethodLength
|
|
137
|
+
# rubocop:disable Metrics/AbcSize
|
|
114
138
|
def run_with_other_concepts(table, list1, list2)
|
|
115
139
|
questions = []
|
|
116
140
|
|
|
@@ -133,17 +157,17 @@ private
|
|
|
133
157
|
q = Question.new(:choice)
|
|
134
158
|
q.name = "#{name(:id)}-#{num}-f1false-#{table.name}"
|
|
135
159
|
q.text = random_image_for(name(:raw))
|
|
136
|
-
q.text += lang.text_for(:f1, name(:decorated), table.fields[0].capitalize, e.join('</li><li>'))
|
|
137
|
-
q.good = lang.text_for(:false)
|
|
138
|
-
q.bads << lang.text_for(:misspelling)
|
|
139
|
-
q.bads << lang.text_for(:true)
|
|
160
|
+
q.text += concept.lang.text_for(:f1, name(:decorated), table.fields[0].capitalize, e.join('</li><li>'))
|
|
161
|
+
q.good = concept.lang.text_for(:false)
|
|
162
|
+
q.bads << concept.lang.text_for(:misspelling)
|
|
163
|
+
q.bads << concept.lang.text_for(:true)
|
|
140
164
|
questions << q
|
|
141
165
|
|
|
142
166
|
f4 = a2.shuffle![0]
|
|
143
167
|
q = Question.new(:choice)
|
|
144
168
|
q.name = "#{name(:id)}-#{num}-f2outsider-#{table.name}"
|
|
145
169
|
q.text = random_image_for(name(:raw))
|
|
146
|
-
q.text += lang.text_for(:f2, name(:decorated), table.fields[0].capitalize)
|
|
170
|
+
q.text += concept.lang.text_for(:f2, name(:decorated), table.fields[0].capitalize)
|
|
147
171
|
q.good = f4
|
|
148
172
|
q.bads << e1
|
|
149
173
|
q.bads << e2
|
|
@@ -153,4 +177,8 @@ private
|
|
|
153
177
|
|
|
154
178
|
questions
|
|
155
179
|
end
|
|
180
|
+
# rubocop:enable Lint/BooleanSymbol
|
|
181
|
+
# rubocop:enable Metrics/MethodLength
|
|
182
|
+
# rubocop:enable Metrics/AbcSize
|
|
156
183
|
end
|
|
184
|
+
# rubocop:enable Metrics/ClassLength
|
|
@@ -1,42 +1,49 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'base64_compatible' # TODO: Don't work with Moodle Gift images
|
|
4
3
|
require 'set'
|
|
5
4
|
|
|
6
5
|
require_relative 'base_stage'
|
|
7
6
|
require_relative '../question'
|
|
8
7
|
|
|
8
|
+
# range i1, i2, i3, i4
|
|
9
9
|
class StageI < BaseStage
|
|
10
|
-
#
|
|
11
|
-
|
|
10
|
+
# Stage I: process every image from <def> tag
|
|
11
|
+
# rubocop:disable Metrics/BlockLength
|
|
12
|
+
# rubocop:disable Metrics/MethodLength
|
|
13
|
+
# rubocop:disable Metrics/AbcSize
|
|
14
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
15
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
12
16
|
def run
|
|
13
|
-
|
|
14
|
-
questions
|
|
15
|
-
return questions unless type=="text"
|
|
17
|
+
questions = []
|
|
18
|
+
return questions unless concept.type == 'text'
|
|
16
19
|
|
|
20
|
+
lang = concept.lang
|
|
17
21
|
# for every <image> do this
|
|
18
|
-
images.each do |
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
q.
|
|
27
|
-
q.
|
|
28
|
-
q.
|
|
22
|
+
concept.images.each do |image|
|
|
23
|
+
url = image[:text]
|
|
24
|
+
s = Set.new [name, lang.text_for(:none)]
|
|
25
|
+
concept.neighbors.each { |n| s.add n[:concept].name }
|
|
26
|
+
a = s.to_a
|
|
27
|
+
|
|
28
|
+
# Question type <i1>: choose between 4 options
|
|
29
|
+
if s.count > 3
|
|
30
|
+
q = Question.new(:choice)
|
|
31
|
+
q.name = "#{name}-#{num}-i1choice"
|
|
32
|
+
q.text = lang.text_for(:i1, url)
|
|
33
|
+
q.encode = image[:file]
|
|
34
|
+
q.good = name
|
|
29
35
|
q.bads << lang.text_for(:none)
|
|
30
36
|
q.bads << a[2]
|
|
31
37
|
q.bads << a[3]
|
|
32
38
|
questions << q
|
|
33
39
|
end
|
|
34
40
|
|
|
35
|
-
#Question type <i1>: choose between 4 options, good none (Syntax error)
|
|
36
|
-
if s.count>3
|
|
37
|
-
q=Question.new(:choice)
|
|
38
|
-
q.name="#{name}-#{num}-i1misspelling"
|
|
39
|
-
q.text=lang.text_for(:i1, url
|
|
41
|
+
# Question type <i1>: choose between 4 options, good none (Syntax error)
|
|
42
|
+
if s.count > 3
|
|
43
|
+
q = Question.new(:choice)
|
|
44
|
+
q.name = "#{name}-#{num}-i1misspelling"
|
|
45
|
+
q.text = lang.text_for(:i1, url)
|
|
46
|
+
q.encode = image[:file]
|
|
40
47
|
q.good = lang.text_for(:none)
|
|
41
48
|
q.bads << lang.do_mistake_to(name)
|
|
42
49
|
q.bads << a[2]
|
|
@@ -45,96 +52,76 @@ class StageI < BaseStage
|
|
|
45
52
|
end
|
|
46
53
|
|
|
47
54
|
s.delete(name)
|
|
48
|
-
a=s.to_a
|
|
55
|
+
a = s.to_a
|
|
49
56
|
|
|
50
|
-
#Question type <i1>: choose between 4 options, good none
|
|
51
|
-
if s.count>3
|
|
57
|
+
# Question type <i1>: choose between 4 options, good none
|
|
58
|
+
if s.count > 3
|
|
52
59
|
q = Question.new(:choice)
|
|
53
|
-
q.name="#{name}-#{num}-i1none"
|
|
54
|
-
q.text=lang.text_for(:i1, url
|
|
55
|
-
q.
|
|
60
|
+
q.name = "#{name}-#{num}-i1none"
|
|
61
|
+
q.text = lang.text_for(:i1, url)
|
|
62
|
+
q.encode = image[:file]
|
|
63
|
+
q.good = lang.text_for(:none)
|
|
56
64
|
q.bads << a[1]
|
|
57
65
|
q.bads << a[2]
|
|
58
66
|
q.bads << a[3]
|
|
59
67
|
questions << q
|
|
60
68
|
end
|
|
61
69
|
|
|
62
|
-
#Question type <
|
|
70
|
+
# Question type <i2>: boolean => TRUE
|
|
63
71
|
q = Question.new(:boolean)
|
|
64
|
-
q.name="#{name}-#{num}-i2true"
|
|
65
|
-
q.text=lang.text_for(:i2, url, name
|
|
66
|
-
q.
|
|
72
|
+
q.name = "#{name}-#{num}-i2true"
|
|
73
|
+
q.text = lang.text_for(:i2, url, name)
|
|
74
|
+
q.encode = image[:file]
|
|
75
|
+
q.good = 'TRUE'
|
|
67
76
|
questions << q
|
|
68
77
|
|
|
69
|
-
#Question type <i2>: boolean => FALSE
|
|
70
|
-
if neighbors.count
|
|
78
|
+
# Question type <i2>: boolean => FALSE
|
|
79
|
+
if concept.neighbors.count.positive?
|
|
71
80
|
q = Question.new(:boolean)
|
|
72
|
-
q.name="#{name}-#{num}-i2false"
|
|
73
|
-
q.text=lang.text_for(:i2, url, neighbors[0][:concept].name
|
|
74
|
-
q.
|
|
81
|
+
q.name = "#{name}-#{num}-i2false"
|
|
82
|
+
q.text = lang.text_for(:i2, url, concept.neighbors[0][:concept].name)
|
|
83
|
+
q.encode = image[:file]
|
|
84
|
+
q.good = 'FALSE'
|
|
75
85
|
questions << q
|
|
76
86
|
end
|
|
77
87
|
|
|
78
|
-
#Question type <i3>: hidden name questions
|
|
88
|
+
# Question type <i3>: hidden name questions
|
|
79
89
|
q = Question.new(:short)
|
|
80
|
-
q.name="#{name}-#{num}-i3short"
|
|
81
|
-
q.text=lang.text_for(:i3, url, lang.hide_text(name)
|
|
90
|
+
q.name = "#{name}-#{num}-i3short"
|
|
91
|
+
q.text = lang.text_for(:i3, url, lang.hide_text(name))
|
|
92
|
+
q.encode = image[:file]
|
|
82
93
|
q.shorts << name
|
|
83
|
-
q.shorts << name.gsub(
|
|
94
|
+
q.shorts << name.gsub('-', ' ').gsub('_', ' ')
|
|
84
95
|
questions << q
|
|
85
96
|
|
|
86
|
-
#Question filtered text questions
|
|
87
|
-
texts.each do |t|
|
|
88
|
-
filtered=lang.text_with_connectors(t)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
q = Question.new(:match)
|
|
105
|
-
q.shuffle_off
|
|
106
|
-
q.name = "#{name}-#{num}-i4filtered"
|
|
107
|
-
e.sort!
|
|
108
|
-
s=lang.build_text_from_filtered( filtered, e )
|
|
109
|
-
q.text = lang.text_for(:i4, url , s)
|
|
110
|
-
e.each_with_index do |value,index|
|
|
111
|
-
q.matching << [ (index+1).to_s, filtered[:words][value][:word].downcase ]
|
|
112
|
-
end
|
|
97
|
+
# Question filtered text questions
|
|
98
|
+
concept.texts.each do |t|
|
|
99
|
+
filtered = lang.text_with_connectors(t)
|
|
100
|
+
next if filtered[:words].size < 4
|
|
101
|
+
|
|
102
|
+
indexes = filtered[:indexes]
|
|
103
|
+
groups = indexes.combination(4).to_a.shuffle
|
|
104
|
+
max = (indexes.size / 4).to_i
|
|
105
|
+
groups[0, max].each do |e|
|
|
106
|
+
q = Question.new(:match)
|
|
107
|
+
q.shuffle_off
|
|
108
|
+
q.name = "#{name}-#{num}-i4filtered"
|
|
109
|
+
q.encode = image[:file]
|
|
110
|
+
e.sort!
|
|
111
|
+
s = lang.build_text_from_filtered(filtered, e)
|
|
112
|
+
q.text = lang.text_for(:i4, url, s)
|
|
113
|
+
e.each_with_index do |value, index|
|
|
114
|
+
q.matching << [index.next.to_s, filtered[:words][value][:word].downcase]
|
|
113
115
|
end
|
|
114
|
-
questions << q
|
|
115
116
|
end
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return questions
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
private
|
|
122
|
-
|
|
123
|
-
def html_for_raw_image(filename)
|
|
124
|
-
dirname = File.dirname(@concept_ia.filename)
|
|
125
|
-
filepath = File.join(dirname,filename)
|
|
126
|
-
content = File.open(filepath).read
|
|
127
|
-
content64 = Base64Compatible.encode64( content )
|
|
128
|
-
output =""
|
|
129
|
-
until(content64.nil?) do
|
|
130
|
-
output = output + content64[0,76]+"\n"
|
|
131
|
-
tmp = content64[76,9999999]
|
|
132
|
-
content64 = tmp
|
|
117
|
+
questions << q
|
|
118
|
+
end
|
|
133
119
|
end
|
|
134
|
-
|
|
135
|
-
ext = File.extname(filename)
|
|
136
|
-
output = "<img src='data:image/#{ext};base64,#{output}' />"
|
|
137
|
-
return output
|
|
120
|
+
questions
|
|
138
121
|
end
|
|
139
|
-
|
|
122
|
+
# rubocop:enable Metrics/BlockLength
|
|
123
|
+
# rubocop:enable Metrics/MethodLength
|
|
124
|
+
# rubocop:enable Metrics/AbcSize
|
|
125
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
126
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
140
127
|
end
|
|
@@ -1,52 +1,57 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'base_stage'
|
|
4
4
|
require_relative '../question'
|
|
5
5
|
|
|
6
|
+
# process_sequence
|
|
6
7
|
class StageS < BaseStage
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
# process_sequence
|
|
9
|
+
# rubocop:disable Metrics/MethodLength
|
|
10
|
+
# rubocop:disable Metrics/AbcSize
|
|
11
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
12
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
13
|
+
def run(table, list1, _list2)
|
|
10
14
|
questions = []
|
|
11
|
-
return questions unless
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
#items
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
q
|
|
23
|
-
q.
|
|
24
|
-
q.
|
|
25
|
-
q.matching << [
|
|
26
|
-
q.matching << [ pList1[i+1][:data][0], '2º' ]
|
|
27
|
-
q.matching << [ pList1[i+2][:data][0], '3º' ]
|
|
28
|
-
q.matching << [ pList1[i+3][:data][0], '4º' ]
|
|
15
|
+
return questions unless table.fields.count == 1 && table.sequence? && table.sequence[0] != ''
|
|
16
|
+
|
|
17
|
+
lang = concept.lang
|
|
18
|
+
# Question type <d3sequence>: items are part of a sequence
|
|
19
|
+
if list1.count > 3
|
|
20
|
+
a = 0..(list1.count - 4)
|
|
21
|
+
a.each_entry do |i|
|
|
22
|
+
q = Question.new(:match)
|
|
23
|
+
q.name = "#{name}-#{num}-s1sequence-#{table.name}"
|
|
24
|
+
q.text = random_image_for(name) + lang.text_for(:s1, name, table.fields[0].capitalize, table.sequence[0])
|
|
25
|
+
q.matching << [list1[i + 0][:data][0], '1º']
|
|
26
|
+
q.matching << [list1[i + 1][:data][0], '2º']
|
|
27
|
+
q.matching << [list1[i + 2][:data][0], '3º']
|
|
28
|
+
q.matching << [list1[i + 3][:data][0], '4º']
|
|
29
|
+
q.matching << ['', lang.text_for(:error)]
|
|
29
30
|
questions << q
|
|
30
31
|
end
|
|
31
32
|
end
|
|
32
33
|
|
|
33
|
-
#Question type <d4sequence>: items are part of a reverse sequence
|
|
34
|
-
if
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
q=Question.new
|
|
34
|
+
# Question type <d4sequence>: items are part of a reverse sequence
|
|
35
|
+
if list1.count > 3 && table.sequence.size > 1
|
|
36
|
+
a = 0..(list1.count - 4)
|
|
37
|
+
a.each_entry do |i|
|
|
38
|
+
q = Question.new
|
|
38
39
|
q.set_match
|
|
39
|
-
q.name="#{name}-#{num
|
|
40
|
-
q.text= random_image_for(name) + lang.text_for(:s1, name,
|
|
41
|
-
q.matching << [
|
|
42
|
-
q.matching << [
|
|
43
|
-
q.matching << [
|
|
44
|
-
q.matching << [
|
|
40
|
+
q.name = "#{name}-#{num}-s2sequence-#{table.name}"
|
|
41
|
+
q.text = random_image_for(name) + lang.text_for(:s1, name, table.fields[0].capitalize, table.sequence[1])
|
|
42
|
+
q.matching << [list1[i + 3][:data][0], '1º']
|
|
43
|
+
q.matching << [list1[i + 2][:data][0], '2º']
|
|
44
|
+
q.matching << [list1[i + 1][:data][0], '3º']
|
|
45
|
+
q.matching << [list1[i + 0][:data][0], '4º']
|
|
46
|
+
q.matching << ['', lang.text_for(:error)]
|
|
45
47
|
questions << q
|
|
46
48
|
end
|
|
47
|
-
|
|
49
|
+
end
|
|
48
50
|
|
|
49
|
-
|
|
51
|
+
questions
|
|
50
52
|
end
|
|
51
|
-
|
|
53
|
+
# rubocop:enable Metrics/MethodLength
|
|
54
|
+
# rubocop:enable Metrics/AbcSize
|
|
55
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
56
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
52
57
|
end
|