asker-tool 2.5.9 → 2.7.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 +10 -7
- data/lib/asker/ai/ai.rb +17 -22
- data/lib/asker/ai/ai_calculate.rb +10 -17
- data/lib/asker/ai/code/base_code_ai.rb +5 -30
- data/lib/asker/ai/code/code_ai_factory.rb +6 -12
- data/lib/asker/ai/code/javascript_code_ai.rb +33 -34
- data/lib/asker/ai/code/python_code_ai.rb +35 -36
- data/lib/asker/ai/code/ruby_code_ai.rb +33 -33
- data/lib/asker/ai/code/sql_code_ai.rb +20 -21
- data/lib/asker/ai/concept_ai.rb +12 -22
- data/lib/asker/ai/problem/problem_ai.rb +226 -0
- data/lib/asker/ai/question.rb +34 -45
- data/lib/asker/ai/stages/base_stage.rb +7 -7
- data/lib/asker/ai/stages/main.rb +6 -7
- data/lib/asker/ai/stages/stage_b.rb +62 -28
- data/lib/asker/ai/stages/stage_d.rb +10 -10
- data/lib/asker/ai/stages/stage_f.rb +17 -17
- data/lib/asker/ai/stages/stage_i.rb +8 -18
- data/lib/asker/ai/stages/stage_s.rb +28 -26
- data/lib/asker/ai/stages/stage_t.rb +54 -76
- data/lib/asker/application.rb +15 -14
- data/lib/asker/check_input/check_haml_data.rb +57 -51
- data/lib/asker/check_input/check_table.rb +26 -19
- data/lib/asker/check_input.rb +10 -22
- data/lib/asker/cli.rb +43 -24
- data/lib/asker/data/code.rb +10 -9
- data/lib/asker/data/column.rb +21 -17
- data/lib/asker/data/concept.rb +24 -37
- data/lib/asker/data/data_field.rb +2 -2
- data/lib/asker/data/problem.rb +112 -0
- data/lib/asker/data/project_data.rb +11 -15
- data/lib/asker/data/row.rb +25 -23
- data/lib/asker/data/table.rb +25 -46
- data/lib/asker/data/template.rb +7 -7
- data/lib/asker/data/world.rb +3 -3
- data/lib/asker/{formatter → deprecated}/question_moodlexml_formatter.rb +19 -21
- data/lib/asker/displayer/code_displayer.rb +10 -10
- data/lib/asker/displayer/concept_ai_displayer.erb +1 -1
- data/lib/asker/displayer/concept_ai_displayer.rb +22 -34
- data/lib/asker/displayer/concept_displayer.rb +9 -11
- data/lib/asker/displayer/problem_displayer.rb +45 -0
- data/lib/asker/displayer/stats_displayer.rb +7 -12
- data/lib/asker/exporter/code_gift_exporter.rb +2 -2
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +4 -4
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +7 -7
- data/lib/asker/exporter/concept_doc_exporter.rb +5 -5
- data/lib/asker/exporter/data_gift_exporter.rb +14 -15
- data/lib/asker/exporter/data_moodle_exporter.rb +51 -20
- data/lib/asker/exporter/output_file_exporter.rb +9 -8
- data/lib/asker/exporter/problem_gift_exporter.rb +30 -0
- data/lib/asker/files/language/ca/templates.yaml +6 -0
- data/lib/asker/files/language/du/templates.yaml +6 -0
- data/lib/asker/files/language/en/templates.yaml +7 -1
- data/lib/asker/files/language/es/templates.yaml +6 -0
- data/lib/asker/files/language/fr/templates.yaml +6 -0
- data/lib/asker/formatter/code_string_formatter.rb +5 -5
- data/lib/asker/formatter/concept_doc_formatter.rb +3 -3
- data/lib/asker/formatter/concept_string_formatter.rb +27 -24
- data/lib/asker/formatter/moodle/ddmatch.erb +40 -0
- data/lib/asker/formatter/moodle/gapfill.erb +57 -0
- data/lib/asker/formatter/moodle/ordering.erb +41 -0
- data/lib/asker/formatter/question_gift_formatter.rb +41 -14
- data/lib/asker/formatter/question_hash_formatter.rb +5 -6
- data/lib/asker/formatter/question_moodle_formatter.rb +14 -7
- data/lib/asker/formatter/rb2haml_formatter.rb +8 -7
- data/lib/asker/lang/lang.rb +16 -16
- data/lib/asker/lang/lang_factory.rb +13 -16
- data/lib/asker/lang/text_actions.rb +20 -18
- data/lib/asker/loader/code_loader.rb +10 -22
- data/lib/asker/loader/content_loader.rb +42 -49
- data/lib/asker/loader/directory_loader.rb +13 -16
- data/lib/asker/loader/embedded_file.rb +29 -24
- data/lib/asker/loader/file_loader.rb +7 -6
- data/lib/asker/loader/haml_loader.rb +6 -5
- data/lib/asker/loader/image_url_loader.rb +21 -18
- data/lib/asker/loader/input_loader.rb +27 -14
- data/lib/asker/loader/problem_loader.rb +88 -0
- data/lib/asker/loader/project_loader.rb +11 -28
- data/lib/asker/logger.rb +22 -13
- data/lib/asker/skeleton.rb +27 -43
- data/lib/asker/start.rb +44 -0
- data/lib/asker/version.rb +1 -1
- data/lib/asker.rb +7 -53
- metadata +12 -20
- data/lib/asker/ai/code/problem_code_ai.rb +0 -176
- data/lib/asker/exporter/code_moodle_exporter.rb +0 -15
- data/lib/asker/exporter/concept_ai_moodle_exporter.rb +0 -15
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
require_relative "../logger"
|
|
2
|
+
|
|
3
|
+
class Problem
|
|
4
|
+
attr_accessor :lang
|
|
5
|
+
attr_accessor :context
|
|
6
|
+
attr_accessor :process
|
|
7
|
+
attr_accessor :filename
|
|
8
|
+
attr_accessor :varnames
|
|
9
|
+
attr_accessor :cases
|
|
10
|
+
attr_accessor :descs
|
|
11
|
+
attr_accessor :asks
|
|
12
|
+
attr_accessor :questions
|
|
13
|
+
|
|
14
|
+
@@id = 0
|
|
15
|
+
def initialize
|
|
16
|
+
@@id += 1
|
|
17
|
+
@id = @@id
|
|
18
|
+
@lang = nil
|
|
19
|
+
@context = nil
|
|
20
|
+
@process = false
|
|
21
|
+
@filename = "?"
|
|
22
|
+
@varnames = []
|
|
23
|
+
@cases = []
|
|
24
|
+
@descs = []
|
|
25
|
+
@asks = []
|
|
26
|
+
@questions = []
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.from(values)
|
|
30
|
+
problem = Problem.new
|
|
31
|
+
fields = %i[filename varnames cases descs asks]
|
|
32
|
+
fields.each do |fieldname|
|
|
33
|
+
methodname = "#{fieldname}=".to_sym
|
|
34
|
+
problem.send(methodname, values[fieldname])
|
|
35
|
+
end
|
|
36
|
+
problem.validate
|
|
37
|
+
problem
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def desc
|
|
41
|
+
@descs.first
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def process?
|
|
45
|
+
@process
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def name
|
|
49
|
+
"problem#{@id}"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def validate
|
|
53
|
+
validate_varnames
|
|
54
|
+
validate_cases
|
|
55
|
+
validate_asks
|
|
56
|
+
validate_descs
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def validate_varnames
|
|
62
|
+
if !@varnames.size.zero? && @cases.size.zero?
|
|
63
|
+
Logger.warn "Problem: No problem/varnames defined with no problem/case"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
@varnames.each_with_index do |varname1, index1|
|
|
67
|
+
@varnames.each_with_index do |varname2, index2|
|
|
68
|
+
next if index1 == index2
|
|
69
|
+
if varname1.include? varname2
|
|
70
|
+
Logger.error "Problem: varname(#{varname1}) includes varname(#{varname2}). Change one of them!"
|
|
71
|
+
exit 1
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def validate_cases
|
|
78
|
+
@cases.each do |acase|
|
|
79
|
+
if acase.size != @varnames.size
|
|
80
|
+
Logger.error "Problem: problem/cases size not equal to problem/varnames size"
|
|
81
|
+
Logger.error " : cases size #{acase.size} (#{acase.join(",")})"
|
|
82
|
+
Logger.error " : varnames size #{@varnames.size} (#{@varnames.join(",")})"
|
|
83
|
+
exit 1
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def validate_asks
|
|
89
|
+
if @asks.size.zero?
|
|
90
|
+
Logger.warn "Problem: No problem/ask"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
@asks.each do |ask|
|
|
94
|
+
Logger.warn "Problem: No problem/ask/text" if ask[:text].nil?
|
|
95
|
+
if ask[:answer].nil? && ask[:steps].size.zero?
|
|
96
|
+
Logger.error "Problem: No problem/ask/answer and no problem/ask/steps"
|
|
97
|
+
exit 1
|
|
98
|
+
end
|
|
99
|
+
if !ask[:answer].nil? && !ask[:steps].size.zero?
|
|
100
|
+
Logger.error "Problem: Choose problem/ask/answer or problem/ask/steps"
|
|
101
|
+
exit 1
|
|
102
|
+
end
|
|
103
|
+
if ask[:steps].size > 0 && ask[:steps].size < 4
|
|
104
|
+
Logger.warn "Problem: problem/ask/steps less than 4"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def validate_descs
|
|
110
|
+
# require "debug"; binding.break
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "singleton"
|
|
4
4
|
|
|
5
5
|
class ProjectData
|
|
6
6
|
include Singleton
|
|
@@ -11,11 +11,11 @@ class ProjectData
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def reset
|
|
14
|
-
@default = {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
@default = {inputbasedir: FileUtils.pwd,
|
|
15
|
+
stages: {d: true, b: true, f: true, i: true, s: true, t: true},
|
|
16
|
+
threshold: 0.5,
|
|
17
|
+
outputdir: "output",
|
|
18
|
+
weights: "1, 1, 1"}
|
|
19
19
|
@param = {}
|
|
20
20
|
end
|
|
21
21
|
|
|
@@ -36,17 +36,15 @@ class ProjectData
|
|
|
36
36
|
# IMPORTANT: We need at least these values
|
|
37
37
|
# * process_file
|
|
38
38
|
# * inputdirs
|
|
39
|
-
# rubocop:disable Metrics/MethodLength
|
|
40
|
-
# rubocop:disable Metrics/AbcSize
|
|
41
39
|
def open
|
|
42
|
-
ext = File.extname(@param[:process_file]) ||
|
|
40
|
+
ext = File.extname(@param[:process_file]) || ".haml"
|
|
43
41
|
@param[:projectname] = @param[:projectname] ||
|
|
44
|
-
|
|
42
|
+
File.basename(@param[:process_file], ext)
|
|
45
43
|
|
|
46
|
-
@param[:logname] = "#{@param[:projectname]}
|
|
44
|
+
@param[:logname] = "#{@param[:projectname]}.log"
|
|
47
45
|
@param[:outputname] = "#{@param[:projectname]}-gift.txt"
|
|
48
|
-
@param[:lessonname] = "#{@param[:projectname]}
|
|
49
|
-
@param[:yamlname] = "#{@param[:projectname]}.yaml"
|
|
46
|
+
@param[:lessonname] = "#{@param[:projectname]}.txt"
|
|
47
|
+
@param[:yamlname] = "#{@param[:projectname]}-questions.yaml"
|
|
50
48
|
@param[:moodlename] = "#{@param[:projectname]}-moodle.xml"
|
|
51
49
|
|
|
52
50
|
outputdir = get(:outputdir)
|
|
@@ -58,6 +56,4 @@ class ProjectData
|
|
|
58
56
|
|
|
59
57
|
Dir.mkdir(outputdir) unless Dir.exist?(outputdir)
|
|
60
58
|
end
|
|
61
|
-
# rubocop:enable Metrics/MethodLength
|
|
62
|
-
# rubocop:enable Metrics/AbcSize
|
|
63
59
|
end
|
data/lib/asker/data/row.rb
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative "column"
|
|
4
|
+
require_relative "../logger"
|
|
4
5
|
|
|
5
|
-
##
|
|
6
|
-
# Row objects
|
|
7
6
|
class Row
|
|
8
7
|
attr_reader :table, :index, :id
|
|
9
8
|
attr_reader :langs, :types, :raws, :columns
|
|
@@ -15,14 +14,14 @@ class Row
|
|
|
15
14
|
# @param index (Integer)
|
|
16
15
|
# @param xml_data (XML)
|
|
17
16
|
def initialize(table, index, xml_data)
|
|
18
|
-
@table
|
|
19
|
-
@index
|
|
20
|
-
@id
|
|
21
|
-
@langs
|
|
22
|
-
@types
|
|
23
|
-
@raws
|
|
17
|
+
@table = table
|
|
18
|
+
@index = index
|
|
19
|
+
@id = "#{@table.id}.#{@index}"
|
|
20
|
+
@langs = @table.langs
|
|
21
|
+
@types = @table.types
|
|
22
|
+
@raws = []
|
|
24
23
|
@columns = []
|
|
25
|
-
@simple
|
|
24
|
+
@simple = {lang: true, type: true}
|
|
26
25
|
read_data_from_xml(xml_data)
|
|
27
26
|
end
|
|
28
27
|
|
|
@@ -40,14 +39,17 @@ class Row
|
|
|
40
39
|
build_row_with_n_columns(xml_data)
|
|
41
40
|
end
|
|
42
41
|
|
|
43
|
-
|
|
42
|
+
unless @columns.size == @table.fields.size
|
|
43
|
+
Logger.error "Row: columns size != table.fields.size (#{xml_data})"
|
|
44
|
+
exit 1
|
|
45
|
+
end
|
|
44
46
|
end
|
|
45
47
|
|
|
46
48
|
def build_row_with_1_column(xml_data)
|
|
47
49
|
# When row tag only has text, we add this text as one value array
|
|
48
50
|
# This is usefull for tables with only one columns
|
|
49
51
|
@columns = [Column.new(self, @raws.size, xml_data)]
|
|
50
|
-
@raws
|
|
52
|
+
@raws = [xml_data.text.strip.to_s]
|
|
51
53
|
|
|
52
54
|
# read attributes from XML data
|
|
53
55
|
read_lang_from_xml(xml_data)
|
|
@@ -55,9 +57,9 @@ class Row
|
|
|
55
57
|
end
|
|
56
58
|
|
|
57
59
|
def read_lang_from_xml(xml_data)
|
|
58
|
-
return unless xml_data.attributes[
|
|
60
|
+
return unless xml_data.attributes["lang"]
|
|
59
61
|
|
|
60
|
-
code = xml_data.attributes[
|
|
62
|
+
code = xml_data.attributes["lang"].strip
|
|
61
63
|
return if code == @langs[0].code
|
|
62
64
|
|
|
63
65
|
@langs = [LangFactory.instance.get(code)]
|
|
@@ -66,9 +68,9 @@ class Row
|
|
|
66
68
|
end
|
|
67
69
|
|
|
68
70
|
def read_type_from_xml(xml_data)
|
|
69
|
-
return unless xml_data.attributes[
|
|
71
|
+
return unless xml_data.attributes["type"]
|
|
70
72
|
|
|
71
|
-
type = xml_data.attributes[
|
|
73
|
+
type = xml_data.attributes["type"].strip
|
|
72
74
|
return if type == @types[0]
|
|
73
75
|
|
|
74
76
|
@types = [type]
|
|
@@ -80,11 +82,11 @@ class Row
|
|
|
80
82
|
def build_row_with_n_columns(xml_data)
|
|
81
83
|
xml_data.elements.each do |i|
|
|
82
84
|
case i.name
|
|
83
|
-
when
|
|
85
|
+
when "lang"
|
|
84
86
|
read_langs_from_xml(i)
|
|
85
|
-
when
|
|
87
|
+
when "type"
|
|
86
88
|
read_types_from_xml(i)
|
|
87
|
-
when
|
|
89
|
+
when "col"
|
|
88
90
|
# When row has several columns, we add every value to the array
|
|
89
91
|
@columns << Column.new(self, @raws.size, i) # Column Objects
|
|
90
92
|
@raws << i.text.to_s
|
|
@@ -94,9 +96,9 @@ class Row
|
|
|
94
96
|
# rubocop:enable Metrics/MethodLength
|
|
95
97
|
|
|
96
98
|
def read_langs_from_xml(xml_data)
|
|
97
|
-
j = xml_data.text.split(
|
|
99
|
+
j = xml_data.text.split(",")
|
|
98
100
|
codes = @langs.map(&:code)
|
|
99
|
-
return if j.join(
|
|
101
|
+
return if j.join(",") == codes.join(",")
|
|
100
102
|
|
|
101
103
|
@langs = []
|
|
102
104
|
j.each { |k| @langs << LangFactory.instance.get(k.strip.to_s) }
|
|
@@ -105,8 +107,8 @@ class Row
|
|
|
105
107
|
end
|
|
106
108
|
|
|
107
109
|
def read_types_from_xml(xml_data)
|
|
108
|
-
j = xml_data.text.split(
|
|
109
|
-
return if j.join(
|
|
110
|
+
j = xml_data.text.split(",")
|
|
111
|
+
return if j.join(",") == @types.join(",")
|
|
110
112
|
|
|
111
113
|
@types = []
|
|
112
114
|
j.each { |k| @types << k.strip.to_s }
|
data/lib/asker/data/table.rb
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
3
|
+
require_relative "row"
|
|
4
|
+
require_relative "template"
|
|
5
|
+
require_relative "../logger"
|
|
5
6
|
|
|
6
|
-
# Contains data table information
|
|
7
7
|
class Table
|
|
8
8
|
attr_reader :name, :id
|
|
9
9
|
attr_reader :fields, :sequence
|
|
@@ -14,30 +14,25 @@ class Table
|
|
|
14
14
|
attr_reader :simple
|
|
15
15
|
|
|
16
16
|
##
|
|
17
|
-
# initialize Table object
|
|
18
17
|
# @param concept (Concept)
|
|
19
18
|
# @param xml_data (XML)
|
|
20
19
|
def initialize(concept, xml_data)
|
|
21
20
|
@concept = concept
|
|
22
21
|
read_attributes_from_xml(xml_data)
|
|
23
22
|
|
|
24
|
-
@simple = {
|
|
25
|
-
@types
|
|
26
|
-
@langs
|
|
23
|
+
@simple = {lang: true, type: true}
|
|
24
|
+
@types = ["text"] * @fields.size
|
|
25
|
+
@langs = [@concept.lang] * @fields.size
|
|
27
26
|
|
|
28
27
|
@datarows = [] # DEV experiment replace row data with row objects
|
|
29
28
|
read_data_from_xml(xml_data)
|
|
30
29
|
@rows = @datarows.map(&:raws)
|
|
31
30
|
end
|
|
32
31
|
|
|
33
|
-
##
|
|
34
|
-
# Return table name
|
|
35
32
|
def to_s
|
|
36
33
|
@name.to_s
|
|
37
34
|
end
|
|
38
35
|
|
|
39
|
-
##
|
|
40
|
-
# Return true if table has a sequence defined
|
|
41
36
|
def sequence?
|
|
42
37
|
@sequence.size.positive?
|
|
43
38
|
end
|
|
@@ -48,7 +43,7 @@ class Table
|
|
|
48
43
|
# * types(index) => Return type for fields[index]
|
|
49
44
|
# @param index (Integer)
|
|
50
45
|
def types(index = :all)
|
|
51
|
-
@types = ([
|
|
46
|
+
@types = (["text"] * @fields.size) if @types.nil?
|
|
52
47
|
return @types if index == :all
|
|
53
48
|
|
|
54
49
|
@types[index]
|
|
@@ -68,75 +63,59 @@ class Table
|
|
|
68
63
|
##
|
|
69
64
|
# Fill:fields, name and id from XML input
|
|
70
65
|
# @param xml_data (XML)
|
|
71
|
-
# rubocop:disable Metrics/AbcSize
|
|
72
66
|
def read_attributes_from_xml(xml_data)
|
|
73
|
-
|
|
74
|
-
t = xml_data.attributes['fields'].to_s.strip.split(',')
|
|
67
|
+
t = xml_data.attributes["fields"].to_s.strip.split(",")
|
|
75
68
|
t.each(&:strip!)
|
|
76
69
|
@fields = t || []
|
|
77
70
|
|
|
78
|
-
@name =
|
|
71
|
+
@name = ""
|
|
79
72
|
@fields.each { |i| @name = "#{@name}$#{i.to_s.strip.downcase}" }
|
|
80
73
|
@id = "#{@concept.name}.#{@name}"
|
|
81
74
|
|
|
82
75
|
@sequence = []
|
|
83
|
-
return unless xml_data.attributes[
|
|
76
|
+
return unless xml_data.attributes["sequence"]
|
|
84
77
|
|
|
85
|
-
@sequence = xml_data.attributes[
|
|
78
|
+
@sequence = xml_data.attributes["sequence"].to_s.split(",")
|
|
86
79
|
end
|
|
87
|
-
# rubocop:enable Metrics/AbcSize
|
|
88
80
|
|
|
89
|
-
##
|
|
90
|
-
# Build table data from xml input
|
|
91
|
-
# @param xml_data (XML)
|
|
92
|
-
# rubocop:disable Metrics/MethodLength
|
|
93
|
-
# rubocop:disable Metrics/AbcSize
|
|
94
81
|
def read_data_from_xml(xml_data)
|
|
95
82
|
xml_data.elements.each do |i|
|
|
96
83
|
case i.name
|
|
97
|
-
when
|
|
84
|
+
when "lang"
|
|
98
85
|
read_lang_from_xml(i)
|
|
99
|
-
when
|
|
86
|
+
when "row"
|
|
100
87
|
@datarows << Row.new(self, @datarows.size, i)
|
|
101
|
-
when
|
|
102
|
-
@sequence = i.text.split(
|
|
103
|
-
when
|
|
88
|
+
when "sequence"
|
|
89
|
+
@sequence = i.text.split(",")
|
|
90
|
+
when "template"
|
|
104
91
|
@datarows += Template.new(self, @datarows.size, i).datarows
|
|
105
|
-
when
|
|
92
|
+
when "type"
|
|
106
93
|
read_type_from_xml(i)
|
|
107
94
|
else
|
|
108
|
-
|
|
95
|
+
Logger.warn "Table: Tag unkown (concept/table/#{i.name})"
|
|
109
96
|
end
|
|
110
97
|
end
|
|
111
98
|
end
|
|
112
|
-
# rubocop:enable Metrics/MethodLength
|
|
113
|
-
# rubocop:enable Metrics/AbcSize
|
|
114
99
|
|
|
115
|
-
# rubocop:disable Metrics/MethodLength
|
|
116
|
-
# rubocop:disable Metrics/AbcSize
|
|
117
|
-
# rubocop:disable Style/ConditionalAssignment
|
|
118
100
|
def read_lang_from_xml(xml_data)
|
|
119
|
-
j = xml_data.text.split(
|
|
101
|
+
j = xml_data.text.split(",")
|
|
120
102
|
codes = @langs.map(&:code)
|
|
121
|
-
return if j.join(
|
|
103
|
+
return if j.join(",") == codes.join(",")
|
|
122
104
|
|
|
123
105
|
simple_off(:lang)
|
|
124
106
|
@langs = []
|
|
125
107
|
j.each do |k|
|
|
126
|
-
if [
|
|
127
|
-
@
|
|
108
|
+
@langs << if ["*", ""].include? k.strip
|
|
109
|
+
@concept.lang
|
|
128
110
|
else
|
|
129
|
-
|
|
111
|
+
LangFactory.instance.get(k.strip.to_s)
|
|
130
112
|
end
|
|
131
113
|
end
|
|
132
114
|
end
|
|
133
|
-
# rubocop:enable Metrics/MethodLength
|
|
134
|
-
# rubocop:enable Metrics/AbcSize
|
|
135
|
-
# rubocop:enable Style/ConditionalAssignment
|
|
136
115
|
|
|
137
116
|
def read_type_from_xml(xml_data)
|
|
138
|
-
j = xml_data.text.split(
|
|
139
|
-
return if j.join(
|
|
117
|
+
j = xml_data.text.split(",")
|
|
118
|
+
return if j.join(",") == @types.join(",")
|
|
140
119
|
|
|
141
120
|
simple_off(:type)
|
|
142
121
|
@types = []
|
data/lib/asker/data/template.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: false
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require_relative
|
|
3
|
+
require "rexml/document"
|
|
4
|
+
require_relative "row"
|
|
5
5
|
|
|
6
6
|
# This class process "template" tag used by Tables
|
|
7
7
|
class Template
|
|
@@ -19,10 +19,10 @@ class Template
|
|
|
19
19
|
vars = {}
|
|
20
20
|
v = xml.attributes
|
|
21
21
|
v.keys.each do |i|
|
|
22
|
-
if i ==
|
|
22
|
+
if i == "mode"
|
|
23
23
|
@mode = v[i].to_sym
|
|
24
24
|
else
|
|
25
|
-
vars[i] = v[i].split(
|
|
25
|
+
vars[i] = v[i].split(",")
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
# fill_vars_values(vars,mode)
|
|
@@ -34,13 +34,13 @@ class Template
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def load_template_from(xml)
|
|
37
|
-
template =
|
|
37
|
+
template = ""
|
|
38
38
|
xml.elements.each { |i| template << i.to_s + "\n" }
|
|
39
39
|
template
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def apply_vars_to_template(vars, template)
|
|
43
|
-
output =
|
|
43
|
+
output = ""
|
|
44
44
|
return output if vars.size.zero?
|
|
45
45
|
|
|
46
46
|
max = vars.first[1].size
|
|
@@ -57,7 +57,7 @@ class Template
|
|
|
57
57
|
data = "<template>\n#{data_string}\n</template>"
|
|
58
58
|
xml = REXML::Document.new(data)
|
|
59
59
|
xml.root.elements.each do |i|
|
|
60
|
-
if i.name ==
|
|
60
|
+
if i.name == "row"
|
|
61
61
|
datarows << Row.new(table, index, i)
|
|
62
62
|
index += 1
|
|
63
63
|
end
|
data/lib/asker/data/world.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative
|
|
3
|
+
require_relative "../loader/image_url_loader"
|
|
4
4
|
|
|
5
5
|
class World
|
|
6
6
|
# TODO: change how World class works ?
|
|
@@ -37,7 +37,7 @@ class World
|
|
|
37
37
|
|
|
38
38
|
concepts[c.name] = c
|
|
39
39
|
filenames << c.filename
|
|
40
|
-
contexts
|
|
40
|
+
contexts << c.context
|
|
41
41
|
end
|
|
42
42
|
filenames.uniq!
|
|
43
43
|
contexts.uniq!
|
|
@@ -52,7 +52,7 @@ class World
|
|
|
52
52
|
urls = {}
|
|
53
53
|
|
|
54
54
|
@concepts&.each_key { |key| searchs << key }
|
|
55
|
-
@contexts.each { |filter| searchs << filter.join(
|
|
55
|
+
@contexts.each { |filter| searchs << filter.join(" ").to_s }
|
|
56
56
|
searchs.each do |search|
|
|
57
57
|
threads << Thread.new { urls[search] = ImageUrlLoader.load(search) }
|
|
58
58
|
end
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
1
|
# Transform Questions into Gift format
|
|
4
2
|
module QuestionMoodleXMLFormatter
|
|
5
3
|
def self.to_s(question)
|
|
@@ -18,51 +16,51 @@ module QuestionMoodleXMLFormatter
|
|
|
18
16
|
def self.choice_to_s(question)
|
|
19
17
|
s = []
|
|
20
18
|
|
|
21
|
-
penalties = [
|
|
19
|
+
penalties = ["", "%-50%", "%-33.33333%", "%-25%", "%-20%"]
|
|
22
20
|
penalty = penalties[question.bads.size]
|
|
23
21
|
|
|
24
22
|
s << "<!-- question: #{question.name} -->"
|
|
25
23
|
s << '<question type="multichoice">'
|
|
26
|
-
s <<
|
|
24
|
+
s << " <name>"
|
|
27
25
|
s << " <text>#{question.name}</text>"
|
|
28
|
-
s <<
|
|
26
|
+
s << " </name>"
|
|
29
27
|
s << ' <questiontext format="html">'
|
|
30
28
|
s << " <text><![CDATA[#{question.text}]]></text>"
|
|
31
|
-
s <<
|
|
29
|
+
s << " </questiontext>"
|
|
32
30
|
s << ' <generalfeedback format="html">'
|
|
33
31
|
s << " <text>#{question.feedback}</text>"
|
|
34
|
-
s <<
|
|
35
|
-
s <<
|
|
32
|
+
s << " </generalfeedback>"
|
|
33
|
+
s << " <defaultgrade>1.0000000</defaultgrade>"
|
|
36
34
|
s << " <penalty>#{penalty}</penalty>"
|
|
37
|
-
s <<
|
|
38
|
-
s <<
|
|
35
|
+
s << " <hidden>0</hidden>"
|
|
36
|
+
s << " <single>true</single>"
|
|
39
37
|
s << " <shuffleanswers>#{question.shuffle?}</shuffleanswers>"
|
|
40
|
-
s <<
|
|
38
|
+
s << " <answernumbering>abc</answernumbering>"
|
|
41
39
|
s << ' <incorrectfeedback format="html">'
|
|
42
40
|
s << " <text>#{question.feedback}</text>"
|
|
43
|
-
s <<
|
|
41
|
+
s << " </incorrectfeedback>"
|
|
44
42
|
s << ' <answer fraction="100" format="html">'
|
|
45
43
|
s << " <text>#{question.good}</text>"
|
|
46
|
-
s <<
|
|
44
|
+
s << " </answer>"
|
|
47
45
|
s << ' <answer fraction="-25" format="html">'
|
|
48
46
|
s << " <text>#{question.bad[0]}</text>"
|
|
49
|
-
s <<
|
|
50
|
-
s <<
|
|
47
|
+
s << " </answer>"
|
|
48
|
+
s << " </question>"
|
|
51
49
|
s << ' <answer fraction="-25" format="html">'
|
|
52
50
|
s << " <text>#{question.bad[1]}</text>"
|
|
53
|
-
s <<
|
|
54
|
-
s <<
|
|
51
|
+
s << " </answer>"
|
|
52
|
+
s << " </question>"
|
|
55
53
|
s << ' <answer fraction="-25" format="html">'
|
|
56
54
|
s << " <text>#{question.bad[2]}</text>"
|
|
57
|
-
s <<
|
|
58
|
-
s <<
|
|
55
|
+
s << " </answer>"
|
|
56
|
+
s << " </question>"
|
|
59
57
|
s
|
|
60
58
|
end
|
|
61
59
|
|
|
62
|
-
def self.sanitize(input =
|
|
60
|
+
def self.sanitize(input = "")
|
|
63
61
|
output = input.dup
|
|
64
62
|
output.tr!("\n", " ")
|
|
65
|
-
output.tr!(":", "
|
|
63
|
+
output.tr!(":", ":")
|
|
66
64
|
output.tr!("=", "\\=")
|
|
67
65
|
# output.gsub!('{', "\\{")
|
|
68
66
|
# output.gsub!('}', "\\}")
|
|
@@ -19,13 +19,13 @@ module CodeDisplayer
|
|
|
19
19
|
|
|
20
20
|
e = code.lines.size
|
|
21
21
|
q = code.questions.size
|
|
22
|
-
factor =
|
|
22
|
+
factor = "Unkown"
|
|
23
23
|
factor = (q.to_f / e).round(2).to_s unless e.zero?
|
|
24
24
|
my_screen_table.add_row [Rainbow(File.basename(code.filename)).green,
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
code.type,
|
|
26
|
+
q,
|
|
27
|
+
e,
|
|
28
|
+
factor]
|
|
29
29
|
total_c += 1
|
|
30
30
|
total_q += q
|
|
31
31
|
total_e += e
|
|
@@ -33,13 +33,13 @@ module CodeDisplayer
|
|
|
33
33
|
|
|
34
34
|
my_screen_table.add_separator
|
|
35
35
|
my_screen_table.add_row [Rainbow("TOTAL = #{total_c}").bright,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
" ",
|
|
37
|
+
Rainbow(total_q.to_s).bright,
|
|
38
|
+
Rainbow(total_e.to_s).bright,
|
|
39
|
+
Rainbow((total_q / total_e.to_f).round(2)).bright]
|
|
40
40
|
return unless total_c.positive?
|
|
41
41
|
|
|
42
|
-
Logger.verboseln "\n[INFO] Showing
|
|
42
|
+
Logger.verboseln "\n[INFO] Showing CODEs statistics"
|
|
43
43
|
Logger.verboseln my_screen_table.to_s
|
|
44
44
|
end
|
|
45
45
|
end
|