asker-tool 2.1.7 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +1 -1
- data/bin/asker +1 -1
- data/lib/asker/ai/ai.rb +6 -3
- data/lib/asker/ai/ai_calculate.rb +20 -6
- data/lib/asker/ai/concept_ai.rb +11 -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 +114 -73
- data/lib/asker/application.rb +8 -7
- data/lib/asker/checker.rb +6 -8
- data/lib/asker/cli.rb +27 -9
- data/lib/asker/data/code.rb +4 -1
- data/lib/asker/data/concept.rb +67 -21
- data/lib/asker/data/table.rb +2 -0
- data/lib/asker/data/template.rb +3 -1
- data/lib/asker/data/world.rb +7 -4
- 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 +23 -22
- data/lib/asker/displayer/concept_displayer.rb +9 -4
- data/lib/asker/displayer/stats_displayer.rb +8 -0
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +7 -11
- data/lib/asker/exporter/concept_ai_moodle_exporter.rb +44 -0
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +6 -3
- 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} +14 -4
- 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 +28 -49
- data/lib/asker/files/language/en/templates.yaml +19 -19
- data/lib/asker/files/language/es/mistakes.yaml +9 -7
- data/lib/asker/files/language/es/templates.yaml +19 -19
- data/lib/asker/files/language/fr/connectors.yaml +68 -84
- data/lib/asker/files/language/fr/templates.yaml +22 -22
- 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 +21 -19
- data/lib/asker/formatter/question_moodle_formatter.rb +27 -0
- data/lib/asker/lang/lang_factory.rb +7 -1
- data/lib/asker/loader/code_loader.rb +1 -1
- data/lib/asker/loader/content_loader.rb +7 -7
- 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 +1 -1
- data/lib/asker/loader/image_url_loader.rb +4 -3
- data/lib/asker/loader/input_loader.rb +1 -1
- data/lib/asker/loader/project_loader.rb +14 -5
- data/lib/asker/logger.rb +29 -4
- data/lib/asker/project.rb +14 -79
- data/lib/asker/skeleton.rb +3 -2
- data/lib/asker.rb +37 -9
- metadata +19 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a17926e45cfc0549f76ae3d8ec9c5313565847e3615653f7520344e03eea63f7
|
4
|
+
data.tar.gz: 717620e1a5d56c65dc0ec601de61ffef208f3e21087e71e84a4c421e9e65c67f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ec3c2b84781c6c723edfbb0e5570edaabb8e26fd0d732bb9fa155d7b6fb5762115a44ba75899af7e0e0b399d6b764562de77dd31b0b2fe128c5dd97b39caf7d
|
7
|
+
data.tar.gz: 3f1aa7b3ce5a9f59f3c373bd246f5fd8e8000a163ec539f943f32144fff057f80b44ae06bc127a31eb3ad71de0bb431d010a737491e57695c202e97534674a69
|
data/{LICENSE.txt → LICENSE}
RENAMED
File without changes
|
data/README.md
CHANGED
data/bin/asker
CHANGED
data/lib/asker/ai/ai.rb
CHANGED
@@ -6,14 +6,14 @@ require_relative 'ai_calculate'
|
|
6
6
|
# Description: Method to be included into every ConceptAI instance.
|
7
7
|
# * make_questions: use AI to fill @questions Array
|
8
8
|
module AI
|
9
|
-
include
|
9
|
+
include AICalculate
|
10
10
|
|
11
11
|
def make_questions
|
12
|
-
return unless process?
|
12
|
+
return unless concept.process?
|
13
13
|
|
14
14
|
make_questions_stages_di
|
15
15
|
# Process every table of this concept
|
16
|
-
tables.each do |tab|
|
16
|
+
concept.tables.each do |tab|
|
17
17
|
list1, list2 = get_list1_and_list2_from(tab)
|
18
18
|
make_questions_stages_bsf(tab, list1, list2)
|
19
19
|
make_questions_stages_t(tab, list1, list2)
|
@@ -23,11 +23,13 @@ module AI
|
|
23
23
|
exclude_questions
|
24
24
|
end
|
25
25
|
|
26
|
+
# Make questions for states D and I
|
26
27
|
def make_questions_stages_di
|
27
28
|
@questions[:d] = StageD.new(self).run # Process every def{type=text}
|
28
29
|
@questions[:i] = StageI.new(self).run # Process every def{type=image_url}
|
29
30
|
end
|
30
31
|
|
32
|
+
# Make questions for stages B, S and F
|
31
33
|
def make_questions_stages_bsf(tab, list1, list2)
|
32
34
|
# Stage B: process table to make match questions
|
33
35
|
@questions[:b] += StageB.new(self).run(tab, list1, list2)
|
@@ -37,6 +39,7 @@ module AI
|
|
37
39
|
@questions[:f] += StageF.new(self).run(tab, list1, list2)
|
38
40
|
end
|
39
41
|
|
42
|
+
# Make questions for stage T
|
40
43
|
def make_questions_stages_t(tab, list1, list2)
|
41
44
|
# Stage T: process_tableXfields
|
42
45
|
list3 = list1 + list2
|
@@ -1,29 +1,39 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Methods that calculate something
|
4
|
-
module
|
5
|
-
|
4
|
+
module AICalculate
|
5
|
+
##
|
6
|
+
# Calculate and return list1 and list2
|
7
|
+
# * return list1 (Array) List with all the rows from the table
|
8
|
+
# * return list2 (Array) List with similar rows (same table name) from the neighbours tables
|
9
|
+
# @param p_table (Table)
|
10
|
+
# rubocop:disable Metrics/MethodLength
|
11
|
+
# rubocop:disable Metrics/AbcSize
|
12
|
+
def get_list1_and_list2_from(p_table)
|
6
13
|
# create <list1> with all the rows from the table
|
7
14
|
list1 = []
|
8
15
|
count = 1
|
9
|
-
|
16
|
+
p_table.rows.each do |i|
|
10
17
|
list1 << { id: count, weight: 0, data: i }
|
11
18
|
count += 1
|
12
19
|
end
|
13
20
|
|
14
21
|
# create a <list2> with similar rows (same table name) from the neighbours tables
|
15
22
|
list2 = []
|
16
|
-
neighbors.each do |n|
|
23
|
+
concept.neighbors.each do |n|
|
17
24
|
n[:concept].tables.each do |t2|
|
18
|
-
next if t2.name !=
|
25
|
+
next if t2.name != p_table.name
|
26
|
+
|
19
27
|
t2.rows.each do |i|
|
20
28
|
list2 << { id: count, weight: 0, data: i }
|
21
29
|
count += 1
|
22
30
|
end
|
23
31
|
end
|
24
32
|
end
|
25
|
-
|
33
|
+
[list1, list2]
|
26
34
|
end
|
35
|
+
# rubocop:enable Metrics/MethodLength
|
36
|
+
# rubocop:enable Metrics/AbcSize
|
27
37
|
|
28
38
|
def calculate_nearness_between_texts(text1, text2)
|
29
39
|
return 0.0 if text2.nil? || text2.empty?
|
@@ -34,6 +44,8 @@ module AI_calculate
|
|
34
44
|
(count * 100 / words.count)
|
35
45
|
end
|
36
46
|
|
47
|
+
# rubocop:disable Metrics/MethodLength
|
48
|
+
# rubocop:disable Metrics/AbcSize
|
37
49
|
def reorder_list_with_row(list, row)
|
38
50
|
# evaluate every row of the list2
|
39
51
|
list.each do |r|
|
@@ -52,4 +64,6 @@ module AI_calculate
|
|
52
64
|
list.sort! { |a, b| a[:weight] <=> b[:weight] }
|
53
65
|
list.reverse!
|
54
66
|
end
|
67
|
+
# rubocop:enable Metrics/MethodLength
|
68
|
+
# rubocop:enable Metrics/AbcSize
|
55
69
|
end
|
data/lib/asker/ai/concept_ai.rb
CHANGED
@@ -17,15 +17,21 @@ class ConceptAI
|
|
17
17
|
attr_reader :questions
|
18
18
|
attr_reader :excluded_questions
|
19
19
|
|
20
|
+
##
|
21
|
+
# Initialize ConcepAI
|
22
|
+
# @param concept (Concept)
|
23
|
+
# @param world (World)
|
20
24
|
def initialize(concept, world)
|
21
25
|
@concept = concept
|
22
26
|
@world = world
|
23
27
|
@questions = { d: [], b: [], f: [], i: [], s: [], t: [] }
|
24
28
|
@excluded_questions = { d: [], b: [], f: [], i: [], s: [], t: [] }
|
25
|
-
@num = 0 #
|
29
|
+
@num = 0 # Add a unique number to every question
|
26
30
|
make_questions
|
27
31
|
end
|
28
32
|
|
33
|
+
##
|
34
|
+
# Generates and return new "num" value
|
29
35
|
def num
|
30
36
|
@num += 1
|
31
37
|
@num.to_s
|
@@ -33,9 +39,12 @@ class ConceptAI
|
|
33
39
|
|
34
40
|
# If a method call is missing, then delegate to concept parent.
|
35
41
|
def method_missing(method, *args, &block)
|
42
|
+
raise "[DEBUG] ConceptAI.#{method}(#{args})"
|
36
43
|
@concept.send(method, *args, &block)
|
37
44
|
end
|
38
45
|
|
46
|
+
##
|
47
|
+
# Generates random image URL
|
39
48
|
def random_image_for(_conceptname)
|
40
49
|
return '' if rand <= Project.instance.get(:threshold)
|
41
50
|
|
@@ -45,6 +54,6 @@ class ConceptAI
|
|
45
54
|
return '' if values.nil?
|
46
55
|
|
47
56
|
values.shuffle!
|
48
|
-
"<img src=\"#{values[0]}\" alt
|
57
|
+
"<img src=\"#{values[0]}\" alt=\"image\"><br/>"
|
49
58
|
end
|
50
59
|
end
|
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
|