asker-tool 2.1.5 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -17
  3. data/bin/asker +2 -1
  4. data/lib/asker/ai/ai.rb +10 -3
  5. data/lib/asker/ai/ai_calculate.rb +20 -6
  6. data/lib/asker/ai/code/base_code_ai.rb +104 -0
  7. data/lib/asker/{code/ai → ai/code}/code_ai_factory.rb +11 -1
  8. data/lib/asker/{code/ai → ai/code}/javascript_code_ai.rb +2 -5
  9. data/lib/asker/ai/code/problem_code_ai.rb +176 -0
  10. data/lib/asker/{code/ai → ai/code}/python_code_ai.rb +2 -5
  11. data/lib/asker/{code/ai → ai/code}/ruby_code_ai.rb +14 -7
  12. data/lib/asker/{code/ai → ai/code}/sql_code_ai.rb +2 -5
  13. data/lib/asker/ai/concept_ai.rb +13 -3
  14. data/lib/asker/ai/question.rb +28 -6
  15. data/lib/asker/ai/stages/base_stage.rb +45 -6
  16. data/lib/asker/ai/stages/stage_b.rb +100 -50
  17. data/lib/asker/ai/stages/stage_d.rb +75 -90
  18. data/lib/asker/ai/stages/stage_f.rb +64 -36
  19. data/lib/asker/ai/stages/stage_i.rb +79 -92
  20. data/lib/asker/ai/stages/stage_s.rb +41 -36
  21. data/lib/asker/ai/stages/stage_t.rb +149 -108
  22. data/lib/asker/application.rb +19 -11
  23. data/lib/asker/cli.rb +31 -44
  24. data/lib/asker/data/code.rb +62 -0
  25. data/lib/asker/data/column.rb +31 -21
  26. data/lib/asker/data/concept.rb +109 -65
  27. data/lib/asker/data/data_field.rb +14 -0
  28. data/lib/asker/data/project_data.rb +63 -0
  29. data/lib/asker/data/row.rb +75 -52
  30. data/lib/asker/data/table.rb +91 -42
  31. data/lib/asker/data/template.rb +3 -1
  32. data/lib/asker/data/world.rb +51 -35
  33. data/lib/asker/displayer/code_displayer.rb +7 -0
  34. data/lib/asker/displayer/concept_ai_displayer.erb +10 -0
  35. data/lib/asker/displayer/concept_ai_displayer.rb +74 -53
  36. data/lib/asker/displayer/concept_displayer.rb +16 -9
  37. data/lib/asker/displayer/stats_displayer.rb +12 -3
  38. data/lib/asker/exporter/concept_ai_gift_exporter.rb +19 -11
  39. data/lib/asker/exporter/concept_ai_moodle_exporter.rb +44 -0
  40. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +13 -6
  41. data/lib/asker/exporter/concept_doc_exporter.rb +14 -1
  42. data/lib/asker/exporter/data_gift_exporter.rb +29 -0
  43. data/lib/asker/exporter/output_file_exporter.rb +9 -6
  44. data/lib/asker/files/{config.ini → asker.ini} +48 -1
  45. data/lib/asker/files/example-concept.haml +0 -1
  46. data/lib/asker/files/language/du/connectors.yaml +81 -0
  47. data/lib/asker/{lang/locales/fr → files/language/du}/mistakes.yaml +1 -1
  48. data/lib/asker/files/language/du/templates.yaml +29 -0
  49. data/lib/asker/{lang/locales → files/language}/en/connectors.yaml +0 -0
  50. data/lib/asker/{lang/locales → files/language}/en/mistakes.yaml +0 -0
  51. data/lib/asker/files/language/en/templates.yaml +29 -0
  52. data/lib/asker/{lang/locales → files/language}/es/connectors.yaml +0 -0
  53. data/lib/asker/files/language/es/mistakes.yaml +84 -0
  54. data/lib/asker/files/language/es/templates.yaml +29 -0
  55. data/lib/asker/files/language/fr/connectors.yaml +76 -0
  56. data/lib/asker/{lang/locales/es → files/language/fr}/mistakes.yaml +0 -0
  57. data/lib/asker/files/language/fr/templates.yaml +29 -0
  58. data/lib/asker/{lang/locales → files/language}/javascript/connectors.yaml +0 -0
  59. data/lib/asker/{lang/locales → files/language}/javascript/mistakes.yaml +0 -0
  60. data/lib/asker/{lang/locales → files/language}/javascript/templates.yaml +0 -0
  61. data/lib/asker/{lang/locales → files/language}/math/connectors.yaml +0 -0
  62. data/lib/asker/{lang/locales → files/language}/math/mistakes.yaml +0 -0
  63. data/lib/asker/{lang/locales → files/language}/math/templates.yaml +0 -0
  64. data/lib/asker/{lang/locales → files/language}/python/connectors.yaml +0 -0
  65. data/lib/asker/{lang/locales → files/language}/python/mistakes.yaml +0 -0
  66. data/lib/asker/{lang/locales → files/language}/python/templates.yaml +0 -0
  67. data/lib/asker/{lang/locales → files/language}/ruby/connectors.yaml +0 -0
  68. data/lib/asker/{lang/locales → files/language}/ruby/mistakes.yaml +0 -0
  69. data/lib/asker/{lang/locales → files/language}/ruby/templates.yaml +0 -0
  70. data/lib/asker/{lang/locales → files/language}/sql/connectors.yaml +0 -0
  71. data/lib/asker/{lang/locales → files/language}/sql/mistakes.yaml +0 -0
  72. data/lib/asker/{lang/locales → files/language}/sql/templates.yaml +0 -0
  73. data/lib/asker/formatter/concept_doc_formatter.rb +0 -4
  74. data/lib/asker/formatter/concept_string_formatter.rb +7 -4
  75. data/lib/asker/formatter/moodle/matching.erb +38 -0
  76. data/lib/asker/formatter/moodle/multichoice.erb +49 -0
  77. data/lib/asker/formatter/moodle/shortanswer.erb +30 -0
  78. data/lib/asker/formatter/moodle/truefalse.erb +47 -0
  79. data/lib/asker/formatter/question_gift_formatter.rb +30 -20
  80. data/lib/asker/formatter/question_moodle_formatter.rb +27 -0
  81. data/lib/asker/{checker.rb → input_checker.rb} +126 -49
  82. data/lib/asker/lang/lang.rb +17 -10
  83. data/lib/asker/lang/lang_factory.rb +32 -5
  84. data/lib/asker/lang/text_actions.rb +87 -69
  85. data/lib/asker/loader/code_loader.rb +4 -4
  86. data/lib/asker/loader/content_loader.rb +21 -19
  87. data/lib/asker/loader/directory_loader.rb +1 -8
  88. data/lib/asker/loader/embedded_file.rb +42 -0
  89. data/lib/asker/loader/file_loader.rb +3 -14
  90. data/lib/asker/loader/haml_loader.rb +15 -0
  91. data/lib/asker/loader/image_url_loader.rb +8 -12
  92. data/lib/asker/loader/input_loader.rb +13 -15
  93. data/lib/asker/loader/project_loader.rb +25 -15
  94. data/lib/asker/logger.rb +36 -9
  95. data/lib/asker/skeleton.rb +23 -13
  96. data/lib/asker.rb +76 -42
  97. metadata +53 -54
  98. data/lib/asker/code/ai/base_code_ai.rb +0 -48
  99. data/lib/asker/code/code.rb +0 -53
  100. data/lib/asker/lang/locales/du/templates.yaml +0 -50
  101. data/lib/asker/lang/locales/en/templates.yaml +0 -29
  102. data/lib/asker/lang/locales/es/templates.yaml +0 -29
  103. data/lib/asker/lang/locales/fr/connectors.yaml +0 -92
  104. data/lib/asker/lang/locales/fr/templates.yaml +0 -29
  105. data/lib/asker/project.rb +0 -172
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  require_relative 'row'
4
4
  require_relative 'template'
