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.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -7
  3. data/lib/asker/ai/ai.rb +17 -22
  4. data/lib/asker/ai/ai_calculate.rb +10 -17
  5. data/lib/asker/ai/code/base_code_ai.rb +5 -30
  6. data/lib/asker/ai/code/code_ai_factory.rb +6 -12
  7. data/lib/asker/ai/code/javascript_code_ai.rb +33 -34
  8. data/lib/asker/ai/code/python_code_ai.rb +35 -36
  9. data/lib/asker/ai/code/ruby_code_ai.rb +33 -33
  10. data/lib/asker/ai/code/sql_code_ai.rb +20 -21
  11. data/lib/asker/ai/concept_ai.rb +12 -22
  12. data/lib/asker/ai/problem/problem_ai.rb +226 -0
  13. data/lib/asker/ai/question.rb +34 -45
  14. data/lib/asker/ai/stages/base_stage.rb +7 -7
  15. data/lib/asker/ai/stages/main.rb +6 -7
  16. data/lib/asker/ai/stages/stage_b.rb +62 -28
  17. data/lib/asker/ai/stages/stage_d.rb +10 -10
  18. data/lib/asker/ai/stages/stage_f.rb +17 -17
  19. data/lib/asker/ai/stages/stage_i.rb +8 -18
  20. data/lib/asker/ai/stages/stage_s.rb +28 -26
  21. data/lib/asker/ai/stages/stage_t.rb +54 -76
  22. data/lib/asker/application.rb +15 -14
  23. data/lib/asker/check_input/check_haml_data.rb +57 -51
  24. data/lib/asker/check_input/check_table.rb +26 -19
  25. data/lib/asker/check_input.rb +10 -22
  26. data/lib/asker/cli.rb +43 -24
  27. data/lib/asker/data/code.rb +10 -9
  28. data/lib/asker/data/column.rb +21 -17
  29. data/lib/asker/data/concept.rb +24 -37
  30. data/lib/asker/data/data_field.rb +2 -2
  31. data/lib/asker/data/problem.rb +112 -0
  32. data/lib/asker/data/project_data.rb +11 -15
  33. data/lib/asker/data/row.rb +25 -23
  34. data/lib/asker/data/table.rb +25 -46
  35. data/lib/asker/data/template.rb +7 -7
  36. data/lib/asker/data/world.rb +3 -3
  37. data/lib/asker/{formatter → deprecated}/question_moodlexml_formatter.rb +19 -21
  38. data/lib/asker/displayer/code_displayer.rb +10 -10
  39. data/lib/asker/displayer/concept_ai_displayer.erb +1 -1
  40. data/lib/asker/displayer/concept_ai_displayer.rb +22 -34
  41. data/lib/asker/displayer/concept_displayer.rb +9 -11
  42. data/lib/asker/displayer/problem_displayer.rb +45 -0
  43. data/lib/asker/displayer/stats_displayer.rb +7 -12
  44. data/lib/asker/exporter/code_gift_exporter.rb +2 -2
  45. data/lib/asker/exporter/concept_ai_gift_exporter.rb +4 -4
  46. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +7 -7
  47. data/lib/asker/exporter/concept_doc_exporter.rb +5 -5
  48. data/lib/asker/exporter/data_gift_exporter.rb +14 -15
  49. data/lib/asker/exporter/data_moodle_exporter.rb +51 -20
  50. data/lib/asker/exporter/output_file_exporter.rb +9 -8
  51. data/lib/asker/exporter/problem_gift_exporter.rb +30 -0
  52. data/lib/asker/files/language/ca/templates.yaml +6 -0
  53. data/lib/asker/files/language/du/templates.yaml +6 -0
  54. data/lib/asker/files/language/en/templates.yaml +7 -1
  55. data/lib/asker/files/language/es/templates.yaml +6 -0
  56. data/lib/asker/files/language/fr/templates.yaml +6 -0
  57. data/lib/asker/formatter/code_string_formatter.rb +5 -5
  58. data/lib/asker/formatter/concept_doc_formatter.rb +3 -3
  59. data/lib/asker/formatter/concept_string_formatter.rb +27 -24
  60. data/lib/asker/formatter/moodle/ddmatch.erb +40 -0
  61. data/lib/asker/formatter/moodle/gapfill.erb +57 -0
  62. data/lib/asker/formatter/moodle/ordering.erb +41 -0
  63. data/lib/asker/formatter/question_gift_formatter.rb +41 -14
  64. data/lib/asker/formatter/question_hash_formatter.rb +5 -6
  65. data/lib/asker/formatter/question_moodle_formatter.rb +14 -7
  66. data/lib/asker/formatter/rb2haml_formatter.rb +8 -7
  67. data/lib/asker/lang/lang.rb +16 -16
  68. data/lib/asker/lang/lang_factory.rb +13 -16
  69. data/lib/asker/lang/text_actions.rb +20 -18
  70. data/lib/asker/loader/code_loader.rb +10 -22
  71. data/lib/asker/loader/content_loader.rb +42 -49
  72. data/lib/asker/loader/directory_loader.rb +13 -16
  73. data/lib/asker/loader/embedded_file.rb +29 -24
  74. data/lib/asker/loader/file_loader.rb +7 -6
  75. data/lib/asker/loader/haml_loader.rb +6 -5
  76. data/lib/asker/loader/image_url_loader.rb +21 -18
  77. data/lib/asker/loader/input_loader.rb +27 -14
  78. data/lib/asker/loader/problem_loader.rb +88 -0
  79. data/lib/asker/loader/project_loader.rb +11 -28
  80. data/lib/asker/logger.rb +22 -13
  81. data/lib/asker/skeleton.rb +27 -43
  82. data/lib/asker/start.rb +44 -0
  83. data/lib/asker/version.rb +1 -1
  84. data/lib/asker.rb +7 -53
  85. metadata +12 -20
  86. data/lib/asker/ai/code/problem_code_ai.rb +0 -176
  87. data/lib/asker/exporter/code_moodle_exporter.rb +0 -15
  88. 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 'singleton'
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 = { 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' }
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]) || '.haml'
40
+ ext = File.extname(@param[:process_file]) || ".haml"
43
41
  @param[:projectname] = @param[:projectname] ||
