asker-tool 2.6.0 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -4
  3. data/lib/asker/ai/ai.rb +6 -6
  4. data/lib/asker/ai/ai_calculate.rb +3 -3
  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/stage_b.rb +62 -28
  16. data/lib/asker/ai/stages/stage_d.rb +10 -10
  17. data/lib/asker/ai/stages/stage_f.rb +17 -17
  18. data/lib/asker/ai/stages/stage_i.rb +8 -18
  19. data/lib/asker/ai/stages/stage_s.rb +28 -26
  20. data/lib/asker/ai/stages/stage_t.rb +40 -51
  21. data/lib/asker/application.rb +15 -14
  22. data/lib/asker/check_input/check_haml_data.rb +52 -51
  23. data/lib/asker/check_input/check_table.rb +17 -20
  24. data/lib/asker/check_input.rb +10 -23
  25. data/lib/asker/cli.rb +43 -24
  26. data/lib/asker/data/code.rb +10 -9
  27. data/lib/asker/data/column.rb +21 -17
  28. data/lib/asker/data/concept.rb +24 -37
  29. data/lib/asker/data/data_field.rb +2 -2
  30. data/lib/asker/data/problem.rb +112 -0
  31. data/lib/asker/data/project_data.rb +11 -15
  32. data/lib/asker/data/row.rb +25 -23
  33. data/lib/asker/data/table.rb +25 -46
  34. data/lib/asker/data/template.rb +7 -7
  35. data/lib/asker/data/world.rb +3 -3
  36. data/lib/asker/{formatter → deprecated}/question_moodlexml_formatter.rb +19 -21
  37. data/lib/asker/displayer/code_displayer.rb +10 -10
  38. data/lib/asker/displayer/concept_ai_displayer.erb +1 -1
  39. data/lib/asker/displayer/concept_ai_displayer.rb +16 -16
  40. data/lib/asker/displayer/concept_displayer.rb +4 -2
  41. data/lib/asker/displayer/problem_displayer.rb +45 -0
  42. data/lib/asker/displayer/stats_displayer.rb +7 -12
  43. data/lib/asker/exporter/code_gift_exporter.rb +2 -2
  44. data/lib/asker/exporter/concept_ai_gift_exporter.rb +4 -4
  45. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +7 -7
  46. data/lib/asker/exporter/concept_doc_exporter.rb +5 -5
  47. data/lib/asker/exporter/data_gift_exporter.rb +14 -15
  48. data/lib/asker/exporter/data_moodle_exporter.rb +51 -20
  49. data/lib/asker/exporter/output_file_exporter.rb +9 -8
  50. data/lib/asker/exporter/problem_gift_exporter.rb +30 -0
  51. data/lib/asker/files/language/ca/templates.yaml +6 -0
  52. data/lib/asker/files/language/du/templates.yaml +6 -0
  53. data/lib/asker/files/language/en/templates.yaml +7 -1
  54. data/lib/asker/files/language/es/templates.yaml +6 -0
  55. data/lib/asker/files/language/fr/templates.yaml +6 -0
  56. data/lib/asker/formatter/code_string_formatter.rb +5 -5
  57. data/lib/asker/formatter/concept_doc_formatter.rb +3 -3
  58. data/lib/asker/formatter/concept_string_formatter.rb +6 -6
  59. data/lib/asker/formatter/moodle/ddmatch.erb +40 -0
  60. data/lib/asker/formatter/moodle/gapfill.erb +57 -0
  61. data/lib/asker/formatter/moodle/ordering.erb +41 -0
  62. data/lib/asker/formatter/question_gift_formatter.rb +41 -14
  63. data/lib/asker/formatter/question_hash_formatter.rb +5 -6
  64. data/lib/asker/formatter/question_moodle_formatter.rb +14 -7
  65. data/lib/asker/formatter/rb2haml_formatter.rb +8 -7
  66. data/lib/asker/lang/lang.rb +16 -16
  67. data/lib/asker/lang/lang_factory.rb +13 -16
  68. data/lib/asker/lang/text_actions.rb +20 -18
  69. data/lib/asker/loader/code_loader.rb +10 -22
  70. data/lib/asker/loader/content_loader.rb +42 -49
  71. data/lib/asker/loader/directory_loader.rb +13 -16
  72. data/lib/asker/loader/embedded_file.rb +14 -14
  73. data/lib/asker/loader/file_loader.rb +5 -4
  74. data/lib/asker/loader/haml_loader.rb +4 -3
  75. data/lib/asker/loader/image_url_loader.rb +6 -5
  76. data/lib/asker/loader/input_loader.rb +24 -10
  77. data/lib/asker/loader/problem_loader.rb +88 -0
  78. data/lib/asker/loader/project_loader.rb +5 -12
  79. data/lib/asker/logger.rb +19 -10
  80. data/lib/asker/skeleton.rb +19 -35
  81. data/lib/asker/start.rb +44 -0
  82. data/lib/asker/version.rb +1 -1
  83. data/lib/asker.rb +7 -52
  84. metadata +12 -6
  85. data/lib/asker/ai/code/problem_code_ai.rb +0 -176
  86. data/lib/asker/exporter/code_moodle_exporter.rb +0 -15
  87. data/lib/asker/exporter/concept_ai_moodle_exporter.rb +0 -15