@@ -6,75 +6,96 @@ require_relative 'template'
6
6
  # Contains data table information
7
7
  class Table
8
8
  attr_reader :name, :id
9
- attr_reader :fields, :langs, :types, :sequence
10
- attr_reader :datarows, :rows
9
+ attr_reader :fields, :sequence
10
+ attr_reader :langs
11
+ attr_reader :datarows # DEV: experimental replace for Row objects
12
+ attr_reader :rows # Row objects are Datarows.raws values
13
+ # Table is simple when all their rows and col has the same lang and type value
11
14
  attr_reader :simple
12
15
 
16
+ ##
17
+ # initialize Table object
18
+ # @param concept (Concept)
19
+ # @param xml_data (XML)
13
20
  def initialize(concept, xml_data)
14
21
  @concept = concept
22
+ read_attributes_from_xml(xml_data)
15
23
 
16
- # read attributes from XML data
17
- t = xml_data.attributes['fields'].to_s.strip.split(',')
18
- t.each { |i| i.strip! }
19
- @fields = t || []
24
+ @simple = { lang: true, type: true }
20
25
  @types = ['text'] * @fields.size
21
26
  @langs = [@concept.lang] * @fields.size
22
27
 
23
- @name = ''
24
- @fields.each { |i| @name=@name + '$' + i.to_s.strip.downcase}
25
- @id = @concept.name.to_s + '.' + @name
26
- @simple = { lang: true, type: true }
27
-
28
- @sequence = []
29
- if xml_data.attributes['sequence']
30
- t = xml_data.attributes['sequence'].to_s || ""
31
- @sequence = t.split(",")
32
- # puts "[DEPRECATED] sequence attr on table <#{@name}>"
33
- end
34
-
35
- @datarows = [] #DEV experiment replace row data with row objects
28
+ @datarows = [] # DEV experiment replace row data with row objects
36
29
  read_data_from_xml(xml_data)
