asker-tool 2.1.3 → 2.2.0
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 +18 -19
- 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 +12 -2
- 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 +24 -7
- data/lib/asker/checker.rb +149 -52
- data/lib/asker/cli.rb +37 -32
- data/lib/asker/data/code.rb +76 -0
- data/lib/asker/data/column.rb +31 -21
- data/lib/asker/data/concept.rb +108 -65
- data/lib/asker/data/data_field.rb +14 -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 +61 -32
- data/lib/asker/{exporter/code_screen_exporter.rb → displayer/code_displayer.rb} +13 -6
- data/lib/asker/displayer/concept_ai_displayer.erb +10 -0
- data/lib/asker/displayer/concept_ai_displayer.rb +133 -0
- data/lib/asker/displayer/concept_displayer.rb +34 -0
- data/lib/asker/displayer/stats_displayer.rb +22 -0
- data/lib/asker/exporter/code_gift_exporter.rb +10 -11
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +21 -13
- data/lib/asker/exporter/concept_ai_moodle_exporter.rb +44 -0
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +14 -9
- data/lib/asker/exporter/concept_doc_exporter.rb +21 -14
- data/lib/asker/exporter/data_gift_exporter.rb +29 -0
- data/lib/asker/exporter/output_file_exporter.rb +21 -0
- data/lib/asker/files/{config.ini → asker.ini} +48 -1
- data/lib/asker/files/example-concept.haml +24 -8
- data/lib/asker/files/language/du/connectors.yaml +81 -0
- data/lib/asker/files/language/du/mistakes.yaml +82 -0
- data/lib/asker/files/language/du/templates.yaml +29 -0
- data/lib/asker/files/language/en/connectors.yaml +44 -0
- data/lib/asker/files/language/en/mistakes.yaml +37 -0
- data/lib/asker/files/language/en/templates.yaml +29 -0
- data/lib/asker/files/language/es/connectors.yaml +92 -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/files/language/fr/mistakes.yaml +82 -0
- data/lib/asker/files/language/fr/templates.yaml +29 -0
- data/lib/asker/files/language/javascript/connectors.yaml +11 -0
- data/lib/asker/files/language/javascript/mistakes.yaml +30 -0
- data/lib/asker/files/language/javascript/templates.yaml +3 -0
- data/lib/asker/files/language/math/connectors.yaml +2 -0
- data/lib/asker/files/language/math/mistakes.yaml +2 -0
- data/lib/asker/files/language/math/templates.yaml +1 -0
- data/lib/asker/files/language/python/connectors.yaml +11 -0
- data/lib/asker/files/language/python/mistakes.yaml +26 -0
- data/lib/asker/files/language/python/templates.yaml +3 -0
- data/lib/asker/files/language/ruby/connectors.yaml +11 -0
- data/lib/asker/files/language/ruby/mistakes.yaml +33 -0
- data/lib/asker/files/language/ruby/templates.yaml +3 -0
- data/lib/asker/files/language/sql/connectors.yaml +6 -0
- data/lib/asker/files/language/sql/mistakes.yaml +11 -0
- data/lib/asker/files/language/sql/templates.yaml +2 -0
- data/lib/asker/formatter/concept_string_formatter.rb +13 -9
- 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/lang/lang.rb +18 -12
- 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 +16 -12
- data/lib/asker/loader/directory_loader.rb +3 -3
- data/lib/asker/loader/embedded_file.rb +42 -0
- data/lib/asker/loader/file_loader.rb +3 -12
- data/lib/asker/loader/haml_loader.rb +15 -0
- data/lib/asker/loader/image_url_loader.rb +9 -11
- data/lib/asker/loader/input_loader.rb +24 -8
- data/lib/asker/loader/project_loader.rb +42 -30
- data/lib/asker/logger.rb +30 -6
- data/lib/asker/project.rb +28 -117
- data/lib/asker/skeleton.rb +40 -29
- data/lib/asker.rb +68 -79
- metadata +57 -74
- data/docs/changelog/v2.1.md +0 -99
- data/docs/commands.md +0 -12
- data/docs/contributions.md +0 -18
- data/docs/history.md +0 -40
- data/docs/idea.md +0 -44
- data/docs/inputs/README.md +0 -39
- data/docs/inputs/code.md +0 -69
- data/docs/inputs/concepts.md +0 -142
- data/docs/inputs/jedi.md +0 -68
- data/docs/inputs/tables.md +0 -112
- data/docs/inputs/templates.md +0 -87
- data/docs/install/README.md +0 -38
- data/docs/install/manual.md +0 -26
- data/docs/install/scripts.md +0 -38
- data/docs/revise/asker-file.md +0 -41
- data/docs/revise/buenas-practicas/01-convocatoria.md +0 -30
- data/docs/revise/buenas-practicas/02-formulario.md +0 -35
- data/docs/revise/buenas-practicas/03-descripcion.md +0 -63
- data/docs/revise/buenas-practicas/04-resultados.md +0 -17
- data/docs/revise/buenas-practicas/05-reproducir.md +0 -10
- data/docs/revise/ejemplos/01/README.md +0 -27
- data/docs/revise/ejemplos/02/README.md +0 -31
- data/docs/revise/ejemplos/03/README.md +0 -31
- data/docs/revise/ejemplos/04/README.md +0 -37
- data/docs/revise/ejemplos/05/README.md +0 -25
- data/docs/revise/ejemplos/06/README.md +0 -43
- data/docs/revise/ejemplos/README.md +0 -11
- data/docs/revise/projects.md +0 -74
- data/lib/asker/code/ai/base_code_ai.rb +0 -48
- data/lib/asker/code/code.rb +0 -53
- data/lib/asker/exporter/concept_ai_screen_exporter.rb +0 -115
- data/lib/asker/exporter/concept_screen_exporter.rb +0 -25
- data/lib/asker/exporter/main.rb +0 -9
data/lib/asker/ai/question.rb
CHANGED
|
@@ -1,18 +1,31 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require 'set'
|
|
3
4
|
|
|
4
5
|
# Define Question class
|
|
5
6
|
class Question
|
|
6
|
-
attr_accessor :name
|
|
7
|
-
attr_accessor :
|
|
8
|
-
attr_accessor :
|
|
9
|
-
|
|
10
|
-
attr_accessor :
|
|
7
|
+
attr_accessor :name # Question name used as identification
|
|
8
|
+
attr_accessor :comment # Comments asociated
|
|
9
|
+
attr_accessor :text # The real text of the question
|
|
10
|
+
attr_accessor :good # The correct answer
|
|
11
|
+
attr_accessor :bads # Bads answers used by choice type question
|
|
12
|
+
attr_accessor :matching # Matching answers used by match type question
|
|
13
|
+
attr_accessor :shorts # Short answers used by short type question
|
|
14
|
+
attr_accessor :feedback # Question feedbak
|
|
15
|
+
attr_reader :type # Question type: :choice, :match, :boolean, :short
|
|
16
|
+
attr_accessor :tags
|
|
17
|
+
attr_accessor :lang # Info used when export (YAML)
|
|
18
|
+
attr_accessor :encode # image base64 content used when export Moodle xml
|
|
11
19
|
|
|
20
|
+
# Initialize object
|
|
21
|
+
# @param type (Symbol) Question type: choice, match, boolean, short
|
|
12
22
|
def initialize(type = :choice)
|
|
13
23
|
reset(type)
|
|
14
24
|
end
|
|
15
25
|
|
|
26
|
+
# Reset attributes
|
|
27
|
+
# @param type (Symbol) Question type: choice, match, boolean, short
|
|
28
|
+
# rubocop:disable Metrics/MethodLength
|
|
16
29
|
def reset(type = :choice)
|
|
17
30
|
@name = ''
|
|
18
31
|
@comment = ''
|
|
@@ -26,32 +39,41 @@ class Question
|
|
|
26
39
|
shuffle_on
|
|
27
40
|
@tags = Set.new
|
|
28
41
|
@lang = nil
|
|
42
|
+
@encode = :none
|
|
29
43
|
end
|
|
44
|
+
# rubocop:enable Metrics/MethodLength
|
|
30
45
|
|
|
46
|
+
# Set choice type
|
|
31
47
|
def set_choice
|
|
32
48
|
@type = :choice
|
|
33
49
|
end
|
|
34
50
|
|
|
51
|
+
# Set match type
|
|
35
52
|
def set_match
|
|
36
53
|
@type = :match
|
|
37
54
|
end
|
|
38
55
|
|
|
56
|
+
# Set boolean type
|
|
39
57
|
def set_boolean
|
|
40
58
|
@type = :boolean
|
|
41
59
|
end
|
|
42
60
|
|
|
61
|
+
# Set short type
|
|
43
62
|
def set_short
|
|
44
63
|
@type = :short
|
|
45
64
|
end
|
|
46
65
|
|
|
66
|
+
# Set shuffle off
|
|
47
67
|
def shuffle_off
|
|
48
68
|
@shuffle = false
|
|
49
69
|
end
|
|
50
70
|
|
|
71
|
+
# Set shuffle on
|
|
51
72
|
def shuffle_on
|
|
52
73
|
@shuffle = true
|
|
53
74
|
end
|
|
54
75
|
|
|
76
|
+
# Return shuffle value
|
|
55
77
|
def shuffle?
|
|
56
78
|
@shuffle
|
|
57
79
|
end
|
|
@@ -1,16 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
|
|
3
|
+
# Base Stage class
|
|
2
4
|
class BaseStage
|
|
5
|
+
#
|
|
6
|
+
# Initialize Stage with ConceptAI
|
|
7
|
+
# @param concept_ai (ConceptAI)
|
|
3
8
|
def initialize(concept_ai)
|
|
4
9
|
@concept_ai = concept_ai
|
|
5
10
|
end
|
|
6
11
|
|
|
7
|
-
# If a method we call is missing, pass the call onto
|
|
8
|
-
# the object we delegate to.
|
|
9
|
-
def method_missing(m, *args, &block)
|
|
10
|
-
@concept_ai.send(m, *args, &block)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
12
|
def run
|
|
14
13
|
raise 'Implement run method!'
|
|
15
14
|
end
|
|
15
|
+
|
|
16
|
+
def concept
|
|
17
|
+
@concept_ai.concept
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def name(option = :raw)
|
|
21
|
+
@concept_ai.concept.name(option)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def names
|
|
25
|
+
raise 'Change names by concept.names'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def num
|
|
29
|
+
@concept_ai.num
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def lang
|
|
33
|
+
raise 'Change lang by concept.lang'
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def type
|
|
37
|
+
raise 'Change type by concept.type'
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def texts
|
|
41
|
+
raise 'Change texts by cocept.texts'
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def images
|
|
45
|
+
raise 'Change images by cocept.images'
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def neighbors
|
|
49
|
+
raise 'Change neighbors by concept.neighbors'
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def random_image_for(option)
|
|
53
|
+
@concept_ai.random_image_for(option)
|
|
54
|
+
end
|
|
16
55
|
end
|
|
@@ -1,87 +1,137 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'set'
|
|
4
4
|
|
|
5
5
|
require_relative 'base_stage'
|
|
6
6
|
require_relative '../question'
|
|
7
7
|
|
|
8
|
+
##
|
|
9
|
+
# range b1
|
|
8
10
|
class StageB < BaseStage
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
##
|
|
12
|
+
# Process table data to generate match questions
|
|
13
|
+
# @param table (Table)
|
|
14
|
+
# @param list1 (Array) Rows that belong to this table
|
|
15
|
+
# @param list2 (Array) List with similar rows (same table name) from the neighbours tables
|
|
16
|
+
# rubocop:disable Metrics/AbcSize
|
|
17
|
+
# rubocop:disable Metrics/MethodLength
|
|
18
|
+
def run(table, list1, list2)
|
|
13
19
|
questions = []
|
|
14
|
-
return questions if
|
|
20
|
+
return questions if table.fields.count < 2
|
|
15
21
|
|
|
16
|
-
return questions unless type == 'text'
|
|
22
|
+
return questions unless concept.type == 'text'
|
|
17
23
|
|
|
18
|
-
if
|
|
19
|
-
questions += process_table_match2fields(
|
|
20
|
-
elsif
|
|
21
|
-
questions += process_table_match2fields(
|
|
22
|
-
questions += process_table_match2fields(
|
|
23
|
-
elsif
|
|
24
|
-
questions += process_table_match2fields(
|
|
25
|
-
questions += process_table_match2fields(
|
|
26
|
-
questions += process_table_match2fields(
|
|
24
|
+
if table.fields.count == 2
|
|
25
|
+
questions += process_table_match2fields(table, list1, list2, 0, 1)
|
|
26
|
+
elsif table.fields.count == 3
|
|
27
|
+
questions += process_table_match2fields(table, list1, list2, 0, 1)
|
|
28
|
+
questions += process_table_match2fields(table, list1, list2, 0, 2)
|
|
29
|
+
elsif table.fields.count == 4
|
|
30
|
+
questions += process_table_match2fields(table, list1, list2, 0, 1)
|
|
31
|
+
questions += process_table_match2fields(table, list1, list2, 0, 2)
|
|
32
|
+
questions += process_table_match2fields(table, list1, list2, 0, 3)
|
|
27
33
|
end
|
|
28
34
|
|
|
29
35
|
questions
|
|
30
36
|
end
|
|
37
|
+
# rubocop:enable Metrics/AbcSize
|
|
38
|
+
# rubocop:enable Metrics/MethodLength
|
|
31
39
|
|
|
32
|
-
|
|
40
|
+
##
|
|
41
|
+
# Process table data to generate match questions
|
|
42
|
+
# @param p_table (Table)
|
|
43
|
+
# @param list1 (Array) Rows that belong to this table
|
|
44
|
+
# @param list2 (Array) List with similar rows (same table name) from the neighbours tables
|
|
45
|
+
# @param index1 (Integer) Use this field number
|
|
46
|
+
# @param index2 (Integer) Use this field number
|
|
47
|
+
# rubocop:disable Metrics/AbcSize
|
|
48
|
+
# rubocop:disable Metrics/MethodLength
|
|
49
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
50
|
+
# rubocop:disable Style/ConditionalAssignment
|
|
51
|
+
# rubocop:disable Metrics/BlockLength
|
|
52
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
53
|
+
def process_table_match2fields(p_table, list1, list2, index1, index2)
|
|
33
54
|
questions = []
|
|
55
|
+
lang = concept.lang
|
|
34
56
|
|
|
35
|
-
if
|
|
36
|
-
|
|
37
|
-
e = [
|
|
57
|
+
if list1.count > 3
|
|
58
|
+
list1.each_cons(4) do |e1, e2, e3, e4|
|
|
59
|
+
e = [e1, e2, e3, e4]
|
|
38
60
|
|
|
39
|
-
#Question type <b1match>: match 4 items from the same table
|
|
61
|
+
# Question type <b1match>: match 4 items from the same table
|
|
40
62
|
e.shuffle!
|
|
41
|
-
q=Question.new(:match)
|
|
42
|
-
q.name="#{name}-#{num
|
|
43
|
-
q.
|
|
44
|
-
q.
|
|
45
|
-
q.
|
|
46
|
-
|
|
47
|
-
q.matching << [
|
|
63
|
+
q = Question.new(:match)
|
|
64
|
+
q.name = "#{name}-#{num}-b1match4x4-#{p_table.name}"
|
|
65
|
+
q.tags << 'match'
|
|
66
|
+
q.tags << 'random'
|
|
67
|
+
q.text = random_image_for(name) \
|
|
68
|
+
+ lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
|
|
69
|
+
q.matching << [e[0][:data][index1], e[0][:data][index2]]
|
|
70
|
+
q.matching << [e[1][:data][index1], e[1][:data][index2]]
|
|
71
|
+
q.matching << [e[2][:data][index1], e[2][:data][index2]]
|
|
72
|
+
q.matching << [e[3][:data][index1], e[3][:data][index2]]
|
|
73
|
+
# Add an extra line
|
|
74
|
+
if list2.count.positive?
|
|
75
|
+
q.matching << ['', list2[0][:data][index2]]
|
|
76
|
+
else
|
|
77
|
+
q.tags << 'misspell'
|
|
78
|
+
q.matching << ['', lang.do_mistake_to(e[0][:data][index2])]
|
|
79
|
+
end
|
|
48
80
|
questions << q
|
|
49
81
|
|
|
50
82
|
# Question type <b1match>: match 3 items from table-A and 1 item with error
|
|
51
83
|
e.shuffle!
|
|
52
|
-
q=Question.new(:match)
|
|
53
|
-
q.name="#{name}-#{num
|
|
54
|
-
q.
|
|
55
|
-
q.
|
|
56
|
-
q.
|
|
57
|
-
|
|
58
|
-
q.matching << [
|
|
84
|
+
q = Question.new(:match)
|
|
85
|
+
q.name = "#{name}-#{num}-b1match3x1misspelled-#{p_table.name}"
|
|
86
|
+
q.tags << 'match'
|
|
87
|
+
q.tags << 'random'
|
|
88
|
+
q.text = random_image_for(name) \
|
|
89
|
+
+ lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
|
|
90
|
+
q.matching << [e[0][:data][index1], e[0][:data][index2]]
|
|
91
|
+
q.matching << [e[1][:data][index1], e[1][:data][index2]]
|
|
92
|
+
q.matching << [e[2][:data][index1], e[2][:data][index2]]
|
|
93
|
+
q.matching << [lang.do_mistake_to(e[3][:data][index1]), lang.text_for(:misspelling)]
|
|
94
|
+
# Add an extra line
|
|
95
|
+
if list2.count.positive?
|
|
96
|
+
q.matching << ['', list2[0][:data][index2]]
|
|
97
|
+
else
|
|
98
|
+
q.tags << 'misspell'
|
|
99
|
+
q.matching << ['', lang.do_mistake_to(e[0][:data][index2])]
|
|
100
|
+
end
|
|
59
101
|
questions << q
|
|
60
102
|
end
|
|
61
103
|
end
|
|
62
104
|
|
|
63
|
-
if
|
|
64
|
-
s=Set.new
|
|
65
|
-
|
|
66
|
-
s.add(
|
|
105
|
+
if list1.count > 2 && list2.count.positive?
|
|
106
|
+
s = Set.new
|
|
107
|
+
list1.each do |i|
|
|
108
|
+
s.add(i[:data][index1] + '<=>' + i[:data][index2])
|
|
67
109
|
end
|
|
68
|
-
s.add(
|
|
69
|
-
a=s.to_a
|
|
110
|
+
s.add(list2[0][:data][index1] + '<=>' + list2[0][:data][index2])
|
|
70
111
|
|
|
71
112
|
# Question 3 items from table-A, and 1 item from table-B
|
|
72
113
|
if s.count > 3
|
|
73
|
-
q=Question.new(:match)
|
|
74
|
-
q.name="#{name}-#{num
|
|
75
|
-
q.
|
|
76
|
-
q.
|
|
77
|
-
q.
|
|
78
|
-
|
|
79
|
-
q.matching << [
|
|
114
|
+
q = Question.new(:match)
|
|
115
|
+
q.name = "#{name}-#{num}-b1match3x1-#{p_table.name}"
|
|
116
|
+
q.tags << 'match'
|
|
117
|
+
q.tags << 'random'
|
|
118
|
+
q.text = random_image_for(name) \
|
|
119
|
+
+ lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
|
|
120
|
+
q.matching << [list1[0][:data][index1], list1[0][:data][index2]]
|
|
121
|
+
q.matching << [list1[1][:data][index1], list1[1][:data][index2]]
|
|
122
|
+
q.matching << [list1[2][:data][index1], list1[2][:data][index2]]
|
|
123
|
+
q.matching << [list2[0][:data][index1], lang.text_for(:error)]
|
|
124
|
+
q.matching << ['', lang.do_mistake_to(list1[0][:data][index2])]
|
|
80
125
|
questions << q
|
|
81
126
|
end
|
|
82
127
|
end
|
|
83
128
|
|
|
84
|
-
|
|
129
|
+
questions
|
|
85
130
|
end
|
|
86
|
-
|
|
131
|
+
# rubocop:enable Metrics/AbcSize
|
|
132
|
+
# rubocop:enable Metrics/MethodLength
|
|
133
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
134
|
+
# rubocop:enable Style/ConditionalAssignment
|
|
135
|
+
# rubocop:enable Metrics/BlockLength
|
|
136
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
87
137
|
end
|
|
@@ -1,160 +1,145 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'set'
|
|
4
4
|
|
|
5
5
|
require_relative 'base_stage'
|
|
6
6
|
require_relative '../question'
|
|
7
7
|
|
|
8
|
+
# range d1-d4
|
|
8
9
|
class StageD < BaseStage
|
|
9
|
-
#
|
|
10
|
-
|
|
10
|
+
# rubocop:disable Lint/BooleanSymbol
|
|
11
|
+
# rubocop:disable Metrics/MethodLength
|
|
12
|
+
# rubocop:disable Metrics/AbcSize
|
|
13
|
+
# rubocop:disable Metrics/BlockLength
|
|
14
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
15
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
|
11
16
|
def run
|
|
12
17
|
# Stage D: process every definition, I mean every <def> tag
|
|
13
18
|
questions = []
|
|
14
|
-
return questions unless type == 'text'
|
|
19
|
+
return questions unless concept.type == 'text'
|
|
15
20
|
|
|
21
|
+
lang = concept.lang
|
|
16
22
|
# for every <text> do this
|
|
17
|
-
texts.each do |t|
|
|
18
|
-
s=Set.new [name(:raw), lang.text_for(:none)]
|
|
19
|
-
neighbors.each { |n| s.add n[:concept].name(:decorated) }
|
|
20
|
-
a=s.to_a
|
|
23
|
+
concept.texts.each do |t|
|
|
24
|
+
s = Set.new [name(:raw), lang.text_for(:none)]
|
|
25
|
+
concept.neighbors.each { |n| s.add n[:concept].name(:decorated) }
|
|
26
|
+
a = s.to_a
|
|
21
27
|
|
|
22
28
|
# Question choose between 4 options
|
|
23
29
|
if s.count > 3
|
|
24
|
-
q=Question.new(:choice)
|
|
25
|
-
q.name="#{name(:id)}-#{num}-d1choose"
|
|
26
|
-
q.text=random_image_for(name(:raw)) + lang.text_for(:d1,t)
|
|
27
|
-
q.good=name(:raw)
|
|
30
|
+
q = Question.new(:choice)
|
|
31
|
+
q.name = "#{name(:id)}-#{num}-d1choose"
|
|
32
|
+
q.text = random_image_for(name(:raw)) + lang.text_for(:d1, t)
|
|
33
|
+
q.good = name(:raw)
|
|
28
34
|
q.bads << lang.text_for(:none)
|
|
29
35
|
q.bads << a[2]
|
|
30
36
|
q.bads << a[3]
|
|
31
37
|
questions << q
|
|
32
38
|
end
|
|
33
39
|
|
|
34
|
-
#Question choose between 4 options, good none (Syntax error)
|
|
35
|
-
if s.count>3
|
|
36
|
-
q=Question.new(:choice)
|
|
37
|
-
q.name="#{name(:id)}-#{num}-d1none-misspelled"
|
|
38
|
-
q.text=random_image_for(name(:raw)) + lang.text_for(:d1,t)
|
|
40
|
+
# Question choose between 4 options, good none (Syntax error)
|
|
41
|
+
if s.count > 3
|
|
42
|
+
q = Question.new(:choice)
|
|
43
|
+
q.name = "#{name(:id)}-#{num}-d1none-misspelled"
|
|
44
|
+
q.text = random_image_for(name(:raw)) + lang.text_for(:d1, t)
|
|
39
45
|
q.good = lang.text_for(:none)
|
|
40
46
|
q.bads << lang.do_mistake_to(name(:raw))
|
|
41
47
|
q.bads << a[2]
|
|
42
48
|
q.bads << a[3]
|
|
43
|
-
q.feedback="Option misspelled!: #{name(:raw)}"
|
|
49
|
+
q.feedback = "Option misspelled!: #{name(:raw)}"
|
|
44
50
|
questions << q
|
|
45
51
|
end
|
|
46
52
|
|
|
47
53
|
s.delete(name(:raw))
|
|
48
|
-
a=s.to_a
|
|
54
|
+
a = s.to_a
|
|
49
55
|
|
|
50
|
-
#Question choose between 4 options, good none
|
|
51
|
-
if s.count>3
|
|
56
|
+
# Question choose between 4 options, good none
|
|
57
|
+
if s.count > 3
|
|
52
58
|
q = Question.new(:choice)
|
|
53
|
-
q.name="#{name(:id)}-#{num}-d1none"
|
|
54
|
-
q.text=random_image_for(name(:raw)) + lang.text_for(:d1,t)
|
|
55
|
-
q.good=lang.text_for(:none)
|
|
59
|
+
q.name = "#{name(:id)}-#{num}-d1none"
|
|
60
|
+
q.text = random_image_for(name(:raw)) + lang.text_for(:d1, t)
|
|
61
|
+
q.good = lang.text_for(:none)
|
|
56
62
|
q.bads << a[1]
|
|
57
63
|
q.bads << a[2]
|
|
58
64
|
q.bads << a[3]
|
|
59
65
|
questions << q
|
|
60
66
|
end
|
|
61
67
|
|
|
62
|
-
#Question
|
|
63
|
-
#q = Question.new(:boolean)
|
|
64
|
-
#q.name="#{name}-#{num}-d2true"
|
|
65
|
-
#q.text=random_image_for(name) + lang.text_for(:d2,name,t)
|
|
66
|
-
#q.good="TRUE"
|
|
67
|
-
#questions << q
|
|
68
|
-
|
|
68
|
+
# Question choice => mispelled
|
|
69
69
|
q = Question.new(:choice)
|
|
70
|
-
q.name="#{name(:id)}-#{num}-d2def-mispelled"
|
|
71
|
-
q.text=random_image_for(name(:raw)) + lang.text_for(:d2,name(:decorated), lang.do_mistake_to(t)
|
|
72
|
-
q.good=lang.text_for(:misspelling)
|
|
70
|
+
q.name = "#{name(:id)}-#{num}-d2def-mispelled"
|
|
71
|
+
q.text = random_image_for(name(:raw)) + lang.text_for(:d2, name(:decorated), lang.do_mistake_to(t))
|
|
72
|
+
q.good = lang.text_for(:misspelling)
|
|
73
73
|
q.bads << lang.text_for(:true)
|
|
74
74
|
q.bads << lang.text_for(:false)
|
|
75
|
-
q.feedback="Definition text mispelled!: #{t}"
|
|
75
|
+
q.feedback = "Definition text mispelled!: #{t}"
|
|
76
76
|
questions << q
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
end
|
|
78
|
+
# Question choice => name mispelled
|
|
79
|
+
q = Question.new(:choice)
|
|
80
|
+
q.name = "#{name(:id)}-#{num}-d2name-mispelled"
|
|
81
|
+
q.text = random_image_for(name(:raw)) + lang.text_for(:d2, lang.do_mistake_to(name(:raw)), t)
|
|
82
|
+
q.good = lang.text_for(:misspelling)
|
|
83
|
+
q.bads << lang.text_for(:true)
|
|
84
|
+
q.bads << lang.text_for(:false)
|
|
85
|
+
q.feedback = "Concept name mispelled!: #{name(:raw)}"
|
|
86
|
+
questions << q
|
|
88
87
|
|
|
88
|
+
# Question choice => true
|
|
89
89
|
q = Question.new(:choice)
|
|
90
|
-
q.name="#{name(:id)}-#{num}-d2true"
|
|
91
|
-
q.text=random_image_for(name(:raw)) + lang.text_for(:d2, name(:raw), t
|
|
90
|
+
q.name = "#{name(:id)}-#{num}-d2true"
|
|
91
|
+
q.text = random_image_for(name(:raw)) + lang.text_for(:d2, name(:raw), t)
|
|
92
92
|
q.good = lang.text_for(:true)
|
|
93
93
|
q.bads << lang.text_for(:misspelling)
|
|
94
94
|
q.bads << lang.text_for(:false)
|
|
95
95
|
questions << q
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
# Question choice => false
|
|
98
|
+
if a.size > 1
|
|
98
99
|
q = Question.new(:choice)
|
|
99
|
-
q.name="#{name(:id)}-#{num}-d2false-misspelled"
|
|
100
|
-
q.text=random_image_for(name(:raw)) + lang.text_for(:d2, a[1], t)
|
|
100
|
+
q.name = "#{name(:id)}-#{num}-d2false-misspelled"
|
|
101
|
+
q.text = random_image_for(name(:raw)) + lang.text_for(:d2, a[1], t)
|
|
101
102
|
q.good = lang.text_for(:false)
|
|
102
103
|
q.bads << lang.text_for(:misspelling)
|
|
103
104
|
q.bads << lang.text_for(:true)
|
|
104
105
|
questions << q
|
|
105
106
|
end
|
|
106
107
|
|
|
107
|
-
#Question
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if type=="text"
|
|
117
|
-
#Question hidden name questions
|
|
118
|
-
q = Question.new(:short)
|
|
119
|
-
q.name="#{name(:id)}-#{num}-d3hidden"
|
|
120
|
-
q.text=random_image_for(name(:raw)) + lang.text_for(:d3, lang.hide_text(name(:raw)), t )
|
|
121
|
-
q.shorts << name(:raw)
|
|
122
|
-
q.shorts << name(:raw).gsub("-"," ").gsub("_"," ")
|
|
123
|
-
names.each do |n|
|
|
124
|
-
q.shorts << n if n!=name
|
|
125
|
-
end
|
|
126
|
-
questions << q
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
# indexes = []
|
|
130
|
-
# exclude = ["[", "]", "(", ")", "\"" ]
|
|
131
|
-
# filtered[:words].each_with_index do |item,index|
|
|
132
|
-
# flag=true
|
|
133
|
-
# exclude.each { |e| flag=false if (item[:word].include?(e)) }
|
|
134
|
-
# indexes << index if flag
|
|
135
|
-
# end
|
|
108
|
+
# Question hidden name questions
|
|
109
|
+
q = Question.new(:short)
|
|
110
|
+
q.name = "#{name(:id)}-#{num}-d3hidden"
|
|
111
|
+
q.text = random_image_for(name(:raw)) + lang.text_for(:d3, lang.hide_text(name(:raw)), t)
|
|
112
|
+
q.shorts << name(:raw)
|
|
113
|
+
q.shorts << name(:raw).gsub('-', ' ').gsub('_', ' ')
|
|
114
|
+
concept.names.each { |n| q.shorts << n if n != name }
|
|
115
|
+
questions << q
|
|
136
116
|
|
|
137
|
-
#Question filtered text questions
|
|
138
|
-
filtered=lang.text_with_connectors(t)
|
|
117
|
+
# Question filtered text questions
|
|
118
|
+
filtered = lang.text_with_connectors(t)
|
|
139
119
|
indexes = filtered[:indexes]
|
|
140
120
|
|
|
141
|
-
groups =
|
|
142
|
-
max
|
|
143
|
-
groups[0,max].each do |e|
|
|
121
|
+
groups = indexes.combination(4).to_a.shuffle
|
|
122
|
+
max = (indexes.size / 4).to_i
|
|
123
|
+
groups[0, max].each do |e|
|
|
144
124
|
e.sort!
|
|
145
125
|
q = Question.new(:match)
|
|
146
126
|
q.shuffle_off
|
|
147
127
|
q.name = "#{name}-#{num}-d4filtered"
|
|
148
|
-
s = lang.build_text_from_filtered(
|
|
149
|
-
q.text = random_image_for(name(:raw)) + lang.text_for(:d4, name(:raw)
|
|
150
|
-
e.each_with_index do |value,index|
|
|
151
|
-
q.matching << [
|
|
128
|
+
s = lang.build_text_from_filtered(filtered, e)
|
|
129
|
+
q.text = random_image_for(name(:raw)) + lang.text_for(:d4, name(:raw), s)
|
|
130
|
+
e.each_with_index do |value, index|
|
|
131
|
+
q.matching << [(index + 1).to_s, filtered[:words][value][:word].downcase]
|
|
152
132
|
end
|
|
153
133
|
questions << q
|
|
154
134
|
end
|
|
155
135
|
end
|
|
156
136
|
|
|
157
|
-
|
|
137
|
+
questions
|
|
158
138
|
end
|
|
159
|
-
|
|
139
|
+
# rubocop:enable Lint/BooleanSymbol
|
|
140
|
+
# rubocop:enable Metrics/MethodLength
|
|
141
|
+
# rubocop:enable Metrics/AbcSize
|
|
142
|
+
# rubocop:enable Metrics/BlockLength
|
|
143
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
144
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
|
160
145
|
end
|