asker-tool 2.1.7 → 2.2.3
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 +14 -15
- 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 +12 -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 +90 -49
- data/lib/asker/ai/stages/stage_d.rb +69 -90
- data/lib/asker/ai/stages/stage_f.rb +47 -38
- 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 +7 -16
- data/lib/asker/check_input/check_haml_data.rb +264 -0
- data/lib/asker/check_input/check_table.rb +104 -0
- data/lib/asker/check_input.rb +51 -0
- data/lib/asker/cli.rb +47 -44
- data/lib/asker/data/code.rb +5 -16
- data/lib/asker/data/concept.rb +71 -24
- data/lib/asker/data/project_data.rb +63 -0
- data/lib/asker/data/table.rb +2 -0
- data/lib/asker/data/template.rb +3 -1
- data/lib/asker/data/world.rb +8 -16
- 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 +24 -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 +45 -0
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +6 -3
- data/lib/asker/exporter/concept_doc_exporter.rb +12 -2
- data/lib/asker/exporter/data_gift_exporter.rb +31 -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_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 +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 +12 -14
- 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 +1 -6
- data/lib/asker/loader/haml_loader.rb +9 -5
- data/lib/asker/loader/image_url_loader.rb +8 -9
- data/lib/asker/loader/input_loader.rb +5 -6
- data/lib/asker/loader/project_loader.rb +18 -10
- data/lib/asker/logger.rb +36 -9
- data/lib/asker/skeleton.rb +3 -2
- data/lib/asker/version.rb +9 -0
- data/lib/asker.rb +72 -43
- metadata +60 -18
- data/lib/asker/checker.rb +0 -455
- data/lib/asker/project.rb +0 -146
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04d190919a7d7b95571b648c9c265903acdeae0ca4b698139218de32cfe0ee3c
|
4
|
+
data.tar.gz: fcb0b10af1a109958c8ff04dde61ff484ffbed75443a41898b97b9d633d915f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 022d75e6c3d4a2fedb183e60d86d64ab3b6494decd2ca5e1e8741824947bc2e3dadc902e6f7543978666d1833a29b7305794b33a84bfcfc07da6139c95f3009f
|
7
|
+
data.tar.gz: 713a78b38a4155700ad1e11cb562638b43bbbc479d2ffa2ef9726befa1b5e6b49283795cd141aee5871a8dbd37e04652c51cd98c1e0489b0c8cfa429b2002c42
|
data/{LICENSE.txt → LICENSE}
RENAMED
File without changes
|
data/README.md
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/asker-tool.svg)](https://badge.fury.io/rb/asker-tool)
|
2
|
+
![GitHub](https://img.shields.io/github/license/dvarrui/asker)
|
3
|
+
![Gem](https://img.shields.io/gem/dv/asker-tool/2.2.1)
|
2
4
|
|
3
|
-
|
5
|
+
# ASKER (devel 2.3)
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
+
Generate a lot of questions from an _input_ text file with on your own _definitions_. In a way, this _input file_ is a concept map.
|
8
|
+
|
9
|
+
![logo](./docs/images/logo.png)
|
7
10
|
|
8
11
|
ASKER helps trainers to create a huge amount of questions, from a definitions (_conceptual entities_) input file.
|
9
12
|
|
@@ -11,32 +14,29 @@ ASKER helps trainers to create a huge amount of questions, from a definitions (_
|
|
11
14
|
* Multiplatform.
|
12
15
|
* Ruby program.
|
13
16
|
|
14
|
-
|
15
|
-
# Installation
|
17
|
+
## Installation
|
16
18
|
|
17
19
|
1. Install Ruby on your system.
|
18
20
|
2. `gem install asker-tool`
|
19
21
|
|
20
|
-
|
21
|
-
# Usage
|
22
|
+
## Usage
|
22
23
|
|
23
24
|
Steps:
|
24
25
|
|
25
26
|
1. Create an input file with your definitions (_conceptual entities_).
|
26
27
|
1. Run _asker_ and get the results into `output` directory.
|
27
28
|
|
28
|
-
Example: Running `asker` with our example input file as argument (`
|
29
|
+
Example: Running `asker` with our example input file as argument (`acdc.haml`):
|
29
30
|
|
30
31
|
```
|
31
|
-
asker docs/examples/
|
32
|
+
asker docs/examples/bands/acdc.haml
|
32
33
|
```
|
33
34
|
|
34
35
|
* Output files created into the `output` folder.
|
35
|
-
* More [example input files](
|
36
|
+
* More [example input files](./docs/examples).
|
36
37
|
* More asker input files at `github/dvarrui/asker-inputs` repository.
|
37
38
|
|
38
|
-
|
39
|
-
# Documentation
|
39
|
+
## Documentation
|
40
40
|
|
41
41
|
* [Installation](https://github.com/dvarrui/asker/blob/devel/docs/install/README.md)
|
42
42
|
* [Inputs](https://github.com/dvarrui/asker/blob/devel/docs/inputs/README.md)
|
@@ -45,8 +45,7 @@ asker docs/examples/starwars/jedi.haml
|
|
45
45
|
* [Base idea](https://github.com/dvarrui/asker/blob/devel/docs/idea.md)
|
46
46
|
* [History](https://github.com/dvarrui/asker/blob/devel/docs/history.md)
|
47
47
|
|
48
|
-
|
49
|
-
# Contact
|
48
|
+
## Contact
|
50
49
|
|
51
50
|
* **Email**: `teuton.software@protonmail.com`
|
52
51
|
* **Twitter**: `@SoftwareTeuton`
|
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,11 +39,14 @@ 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
|
-
return '' if rand <=
|
49
|
+
return '' if rand <= ProjectData.instance.get(:threshold)
|
41
50
|
|
42
51
|
keys = @world.image_urls.keys
|
43
52
|
keys.shuffle!
|
@@ -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,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'set'
|
4
4
|
|
@@ -6,82 +6,123 @@ require_relative 'base_stage'
|
|
6
6
|
require_relative '../question'
|
7
7
|
|
8
8
|
class StageB < BaseStage
|
9
|
+
##
|
9
10
|
# range b1
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
# Process table data to generate match questions
|
12
|
+
# @param table (Table)
|
13
|
+
# @param list1 (Array) Rows that belong to this table
|
14
|
+
# @param list2 (Array) List with similar rows (same table name) from the neighbours tables
|
15
|
+
def run(table, list1, list2)
|
13
16
|
questions = []
|
14
|
-
return questions if
|
17
|
+
return questions if table.fields.count < 2
|
15
18
|
|
16
|
-
return questions unless type == 'text'
|
19
|
+
return questions unless concept.type == 'text'
|
17
20
|
|
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(
|
21
|
+
if table.fields.count == 2
|
22
|
+
questions += process_table_match2fields(table, list1, list2, 0, 1)
|
23
|
+
elsif table.fields.count == 3
|
24
|
+
questions += process_table_match2fields(table, list1, list2, 0, 1)
|
25
|
+
questions += process_table_match2fields(table, list1, list2, 0, 2)
|
26
|
+
elsif table.fields.count == 4
|
27
|
+
questions += process_table_match2fields(table, list1, list2, 0, 1)
|
28
|
+
questions += process_table_match2fields(table, list1, list2, 0, 2)
|
29
|
+
questions += process_table_match2fields(table, list1, list2, 0, 3)
|
27
30
|
end
|
28
31
|
|
29
32
|
questions
|
30
33
|
end
|
34
|
+
# rubocop:enable Metrics/AbcSize
|
35
|
+
# rubocop:enable Metrics/MethodLength
|
31
36
|
|
32
|
-
|
37
|
+
##
|
38
|
+
# Process table data to generate match questions
|
39
|
+
# @param p_table (Table)
|
40
|
+
# @param list1 (Array) Rows that belong to this table
|
41
|
+
# @param list2 (Array) List with similar rows (same table name) from the neighbours tables
|
42
|
+
# @param index1 (Integer) Use this field number
|
43
|
+
# @param index2 (Integer) Use this field number
|
44
|
+
def process_table_match2fields(p_table, list1, list2, index1, index2)
|
33
45
|
questions = []
|
46
|
+
lang = concept.lang
|
34
47
|
|
35
|
-
if
|
36
|
-
|
37
|
-
e = [
|
48
|
+
if list1.count > 3
|
49
|
+
list1.each_cons(4) do |e1, e2, e3, e4|
|
50
|
+
e = [e1, e2, e3, e4]
|
38
51
|
|
39
|
-
#Question type <b1match>: match 4 items from the same table
|
52
|
+
# Question type <b1match>: match 4 items from the same table
|
40
53
|
e.shuffle!
|
41
|
-
q=Question.new(:match)
|
42
|
-
q.name="#{name}-#{num
|
43
|
-
q.
|
44
|
-
q.
|
45
|
-
q.
|
46
|
-
|
47
|
-
q.matching << [
|
54
|
+
q = Question.new(:match)
|
55
|
+
q.name = "#{name}-#{num}-b1match4x4-#{p_table.name}"
|
56
|
+
q.tags << 'match'
|
57
|
+
q.tags << 'random'
|
58
|
+
q.text = random_image_for(name) \
|
59
|
+
+ lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
|
60
|
+
q.matching << [e[0][:data][index1], e[0][:data][index2]]
|
61
|
+
q.matching << [e[1][:data][index1], e[1][:data][index2]]
|
62
|
+
q.matching << [e[2][:data][index1], e[2][:data][index2]]
|
63
|
+
q.matching << [e[3][:data][index1], e[3][:data][index2]]
|
64
|
+
# Add an extra line
|
65
|
+
if list2.count.positive?
|
66
|
+
q.matching << ['', list2[0][:data][index2]]
|
67
|
+
else
|
68
|
+
q.tags << 'misspell'
|
69
|
+
q.matching << ['', lang.do_mistake_to(e[0][:data][index2])]
|
70
|
+
end
|
48
71
|
questions << q
|
49
72
|
|
50
73
|
# Question type <b1match>: match 3 items from table-A and 1 item with error
|
51
74
|
e.shuffle!
|
52
|
-
q=Question.new(:match)
|
53
|
-
q.name="#{name}-#{num
|
54
|
-
q.
|
55
|
-
q.
|
56
|
-
q.
|
57
|
-
|
58
|
-
q.matching << [
|
75
|
+
q = Question.new(:match)
|
76
|
+
q.name = "#{name}-#{num}-b1match3x1misspelled-#{p_table.name}"
|
77
|
+
q.tags << 'match'
|
78
|
+
q.tags << 'random'
|
79
|
+
q.text = random_image_for(name) \
|
80
|
+
+ lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
|
81
|
+
q.matching << [e[0][:data][index1], e[0][:data][index2]]
|
82
|
+
q.matching << [e[1][:data][index1], e[1][:data][index2]]
|
83
|
+
q.matching << [e[2][:data][index1], e[2][:data][index2]]
|
84
|
+
q.matching << [lang.do_mistake_to(e[3][:data][index1]), lang.text_for(:misspelling)]
|
85
|
+
# Add an extra line
|
86
|
+
if list2.count.positive?
|
87
|
+
q.matching << ['', list2[0][:data][index2]]
|
88
|
+
else
|
89
|
+
q.tags << 'misspell'
|
90
|
+
q.matching << ['', lang.do_mistake_to(e[0][:data][index2])]
|
91
|
+
end
|
59
92
|
questions << q
|
60
93
|
end
|
61
94
|
end
|
62
95
|
|
63
|
-
if
|
64
|
-
s=Set.new
|
65
|
-
|
66
|
-
s.add(
|
96
|
+
if list1.count > 2 && list2.count.positive?
|
97
|
+
s = Set.new
|
98
|
+
list1.each do |i|
|
99
|
+
s.add(i[:data][index1] + '<=>' + i[:data][index2])
|
67
100
|
end
|
68
|
-
s.add(
|
69
|
-
a=s.to_a
|
101
|
+
s.add(list2[0][:data][index1] + '<=>' + list2[0][:data][index2])
|
70
102
|
|
71
103
|
# Question 3 items from table-A, and 1 item from table-B
|
72
104
|
if s.count > 3
|
73
|
-
q=Question.new(:match)
|
74
|
-
q.name="#{name}-#{num
|
75
|
-
q.
|
76
|
-
q.
|
77
|
-
q.
|
78
|
-
|
79
|
-
q.matching << [
|
105
|
+
q = Question.new(:match)
|
106
|
+
q.name = "#{name}-#{num}-b1match3x1-#{p_table.name}"
|
107
|
+
q.tags << 'match'
|
108
|
+
q.tags << 'random'
|
109
|
+
q.text = random_image_for(name) \
|
110
|
+
+ lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
|
111
|
+
q.matching << [list1[0][:data][index1], list1[0][:data][index2]]
|
112
|
+
q.matching << [list1[1][:data][index1], list1[1][:data][index2]]
|
113
|
+
q.matching << [list1[2][:data][index1], list1[2][:data][index2]]
|
114
|
+
q.matching << [list2[0][:data][index1], lang.text_for(:error)]
|
115
|
+
q.matching << ['', lang.do_mistake_to(list1[0][:data][index2])]
|
80
116
|
questions << q
|
81
117
|
end
|
82
118
|
end
|
83
119
|
|
84
|
-
|
120
|
+
questions
|
85
121
|
end
|
86
|
-
|
122
|
+
# rubocop:enable Metrics/AbcSize
|
123
|
+
# rubocop:enable Metrics/MethodLength
|
124
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
125
|
+
# rubocop:enable Style/ConditionalAssignment
|
126
|
+
# rubocop:enable Metrics/BlockLength
|
127
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
87
128
|
end
|