37
- @rows = @datarows.map { |r| r.raws }
30
+ @rows = @datarows.map(&:raws)
38
31
  end
39
32
 
33
+ ##
34
+ # Return table name
40
35
  def to_s
41
36
  @name.to_s
42
37
  end
43
38
 
39
+ ##
40
+ # Return true if table has a sequence defined
44
41
  def sequence?
45
- @sequence.size > 0
42
+ @sequence.size.positive?
46
43
  end
47
44
 
45
+ ##
46
+ # Return fields type:
47
+ # * types(:all) => Return an Array with all field types
48
+ # * types(index) => Return type for fields[index]
49
+ # @param index (Integer)
48
50
  def types(index = :all)
49
51
  @types = (['text'] * @fields.size) if @types.nil?
50
52
  return @types if index == :all
53
+
51
54
  @types[index]
52
55
  end
53
56
 
57
+ ##
58
+ # Set table to simple off
59
+ # * simple_off(:lang) => Set table simple lang FALSE
60
+ # * simple_off(:type) => Set table simple type FALSE
61
+ # @param option (Symbol)
54
62
  def simple_off(option)
55
63
  @simple[option] = false
56
64
  end
57
65
 
58
66
  private
59
67
 
68
+ ##
69
+ # Fill:fields, name and id from XML input
70
+ # @param xml_data (XML)
71
+ # rubocop:disable Metrics/AbcSize
72
+ def read_attributes_from_xml(xml_data)
73
+ # read attributes from XML data
74
+ t = xml_data.attributes['fields'].to_s.strip.split(',')
75
+ t.each(&:strip!)
76
+ @fields = t || []
77
+
78
+ @name = ''
79
+ @fields.each { |i| @name = "#{@name}$#{i.to_s.strip.downcase}" }
80
+ @id = "#{@concept.name}.#{@name}"
81
+
82
+ @sequence = []
83
+ return unless xml_data.attributes['sequence']
84
+
85
+ @sequence = xml_data.attributes['sequence'].to_s.split(',')
86
+ end
87
+ # rubocop:enable Metrics/AbcSize
88
+
89
+ ##
90
+ # Build table data from xml input
91
+ # @param xml_data (XML)
92
+ # rubocop:disable Metrics/MethodLength
93
+ # rubocop:disable Metrics/AbcSize
60
94
  def read_data_from_xml(xml_data)
61
95
  xml_data.elements.each do |i|
62
96
  case i.name
63
97
  when 'lang'
64
- j = i.text.split(',')
65
- codes = @langs.map(&:code)
66
-
67
- if j.join(',') != codes.join(',')
68
- simple_off(:lang)
69
- @langs = []
70
- j.each do |k|
71
- if k.strip == '*' || k.strip == ''
72
- @langs << @concept.lang
73
- else
74
- @langs << LangFactory.instance.get(k.strip.to_s)
75
- end
76
- end
77
- end
98
+ read_lang_from_xml(i)
78
99
  when 'row'
