asker-tool 2.1.2 → 2.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/{LICENSE → LICENSE.txt} +0 -0
  3. data/README.md +17 -18
  4. data/bin/asker +1 -0
  5. data/lib/asker.rb +43 -74
  6. data/lib/asker/ai/ai.rb +4 -0
  7. data/lib/asker/ai/code/base_code_ai.rb +104 -0
  8. data/lib/asker/{code/ai → ai/code}/code_ai_factory.rb +11 -1
  9. data/lib/asker/{code/ai → ai/code}/javascript_code_ai.rb +2 -5
  10. data/lib/asker/ai/code/problem_code_ai.rb +176 -0
  11. data/lib/asker/{code/ai → ai/code}/python_code_ai.rb +2 -5
  12. data/lib/asker/{code/ai → ai/code}/ruby_code_ai.rb +14 -7
  13. data/lib/asker/{code/ai → ai/code}/sql_code_ai.rb +2 -5
  14. data/lib/asker/ai/concept_ai.rb +1 -0
  15. data/lib/asker/ai/stages/stage_t.rb +76 -76
  16. data/lib/asker/application.rb +19 -3
  17. data/lib/asker/checker.rb +152 -53
  18. data/lib/asker/cli.rb +19 -22
  19. data/lib/asker/data/code.rb +73 -0
  20. data/lib/asker/data/column.rb +31 -21
  21. data/lib/asker/data/concept.rb +42 -45
  22. data/lib/asker/data/data_field.rb +14 -0
  23. data/lib/asker/data/row.rb +75 -52
  24. data/lib/asker/data/table.rb +89 -42
  25. data/lib/asker/data/world.rb +58 -32
  26. data/lib/asker/{exporter/code_screen_exporter.rb → displayer/code_displayer.rb} +6 -6
  27. data/lib/asker/displayer/concept_ai_displayer.rb +132 -0
  28. data/lib/asker/displayer/concept_displayer.rb +29 -0
  29. data/lib/asker/displayer/stats_displayer.rb +14 -0
  30. data/lib/asker/exporter/code_gift_exporter.rb +10 -11
  31. data/lib/asker/exporter/concept_ai_gift_exporter.rb +23 -11
  32. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +9 -7
  33. data/lib/asker/exporter/concept_doc_exporter.rb +9 -15
  34. data/lib/asker/exporter/output_file_exporter.rb +18 -0
  35. data/lib/asker/files/config.ini +37 -0
  36. data/lib/asker/files/example-code.haml +0 -0
  37. data/lib/asker/files/example-concept.haml +29 -0
  38. data/lib/asker/files/language/du/templates.yaml +50 -0
  39. data/lib/asker/files/language/en/connectors.yaml +44 -0
  40. data/lib/asker/files/language/en/mistakes.yaml +37 -0
  41. data/lib/asker/files/language/en/templates.yaml +29 -0
  42. data/lib/asker/files/language/es/connectors.yaml +92 -0
  43. data/lib/asker/files/language/es/mistakes.yaml +82 -0
  44. data/lib/asker/files/language/es/templates.yaml +29 -0
  45. data/lib/asker/files/language/fr/connectors.yaml +92 -0
  46. data/lib/asker/files/language/fr/mistakes.yaml +82 -0
  47. data/lib/asker/files/language/fr/templates.yaml +29 -0
  48. data/lib/asker/files/language/javascript/connectors.yaml +11 -0
  49. data/lib/asker/files/language/javascript/mistakes.yaml +30 -0
  50. data/lib/asker/files/language/javascript/templates.yaml +3 -0
  51. data/lib/asker/files/language/math/connectors.yaml +2 -0
  52. data/lib/asker/files/language/math/mistakes.yaml +2 -0
  53. data/lib/asker/files/language/math/templates.yaml +1 -0
  54. data/lib/asker/files/language/python/connectors.yaml +11 -0
  55. data/lib/asker/files/language/python/mistakes.yaml +26 -0
  56. data/lib/asker/files/language/python/templates.yaml +3 -0
  57. data/lib/asker/files/language/ruby/connectors.yaml +11 -0
  58. data/lib/asker/files/language/ruby/mistakes.yaml +33 -0
  59. data/lib/asker/files/language/ruby/templates.yaml +3 -0
  60. data/lib/asker/files/language/sql/connectors.yaml +6 -0
  61. data/lib/asker/files/language/sql/mistakes.yaml +11 -0
  62. data/lib/asker/files/language/sql/templates.yaml +2 -0
  63. data/lib/asker/formatter/concept_string_formatter.rb +9 -8
  64. data/lib/asker/formatter/question_gift_formatter.rb +9 -1
  65. data/lib/asker/lang/lang.rb +18 -12
  66. data/lib/asker/lang/lang_factory.rb +26 -5
  67. data/lib/asker/lang/text_actions.rb +87 -69
  68. data/lib/asker/loader/code_loader.rb +3 -3
  69. data/lib/asker/loader/content_loader.rb +9 -5
  70. data/lib/asker/loader/file_loader.rb +2 -11
  71. data/lib/asker/loader/haml_loader.rb +15 -0
  72. data/lib/asker/loader/image_url_loader.rb +5 -8
  73. data/lib/asker/loader/input_loader.rb +23 -7
  74. data/lib/asker/loader/project_loader.rb +32 -29
  75. data/lib/asker/logger.rb +3 -4
  76. data/lib/asker/project.rb +28 -52
  77. data/lib/asker/skeleton.rb +73 -0
  78. metadata +62 -73
  79. data/docs/changelog/v2.1.md +0 -99
  80. data/docs/commands.md +0 -15
  81. data/docs/contributions.md +0 -18
  82. data/docs/history.md +0 -40
  83. data/docs/idea.md +0 -44
  84. data/docs/inputs/README.md +0 -39
  85. data/docs/inputs/code.md +0 -69
  86. data/docs/inputs/concepts.md +0 -142
  87. data/docs/inputs/jedi.md +0 -68
  88. data/docs/inputs/tables.md +0 -112
  89. data/docs/inputs/templates.md +0 -87
  90. data/docs/install/README.md +0 -38
  91. data/docs/install/manual.md +0 -26
  92. data/docs/install/scripts.md +0 -26
  93. data/docs/revise/asker-file.md +0 -41
  94. data/docs/revise/buenas-practicas/01-convocatoria.md +0 -30
  95. data/docs/revise/buenas-practicas/02-formulario.md +0 -35
  96. data/docs/revise/buenas-practicas/03-descripcion.md +0 -63
  97. data/docs/revise/buenas-practicas/04-resultados.md +0 -17
  98. data/docs/revise/buenas-practicas/05-reproducir.md +0 -10
  99. data/docs/revise/ejemplos/01/README.md +0 -27
  100. data/docs/revise/ejemplos/02/README.md +0 -31
  101. data/docs/revise/ejemplos/03/README.md +0 -31
  102. data/docs/revise/ejemplos/04/README.md +0 -37
  103. data/docs/revise/ejemplos/05/README.md +0 -25
  104. data/docs/revise/ejemplos/06/README.md +0 -43
  105. data/docs/revise/ejemplos/README.md +0 -11
  106. data/docs/revise/projects.md +0 -74
  107. data/lib/asker/code/ai/base_code_ai.rb +0 -48
  108. data/lib/asker/code/code.rb +0 -53
  109. data/lib/asker/exporter/concept_ai_screen_exporter.rb +0 -115
  110. data/lib/asker/exporter/concept_screen_exporter.rb +0 -25
  111. data/lib/asker/exporter/main.rb +0 -9