44
- File.basename(@param[:process_file], ext)
42
+ File.basename(@param[:process_file], ext)
45
43
 
46
- @param[:logname] = "#{@param[:projectname]}-log.txt"
44
+ @param[:logname] = "#{@param[:projectname]}.log"
47
45
  @param[:outputname] = "#{@param[:projectname]}-gift.txt"
48
- @param[:lessonname] = "#{@param[:projectname]}-doc.txt"
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
@@ -1,9 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'column'
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 = table
19
- @index = index
20
- @id = "#{@table.id}.#{@index}"
21
- @langs = @table.langs
22
- @types = @table.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 = { lang: true, type: true }
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
- raise "[ERROR] Row: #{xml_data}" unless @columns.size == @table.fields.size
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 = [xml_data.text.strip.to_s]
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['lang']
60
+ return unless xml_data.attributes["lang"]
59
61
 
60
- code = xml_data.attributes['lang'].strip
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['type']
71
+ return unless xml_data.attributes["type"]
70
72
 
71
- type = xml_data.attributes['type'].strip
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 'lang'
85
+ when "lang"
84
86
  read_langs_from_xml(i)
85
- when 'type'
87
+ when "type"
86
88
  read_types_from_xml(i)
87
- when 'col'
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(',') == codes.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(',') == @types.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 }
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'row'
4
- require_relative 'template'
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 = { lang: true, type: true }
25
- @types = ['text'] * @fields.size
26
- @langs = [@concept.lang] * @fields.size
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 = (['text'] * @fields.size) if @types.nil?
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
- # read attributes from XML data
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['sequence']
76
+ return unless xml_data.attributes["sequence"]
84
77
 
85
- @sequence = xml_data.attributes['sequence'].to_s.split(',')
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 'lang'
84
+ when "lang"
98
85
  read_lang_from_xml(i)
99
- when 'row'
86
+ when "row"
100
87
  @datarows << Row.new(self, @datarows.size, i)
101
- when 'sequence'
102
- @sequence = i.text.split(',')
103
- when 'template'
88
+ when "sequence"
89
+ @sequence = i.text.split(",")
90
+ when "template"
104
91
  @datarows += Template.new(self, @datarows.size, i).datarows