79
100
  @datarows << Row.new(self, @datarows.size, i)
80
101
  when 'sequence'
@@ -82,15 +103,43 @@ class Table
82
103
  when 'template'
83
104
  @datarows += Template.new(self, @datarows.size, i).datarows
84
105
  when 'type'
85
- j = i.text.split(',')
86
- if j.join(',') != @types.join(',')
87
- simple_off(:type)
88
- @types = []
89
- j.each { |k| @types << k.strip.to_s }
90
- end
106
+ read_type_from_xml(i)
91
107
  else
92
108
  puts Rainbow("[ERROR] concept/table#xml_data with #{i.name}").red.bright
93
109
  end
94
110
  end
95
111
  end
112
+ # rubocop:enable Metrics/MethodLength
113
+ # rubocop:enable Metrics/AbcSize
114
+
115
+ # rubocop:disable Metrics/MethodLength
116
+ # rubocop:disable Metrics/AbcSize
117
+ # rubocop:disable Style/ConditionalAssignment
118
+ def read_lang_from_xml(xml_data)
119
+ j = xml_data.text.split(',')
120
+ codes = @langs.map(&:code)
121
+ return if j.join(',') == codes.join(',')
122
+
123
+ simple_off(:lang)
124
+ @langs = []
125
+ j.each do |k|
126
+ if ['*', ''].include? k.strip
127
+ @langs << @concept.lang
128
+ else
129
+ @langs << LangFactory.instance.get(k.strip.to_s)
130
+ end
131
+ end
132
+ end
133
+ # rubocop:enable Metrics/MethodLength
134
+ # rubocop:enable Metrics/AbcSize
135
+ # rubocop:enable Style/ConditionalAssignment
136
+
137
+ def read_type_from_xml(xml_data)
138
+ j = xml_data.text.split(',')
139
+ return if j.join(',') == @types.join(',')
140
+
141
+ simple_off(:type)
142
+ @types = []
143
+ j.each { |k| @types << k.strip.to_s }
144
+ end
96
145
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: false
1
2
 
2
3
  require 'rexml/document'
3
4
  require_relative 'row'
@@ -40,7 +41,8 @@ class Template
40
41
 
41
42
  def apply_vars_to_template(vars, template)
42
43
  output = ''
43
- return if vars.size.zero?
44
+ return output if vars.size.zero?
45
+
44
46
  max = vars.first[1].size
45
47
  (1..max).each do |index|
46
48
  t = template.dup
@@ -1,50 +1,23 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  require_relative '../loader/image_url_loader'
3
- require_relative '../project'
4
- require_relative '../logger'
5
4
 
6
5
  class World
7
6
  attr_reader :concepts, :filenames, :contexts, :image_urls
8
7
 
9
- def initialize(concepts, show_progress=true)
8
+ def initialize(concepts, internet = true)
10
9
  find_neighbors_for_every_concept(concepts)
11
-
12
- @concepts = {}
13
- @filenames = []
14
- @contexts = []
15
- @image_urls = {}
16
-
17
- concepts.each do |c|
18
- if c.process
19
- @concepts[c.name] = c
20
- @filenames << c.filename
21
- @contexts << c.context
22
- end
23
- end
24
- @filenames.uniq!
25
- @contexts.uniq!
26
-
27
- Logger.verbose "\n[INFO] Loading data from Internet" if show_progress
28
- threads = []
29
- concepts.each do |c|
30
- print('.') if show_progress
31
- # puts "[DEBUG] #{c.name}\n"
32
- # filter = [ c.name.clone ] + c.context.clone
33
- filter = c.name.clone
34
- threads << Thread.new { @image_urls[c.name] = ImageUrlLoader::load(filter) }
35
- end
36
- @contexts.each do |filter|
37
- print('.') if show_progress
38
- threads << Thread.new { @image_urls[ filter.join('.').to_s ] = ImageUrlLoader::load(filter) }
39
- end
40
- threads.each { |t| t.join } # wait for all threads to finish
41
- print("\n") if show_progress
10
+ @concepts, @filenames, @contexts = get_lists_from(concepts)
11
+ @image_urls = find_url_images_from_internet(internet)
42
12
  end
