asker-tool 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/README.md +53 -0
- data/bin/asker +4 -0
- data/docs/changelog/v2.1.md +99 -0
- data/docs/commands.md +15 -0
- data/docs/contributions.md +18 -0
- data/docs/history.md +40 -0
- data/docs/idea.md +44 -0
- data/docs/inputs/README.md +39 -0
- data/docs/inputs/code.md +69 -0
- data/docs/inputs/concepts.md +142 -0
- data/docs/inputs/jedi.md +68 -0
- data/docs/inputs/tables.md +112 -0
- data/docs/inputs/templates.md +87 -0
- data/docs/install/README.md +38 -0
- data/docs/install/manual.md +26 -0
- data/docs/install/scripts.md +26 -0
- data/docs/revise/asker-file.md +41 -0
- data/docs/revise/buenas-practicas/01-convocatoria.md +30 -0
- data/docs/revise/buenas-practicas/02-formulario.md +35 -0
- data/docs/revise/buenas-practicas/03-descripcion.md +63 -0
- data/docs/revise/buenas-practicas/04-resultados.md +17 -0
- data/docs/revise/buenas-practicas/05-reproducir.md +10 -0
- data/docs/revise/ejemplos/01/README.md +27 -0
- data/docs/revise/ejemplos/02/README.md +31 -0
- data/docs/revise/ejemplos/03/README.md +31 -0
- data/docs/revise/ejemplos/04/README.md +37 -0
- data/docs/revise/ejemplos/05/README.md +25 -0
- data/docs/revise/ejemplos/06/README.md +43 -0
- data/docs/revise/ejemplos/README.md +11 -0
- data/docs/revise/projects.md +74 -0
- data/lib/asker.rb +103 -0
- data/lib/asker/ai/ai.rb +70 -0
- data/lib/asker/ai/ai_calculate.rb +55 -0
- data/lib/asker/ai/concept_ai.rb +49 -0
- data/lib/asker/ai/question.rb +58 -0
- data/lib/asker/ai/stages/base_stage.rb +16 -0
- data/lib/asker/ai/stages/main.rb +8 -0
- data/lib/asker/ai/stages/stage_b.rb +87 -0
- data/lib/asker/ai/stages/stage_d.rb +160 -0
- data/lib/asker/ai/stages/stage_f.rb +156 -0
- data/lib/asker/ai/stages/stage_i.rb +140 -0
- data/lib/asker/ai/stages/stage_s.rb +52 -0
- data/lib/asker/ai/stages/stage_t.rb +170 -0
- data/lib/asker/application.rb +30 -0
- data/lib/asker/checker.rb +356 -0
- data/lib/asker/cli.rb +85 -0
- data/lib/asker/code/ai/base_code_ai.rb +48 -0
- data/lib/asker/code/ai/code_ai_factory.rb +26 -0
- data/lib/asker/code/ai/javascript_code_ai.rb +167 -0
- data/lib/asker/code/ai/python_code_ai.rb +167 -0
- data/lib/asker/code/ai/ruby_code_ai.rb +169 -0
- data/lib/asker/code/ai/sql_code_ai.rb +69 -0
- data/lib/asker/code/code.rb +53 -0
- data/lib/asker/data/column.rb +62 -0
- data/lib/asker/data/concept.rb +183 -0
- data/lib/asker/data/data_field.rb +87 -0
- data/lib/asker/data/row.rb +93 -0
- data/lib/asker/data/table.rb +96 -0
- data/lib/asker/data/template.rb +65 -0
- data/lib/asker/data/world.rb +53 -0
- data/lib/asker/exporter/code_gift_exporter.rb +35 -0
- data/lib/asker/exporter/code_screen_exporter.rb +45 -0
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +33 -0
- data/lib/asker/exporter/concept_ai_screen_exporter.rb +115 -0
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +33 -0
- data/lib/asker/exporter/concept_doc_exporter.rb +21 -0
- data/lib/asker/exporter/concept_screen_exporter.rb +25 -0
- data/lib/asker/exporter/main.rb +9 -0
- data/lib/asker/files/config.ini +40 -0
- data/lib/asker/formatter/code_string_formatter.rb +16 -0
- data/lib/asker/formatter/concept_doc_formatter.rb +37 -0
- data/lib/asker/formatter/concept_string_formatter.rb +66 -0
- data/lib/asker/formatter/question_gift_formatter.rb +65 -0
- data/lib/asker/formatter/question_hash_formatter.rb +40 -0
- data/lib/asker/formatter/question_moodlexml_formatter.rb +71 -0
- data/lib/asker/formatter/rb2haml_formatter.rb +26 -0
- data/lib/asker/lang/lang.rb +42 -0
- data/lib/asker/lang/lang_factory.rb +19 -0
- data/lib/asker/lang/text_actions.rb +150 -0
- data/lib/asker/loader/code_loader.rb +53 -0
- data/lib/asker/loader/content_loader.rb +101 -0
- data/lib/asker/loader/directory_loader.rb +58 -0
- data/lib/asker/loader/file_loader.rb +33 -0
- data/lib/asker/loader/image_url_loader.rb +61 -0
- data/lib/asker/loader/input_loader.rb +24 -0
- data/lib/asker/loader/project_loader.rb +71 -0
- data/lib/asker/logger.rb +21 -0
- data/lib/asker/project.rb +170 -0
- metadata +261 -0
data/lib/asker/ai/ai.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'stages/main'
|
4
|
+
require_relative 'ai_calculate'
|
5
|
+
|
6
|
+
# Description: Method to be included into every ConceptAI instance.
|
7
|
+
# * make_questions: use AI to fill @questions Array
|
8
|
+
module AI
|
9
|
+
include AI_calculate
|
10
|
+
|
11
|
+
def make_questions
|
12
|
+
return unless process?
|
13
|
+
|
14
|
+
make_questions_stages_di
|
15
|
+
# Process every table of this concept
|
16
|
+
tables.each do |tab|
|
17
|
+
list1, list2 = get_list1_and_list2_from(tab)
|
18
|
+
make_questions_stages_bsf(tab, list1, list2)
|
19
|
+
make_questions_stages_t(tab, list1, list2)
|
20
|
+
end
|
21
|
+
# -------------------------------------------------------
|
22
|
+
# Exclude questions as is defined into config.ini params
|
23
|
+
exclude_questions
|
24
|
+
end
|
25
|
+
|
26
|
+
def make_questions_stages_di
|
27
|
+
@questions[:d] = StageD.new(self).run # Process every def{type=text}
|
28
|
+
@questions[:i] = StageI.new(self).run # Process every def{type=image_url}
|
29
|
+
end
|
30
|
+
|
31
|
+
def make_questions_stages_bsf(tab, list1, list2)
|
32
|
+
# Stage B: process table to make match questions
|
33
|
+
@questions[:b] += StageB.new(self).run(tab, list1, list2)
|
34
|
+
# Stage S: process tables with sequences
|
35
|
+
@questions[:s] += StageS.new(self).run(tab, list1, list2)
|
36
|
+
# Stage F: process tables with only 1 field
|
37
|
+
@questions[:f] += StageF.new(self).run(tab, list1, list2)
|
38
|
+
end
|
39
|
+
|
40
|
+
def make_questions_stages_t(tab, list1, list2)
|
41
|
+
# Stage T: process_tableXfields
|
42
|
+
list3 = list1 + list2
|
43
|
+
list1.each do |row|
|
44
|
+
reorder_list_with_row(list3, row)
|
45
|
+
@questions[:t] += StageT.new(self).run(tab, row, list3)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def exclude_questions
|
50
|
+
param = Application.instance.config['questions']['exclude']
|
51
|
+
return if param.nil?
|
52
|
+
|
53
|
+
tags = param.split(',').each(&:strip!)
|
54
|
+
input = { d: [], b: [], f: [], i: [], s: [], t: [] }
|
55
|
+
output = { d: [], b: [], f: [], i: [], s: [], t: [] }
|
56
|
+
|
57
|
+
@questions.each_pair do |key, qlist|
|
58
|
+
output[key] = qlist.select { |q| string_has_this_tags?(q.name, tags) }
|
59
|
+
input[key] = @questions[key] - output[key]
|
60
|
+
end
|
61
|
+
@questions = input
|
62
|
+
@excluded_questions = output
|
63
|
+
end
|
64
|
+
|
65
|
+
def string_has_this_tags?(input, tags)
|
66
|
+
flag = false
|
67
|
+
tags.each { |e| flag = true if input.include? e }
|
68
|
+
flag
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Methods that calculate something
|
4
|
+
module AI_calculate
|
5
|
+
def get_list1_and_list2_from(ltable)
|
6
|
+
# create <list1> with all the rows from the table
|
7
|
+
list1 = []
|
8
|
+
count = 1
|
9
|
+
ltable.rows.each do |i|
|
10
|
+
list1 << { id: count, weight: 0, data: i }
|
11
|
+
count += 1
|
12
|
+
end
|
13
|
+
|
14
|
+
# create a <list2> with similar rows (same table name) from the neighbours tables
|
15
|
+
list2 = []
|
16
|
+
neighbors.each do |n|
|
17
|
+
n[:concept].tables.each do |t2|
|
18
|
+
next if t2.name != ltable.name
|
19
|
+
t2.rows.each do |i|
|
20
|
+
list2 << { id: count, weight: 0, data: i }
|
21
|
+
count += 1
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
return list1, list2
|
26
|
+
end
|
27
|
+
|
28
|
+
def calculate_nearness_between_texts(text1, text2)
|
29
|
+
return 0.0 if text2.nil? || text2.empty?
|
30
|
+
|
31
|
+
words = text1.split(' ')
|
32
|
+
count = 0
|
33
|
+
words.each { |w| count += 1 if text2.include?(w) }
|
34
|
+
(count * 100 / words.count)
|
35
|
+
end
|
36
|
+
|
37
|
+
def reorder_list_with_row(list, row)
|
38
|
+
# evaluate every row of the list2
|
39
|
+
list.each do |r|
|
40
|
+
if r[:id] == row[:id]
|
41
|
+
r[:weight] = -300
|
42
|
+
else
|
43
|
+
val = 0
|
44
|
+
s = row[:data].count
|
45
|
+
s.times do |i|
|
46
|
+
val += calculate_nearness_between_texts(row[:data][i], r[:data][i])
|
47
|
+
end
|
48
|
+
val /= s
|
49
|
+
r[:weight] = val
|
50
|
+
end
|
51
|
+
end
|
52
|
+
list.sort! { |a, b| a[:weight] <=> b[:weight] }
|
53
|
+
list.reverse!
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../lang/lang'
|
4
|
+
require_relative 'ai'
|
5
|
+
require_relative 'question'
|
6
|
+
|
7
|
+
# ConceptAI: Add more info to every Concept instance.
|
8
|
+
# Encapsulating AI data => questions
|
9
|
+
# * concept
|
10
|
+
# * questions
|
11
|
+
# * num
|
12
|
+
# * random_image_for
|
13
|
+
class ConceptAI
|
14
|
+
include AI
|
15
|
+
|
16
|
+
attr_reader :concept
|
17
|
+
attr_reader :questions
|
18
|
+
attr_reader :excluded_questions
|
19
|
+
|
20
|
+
def initialize(concept, world)
|
21
|
+
@concept = concept
|
22
|
+
@world = world
|
23
|
+
@questions = { d: [], b: [], f: [], i: [], s: [], t: [] }
|
24
|
+
@excluded_questions = { d: [], b: [], f: [], i: [], s: [], t: [] }
|
25
|
+
@num = 0 # Used to add a unique number to every question
|
26
|
+
end
|
27
|
+
|
28
|
+
def num
|
29
|
+
@num += 1
|
30
|
+
@num.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
# If a method call is missing, then delegate to concept parent.
|
34
|
+
def method_missing(method, *args, &block)
|
35
|
+
@concept.send(method, *args, &block)
|
36
|
+
end
|
37
|
+
|
38
|
+
def random_image_for(_conceptname)
|
39
|
+
return '' if rand <= Project.instance.get(:threshold)
|
40
|
+
|
41
|
+
keys = @world.image_urls.keys
|
42
|
+
keys.shuffle!
|
43
|
+
values = @world.image_urls[keys[0]] # keys[0] could be conceptname
|
44
|
+
return '' if values.nil?
|
45
|
+
|
46
|
+
values.shuffle!
|
47
|
+
"<img src=\"#{values[0]}\" alt\=\"image\"><br/>"
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
# Define Question class
|
5
|
+
class Question
|
6
|
+
attr_accessor :name, :comment, :text
|
7
|
+
attr_accessor :good, :bads, :matching, :shorts
|
8
|
+
attr_accessor :feedback
|
9
|
+
attr_reader :type
|
10
|
+
attr_accessor :tags, :lang
|
11
|
+
|
12
|
+
def initialize(type = :choice)
|
13
|
+
reset(type)
|
14
|
+
end
|
15
|
+
|
16
|
+
def reset(type = :choice)
|
17
|
+
@name = ''
|
18
|
+
@comment = ''
|
19
|
+
@text = ''
|
20
|
+
@type = type
|
21
|
+
@good = ''
|
22
|
+
@bads = []
|
23
|
+
@matching = []
|
24
|
+
@shorts = []
|
25
|
+
@feedback = nil
|
26
|
+
shuffle_on
|
27
|
+
@tags = Set.new
|
28
|
+
@lang = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def set_choice
|
32
|
+
@type = :choice
|
33
|
+
end
|
34
|
+
|
35
|
+
def set_match
|
36
|
+
@type = :match
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_boolean
|
40
|
+
@type = :boolean
|
41
|
+
end
|
42
|
+
|
43
|
+
def set_short
|
44
|
+
@type = :short
|
45
|
+
end
|
46
|
+
|
47
|
+
def shuffle_off
|
48
|
+
@shuffle = false
|
49
|
+
end
|
50
|
+
|
51
|
+
def shuffle_on
|
52
|
+
@shuffle = true
|
53
|
+
end
|
54
|
+
|
55
|
+
def shuffle?
|
56
|
+
@shuffle
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
class BaseStage
|
3
|
+
def initialize(concept_ai)
|
4
|
+
@concept_ai = concept_ai
|
5
|
+
end
|
6
|
+
|
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
|
+
def run
|
14
|
+
raise 'Implement run method!'
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
require_relative 'base_stage'
|
6
|
+
require_relative '../question'
|
7
|
+
|
8
|
+
class StageB < BaseStage
|
9
|
+
# range b1
|
10
|
+
|
11
|
+
def run(pTable, pList1, pList2)
|
12
|
+
# process table match
|
13
|
+
questions = []
|
14
|
+
return questions if pTable.fields.count < 2
|
15
|
+
|
16
|
+
return questions unless type == 'text'
|
17
|
+
|
18
|
+
if pTable.fields.count>1 then
|
19
|
+
questions += process_table_match2fields(pTable, pList1, pList2, 0, 1)
|
20
|
+
elsif pTable.fields.count>2 then
|
21
|
+
questions += process_table_match2fields(pTable, pList1, pList2, 0, 2)
|
22
|
+
questions += process_table_match2fields(pTable, pList1, pList2, 1, 2)
|
23
|
+
elsif pTable.fields.count>3 then
|
24
|
+
questions += process_table_match2fields(pTable, pList1, pList2, 0, 3)
|
25
|
+
questions += process_table_match2fields(pTable, pList1, pList2, 1, 3)
|
26
|
+
questions += process_table_match2fields(pTable, pList1, pList2, 2, 3)
|
27
|
+
end
|
28
|
+
|
29
|
+
questions
|
30
|
+
end
|
31
|
+
|
32
|
+
def process_table_match2fields(pTable, pList1, pList2, pIndex1, pIndex2)
|
33
|
+
questions = []
|
34
|
+
|
35
|
+
if pList1.count>3
|
36
|
+
pList1.each_cons(4) do |e1,e2,e3,e4|
|
37
|
+
e = [ e1, e2, e3, e4 ]
|
38
|
+
|
39
|
+
#Question type <b1match>: match 4 items from the same table
|
40
|
+
e.shuffle!
|
41
|
+
q=Question.new(:match)
|
42
|
+
q.name="#{name}-#{num.to_s}-b1match4x4-#{pTable.name}"
|
43
|
+
q.text= random_image_for(name) + lang.text_for(:b1, name, pTable.fields[pIndex1].capitalize, pTable.fields[pIndex2].capitalize )
|
44
|
+
q.matching << [ e[0][:data][pIndex1], e[0][:data][pIndex2] ]
|
45
|
+
q.matching << [ e[1][:data][pIndex1], e[1][:data][pIndex2] ]
|
46
|
+
q.matching << [ e[2][:data][pIndex1], e[2][:data][pIndex2] ]
|
47
|
+
q.matching << [ e[3][:data][pIndex1], e[3][:data][pIndex2] ]
|
48
|
+
questions << q
|
49
|
+
|
50
|
+
# Question type <b1match>: match 3 items from table-A and 1 item with error
|
51
|
+
e.shuffle!
|
52
|
+
q=Question.new(:match)
|
53
|
+
q.name="#{name}-#{num.to_s}-b1match3x1misspelled-#{pTable.name}"
|
54
|
+
q.text= random_image_for(name) + lang.text_for(:b1, name, pTable.fields[pIndex1].capitalize, pTable.fields[pIndex2].capitalize )
|
55
|
+
q.matching << [ e[0][:data][pIndex1], e[0][:data][pIndex2] ]
|
56
|
+
q.matching << [ e[1][:data][pIndex1], e[1][:data][pIndex2] ]
|
57
|
+
q.matching << [ e[2][:data][pIndex1], e[2][:data][pIndex2] ]
|
58
|
+
q.matching << [ lang.do_mistake_to(e[3][:data][pIndex1]), lang.text_for(:misspelling) ]
|
59
|
+
questions << q
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
if pList1.count>2 and pList2.count>0
|
64
|
+
s=Set.new
|
65
|
+
pList1.each do |i|
|
66
|
+
s.add( i[:data][pIndex1]+"<=>"+i[:data][pIndex2] )
|
67
|
+
end
|
68
|
+
s.add( pList2[0][:data][pIndex1]+"<=>"+pList2[0][:data][pIndex2] )
|
69
|
+
a=s.to_a
|
70
|
+
|
71
|
+
# Question 3 items from table-A, and 1 item from table-B
|
72
|
+
if s.count > 3
|
73
|
+
q=Question.new(:match)
|
74
|
+
q.name="#{name}-#{num.to_s}-b1match3x1-#{pTable.name}"
|
75
|
+
q.text= random_image_for(name) + lang.text_for(:b1, name , pTable.fields[pIndex1].capitalize, pTable.fields[pIndex2].capitalize)
|
76
|
+
q.matching << [ pList1[0][:data][pIndex1], pList1[0][:data][pIndex2] ]
|
77
|
+
q.matching << [ pList1[1][:data][pIndex1], pList1[1][:data][pIndex2] ]
|
78
|
+
q.matching << [ pList1[2][:data][pIndex1], pList1[2][:data][pIndex2] ]
|
79
|
+
q.matching << [ pList2[0][:data][pIndex1], lang.text_for(:error) ]
|
80
|
+
questions << q
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
return questions
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
require_relative 'base_stage'
|
6
|
+
require_relative '../question'
|
7
|
+
|
8
|
+
class StageD < BaseStage
|
9
|
+
# range d1-d4
|
10
|
+
|
11
|
+
def run
|
12
|
+
# Stage D: process every definition, I mean every <def> tag
|
13
|
+
questions = []
|
14
|
+
return questions unless type == 'text'
|
15
|
+
|
16
|
+
# 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
|
21
|
+
|
22
|
+
# Question choose between 4 options
|
23
|
+
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)
|
28
|
+
q.bads << lang.text_for(:none)
|
29
|
+
q.bads << a[2]
|
30
|
+
q.bads << a[3]
|
31
|
+
questions << q
|
32
|
+
end
|
33
|
+
|
34
|
+
#Question choose between 4 options, good none (Syntax error)
|
35
|
+
if s.count>3 and type=="text" then
|
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)
|
39
|
+
q.good = lang.text_for(:none)
|
40
|
+
q.bads << lang.do_mistake_to(name(:raw))
|
41
|
+
q.bads << a[2]
|
42
|
+
q.bads << a[3]
|
43
|
+
q.feedback="Option misspelled!: #{name(:raw)}"
|
44
|
+
questions << q
|
45
|
+
end
|
46
|
+
|
47
|
+
s.delete(name(:raw))
|
48
|
+
a=s.to_a
|
49
|
+
|
50
|
+
#Question choose between 4 options, good none
|
51
|
+
if s.count>3 then
|
52
|
+
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)
|
56
|
+
q.bads << a[1]
|
57
|
+
q.bads << a[2]
|
58
|
+
q.bads << a[3]
|
59
|
+
questions << q
|
60
|
+
end
|
61
|
+
|
62
|
+
#Question boolean => TRUE
|
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
|
+
|
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)
|
73
|
+
q.bads << lang.text_for(:true)
|
74
|
+
q.bads << lang.text_for(:false)
|
75
|
+
q.feedback="Definition text mispelled!: #{t}"
|
76
|
+
questions << q
|
77
|
+
|
78
|
+
if type=="text"
|
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
|
87
|
+
end
|
88
|
+
|
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 )
|
92
|
+
q.good = lang.text_for(:true)
|
93
|
+
q.bads << lang.text_for(:misspelling)
|
94
|
+
q.bads << lang.text_for(:false)
|
95
|
+
questions << q
|
96
|
+
|
97
|
+
if a.size>1 then
|
98
|
+
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)
|
101
|
+
q.good = lang.text_for(:false)
|
102
|
+
q.bads << lang.text_for(:misspelling)
|
103
|
+
q.bads << lang.text_for(:true)
|
104
|
+
questions << q
|
105
|
+
end
|
106
|
+
|
107
|
+
#Question type <a4desc>: boolean => FALSE
|
108
|
+
#if neighbors.count>0 then
|
109
|
+
# q = Question.new(:boolean)
|
110
|
+
# q.name="#{name}-#{num}-d2false"
|
111
|
+
# q.text=random_image_for(name) + lang.text_for(:d2, neighbors[0][:concept].name, t)
|
112
|
+
# q.good="FALSE"
|
113
|
+
# questions << q
|
114
|
+
#end
|
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
|
136
|
+
|
137
|
+
#Question filtered text questions
|
138
|
+
filtered=lang.text_with_connectors(t)
|
139
|
+
indexes = filtered[:indexes]
|
140
|
+
|
141
|
+
groups = (indexes.combination(4).to_a).shuffle
|
142
|
+
max = (indexes.size/4).to_i
|
143
|
+
groups[0,max].each do |e|
|
144
|
+
e.sort!
|
145
|
+
q = Question.new(:match)
|
146
|
+
q.shuffle_off
|
147
|
+
q.name = "#{name}-#{num}-d4filtered"
|
148
|
+
s = lang.build_text_from_filtered( filtered, e)
|
149
|
+
q.text = random_image_for(name(:raw)) + lang.text_for(:d4, name(:raw) , s)
|
150
|
+
e.each_with_index do |value,index|
|
151
|
+
q.matching << [ (index+1).to_s, filtered[:words][value][:word].downcase ]
|
152
|
+
end
|
153
|
+
questions << q
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
return questions
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|