data/lib/asker/cli.rb CHANGED
@@ -1,50 +1,70 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rainbow'
4
- require 'thor'
5
- require_relative 'version'
6
- require_relative '../asker'
3
+ require "rainbow"
4
+ require "thor"
5
+ require_relative "version"
6
+ require_relative "../asker"
7
7
 
8
8
  ##
9
9
  # Command Line User Interface
10
10
  class CLI < Thor
11
- map ['-h', '--help'] => 'help'
11
+ map ["-h", "--help"] => "help"
12
12
 
13
- map ['-v', '--version'] => 'version'
14
- desc 'version', 'Show the program version'
13
+ map ["-v", "--version"] => "version"
14
+ desc "version", "Show the program version"
15
15
  def version
16
16
  puts "#{Asker::NAME} version #{Asker::VERSION}"
17
17
  exit 0
18
18
  end
19
19
 
20
- map ['--init'] => 'init'
21
- desc 'init', 'Create default INI config file'
20
+ map ["--init"] => "init"
21
+ desc "init", "Create default INI config file"
22
22
  def init
23
23
  Asker.init
24
24
  exit 0
25
25
  end
26
26
 
27
- map ['new','--new'] => 'create_input'
28
- desc 'new DIRPATH', 'Create Asker demo input files'
29
- ##
30
- # Create Asker demo input files
31
- # @param dirname (String) Path to folder
27
+ map ["new", "--new"] => "create_input"
28
+ desc "new PATH", "Create Asker sample input file"
29
+ long_desc <<-LONGDESC
30
+
31
+ Create Asker sample input file (HAML format).
32
+
33
+ Examples:
34
+
35
+ (1) #{Rainbow("asker new foo/bar.haml").aqua}, Create "foo" dir and "bar.haml" file.
36
+ Path to input file can be relative or absolute.
37
+
38
+ (2) #{Rainbow("asker new foo").aqua}, Create "foo" dir and sample HAML file.
39
+ Path to directory can be relative or absolute.
40
+
41
+ LONGDESC
32
42
  def create_input(dirname)
33
43
  Asker.create_input(dirname)
34
44
  exit 0
35
45
  end
36
46
 
37
- map ['--check'] => 'check'
38
- desc 'check FILEPATH', 'Check input HAML file syntax'
47
+ map ["--check"] => "check"
48
+ desc "check FILEPATH", "Check HAML input file syntax"
49
+ long_desc <<-LONGDESC
50
+
51
+ Check HAML input file syntax.
52
+
53
+ Examples:
54
+
55
+ (*) #{Rainbow("asker check foo/bar.haml").aqua}, Check "bar.haml" input file.
56
+ Path to input file can be relative or absolute.
57
+
58
+ LONGDESC
39
59
  def check(filename)
40
60
  # Enable/disable color output
41
- Rainbow.enabled = false if options['color'] == false
61
+ Rainbow.enabled = false if options["color"] == false
42
62
  # Asker start processing input file
43
63
  Asker.check(filename)
44
64
  end
45
65
 