43
13
 
14
+ ##
15
+ # For every concept... find its neighbors
16
+ # @param concepts (Array)
44
17
  def find_neighbors_for_every_concept(concepts)
45
18
  concepts.each do |i|
46
19
  concepts.each do |j|
47
- if (i.id!=j.id) then
20
+ if i.id != j.id
48
21
  i.try_adding_neighbor(j)
49
22
  i.try_adding_references(j)
50
23
  end
@@ -52,4 +25,47 @@ class World
52
25
  end
53
26
  end
54
27
 
28
+ private
29
+
30
+ # rubocop:disable Metrics/MethodLength
31
+ def get_lists_from(input)
32
+ concepts = {}
33
+ filenames = []
34
+ contexts = []
35
+ input.each do |c|
36
+ next unless c.process
37
+
38
+ concepts[c.name] = c
39
+ filenames << c.filename
40
+ contexts << c.context
41
+ end
42
+ filenames.uniq!
43
+ contexts.uniq!
44
+ [concepts, filenames, contexts]
45
+ end
46
+ # rubocop:enable Metrics/MethodLength
47
+
48
+ # rubocop:disable Metrics/MethodLength
49
+ # rubocop:disable Metrics/AbcSize
50
+ # rubocop:disable Metrics/CyclomaticComplexity
51
+ # rubocop:disable Metrics/PerceivedComplexity
52
+ def find_url_images_from_internet(internet)
53
+ return {} unless internet
54
+
55
+ threads = []
56
+ searchs = []
57
+ urls = {}
58
+
59
+ @concepts&.each_key { |key| searchs << key }
60
+ @contexts.each { |filter| searchs << filter.join(' ').to_s }
61
+ searchs.each do |search|
62
+ threads << Thread.new { urls[search] = ImageUrlLoader.load(search) }
63
+ end
64
+ threads.each(&:join) # wait for all threads to finish
65
+ urls
66
+ end
67
+ # rubocop:enable Metrics/MethodLength
68
+ # rubocop:enable Metrics/AbcSize
69
+ # rubocop:enable Metrics/CyclomaticComplexity
70
+ # rubocop:enable Metrics/PerceivedComplexity
55
71
  end
@@ -5,6 +5,11 @@ require_relative '../logger'
5
5
 
6
6
  # Export Code into Screen
7
7
  module CodeDisplayer
8
+ ##
9
+ # Show all "code" data on screen
10
+ # @param codes (Array) List of "code" data
11
+ # rubocop:disable Metrics/AbcSize
12
+ # rubocop:disable Metrics/MethodLength
8
13
  def self.show(codes)
9
14
  return if codes.nil? || codes.size.zero?
10
15
 
@@ -42,4 +47,6 @@ module CodeDisplayer
42
47
  Logger.verboseln "\n[INFO] Showing CODE statistics"
43
48
  Logger.verboseln my_screen_table.to_s
44
49
  end
50
+ # rubocop:enable Metrics/AbcSize
51
+ # rubocop:enable Metrics/MethodLength
45
52
  end
@@ -0,0 +1,10 @@
1
+
2
+ [INFO] Showing CONCEPT statistics
3
+ * Exclude questions: <%= exclude_questions %>
4
+ * Annotations:
5
+ ├── (d) Definitions <= Concept.def
6
+ ├── (b) Table Matching <= Concept.table.rows.columns
7
+ ├── (f) Tables 1 Field <= Concept.table.fields.size==1
8
+ ├── (i) Images URL <= Concept.def{:type => 'file'}
9
+ ├── (s) Sequences <= Concept.table{:sequence => '...'}
10
+ └── (t) Table Rows&Cols <= Concept.table.rows.columns
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'erb'
3
4
  require 'terminal-table'
5
+ require_relative '../application'
4
6
  require_relative '../logger'
5
7
 
6
8
  # Display ConceptAI stat on screen
@@ -8,11 +10,23 @@ class ConceptAIDisplayer
8
10
  ##
9
11
  # Display ConceptAI stat on screen
10
12
  # @param concepts_ai (Array)
13
+ # rubocop:disable Metrics/MethodLength
14
+ # rubocop:disable Metrics/AbcSize
15
+ # rubocop:disable Metrics/CyclomaticComplexity
16
+ # rubocop:disable Metrics/PerceivedComplexity
11
17
  def self.show(concepts_ai)