105
- when 'type'
92
+ when "type"
106
93
  read_type_from_xml(i)
107
94
  else
108
- puts Rainbow("[ERROR] concept/table#xml_data with #{i.name}").red.bright
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(',') == codes.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 ['*', ''].include? k.strip
127
- @langs << @concept.lang
108
+ @langs << if ["*", ""].include? k.strip
109
+ @concept.lang
128
110
  else
129
- @langs << LangFactory.instance.get(k.strip.to_s)
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(',') == @types.join(',')
117
+ j = xml_data.text.split(",")
118
+ return if j.join(",") == @types.join(",")
140
119
 
141
120
  simple_off(:type)
142
121
  @types = []
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: false
2
2
 
3
- require 'rexml/document'
4
- require_relative 'row'
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 == 'mode'
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 == 'row'
60
+ if i.name == "row"
61
61
  datarows << Row.new(table, index, i)
62
62
  index += 1
63
63
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../loader/image_url_loader'
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 << c.context
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(' ').to_s }
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 = ['', '%-50%', '%-33.33333%', '%-25%', '%-20%']
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 << ' <name>'
24
+ s << " <name>"
27
25
  s << " <text>#{question.name}</text>"
28
- s << ' </name>'
26
+ s << " </name>"
29
27
  s << ' <questiontext format="html">'
30
28
  s << " <text><![CDATA[#{question.text}]]></text>"
31
- s << ' </questiontext>'
29
+ s << " </questiontext>"
32
30
  s << ' <generalfeedback format="html">'
33
31
  s << " <text>#{question.feedback}</text>"
34
- s << ' </generalfeedback>'
35
- s << ' <defaultgrade>1.0000000</defaultgrade>'
32
+ s << " </generalfeedback>"
33
+ s << " <defaultgrade>1.0000000</defaultgrade>"
36
34
  s << " <penalty>#{penalty}</penalty>"
37
- s << ' <hidden>0</hidden>'
38
- s << ' <single>true</single>'
35
+ s << " <hidden>0</hidden>"
36
+ s << " <single>true</single>"
39
37
  s << " <shuffleanswers>#{question.shuffle?}</shuffleanswers>"
40
- s << ' <answernumbering>abc</answernumbering>'
38
+ s << " <answernumbering>abc</answernumbering>"
41
39
  s << ' <incorrectfeedback format="html">'
42
40
  s << " <text>#{question.feedback}</text>"
43
- s << ' </incorrectfeedback>'
41
+ s << " </incorrectfeedback>"
44
42
  s << ' <answer fraction="100" format="html">'
45
43
  s << " <text>#{question.good}</text>"
46
- s << ' </answer>'
44
+ s << " </answer>"
47
45
  s << ' <answer fraction="-25" format="html">'
48
46
  s << " <text>#{question.bad[0]}</text>"
49
- s << ' </answer>'
50
- s << ' </question>'
47
+ s << " </answer>"
48
+ s << " </question>"
51
49
  s << ' <answer fraction="-25" format="html">'
52
50
  s << " <text>#{question.bad[1]}</text>"
53
- s << ' </answer>'
54
- s << ' </question>'
51
+ s << " </answer>"
52
+ s << " </question>"
55
53
  s << ' <answer fraction="-25" format="html">'
56
54
  s << " <text>#{question.bad[2]}</text>"
57
- s << ' </answer>'
58
- s << ' </question>'
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 = 'Unkown'
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
- code.type,
26
- q,
27
- e,
28
- factor]
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
- Rainbow(total_q.to_s).bright,
38
- Rainbow(total_e.to_s).bright,
39
- Rainbow((total_q / total_e.to_f).round(2)).bright]
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 CODE statistics"
42
+ Logger.verboseln "\n[INFO] Showing CODEs statistics"
43
43
  Logger.verboseln my_screen_table.to_s
44
44
  end
45
45
  end
@@ -1,5 +1,5 @@
1
1
 
2
- [INFO] Showing CONCEPT statistics
2
+ [INFO] Showing CONCEPTs statistics
3
3
  * Exclude questions: <%= exclude_questions %>
4
4
  * Annotations:
5
5
  ├── (d) Definitions <= Concept.def