46
- map ['f', '-f', '--file'] => 'file'
47
- desc '[file] FILEPATH', 'Build output files, from HAML/XML input file.'
66
+ map ["f", "-f", "--file"] => "file"
67
+ desc "[file] FILEPATH", "Build output files, from HAML/XML input file."
48
68
  long_desc <<-LONGDESC
49
69
 
50
70
  Build questions about contents defined into input file specified.
@@ -53,15 +73,14 @@ class CLI < Thor
53
73
 
54
74
  Examples:
55
75
 
56
- (1) #{Rainbow('asker input/foo/foo.haml').aqua}, Build questions from HAML file.
76
+ (1) #{Rainbow("asker foo/bar.haml").aqua}, Build questions from HAML input file.
77
+ Path to input file can be relative or absolute.
57
78
 
58
- (2) #{Rainbow('asker input/foo/foo.xml').aqua}, Build questions from XML file.
59
-
60
- (3) #{Rainbow('asker projects/foo/foo.yaml').aqua}, Build questions from YAML project file.
79
+ (2) #{Rainbow("asker foo/bar.xml").aqua}, Build questions from XML input file.
80
+ Path to input file can be relative or absolute.
61
81
 
62
82
  LONGDESC
63
83
  def file(filename)
64
- # Asker start processing input file
65
84
  Asker.start(filename)
66
85
  end
67
86
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../ai/code/code_ai_factory'
3
+ require_relative "../ai/code/code_ai_factory"
4
+ require_relative "../logger"
4
5
 
5
6
  class Code
6
7
  attr_reader :dirname, :filename, :type
@@ -23,7 +24,7 @@ class Code
23
24
  end
24
25
 
25
26
  def lines_to_s(lines)
26
- out = ''
27
+ out = ""
27
28
  lines.each_with_index do |line, index|
28
29
  out << format("%2d| #{line}\n", (index + 1))
29
30
  end
@@ -36,7 +37,7 @@ class Code
36
37
  return if filepath.nil?
37
38
 
38
39
  unless File.exist? filepath
39
- puts Rainbow("[ERROR] Unkown file #{filepath}").red.bright
40
+ Logger.warn "Code: Unkown file (#{filepath})"
40
41
  return
41
42
  end
42
43
  content = File.read(filepath)
@@ -45,16 +46,16 @@ class Code
45
46
 
46
47
  def encode_and_split(text, encoding = :default)
47
48
  # Convert text to UTF-8 deleting unknown chars
48
- text ||= '' # Ensure text is not nil
49
- flag = [:default, 'UTF-8'].include? encoding
50
- return text.encode('UTF-8', invalid: :replace).split("\n") if flag
49
+ text ||= "" # Ensure text is not nil
50
+ flag = [:default, "UTF-8"].include? encoding
51
+ return text.encode("UTF-8", invalid: :replace).split("\n") if flag
51
52
 
52
53
  # Convert text from input ENCODING to UTF-8
53
- ec = Encoding::Converter.new(encoding.to_s, 'UTF-8')
54
+ ec = Encoding::Converter.new(encoding.to_s, "UTF-8")
54
55
  begin
55
56
  text = ec.convert(text)
56
- rescue StandardError => e
57
- puts "[ERROR] Encoding: #{e}"
57
+ rescue => e
58
+ Logger.warn "Code: Encoding error (#{e}) with filename (#{@filename})"
58
59
  end
59
60
 
60
61
  text.split("\n")
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "../logger"
4
+
3
5
  # Contain data information for every column
4
6
  # Params:
5
7
  # * +pRow+ - Parent row for this column
@@ -9,28 +11,27 @@ class Column
9
11
  attr_reader :row, :index, :id, :raw, :lang, :type, :simple
10
12
 
11
13
  ##
12
- # initialize Column
13
14
  # @param row (Row)
14
15
  # @param index (Integer)
15
16
  # @param xml_data (XMLdata)
16
17
  def initialize(row, index, xml_data)
17
- @row = row
18
- @index = index
19
- @id = "#{@row.id}.#{@index}"
20
- @raw = ''
21
- @lang = @row.langs[@index]
22
- @type = @row.types[@index]
23
- @simple = { lang: true, type: true }
18
+ @row = row
19
+ @index = index
20
+ @id = "#{@row.id}.#{@index}"
21
+ @raw = ""
22
+ @lang = @row.langs[@index]
23
+ @type = @row.types[@index]
24
+ @simple = {lang: true, type: true}
24
25
  read_data_from_xml(xml_data)