@@ -21,7 +21,6 @@ class CLI < Thor
21
21
 
22
22
  map ['f', '-f', '--file'] => 'file'
23
23
  desc 'file NAME', 'Build output files, from HAML/XML input file.'
24
- option :color, type: :boolean
25
24
  long_desc <<-LONGDESC
26
25
  Create output files, from input file (HAML/XML format).
27
26
 
@@ -33,34 +32,15 @@ class CLI < Thor
33
32
 
34
33
  (2) #{Rainbow('asker input/foo/foo.xml').yellow}, Build questions from XML file.
35
34
 
36
- (3) #{Rainbow('asker file --no-color input/foo/foo.haml').yellow}, Same as (1) but without colors.
37
-
38
- (4) #{Rainbow('asker projects/foo/foo.yaml').yellow}, Build questions from YAML project file.
35
+ (3) #{Rainbow('asker projects/foo/foo.yaml').yellow}, Build questions from YAML project file.
39
36
 
40
37
  LONGDESC
41
38
  ##
42
39
  # Create questions from input file
43
40
  # @param filename (String) Path to input file
44
41
  def file(filename)
45
- # Enable/disable color output
46
- Rainbow.enabled = false if options['color'] == false
47
42
  # Asker start processing input file
48
- Asker.new.start(filename)
49
- end
50
-
51
- map ['i', '-i', '--init'] => 'init'
52
- desc 'init', 'Create default INI config fie'
53
- ##
54
- # Create default INI config file
55
- def init
56
- src = File.join(File.dirname(__FILE__), 'files', 'config.ini')
57
- dst = File.join(Dir.pwd, 'config.ini')
58
- if File.exist? dst
59
- puts "[WARN] Exists file! => #{Rainbow(File.basename(dst)).yellow.bright}"
60
- else
61
- FileUtils.cp(src, dst)
62
- puts "[ OK ] Create file => #{Rainbow(File.basename(dst)).green}"
63
- end
43
+ Asker.start(filename)
64
44
  end
