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
@@ -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
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "erb"
4
+ require "rainbow"
4
5
  require "terminal-table"
5
6
  require_relative "../application"
6
7
  require_relative "../logger"
7
8
 
8
- # Display ConceptAI stat on screen
9
9
  class ConceptAIDisplayer
10
10
  ##
11
11
  # Display ConceptAI stat on screen
@@ -51,7 +51,7 @@ class ConceptAIDisplayer
51
51
  factor = "Unkown"
52
52
  factor = (t.to_f / e).round(2).to_s unless e.zero?
53
53
  screen_table.add_row [Rainbow(concept_ai.concept.name(:screen)).green.bright,
54
- t, e, factor, sd, sb, sf, si, ss, st]
54
+ t, e, factor, sd, sb, sf, si, ss, st]
55
55
 
56
56
  total[:q] += t
57
57
  total[:e] += e
@@ -71,13 +71,13 @@ class ConceptAIDisplayer
71
71
  # Create table TAIL
72
72
  screen_table.add_separator
73
73
  screen_table.add_row [Rainbow("#{total[:c]} concept/s").bright,
74
- Rainbow(total[:q].to_s).bright,
75
- Rainbow(total[:e].to_s).bright,
76
- Rainbow((total[:q].to_f / total[:e]).round(2)).bright,
77
- total[:sd], total[:sb], total[:sf],
78
- total[:si], total[:ss], total[:st]]
74
+ Rainbow(total[:q].to_s).bright,
75
+ Rainbow(total[:e].to_s).bright,
76
+ Rainbow((total[:q].to_f / total[:e]).round(2)).bright,
77
+ total[:sd], total[:sb], total[:sf],
78
+ total[:si], total[:ss], total[:st]]
79
79
  export_notes
80
- Logger.verboseln "#{screen_table}\n"
80
+ Logger.info "#{screen_table}\n"
81
81
  end
82
82
 
83
83
  private_class_method def self.export_excluded_questions(screen_table, concepts_ai)
@@ -107,16 +107,16 @@ class ConceptAIDisplayer
107
107
  total[:ss] += ss
108
108
  total[:st] += st
109
109
  end
110
- screen_table.add_row [Rainbow('Excluded questions').yellow.bright,
111
- total[:q], '-', '-',
112
- total[:sd], total[:sb],
113
- total[:sf], total[:si],
114
- total[:ss], total[:st]]
110
+ screen_table.add_row [Rainbow("Excluded questions").yellow.bright,
111
+ total[:q], "-", "-",
112
+ total[:sd], total[:sb],
113
+ total[:sf], total[:si],
114
+ total[:ss], total[:st]]
115
115
  end
116
116
 
117
117
  private_class_method def self.export_notes
118
- exclude_questions = Application.instance.config['questions']['exclude'].to_s
119
- renderer = ERB.new(File.read(File.join(File.dirname(__FILE__), 'concept_ai_displayer.erb')))
120
- Logger.verboseln renderer.result(binding)
118
+ exclude_questions = Application.instance.config["questions"]["exclude"].to_s
119
+ renderer = ERB.new(File.read(File.join(File.dirname(__FILE__), "concept_ai_displayer.erb")))
120
+ Logger.info Rainbow(renderer.result(binding)).white
121
121
  end
122
122
  end
@@ -7,6 +7,8 @@ module ConceptDisplayer
7
7
  # Show concepts on screen
8
8
  # @param concepts (Array) List of concept data
9
9
  def self.show(concepts)
10
+ return if concepts.nil? || concepts.size.zero?
11
+
10
12
  show_mode = Application.instance.config["global"]["show_mode"]
11
13
  return unless show_mode
12
14
 
@@ -14,8 +16,8 @@ module ConceptDisplayer
14
16
  Logger.verboseln msg
15
17
  case show_mode
16
18
  when "resume"
17
- s = "* Concepts (#{concepts.count}): "
18
- concepts.each { |c| s += c.name + ", " }
19
+ names = concepts.map { |c| c.name }
20
+ s = " * Concepts (#{names.count}): #{names.join(",")}"
19
21
  Logger.verboseln s
20
22
  when "default"
21
23
  # Only show Concepts with process attr true