25
26
  end
26
27
 
27
28
  def to_html
28
29
  case @type
29
- when 'text'
30
+ when "text"
30
31
  return @raw
31
- when 'image_url'
32
- return "<img src=\"#{raw}\" alt\=\"image\">"
33
- when 'textfile_path'
32
+ when "image_url"
33
+ return "<img src=\"#{raw}\" alt=\"image\">"
34
+ when "textfile_path"
34
35
  return "<pre>#{raw}</pre>"
35
36
  end
36
37
  "ERROR type #{@type}"
@@ -39,7 +40,10 @@ class Column
39
40
  private
40
41
 
41
42
  def read_data_from_xml(xml_data)
42
- raise '[ERROR] Column with elements!' if xml_data.elements.count.positive?
43
+ if xml_data.elements.count.positive?
44
+ Logger.error "Column: Do not use elements!"
45
+ exit 1
46
+ end
43
47
 
44
48
  @raw = xml_data.text.strip.to_s
45
49
 
@@ -49,9 +53,9 @@ class Column
49
53
  end
50
54
 
51
55
  def read_lang_from_xml(xml_data)
52
- return unless xml_data.attributes['lang']
56
+ return unless xml_data.attributes["lang"]
53
57
 
54
- code = xml_data.attributes['lang'].strip
58
+ code = xml_data.attributes["lang"].strip
55
59
  return if code == @lang.code
56
60
 
57
61
  @lang = LangFactory.instance.get(code)
@@ -60,9 +64,9 @@ class Column
60
64
  end
61
65
 
62
66
  def read_type_from_xml(xml_data)
63
- return unless xml_data.attributes['type']
67
+ return unless xml_data.attributes["type"]
64
68
 
65
- type = xml_data.attributes['type'].strip
69
+ type = xml_data.attributes["type"].strip
66
70
  return if type == @type.to_s
67
71
 
68
72
  @type = type
@@ -1,14 +1,14 @@
1
- require 'rainbow'
2
- require 'rexml/document'
1
+ require "rexml/document"
3
2
 
4
- require_relative '../lang/lang_factory'
5
- require_relative '../loader/embedded_file'
6
- require_relative 'table'
7
- require_relative 'data_field'
3
+ require_relative "../lang/lang_factory"
4
+ require_relative "../loader/embedded_file"
5
+ require_relative "../logger"
6
+ require_relative "table"
7
+ require_relative "data_field"
8
8
 
9
9
  class Concept
10
10
  attr_reader :id # Unique identifer (Integer)
11
- attr_reader :lang # Lang code (By default is the same as map lang)
11
+ attr_reader :lang # Lang object
12
12
  attr_reader :context # Context inherits from map
13
13
  attr_reader :names # Names used to identify or name this concept
14
14
  attr_reader :type # type = text -> Name values are only text
@@ -24,24 +24,16 @@ class Concept
24
24
  # @param filename (String)
25
25
  # @param lang_code (String)
26
26
  # @param context (Array)
27
- def initialize(xml_data, filename, lang_code = 'en', context = [])
27
+ def initialize(xml_data, filename, lang, context)
28
28
  @@id += 1
29
29
  @id = @@id
30
30
 
31
31
  @filename = filename
32
32
  @process = false
33
- @lang = LangFactory.instance.get(lang_code)
34
-
35
- if context.class == Array
36
- @context = context
37
- elsif context.nil?
38
- @context = []
39
- else
40
- @context = context.split(',')
41
- @context.collect!(&:strip)
42
- end
43
- @names = ['concept.' + @id.to_s]
44
- @type = 'text'
33
+ @lang = lang # LangFactory.instance.get(lang_code)
34
+ @context = context
35
+ @names = ["concept." + @id.to_s]
36
+ @type = "text"
45
37
 
46
38
  @data = {}
47
39
  @data[:tags] = []
@@ -60,7 +52,7 @@ class Concept
60
52
  end
61
53
 
62
54
  def text