65
45
 
66
46
  map ['c', '-c', '--check'] => 'check'
@@ -75,6 +55,23 @@ class CLI < Thor
75
55
  Asker.check(filename)
76
56
  end
77
57
 
58
+ map ['i', '-i', '--init'] => 'init'
59
+ desc 'init', 'Create default INI config fie'
60
+ ##
61
+ # Create default INI config file
62
+ def init
63
+ Asker.create_configuration
64
+ end
65
+
66
+ map ['n', '-b', '--new', 'new'] => 'create_input'
67
+ desc 'new', 'Create Asker demo input files'
68
+ ##
69
+ # Create Asker demo input files
70
+ # @param dirname (String) Path to folder
71
+ def create_input(dirname)
72
+ Asker.create_input(dirname)
73
+ end
74
+
78
75
  ##
79
76
  # This actions are equals:
80
77
  # * asker demo/foo.haml
@@ -0,0 +1,73 @@
1
+ require_relative '../ai/code/code_ai_factory'
2
+ require_relative '../project'
3
+ require_relative '../logger'
4
+ require_relative '../formatter/code_string_formatter'
5
+
6
+ ##
7
+ # Code data object
8
+ class Code
9
+ attr_reader :dirname, :filename, :type
10
+ attr_accessor :process, :features
11
+ attr_reader :lines, :questions
12
+
13
+ ##
14
+ # Initialize Code object
15
+ # @param dirname (String)
16
+ # @param filename (String)
17
+ # @param type (String)
18
+ def initialize(dirname, filename, type)
19
+ @dirname = dirname
20
+ @filename = filename
21
+ @type = type
22
+ @filepath = File.join(@dirname, @filename)
23
+ @process = false
24
+ @features = []
25
+ @lines = load(@filepath)
26
+ @questions = []
27
+ end
28
+
29
+ def process?
30
+ @process
31
+ end
32
+
33
+ def lines_to_s(lines)
34
+ out = ''
35
+ lines.each_with_index do |line, index|
36
+ out << format("%2d| #{line}\n", (index + 1))
37
+ end
38
+ out
39
+ end
40
+
41
+ def debug
42
+ Logger.verbose CodeStringFormatter.to_s(self)
43
+ end
44
+
45
+ private
46
+
47
+ def load(filepath)
48
+ return if filepath.nil?
49
+ unless File.exist? filepath
50
+ Logger.verboseln Rainbow("[ERROR] Unkown file #{filepath}").red.bright
51
+ return
52
+ end
53
+ content = File.read(filepath)
54
+ encode_and_split(content)
55
+ end
56
+
57
+ def encode_and_split(text, encoding = :default)
58
+ # Convert text to UTF-8 deleting unknown chars
59
+ text = text || '' # Ensure text is not nil
60
+ flag = [:default, 'UTF-8'].include? encoding
61
+ return text.encode('UTF-8', invalid: :replace).split("\n") if flag
62
+
63
+ # Convert text from input ENCODING to UTF-8
64
+ ec = Encoding::Converter.new(encoding.to_s, 'UTF-8')
65
+ begin
66
+ text = ec.convert(text)
67
+ rescue StandardError => e
68
+ puts "[ERROR] Encoding: #{e}"
69
+ end
70
+
71
+ text.split("\n")
72
+ end
73
+ end
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # encoding: utf-8
3
2
 