@@ -0,0 +1,45 @@
1
+ require "terminal-table"
2
+ require_relative "../logger"
3
+
4
+ module ProblemDisplayer
5
+ ##
6
+ # Show all "problem" data on screen
7
+ # @param problems (Array) List of "problems" data
8
+ def self.show(problems)
9
+ return if problems.nil? || problems.size.zero?
10
+
11
+ total_p = total_q = total_e = 0
12
+ my_screen_table = Terminal::Table.new do |st|
13
+ st << %w[Problem Desc Questions Entries xFactor]
14
+ st << :separator
15
+ end
16
+
17
+ problems.each do |problem|
18
+ next unless problem.process?
19
+
20
+ e = problem.cases.size
21
+ problem.asks.each do |ask|
22
+ e += ask[:steps].size
23
+ e += 1 if !ask[:answer].nil?
24
+ end
25
+
26
+ q = problem.questions.size
27
+ factor = "Unkown"
28
+ factor = (q.to_f / e).round(2).to_s unless e.zero?
29
+ desc = Rainbow(problem.desc[0, 24]).green
30
+ my_screen_table.add_row [problem.name, desc, q, e, factor]
31
+ total_p += 1
32
+ total_q += q
33
+ total_e += e
34
+ end
35
+ return unless total_p.positive?
36
+
37
+ my_screen_table.add_separator
38
+ my_screen_table.add_row [Rainbow("TOTAL = #{total_p}").bright, "",
39
+ Rainbow(total_q.to_s).bright,
40
+ Rainbow(total_e.to_s).bright,
41
+ Rainbow((total_q / total_e.to_f).round(2)).bright]
42
+ Logger.verboseln Rainbow("\n[INFO] Showing PROBLEMs statistics").white
43
+ Logger.verboseln my_screen_table.to_s
44
+ end
45
+ end
@@ -1,22 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../application'
4
- require_relative 'concept_ai_displayer'
5
- require_relative 'code_displayer'
3
+ require_relative "../application"
4
+ require_relative "concept_ai_displayer"
5
+ require_relative "code_displayer"
6
+ require_relative "problem_displayer"
6
7
 
7
- # Display Stats on screen.
8
- # * Display all "Concept AI"
9
- # * Display all "Code"
10
8
  module StatsDisplayer
11
- # Display Stats on screen.
12
- # * Display all "Concept AI"
13
- # * Display all "Code"
14
- # @param data (Hash) With concept_ai list and code list
9
+ # @param data (Hash) With concept_ai, code and problem list
15
10
  def self.show(data)
16
- return unless Application.instance.config['global']['show_mode']
11
+ return unless Application.instance.config["global"]["show_mode"]
17
12
 
18
- # show_final_results
19
13
  ConceptAIDisplayer.show(data[:concepts_ai])
20
14
  CodeDisplayer.show(data[:codes_ai])
15
+ ProblemDisplayer.show(data[:problems])
21
16
  end
22
17
  end
@@ -23,9 +23,9 @@ module CodeGiftExporter
23
23
 
24
24
  private_class_method def self.head(code)
25
25
  s = "\n"
26
- s += '// ' + '=' * 50 + "\n"
26
+ s += "// " + "=" * 50 + "\n"
27
27
  s += "// Code #{code.type}: #{code.filename} (#{code.questions.size})\n"
28
- s += '// ' + '=' * 50 + "\n"
28
+ s += "// " + "=" * 50 + "\n"
29
29
  s
30
30
  end
31
31
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../formatter/question_gift_formatter'
3
+ require_relative "../formatter/question_gift_formatter"
4
4
 
5
5
  # Export ConceptIA data to gift to outputfile
6
6
  module ConceptAIGiftExporter
@@ -20,7 +20,7 @@ module ConceptAIGiftExporter
20
20
  return unless concept_ai.concept.process?
21
21
 
22
22
  file.write head(concept_ai.concept.name)
23
- Application.instance.config['questions']['stages'].each do |stage|
23
+ Application.instance.config["questions"]["stages"].each do |stage|
24
24
  concept_ai.questions[stage].each do |question|
25
25
  file.write(QuestionGiftFormatter.to_s(question))
26
26
  end
@@ -33,9 +33,9 @@ module ConceptAIGiftExporter
33
33
  # @return String
34
34
  private_class_method def self.head(name)
35
35
  s = "\n"
36
- s += '// ' + '=' * 50 + "\n"
36
+ s += "// " + "=" * 50 + "\n"
37
37
  s += "// Concept name: #{name}\n"
38
- s += '// ' + '=' * 50 + "\n"
38
+ s += "// " + "=" * 50 + "\n"
39
39
  s
40
40
  end
41
41
  end
@@ -1,5 +1,5 @@
1
- require 'yaml'
2
- require_relative '../formatter/question_hash_formatter'
1
+ require "yaml"
2
+ require_relative "../formatter/question_hash_formatter"
3
3
 
4
4
  # Use to export data from ConceptIA to YAML format