18
+ stages = Application.instance.config['questions']['stages']
12
19
  # Create table HEAD
13
20
  screen_table = Terminal::Table.new do |st|
14
- st << ['Concept','Questions','Entries','xFactor',
15
- 'd','b','f','i','s','t']
21
+ title = %w[Concept Questions Entries xFactor]
22
+ %w[d b f i s t].each do |i|
23
+ if stages.include? i.to_sym
24
+ title << i
25
+ next
26
+ end
27
+ title << Rainbow(i).yellow.bright
28
+ end
29
+ st << title
16
30
  st << :separator
17
31
  end
18
32
  # Create table BODY
@@ -22,32 +36,38 @@ class ConceptAIDisplayer
22
36
  total[:si] = total[:ss] = total[:st] = 0
23
37
 
24
38
  concepts_ai.each do |concept_ai|
25
- if concept_ai.process?
26
- e = concept_ai.texts.size
27
- concept_ai.tables.each { |t| e += t.fields.size * t.rows.size }
39
+ next unless concept_ai.concept.process?
28
40
 
29
- sd = concept_ai.questions[:d].size
30
- sb = concept_ai.questions[:b].size
31
- sf = concept_ai.questions[:f].size
32
- si = concept_ai.questions[:i].size
33
- ss = concept_ai.questions[:s].size
34
- st = concept_ai.questions[:t].size
35
- t = sd + sb + sf + si + ss + st
41
+ e = concept_ai.concept.texts.size
42
+ e += concept_ai.concept.images.size
43
+ concept_ai.concept.tables.each { |t| e += t.fields.size * t.rows.size }
36
44
 
37
- if e == 0
38
- factor = 'Unkown'
39
- else
40
- factor = (t.to_f/e.to_f).round(2).to_s
41
- end
42
- screen_table.add_row [Rainbow(concept_ai.name(:screen)).green.bright,
43
- t, e, factor, sd, sb, sf, si, ss, st]
45
+ sd = sb = sf = 0
46
+ si = ss = st = 0
47
+ sd = concept_ai.questions[:d].size if stages.include? :d
48
+ sb = concept_ai.questions[:b].size if stages.include? :b
49
+ sf = concept_ai.questions[:f].size if stages.include? :f
50
+ si = concept_ai.questions[:i].size if stages.include? :i
51
+ ss = concept_ai.questions[:s].size if stages.include? :s
52
+ st = concept_ai.questions[:t].size if stages.include? :t
53
+ t = sd + sb + sf + si + ss + st
44
54
 
45
- total[:q] += t ; total[:e] += e; total[:c] += 1
46
- total[:sd] += sd; total[:sb] += sb; total[:sf] += sf
47
- total[:si] += si; total[:ss] += ss; total[:st] += st
48
- end
55
+ factor = 'Unkown'
56
+ factor = (t.to_f / e).round(2).to_s unless e.zero?
57
+ screen_table.add_row [Rainbow(concept_ai.concept.name(:screen)).green.bright,
58
+ t, e, factor, sd, sb, sf, si, ss, st]
59
+
60
+ total[:q] += t
61
+ total[:e] += e
62
+ total[:c] += 1
63
+ total[:sd] += sd
64
+ total[:sb] += sb
65
+ total[:sf] += sf
66
+ total[:si] += si
67
+ total[:ss] += ss
68
+ total[:st] += st
49
69
  end
50
- return if total[:c] == 0 # No concepts to be process?
70
+ return if total[:c].zero? # No concepts to be process?
51
71
 
52
72
  # Add row with excluded questions
53
73
  export_excluded_questions(screen_table, concepts_ai)
@@ -57,13 +77,19 @@ class ConceptAIDisplayer
57
77
  screen_table.add_row [Rainbow("TOTAL = #{total[:c]}").bright,
58
78
  Rainbow(total[:q].to_s).bright,
59
79
  Rainbow(total[:e].to_s).bright,
60
- Rainbow((total[:q].to_f/total[:e].to_f).round(2)).bright,
80
+ Rainbow((total[:q].to_f / total[:e]).round(2)).bright,
61
81
  total[:sd], total[:sb], total[:sf],
62
82
  total[:si], total[:ss], total[:st]]