4
3
  # Contain data information for every column
5
4
  # Params:
@@ -9,10 +8,15 @@
9
8
  class Column
10
9
  attr_reader :row, :index, :id, :raw, :lang, :type, :simple
11
10
 
11
+ ##
12
+ # initialize Column
13
+ # @param row (Row)
14
+ # @param index (Integer)
15
+ # @param xml_data (XMLdata)
12
16
  def initialize(row, index, xml_data)
13
17
  @row = row
14
18
  @index = index
15
- @id = @row.id + '.' + @index.to_s
19
+ @id = "#{@row.id}.#{@index}"
16
20
  @raw = ''
17
21
  @lang = @row.langs[@index]
18
22
  @type = @row.types[@index]
@@ -28,35 +32,41 @@ class Column
28
32
  return "<img src=\"#{raw}\" alt\=\"image\">"
29
33
  when 'textfile_path'
30
34
  return "<pre>#{raw}</pre>"
31
- else
32
- return "ERROR type #{@type}"
33
35
  end
36
+ "ERROR type #{@type}"
34
37
  end
35
38
 
36
39
  private
37
40
 
38
41
  def read_data_from_xml(xml_data)
39
- raise '[ERROR] Column XML data with elements!' if xml_data.elements.count.positive?
42
+ raise '[ERROR] Column with elements!' if xml_data.elements.count.positive?
40
43
 
41
44
  @raw = xml_data.text.strip.to_s
42
45
 
43
46
  # read attributes from XML input data
44
- if xml_data.attributes['lang']
45
- code = xml_data.attributes['lang'].strip
46
- if code != @lang.code
47
- @lang = LangFactory.instance.get(code)
48
- @simple[:lang] = false
49
- @row.simple_off(:lang)
50
- end
51
- end
47
+ read_lang_from_xml(xml_data)
48
+ read_type_from_xml(xml_data)
49
+ end
52
50
 
53
- if xml_data.attributes['type']
54
- type = xml_data.attributes['type'].strip
55
- if type != @type.to_s
56
- @type = type
57
- @simple[:type] = false
58
- @row.simple_off(:type)
59
- end
60
- end
51
+ def read_lang_from_xml(xml_data)
52
+ return unless xml_data.attributes['lang']
53
+
54
+ code = xml_data.attributes['lang'].strip
55
+ return if code == @lang.code
56
+
57
+ @lang = LangFactory.instance.get(code)
58
+ @simple[:lang] = false
59
+ @row.simple_off(:lang)
60
+ end
61
+
62
+ def read_type_from_xml(xml_data)
63
+ return unless xml_data.attributes['type']
64
+
65
+ type = xml_data.attributes['type'].strip
66
+ return if type == @type.to_s
67
+
68
+ @type = type
69
+ @simple[:type] = false
70
+ @row.simple_off(:type)
61
71
  end
62
72
  end
@@ -3,11 +3,13 @@
3
3
  require 'rainbow'
4
4
  require 'rexml/document'
5
5
 
6
- require_relative '../project'
6
+ require_relative '../application'
7
+ require_relative '../logger'
7
8
  require_relative '../lang/lang_factory'
8
9
  require_relative 'table'
9
10
  require_relative 'data_field'
10
11
 
12
+ ##
11
13
  # Store Concept information
12
14
  class Concept
13
15
  attr_reader :id, :lang, :context
@@ -15,8 +17,14 @@ class Concept
15
17
  attr_reader :data
16
18
  attr_accessor :process
17
19
 
18
- @@id = 0
20
+ @@id = 0 # Concept counter
19
21
 
22
+ ##
23
+ # Initilize Concept
24
+ # @param xml_data (XML)
25
+ # @param filename (String)
26
+ # @param lang_code (String)
27
+ # @param context (Array)
20
28
  def initialize(xml_data, filename, lang_code = 'en', context = [])
21
29
  @@id += 1