5
5
  module ConceptAIYAMLExporter
@@ -12,11 +12,11 @@ module ConceptAIYAMLExporter
12
12
  concepts_ai.each do |concept_ai|
13
13
  questions += get_questions_from concept_ai
14
14
  end
15
- params = { lang: project.get(:lang) ,
16
- projectname: project.get(:projectname) }
17
- output = { params: params, questions: questions }
15
+ params = {lang: project.get(:lang),
16
+ projectname: project.get(:projectname)}
17
+ output = {params: params, questions: questions}
18
18
 
19
- yamlfile = File.open(project.get(:yamlpath), 'w')
19
+ yamlfile = File.open(project.get(:yamlpath), "w")
20
20
  yamlfile.write(output.to_yaml)
21
21
  yamlfile.close
22
22
  end
@@ -25,7 +25,7 @@ module ConceptAIYAMLExporter
25
25
  data = []
26
26
  return data unless concept_ai.concept.process?
27
27
 
28
- Application.instance.config['questions']['stages'].each do |stage|
28
+ Application.instance.config["questions"]["stages"].each do |stage|
29
29
  concept_ai.questions[stage].each do |question|
30
30
  question.lang = concept_ai.concept.lang
31
31
  data << QuestionHashFormatter.to_hash(question)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../formatter/concept_doc_formatter'
4
- require_relative '../version'
3
+ require_relative "../formatter/concept_doc_formatter"
4
+ require_relative "../version"
5
5
 
6
6
  ##
7
7
  # Export Concept to Doc file
@@ -9,12 +9,12 @@ module ConceptDocExporter
9
9
  ##
10
10
  # Export array of concepts to doc
11
11
  def self.export_all(concepts, project)
12
- file = File.new(project.get(:lessonpath), 'w')
13
- file.write('=' * 50 + "\n")
12
+ file = File.new(project.get(:lessonpath), "w")
13
+ file.write("=" * 50 + "\n")
14
14
  file.write("Created by : #{Asker::NAME} (version #{Asker::VERSION})\n")
15
15
  file.write("File : #{project.get(:lessonname)}\n")
16
16
  file.write("Time : #{Time.new}\n")
17
- file.write('=' * 50 + "\n")
17
+ file.write("=" * 50 + "\n")
18
18
 
19
19
  concepts.each do |concept|
20
20
  file.write(ConceptDocFormatter.to_s(concept)) if concept.process
@@ -1,30 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'concept_ai_gift_exporter'
4
- require_relative 'code_gift_exporter'
5
- require_relative '../version'
6
- require_relative '../application'
3
+ require_relative "concept_ai_gift_exporter"
4
+ require_relative "code_gift_exporter"
5
+ require_relative "problem_gift_exporter"
6
+ require_relative "../application"
7
+ require_relative "../version"
7
8
 
8
- # Export Data (ConceptIA and Code) to gift to outputfile
9
9
  module DataGiftExporter
10
10
  ##
11
- # Export an array of Data (ConceptAI and Code objects) into GIFT outpufile
11
+ # Export an array of Data (ConceptAIs, Codes and Problems objects) into GIFT file
12
12
  # @param data (Hash)
13
13
  # @param project (Project)
14
14
  def self.export_all(data, project)
15
- file = File.open(project.get(:outputpath), 'w')
16
- file.write('// ' + ('=' * 50) + "\n")
17
- file.write("// Created by : #{Asker::NAME}")
18
- file.write(" (version #{Asker::VERSION})\n")
19
- file.write("// File : #{project.get(:outputname)}\n")
20
- file.write("// Time : #{Time.new}\n")
21
- file.write('// ' + ('=' * 50) + "\n\n")
22
- category = Application.instance.config['questions']['category']
15
+ file = File.open(project.get(:outputpath), "w")
16
+ file.write("// " + ("=" * 50) + "\n")
17
+ file.write("// #{Asker::NAME} : version #{Asker::VERSION}\n")
18
+ file.write("// Filename : #{project.get(:outputname)}\n")
19
+ file.write("// Datetime : #{Time.new}\n")
20
+ file.write("// " + ("=" * 50) + "\n\n")
21
+ category = Application.instance.config["questions"]["category"]
23
22
  file.write("$CATEGORY: $course$/#{category}\n") unless category.nil?
24
23
 
25
24
  ConceptAIGiftExporter.export_all(data[:concepts_ai], file)
26
25
  CodeGiftExporter.export_all(data[:codes_ai], file)
27
-
26
+ ProblemGiftExporter.new.call(data[:problems], file)
28
27
  file.close
29
28
  end
30
29
  end