63
83
  export_notes
64
- Logger.verbose "#{screen_table}\n"
84
+ Logger.verboseln "#{screen_table}\n"
65
85
  end
86
+ # rubocop:enable Metrics/MethodLength
87
+ # rubocop:enable Metrics/AbcSize
88
+ # rubocop:enable Metrics/CyclomaticComplexity
89
+ # rubocop:enable Metrics/PerceivedComplexity
66
90
 
91
+ # rubocop:disable Metrics/MethodLength
92
+ # rubocop:disable Metrics/AbcSize
67
93
  private_class_method def self.export_excluded_questions(screen_table, concepts_ai)
68
94
  # Create table BODY
69
95
  total = {}
@@ -72,19 +98,24 @@ class ConceptAIDisplayer
72
98
  total[:si] = total[:ss] = total[:st] = 0
73
99
 
74
100
  concepts_ai.each do |concept_ai|
75
- if concept_ai.process?
76
- sd = concept_ai.excluded_questions[:d].size
77
- sb = concept_ai.excluded_questions[:b].size
78
- sf = concept_ai.excluded_questions[:f].size
79
- si = concept_ai.excluded_questions[:i].size
80
- ss = concept_ai.excluded_questions[:s].size
81
- st = concept_ai.excluded_questions[:t].size
82
- t = sd + sb + sf + si + ss + st
101
+ next unless concept_ai.concept.process?
83
102
 
84
- total[:q] += t ; total[:c] += 1
85
- total[:sd] += sd; total[:sb] += sb; total[:sf] += sf
86
- total[:si] += si; total[:ss] += ss; total[:st] += st
87
- end
103
+ sd = concept_ai.excluded_questions[:d].size
104
+ sb = concept_ai.excluded_questions[:b].size
105
+ sf = concept_ai.excluded_questions[:f].size
106
+ si = concept_ai.excluded_questions[:i].size
107
+ ss = concept_ai.excluded_questions[:s].size
108
+ st = concept_ai.excluded_questions[:t].size
109
+ t = sd + sb + sf + si + ss + st
110
+
111
+ total[:q] += t
112
+ total[:c] += 1
113
+ total[:sd] += sd
114
+ total[:sb] += sb
115
+ total[:sf] += sf
116
+ total[:si] += si
117
+ total[:ss] += ss
118
+ total[:st] += st
88
119
  end
89
120
  screen_table.add_row [Rainbow('Excluded questions').yellow.bright,
90
121
  total[:q], '-', '-',
@@ -92,22 +123,12 @@ class ConceptAIDisplayer
92
123
  total[:sf], total[:si],
93
124
  total[:ss], total[:st]]
94
125
  end
126
+ # rubocop:enable Metrics/MethodLength
127
+ # rubocop:enable Metrics/AbcSize
95
128
 
96
129
  private_class_method def self.export_notes
97
- Logger.verbose "\n[INFO] Showing CONCEPT statistics\n"
98
- Logger.verbose ' * Exclude questions: ' +
99
- Application.instance.config['questions']['exclude'].to_s
100
- Logger.verbose ' * Annotations:'
101
- Logger.verbose ' ├── (d) Definitions <= Concept.def'
102
- Logger.verbose ' ├── (b) Table Matching <= ' \
103
- 'Concept.table.rows.columns'
104
- Logger.verbose ' ├── (f) Tables 1 Field <= Concept.table.fields.size==1'
105
- Logger.verbose ' ├── (i) Images URL <= ' \
106
- "Concept.def{:type => 'image_url'}"
107
- Logger.verbose ' ├── (s) Sequences <= ' \
108
- "Concept.table{:sequence => '...'}"
109
- Logger.verbose ' └── (t) Table Rows&Cols <= ' \
110
- 'Concept.table.rows.columns'
111
- Logger.verbose "\n"
130
+ exclude_questions = Application.instance.config['questions']['exclude'].to_s
131
+ renderer = ERB.new(File.read(File.join(File.dirname(__FILE__), 'concept_ai_displayer.erb')))
132
+ Logger.verboseln renderer.result(binding)
112
133
  end
113
134
  end
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
1
2
 
3
+ require_relative '../application'
2
4
  require_relative '../formatter/concept_string_formatter'