22
30
  @id = @@id
@@ -72,38 +80,43 @@ class Concept
72
80
  end
73
81
 
74
82
  def calculate_nearness_to_concept(other)
75
- weights = Project.instance.formula_weights
83
+ a = Application.instance.config['ai']['formula_weights']
84
+ weights = a.split(',').map(&:to_f)
76
85
 
77
- li_max1 = @context.count
78
- li_max2 = @data[:tags].count
79
- li_max3 = @data[:tables].count
86
+ max1 = @context.count
87
+ max2 = @data[:tags].count
88
+ max3 = @data[:tables].count
80
89
 
81
- lf_alike1 = lf_alike2 = lf_alike3 = 0.0
90
+ alike1 = alike2 = alike3 = 0.0
82
91
 
83
92
  # check if exists this items from concept1 into concept2
84
- @context.each { |i| lf_alike1 += 1.0 unless other.context.index(i).nil? }
85
- @data[:tags].each { |i| lf_alike2 += 1.0 unless other.tags.index(i).nil? }
86
- @data[:tables].each { |i| lf_alike3 += 1.0 unless other.tables.index(i).nil? }
93
+ @context.each { |i| alike1 += 1.0 unless other.context.index(i).nil? }
94
+ @data[:tags].each { |i| alike2 += 1.0 unless other.tags.index(i).nil? }
95
+ @data[:tables].each { |i| alike3 += 1.0 unless other.tables.index(i).nil? }
87
96
 
88
- lf_alike = (lf_alike1 * weights[0] + lf_alike2 * weights[1] + lf_alike3 * weights[2])
89
- li_max = (li_max1 * weights[0] + li_max2 * weights[1] + li_max3 * weights[2])
90
- (lf_alike * 100.0 / li_max)
97
+ alike = (alike1 * weights[0] + alike2 * weights[1] + alike3 * weights[2])
98
+ max = (max1 * weights[0] + max2 * weights[1] + max3 * weights[2])
99
+ (alike * 100.0 / max)
91
100
  end
92
101
 
102
+ # rubocop:disable Metrics/MethodLength
93
103
  def try_adding_references(other)
94
104
  reference_to = 0
95
- @data[:tags].each { |i| reference_to += 1 unless other.names.index(i.downcase).nil? }
105
+ @data[:tags].each do |i|
106
+ reference_to += 1 unless other.names.index(i.downcase).nil?
107
+ end
96
108
  @data[:texts].each do |t|
97
109
  text = t.clone
98
110
  text.split(' ').each do |word|
99
111
  reference_to += 1 unless other.names.index(word.downcase).nil?
100
112
  end
101
113
  end
102
- if reference_to.positive?
103
- @data[:reference_to] << other.name
104
- other.data[:referenced_by] << name
105
- end
114
+ return unless reference_to.positive?
115
+
116
+ @data[:reference_to] << other.name
117
+ other.data[:referenced_by] << name
106
118
  end
119
+ # rubocop:enable Metrics/MethodLength
107
120
 
108
121
  def method_missing(method)
109
122
  @data[method]
@@ -111,6 +124,7 @@ class Concept
111
124
 
112
125
  private
113
126
 
127
+ # rubocop:disable Metrics/MethodLength
114
128
  def read_data_from_xml(xml_data)
115
129
  xml_data.elements.each do |i|
116
130
  case i.name
@@ -118,24 +132,17 @@ class Concept
118
132
  process_names(i)
119
133
  when 'tags'
120
134
  process_tags(i)
121
- when 'context'
122
- # DEPRECATED: Don't use xml tag <context>
123
- # instead define it as attibute of root xml tag
124
- process_context(i)
125
- when 'text'
126
- # DEPRECATED: Use xml tag <def> instead of <text>
127
- process_text(i)
128
135
  when 'def'
129
136
  process_def(i)
130
137
  when 'table'
131
138
  @data[:tables] << Table.new(self, i)
132
139
  else
133
140
  text = " [ERROR] <#{i.name}> unkown XML attribute for concept #{name}"
134
- msg = Rainbow(text).color(:red)
135
- Project.instance.verbose msg
141
+ Logger.verbose Rainbow(text).color(:red)
136
142
  end
137
143
  end
138
144
  end