63
- @data[:texts][0] || '...'
55
+ @data[:texts][0] || "..."
64
56
  end
65
57
 
66
58
  def process?
@@ -71,16 +63,14 @@ class Concept
71
63
  p = calculate_nearness_to_concept(other)
72
64
  return if p.zero?
73
65
 
74
- @data[:neighbors] << { concept: other, value: p }
66
+ @data[:neighbors] << {concept: other, value: p}
75
67
  # Sort neighbors list
76
68
  @data[:neighbors].sort! { |a, b| a[:value] <=> b[:value] }
77
69
  @data[:neighbors].reverse!
78
70
  end
79
71
 
80
72
  def calculate_nearness_to_concept(other)
81
- a = ProjectData.instance.get(:weights)
82
- # Application.instance.config['ai']['formula_weights']
83
- weights = a.split(',').map(&:to_f)
73
+ weights = ProjectData.instance.get(:weights).split(",").map(&:to_f)
84
74
 
85
75
  max1 = @context.count
86
76
  max2 = @data[:tags].count
@@ -105,7 +95,7 @@ class Concept
105
95
  end
106
96
  @data[:texts].each do |t|
107
97
  text = t.clone
108
- text.split(' ').each do |word|
98
+ text.split(" ").each do |word|
109
99
  reference_to += 1 unless other.names.index(word.downcase).nil?
110
100
  end
111
101
  end
@@ -157,26 +147,25 @@ class Concept
157
147
  when "table"
158
148
  @data[:tables] << Table.new(self, i)
159
149
  else
160
- text = " [ERROR] Concept #{name} with unkown attribute: #{i.name}"
161
- puts Rainbow(text).color(:red)
150
+ Logger.warn "Concept #{name} with unkown attribute: #{i.name}"
162
151
  end
163
152
  end
164
153
  end
165
154
 
166
155
  def process_names(value)
167
156
  @names = []
168
- j = value.text.split(',')
157
+ j = value.text.split(",")
169
158
  j.each { |k| @names << k.strip }
170
- @type = value.attributes['type'].strip if value.attributes['type']
159
+ @type = value.attributes["type"].strip if value.attributes["type"]
171
160
  end
172
161
 
173
162
  def process_tags(value)
174
163
  if value.text.nil? || value.text.size.zero?
175
- puts Rainbow("[ERROR] Concept without tags: #{name} ").red.bright
176
- exit 1
164
+ Logger.warn "Concept: Concept #{name} without <tags>"
165
+ return []
177
166
  end
178
167
 
179
- @data[:tags] = value.text.split(',')
168
+ @data[:tags] = value.text.split(",")
180
169
  @data[:tags].collect!(&:strip)
181
170
  end
182
171
 
@@ -190,14 +179,12 @@ class Concept
190
179
  @data[:images] << EmbeddedFile.load(value.text.strip, File.dirname(@filename))
191
180
  when nil
192
181
  if value.text.nil?
193
- warn Rainbow("[WARN] def: without text!").yellow.bright
182
+ Logger.warn "Concept: def/text empty!"
194
183
  else
195
184
  @data[:texts] << value.text.strip
196
185
  end
197
186
  else
198
- msg = "[ERROR] Unknown type: #{value.attributes['type']}"
199
- puts Rainbow(msg).red.bright
200
- exit 1
187
+ Logger.warn "Concept: Unknown def/type (#{value.attributes["type"]})"
201
188
  end
202
189
  end
203
190
  end
@@ -12,7 +12,7 @@ class DataField
12
12
  # initialize DataField
13
13
  def initialize(data, id, type)
14
14
  @data = data
15
- @id = id.to_i # TODO: revise where it comes from? Is it unique value?
15
+ @id = id.to_i # TODO: revise where it comes from? Is it unique value?
16
16
  @type = type.to_sym
17
17
  end
18
18
 
@@ -94,7 +94,7 @@ class DataField
94
94
  # rubocop:enable Metrics/MethodLength
95
95
 
96
96
  def to_screen(text)
97
- return text[0, 7] + '...' + text[-15, 15] if text.size > 25
97
+ return text[0, 7] + "..." + text[-15, 15] if text.size > 25
98
98
 
99
99
  text
100
100
  end
@@ -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 }