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.
- checksums.yaml +4 -4
- data/README.md +13 -17
- data/bin/asker +2 -1
- data/lib/asker/ai/ai.rb +10 -3
- data/lib/asker/ai/ai_calculate.rb +20 -6
- data/lib/asker/ai/code/base_code_ai.rb +104 -0
- data/lib/asker/{code/ai → ai/code}/code_ai_factory.rb +11 -1
- data/lib/asker/{code/ai → ai/code}/javascript_code_ai.rb +2 -5
- data/lib/asker/ai/code/problem_code_ai.rb +176 -0
- data/lib/asker/{code/ai → ai/code}/python_code_ai.rb +2 -5
- data/lib/asker/{code/ai → ai/code}/ruby_code_ai.rb +14 -7
- data/lib/asker/{code/ai → ai/code}/sql_code_ai.rb +2 -5
- data/lib/asker/ai/concept_ai.rb +13 -3
- data/lib/asker/ai/question.rb +28 -6
- data/lib/asker/ai/stages/base_stage.rb +45 -6
- data/lib/asker/ai/stages/stage_b.rb +100 -50
- data/lib/asker/ai/stages/stage_d.rb +75 -90
- data/lib/asker/ai/stages/stage_f.rb +64 -36
- data/lib/asker/ai/stages/stage_i.rb +79 -92
- data/lib/asker/ai/stages/stage_s.rb +41 -36
- data/lib/asker/ai/stages/stage_t.rb +149 -108
- data/lib/asker/application.rb +19 -11
- data/lib/asker/cli.rb +31 -44
- data/lib/asker/data/code.rb +62 -0
- data/lib/asker/data/column.rb +31 -21
- data/lib/asker/data/concept.rb +109 -65
- data/lib/asker/data/data_field.rb +14 -0
- data/lib/asker/data/project_data.rb +63 -0
- data/lib/asker/data/row.rb +75 -52
- data/lib/asker/data/table.rb +91 -42
- data/lib/asker/data/template.rb +3 -1
- data/lib/asker/data/world.rb +51 -35
- data/lib/asker/displayer/code_displayer.rb +7 -0
- data/lib/asker/displayer/concept_ai_displayer.erb +10 -0
- data/lib/asker/displayer/concept_ai_displayer.rb +74 -53
- data/lib/asker/displayer/concept_displayer.rb +16 -9
- data/lib/asker/displayer/stats_displayer.rb +12 -3
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +19 -11
- data/lib/asker/exporter/concept_ai_moodle_exporter.rb +44 -0
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +13 -6
- data/lib/asker/exporter/concept_doc_exporter.rb +14 -1
- data/lib/asker/exporter/data_gift_exporter.rb +29 -0
- data/lib/asker/exporter/output_file_exporter.rb +9 -6
- data/lib/asker/files/{config.ini → asker.ini} +48 -1
- data/lib/asker/files/example-concept.haml +0 -1
- data/lib/asker/files/language/du/connectors.yaml +81 -0
- data/lib/asker/{lang/locales/fr → files/language/du}/mistakes.yaml +1 -1
- data/lib/asker/files/language/du/templates.yaml +29 -0
- data/lib/asker/{lang/locales → files/language}/en/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/en/mistakes.yaml +0 -0
- data/lib/asker/files/language/en/templates.yaml +29 -0
- data/lib/asker/{lang/locales → files/language}/es/connectors.yaml +0 -0
- data/lib/asker/files/language/es/mistakes.yaml +84 -0
- data/lib/asker/files/language/es/templates.yaml +29 -0
- data/lib/asker/files/language/fr/connectors.yaml +76 -0
- data/lib/asker/{lang/locales/es → files/language/fr}/mistakes.yaml +0 -0
- data/lib/asker/files/language/fr/templates.yaml +29 -0
- data/lib/asker/{lang/locales → files/language}/javascript/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/javascript/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/javascript/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/math/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/math/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/math/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/python/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/python/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/python/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/ruby/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/ruby/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/ruby/templates.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/sql/connectors.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/sql/mistakes.yaml +0 -0
- data/lib/asker/{lang/locales → files/language}/sql/templates.yaml +0 -0
- data/lib/asker/formatter/concept_doc_formatter.rb +0 -4
- data/lib/asker/formatter/concept_string_formatter.rb +7 -4
- data/lib/asker/formatter/moodle/matching.erb +38 -0
- data/lib/asker/formatter/moodle/multichoice.erb +49 -0
- data/lib/asker/formatter/moodle/shortanswer.erb +30 -0
- data/lib/asker/formatter/moodle/truefalse.erb +47 -0
- data/lib/asker/formatter/question_gift_formatter.rb +30 -20
- data/lib/asker/formatter/question_moodle_formatter.rb +27 -0
- data/lib/asker/{checker.rb → input_checker.rb} +126 -49
- data/lib/asker/lang/lang.rb +17 -10
- data/lib/asker/lang/lang_factory.rb +32 -5
- data/lib/asker/lang/text_actions.rb +87 -69
- data/lib/asker/loader/code_loader.rb +4 -4
- data/lib/asker/loader/content_loader.rb +21 -19
- data/lib/asker/loader/directory_loader.rb +1 -8
- data/lib/asker/loader/embedded_file.rb +42 -0
- data/lib/asker/loader/file_loader.rb +3 -14
- data/lib/asker/loader/haml_loader.rb +15 -0
- data/lib/asker/loader/image_url_loader.rb +8 -12
- data/lib/asker/loader/input_loader.rb +13 -15
- data/lib/asker/loader/project_loader.rb +25 -15
- data/lib/asker/logger.rb +36 -9
- data/lib/asker/skeleton.rb +23 -13
- data/lib/asker.rb +76 -42
- metadata +53 -54
- data/lib/asker/code/ai/base_code_ai.rb +0 -48
- data/lib/asker/code/code.rb +0 -53
- data/lib/asker/lang/locales/du/templates.yaml +0 -50
- data/lib/asker/lang/locales/en/templates.yaml +0 -29
- data/lib/asker/lang/locales/es/templates.yaml +0 -29
- data/lib/asker/lang/locales/fr/connectors.yaml +0 -92
- data/lib/asker/lang/locales/fr/templates.yaml +0 -29
- data/lib/asker/project.rb +0 -172
data/lib/asker/data/table.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
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, :
|
10
|
-
attr_reader :
|
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
|
-
|
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
|
-
@
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
data/lib/asker/data/template.rb
CHANGED
@@ -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
|
data/lib/asker/data/world.rb
CHANGED
@@ -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,
|
8
|
+
def initialize(concepts, internet = true)
|
10
9
|
find_neighbors_for_every_concept(concepts)
|
11
|
-
|
12
|
-
@
|
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
|
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
|
-
|
15
|
-
|
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
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
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
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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]
|
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]
|
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.
|
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
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|
-
|
98
|
-
|
99
|
-
|
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
|
-
#
|
11
|
-
|
12
|
-
|
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.
|
19
|
+
Logger.verboseln msg
|
15
20
|
case show_mode
|
16
|
-
when
|
21
|
+
when 'resume'
|
17
22
|
s = "* Concepts (#{concepts.count}): "
|
18
23
|
concepts.each { |c| s += c.name + ', ' }
|
19
|
-
Logger.
|
20
|
-
when
|
24
|
+
Logger.verboseln s
|
25
|
+
when 'default'
|
21
26
|
# Only show Concepts with process attr true
|
22
27
|
concepts.each do |c|
|
23
|
-
Logger.
|
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
|
-
|
7
|
-
|
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[:
|
20
|
+
CodeDisplayer.show(data[:codes_ai])
|
12
21
|
end
|
13
22
|
end
|
@@ -1,29 +1,37 @@
|
|
1
|
-
#
|
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
|
10
|
-
|
11
|
-
|
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
|
-
|
15
|
-
|
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
|
18
|
-
|
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
|
-
|
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"
|