145
+ # rubocop:enable Metrics/MethodLength
139
146
 
140
147
  def process_names(value)
141
148
  @names = []
@@ -145,28 +152,16 @@ class Concept
145
152
  end
146
153
 
147
154
  def process_tags(value)
148
- raise '[Error] tags label empty!' if value.text.nil? || value.text.size.zero?
155
+ if value.text.nil? || value.text.size.zero?
156
+ raise '[Error] tags label empty!'
157
+ end
158
+
149
159
  @data[:tags] = value.text.split(',')
150
160
  @data[:tags].collect!(&:strip)
151
161
  end
152
162
 
153
- def process_context(value)
154
- msg = ' │  ' + Rainbow(' [DEPRECATED] Concept ').yellow
155
- msg += Rainbow(name).yellow.bright
156
- msg += Rainbow(' move <context> tag info to <map>.').yellow
157
- Project.instance.verbose msg
158
- @context = value.text.split(',')
159
- @context.collect!(&:strip)
160
- end
161
-
162
- def process_text(value)
163
- msg = ' │  ' + Rainbow(' [DEPRECATED] Concept ').yellow
164
- msg += Rainbow(name).yellow.bright
165
- msg += Rainbow(' replace <text> tag by <def>.').yellow
166
- Project.instance.verbose msg
167
- @data[:texts] << value.text.strip
168
- end
169
-
163
+ # rubocop:disable Metrics/AbcSize
164
+ # rubocop:disable Metrics/MethodLength
170
165
  def process_def(value)
171
166
  case value.attributes['type']
172
167
  when 'image'
@@ -180,4 +175,6 @@ class Concept
180
175
  @data[:texts] << value.text.strip
181
176
  end
182
177
  end
178
+ # rubocop:enable Metrics/AbcSize
179
+ # rubocop:enable Metrics/MethodLength
183
180
  end
@@ -8,12 +8,19 @@
8
8
  class DataField
9
9
  attr_reader :id, :type
10
10
 
11
+ ##
12
+ # initialize DataField
11
13
  def initialize(data, id, type)
12
14
  @data = data
13
15
  @id = id.to_i # TODO: revise where it comes from? Is it unique value?
14
16
  @type = type.to_sym
15
17
  end
16
18
 
19
+ ##
20
+ # Return internal data
21
+ # @param option (Symbol)
22
+ # @return String
23
+ # rubocop:disable Metrics/MethodLength
17
24
  def get(option = :raw)
18
25
  case @type
19
26
  when :text
@@ -27,6 +34,7 @@ class DataField
27
34
  end
28
35
  raise ".get: data=#{@data}, type=#{@type}, option=#{option}"
29
36
  end
37
+ # rubocop:enable Metrics/MethodLength
30
38
 
31
39
  private
32
40
 
@@ -36,6 +44,7 @@ class DataField
36
44
  @data
37
45
  end
38
46
 
47
+ # rubocop:disable Metrics/MethodLength
39
48
  def get_textfile_path(option)
40
49
  case option
41
50
  when :raw
@@ -50,7 +59,9 @@ class DataField
50
59
  end
51
60
  raise ".get_textfile_path: data=#{@data}, type=#{@type}, option=#{option}"
52
61
  end
62
+ # rubocop:enable Metrics/MethodLength
53
63
 
64
+ # rubocop:disable Metrics/MethodLength
54
65
  def get_textfile_url(option)
55
66
  case option
56
67
  when :raw
@@ -64,7 +75,9 @@ class DataField
64
75
  end
65
76
  raise ".get_textfile_url: data=#{@data}, type=#{@type}, option=#{option}"
66
77
  end
78
+ # rubocop:enable Metrics/MethodLength
67
79
 
80
+ # rubocop:disable Metrics/MethodLength
68
81
  def get_image_url(option)
69
82
  case option
70
83
  when :raw
@@ -78,6 +91,7 @@ class DataField
78
91
  end
79
92
  raise ".get_image_url: data=#{@data}, type=#{@type}, option=#{option}"
80
93
  end
94
+ # rubocop:enable Metrics/MethodLength
81
95
 
82
96
  def to_screen(text)
83
97
  return text[0, 7] + '...' + text[-15, 15] if text.size > 25