3
5
  require_relative '../logger'
4
6
 
@@ -6,22 +8,27 @@ require_relative '../logger'
6
8
  module ConceptDisplayer
7
9
  ##
8
10
  # Show concepts on screen
9
- # @param concepts (Array)
10
- # @param show_mode (Symbol)
11
- def self.show(concepts, show_mode = :default)
12
- return if show_mode == :none
11
+ # @param concepts (Array) List of concept data
12
+ # rubocop:disable Metrics/AbcSize
13
+ # rubocop:disable Metrics/MethodLength
14
+ def self.show(concepts)
15
+ show_mode = Application.instance.config['global']['show_mode']
16
+ return unless show_mode
17
+
13
18
  msg = "\n[INFO] Showing concept data (#{Rainbow(show_mode).bright})"
14
- Logger.verbose msg
19
+ Logger.verboseln msg
15
20
  case show_mode
16
- when :resume
21
+ when 'resume'
17
22
  s = "* Concepts (#{concepts.count}): "
18
23
  concepts.each { |c| s += c.name + ', ' }
19
- Logger.verbose s
20
- when :default
24
+ Logger.verboseln s
25
+ when 'default'
21
26
  # Only show Concepts with process attr true
22
27
  concepts.each do |c|
23
- Logger.verbose ConceptStringFormatter.to_s(c) if c.process?
28
+ Logger.verboseln ConceptStringFormatter.to_s(c) if c.process?
24
29
  end
25
30
  end
26
31
  end
32
+ # rubocop:enable Metrics/AbcSize
33
+ # rubocop:enable Metrics/MethodLength
27
34
  end
@@ -1,13 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../application'
1
4
  require_relative 'concept_ai_displayer'
2
5
  require_relative 'code_displayer'
3
6
 
4
7
  # Display Stats on screen.
8
+ # * Display all "Concept AI"
9
+ # * Display all "Code"
5
10
  module StatsDisplayer
6
- def self.show(data, show_mode)
7
- return if show_mode == :none
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
15
+ def self.show(data)
16
+ return unless Application.instance.config['global']['show_mode']
8
17
 
9
18
  # show_final_results
10
19
  ConceptAIDisplayer.show(data[:concepts_ai])
11
- CodeDisplayer.show(data[:codes])
20
+ CodeDisplayer.show(data[:codes_ai])
12
21
  end
13
22
  end
@@ -1,29 +1,37 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require_relative '../project'
4
3
  require_relative '../formatter/question_gift_formatter'
5
4
 
6
5
  # Export ConceptIA data to gift to outputfile
7
6
  module ConceptAIGiftExporter
8
7
  ##
9
- # Export list of ConceptAI into outpufile
10
- def self.export_all(concepts_ai, project)
11
- concepts_ai.each { |concept_ai| export(concept_ai, project) }
8
+ # Export an array of ConceptAI objects from Project into GIFT outpufile
9
+ # @param concepts_ai (Array)
10
+ # @param file (File)
11
+ def self.export_all(concepts_ai, file)
12
+ concepts_ai.each { |concept_ai| export(concept_ai, file) }
12
13
  end
13
14
 
14
- def self.export(concept_ai, project)
15
- return unless concept_ai.process?
15
+ ##
16
+ # Export 1 concept_ai from project
17
+ # @param concept_ai (ConceptAI)
18
+ # @param file (File)
19
+ private_class_method def self.export(concept_ai, file)
20
+ return unless concept_ai.concept.process?
16
21
 
17
- file = project.get(:outputfile)
18
- file.write head(concept_ai.name)
19
- project.stages.each_key do |stage|
22
+ file.write head(concept_ai.concept.name)
23
+ Application.instance.config['questions']['stages'].each do |stage|
20
24
  concept_ai.questions[stage].each do |question|
21
25
  file.write(QuestionGiftFormatter.to_s(question))
22
26
  end
23
27
  end
24
28
  end
25
29
 
26
- def self.head(name)
30
+ ##
31
+ # Convert Concept name into gift format head
32
+ # @param name (String)
33
+ # @return String
34
+ private_class_method def self.head(name)
27
35
  s = "\n"
28
36
  s += '// ' + '=' * 50 + "\n"
29
37
  s += "// Concept name: #{name}\n"