asker-tool 2.1.3 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +18 -19
  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 +12 -2
  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 +24 -7
  23. data/lib/asker/checker.rb +149 -52
  24. data/lib/asker/cli.rb +37 -32
  25. data/lib/asker/data/code.rb +76 -0
  26. data/lib/asker/data/column.rb +31 -21
  27. data/lib/asker/data/concept.rb +108 -65
  28. data/lib/asker/data/data_field.rb +14 -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 +61 -32
  33. data/lib/asker/{exporter/code_screen_exporter.rb → displayer/code_displayer.rb} +13 -6
  34. data/lib/asker/displayer/concept_ai_displayer.erb +10 -0
  35. data/lib/asker/displayer/concept_ai_displayer.rb +133 -0
  36. data/lib/asker/displayer/concept_displayer.rb +34 -0
  37. data/lib/asker/displayer/stats_displayer.rb +22 -0
  38. data/lib/asker/exporter/code_gift_exporter.rb +10 -11
  39. data/lib/asker/exporter/concept_ai_gift_exporter.rb +21 -13
  40. data/lib/asker/exporter/concept_ai_moodle_exporter.rb +44 -0
  41. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +14 -9
  42. data/lib/asker/exporter/concept_doc_exporter.rb +21 -14
  43. data/lib/asker/exporter/data_gift_exporter.rb +29 -0
  44. data/lib/asker/exporter/output_file_exporter.rb +21 -0
  45. data/lib/asker/files/{config.ini → asker.ini} +48 -1
  46. data/lib/asker/files/example-concept.haml +24 -8
  47. data/lib/asker/files/language/du/connectors.yaml +81 -0
  48. data/lib/asker/files/language/du/mistakes.yaml +82 -0
  49. data/lib/asker/files/language/du/templates.yaml +29 -0
  50. data/lib/asker/files/language/en/connectors.yaml +44 -0
  51. data/lib/asker/files/language/en/mistakes.yaml +37 -0
  52. data/lib/asker/files/language/en/templates.yaml +29 -0
  53. data/lib/asker/files/language/es/connectors.yaml +92 -0
  54. data/lib/asker/files/language/es/mistakes.yaml +84 -0
  55. data/lib/asker/files/language/es/templates.yaml +29 -0
  56. data/lib/asker/files/language/fr/connectors.yaml +76 -0
  57. data/lib/asker/files/language/fr/mistakes.yaml +82 -0
  58. data/lib/asker/files/language/fr/templates.yaml +29 -0
  59. data/lib/asker/files/language/javascript/connectors.yaml +11 -0
  60. data/lib/asker/files/language/javascript/mistakes.yaml +30 -0
  61. data/lib/asker/files/language/javascript/templates.yaml +3 -0
  62. data/lib/asker/files/language/math/connectors.yaml +2 -0
  63. data/lib/asker/files/language/math/mistakes.yaml +2 -0
  64. data/lib/asker/files/language/math/templates.yaml +1 -0
  65. data/lib/asker/files/language/python/connectors.yaml +11 -0
  66. data/lib/asker/files/language/python/mistakes.yaml +26 -0
  67. data/lib/asker/files/language/python/templates.yaml +3 -0
  68. data/lib/asker/files/language/ruby/connectors.yaml +11 -0
  69. data/lib/asker/files/language/ruby/mistakes.yaml +33 -0
  70. data/lib/asker/files/language/ruby/templates.yaml +3 -0
  71. data/lib/asker/files/language/sql/connectors.yaml +6 -0
  72. data/lib/asker/files/language/sql/mistakes.yaml +11 -0
  73. data/lib/asker/files/language/sql/templates.yaml +2 -0
  74. data/lib/asker/formatter/concept_string_formatter.rb +13 -9
  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/lang/lang.rb +18 -12
  82. data/lib/asker/lang/lang_factory.rb +32 -5
  83. data/lib/asker/lang/text_actions.rb +87 -69
  84. data/lib/asker/loader/code_loader.rb +4 -4
  85. data/lib/asker/loader/content_loader.rb +16 -12
  86. data/lib/asker/loader/directory_loader.rb +3 -3
  87. data/lib/asker/loader/embedded_file.rb +42 -0
  88. data/lib/asker/loader/file_loader.rb +3 -12
  89. data/lib/asker/loader/haml_loader.rb +15 -0
  90. data/lib/asker/loader/image_url_loader.rb +9 -11
  91. data/lib/asker/loader/input_loader.rb +24 -8
  92. data/lib/asker/loader/project_loader.rb +42 -30
  93. data/lib/asker/logger.rb +30 -6
  94. data/lib/asker/project.rb +28 -117
  95. data/lib/asker/skeleton.rb +40 -29
  96. data/lib/asker.rb +68 -79
  97. metadata +57 -74
  98. data/docs/changelog/v2.1.md +0 -99
  99. data/docs/commands.md +0 -12
  100. data/docs/contributions.md +0 -18
  101. data/docs/history.md +0 -40
  102. data/docs/idea.md +0 -44
  103. data/docs/inputs/README.md +0 -39
  104. data/docs/inputs/code.md +0 -69
  105. data/docs/inputs/concepts.md +0 -142
  106. data/docs/inputs/jedi.md +0 -68
  107. data/docs/inputs/tables.md +0 -112
  108. data/docs/inputs/templates.md +0 -87
  109. data/docs/install/README.md +0 -38
  110. data/docs/install/manual.md +0 -26
  111. data/docs/install/scripts.md +0 -38
  112. data/docs/revise/asker-file.md +0 -41
  113. data/docs/revise/buenas-practicas/01-convocatoria.md +0 -30
  114. data/docs/revise/buenas-practicas/02-formulario.md +0 -35
  115. data/docs/revise/buenas-practicas/03-descripcion.md +0 -63
  116. data/docs/revise/buenas-practicas/04-resultados.md +0 -17
  117. data/docs/revise/buenas-practicas/05-reproducir.md +0 -10
  118. data/docs/revise/ejemplos/01/README.md +0 -27
  119. data/docs/revise/ejemplos/02/README.md +0 -31
  120. data/docs/revise/ejemplos/03/README.md +0 -31
  121. data/docs/revise/ejemplos/04/README.md +0 -37
  122. data/docs/revise/ejemplos/05/README.md +0 -25
  123. data/docs/revise/ejemplos/06/README.md +0 -43
  124. data/docs/revise/ejemplos/README.md +0 -11
  125. data/docs/revise/projects.md +0 -74
  126. data/lib/asker/code/ai/base_code_ai.rb +0 -48
  127. data/lib/asker/code/code.rb +0 -53
  128. data/lib/asker/exporter/concept_ai_screen_exporter.rb +0 -115
  129. data/lib/asker/exporter/concept_screen_exporter.rb +0 -25
  130. data/lib/asker/exporter/main.rb +0 -9
@@ -1,48 +1,31 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  require_relative '../loader/image_url_loader'
3
4
  require_relative '../project'
5
+ require_relative '../logger'
4
6
 
7
+ ##
8
+ # World data
5
9
  class World
6
10
  attr_reader :concepts, :filenames, :contexts, :image_urls
7
11
 
8
- def initialize(concepts, show_progress=true)
12
+ ##
13
+ # Initialize World object
14
+ # @param concepts (Array)
15
+ # @param show_progress (Boolean)
16
+ def initialize(concepts, show_progress = true)
9
17
  find_neighbors_for_every_concept(concepts)
10
-
11
- @concepts = {}
12
- @filenames = []
13
- @contexts = []
14
- @image_urls = {}
15
-
16
- concepts.each do |c|
17
- if c.process
18
- @concepts[c.name] = c
19
- @filenames << c.filename
20
- @contexts << c.context
21
- end
22
- end
23
- @filenames.uniq!
24
- @contexts.uniq!
25
-
26
- threads = []
27
- concepts.each do |c|
28
- print('.') if show_progress
29
- # puts "[DEBUG] #{c.name}\n"
30
- # filter = [ c.name.clone ] + c.context.clone
31
- filter = c.name.clone
32
- threads << Thread.new { @image_urls[c.name] = ImageUrlLoader::load(filter) }
33
- end
34
- @contexts.each do |filter|
35
- print('.') if show_progress
36
- threads << Thread.new { @image_urls[ filter.join('.').to_s ] = ImageUrlLoader::load(filter) }
37
- end
38
- threads.each { |t| t.join } # wait for all threads to finish
39
- print("\n") if show_progress
18
+ @concepts, @filenames, @contexts = get_lists_from(concepts)
19
+ @image_urls = find_url_images_from_internet(show_progress)
40
20
  end
41
21
 
22
+ ##
23
+ # For every concept... find its neighbors
24
+ # @param concepts (Array)
42
25
  def find_neighbors_for_every_concept(concepts)
43
26
  concepts.each do |i|
44
27
  concepts.each do |j|
45
- if (i.id!=j.id) then
28
+ if i.id != j.id
46
29
  i.try_adding_neighbor(j)
47
30
  i.try_adding_references(j)
48
31
  end
@@ -50,4 +33,50 @@ class World
50
33
  end
51
34
  end
52
35
 
36
+ private
37
+
38
+ # rubocop:disable Metrics/MethodLength
39
+ def get_lists_from(input)
40
+ concepts = {}
41
+ filenames = []
42
+ contexts = []
43
+ input.each do |c|
44
+ next unless c.process
45
+
46
+ concepts[c.name] = c
47
+ filenames << c.filename
48
+ contexts << c.context
49
+ end
50
+ filenames.uniq!
51
+ contexts.uniq!
52
+ [concepts, filenames, contexts]
53
+ end
54
+ # rubocop:enable Metrics/MethodLength
55
+
56
+ # rubocop:disable Metrics/MethodLength
57
+ # rubocop:disable Metrics/AbcSize
58
+ # rubocop:disable Metrics/CyclomaticComplexity
59
+ # rubocop:disable Metrics/PerceivedComplexity
60
+ def find_url_images_from_internet(show_progress)
61
+ return {} unless Application.instance.config['global']['internet'] == 'yes'
62
+
63
+ Logger.verbose "\n[INFO] Loading data from Internet" if show_progress
64
+ threads = []
65
+ searchs = []
66
+ urls = {}
67
+
68
+ @concepts&.each_key { |key| searchs << key }
69
+ @contexts.each { |filter| searchs << filter.join(' ').to_s }
70
+ searchs.each do |search|
71
+ Logger.verbose('.') if show_progress
72
+ threads << Thread.new { urls[search] = ImageUrlLoader.load(search) }
73
+ end
74
+ threads.each(&:join) # wait for all threads to finish
75
+ Logger.verbose("\n") if show_progress
76
+ urls
77
+ end
78
+ # rubocop:enable Metrics/MethodLength
79
+ # rubocop:enable Metrics/AbcSize
80
+ # rubocop:enable Metrics/CyclomaticComplexity
81
+ # rubocop:enable Metrics/PerceivedComplexity
53
82
  end
@@ -1,12 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'terminal-table'
4
+ require_relative '../logger'
4
5
 
5
6
  # Export Code into Screen
6
- module CodeScreenExporter
7
- def self.export_all(codes)
8
- project = Project.instance
9
- return if project.show_mode == :none || codes.nil? || codes.size.zero?
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
13
+ def self.show(codes)
14
+ return if codes.nil? || codes.size.zero?
10
15
 
11
16
  total_c = total_q = total_e = 0
12
17
  my_screen_table = Terminal::Table.new do |st|
@@ -39,7 +44,9 @@ module CodeScreenExporter
39
44
  Rainbow((total_q / total_e.to_f).round(2)).bright]
40
45
  return unless total_c.positive?
41
46
 
42
- project.verboseln "\n[INFO] Showing CODE statistics"
43
- project.verboseln my_screen_table.to_s
47
+ Logger.verboseln "\n[INFO] Showing CODE statistics"
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
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'erb'
4
+ require 'terminal-table'
5
+ require_relative '../application'
6
+ require_relative '../logger'
7
+
8
+ # Display ConceptAI stat on screen
9
+ class ConceptAIDisplayer
10
+ ##
11
+ # Display ConceptAI stat on screen
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
17
+ def self.show(concepts_ai)
18
+ stages = Application.instance.config['questions']['stages']
19
+ # Create table HEAD
20
+ screen_table = Terminal::Table.new do |st|
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
30
+ st << :separator
31
+ end
32
+ # Create table BODY
33
+ total = {}
34
+ total[:q] = total[:e] = total[:c] = 0
35
+ total[:sd] = total[:sb] = total[:sf] = 0
36
+ total[:si] = total[:ss] = total[:st] = 0
37
+
38
+ concepts_ai.each do |concept_ai|
39
+ next unless concept_ai.concept.process?
40
+
41
+ e = concept_ai.concept.texts.size
42
+ concept_ai.concept.tables.each { |t| e += t.fields.size * t.rows.size }
43
+
44
+ sd = sb = sf = 0
45
+ si = ss = st = 0
46
+ sd = concept_ai.questions[:d].size if stages.include? :d
47
+ sb = concept_ai.questions[:b].size if stages.include? :b
48
+ sf = concept_ai.questions[:f].size if stages.include? :f
49
+ si = concept_ai.questions[:i].size if stages.include? :i
50
+ ss = concept_ai.questions[:s].size if stages.include? :s
51
+ st = concept_ai.questions[:t].size if stages.include? :t
52
+ t = sd + sb + sf + si + ss + st
53
+
54
+ factor = 'Unkown'
55
+ factor = (t.to_f / e).round(2).to_s unless e.zero?
56
+ screen_table.add_row [Rainbow(concept_ai.concept.name(:screen)).green.bright,
57
+ t, e, factor, sd, sb, sf, si, ss, st]
58
+
59
+ total[:q] += t
60
+ total[:e] += e
61
+ total[:c] += 1
62
+ total[:sd] += sd
63
+ total[:sb] += sb
64
+ total[:sf] += sf
65
+ total[:si] += si
66
+ total[:ss] += ss
67
+ total[:st] += st
68
+ end
69
+ return if total[:c].zero? # No concepts to be process?
70
+
71
+ # Add row with excluded questions
72
+ export_excluded_questions(screen_table, concepts_ai)
73
+
74
+ # Create table TAIL
75
+ screen_table.add_separator
76
+ screen_table.add_row [Rainbow("TOTAL = #{total[:c]}").bright,
77
+ Rainbow(total[:q].to_s).bright,
78
+ Rainbow(total[:e].to_s).bright,
79
+ Rainbow((total[:q].to_f / total[:e]).round(2)).bright,
80
+ total[:sd], total[:sb], total[:sf],
81
+ total[:si], total[:ss], total[:st]]
82
+ export_notes
83
+ Logger.verboseln "#{screen_table}\n"
84
+ end
85
+ # rubocop:enable Metrics/MethodLength
86
+ # rubocop:enable Metrics/AbcSize
87
+ # rubocop:enable Metrics/CyclomaticComplexity
88
+ # rubocop:enable Metrics/PerceivedComplexity
89
+
90
+ # rubocop:disable Metrics/MethodLength
91
+ # rubocop:disable Metrics/AbcSize
92
+ private_class_method def self.export_excluded_questions(screen_table, concepts_ai)
93
+ # Create table BODY
94
+ total = {}
95
+ total[:q] = total[:c] = 0
96
+ total[:sd] = total[:sb] = total[:sf] = 0
97
+ total[:si] = total[:ss] = total[:st] = 0
98
+
99
+ concepts_ai.each do |concept_ai|
100
+ next unless concept_ai.concept.process?
101
+
102
+ sd = concept_ai.excluded_questions[:d].size
103
+ sb = concept_ai.excluded_questions[:b].size
104
+ sf = concept_ai.excluded_questions[:f].size
105
+ si = concept_ai.excluded_questions[:i].size
106
+ ss = concept_ai.excluded_questions[:s].size
107
+ st = concept_ai.excluded_questions[:t].size
108
+ t = sd + sb + sf + si + ss + st
109
+
110
+ total[:q] += t
111
+ total[:c] += 1
112
+ total[:sd] += sd
113
+ total[:sb] += sb
114
+ total[:sf] += sf
115
+ total[:si] += si
116
+ total[:ss] += ss
117
+ total[:st] += st
118
+ end
119
+ screen_table.add_row [Rainbow('Excluded questions').yellow.bright,
120
+ total[:q], '-', '-',
121
+ total[:sd], total[:sb],
122
+ total[:sf], total[:si],
123
+ total[:ss], total[:st]]
124
+ end
125
+ # rubocop:enable Metrics/MethodLength
126
+ # rubocop:enable Metrics/AbcSize
127
+
128
+ private_class_method def self.export_notes
129
+ exclude_questions = Application.instance.config['questions']['exclude'].to_s
130
+ renderer = ERB.new(File.read(File.join(File.dirname(__FILE__), 'concept_ai_displayer.erb')))
131
+ Logger.verboseln renderer.result(binding)
132
+ end
133
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../application'
4
+ require_relative '../formatter/concept_string_formatter'
5
+ require_relative '../logger'
6
+
7
+ # Show Concept Data on screen
8
+ module ConceptDisplayer
9
+ ##
10
+ # Show concepts on screen
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
+
18
+ msg = "\n[INFO] Showing concept data (#{Rainbow(show_mode).bright})"
19
+ Logger.verboseln msg
20
+ case show_mode
21
+ when 'resume'
22
+ s = "* Concepts (#{concepts.count}): "
23
+ concepts.each { |c| s += c.name + ', ' }
24
+ Logger.verboseln s
25
+ when 'default'
26
+ # Only show Concepts with process attr true
27
+ concepts.each do |c|
28
+ Logger.verboseln ConceptStringFormatter.to_s(c) if c.process?
29
+ end
30
+ end
31
+ end
32
+ # rubocop:enable Metrics/AbcSize
33
+ # rubocop:enable Metrics/MethodLength
34
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../application'
4
+ require_relative 'concept_ai_displayer'
5
+ require_relative 'code_displayer'
6
+
7
+ # Display Stats on screen.
8
+ # * Display all "Concept AI"
9
+ # * Display all "Code"
10
+ 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
15
+ def self.show(data)
16
+ return unless Application.instance.config['global']['show_mode']
17
+
18
+ # show_final_results
19
+ ConceptAIDisplayer.show(data[:concepts_ai])
20
+ CodeDisplayer.show(data[:codes_ai])
21
+ end
22
+ end
@@ -1,31 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../project'
4
3
  require_relative '../formatter/question_gift_formatter'
5
4
 
6
- # UNDER DEVELOPMENT
7
5
  # Use to export questions from Code to gift format
8
6
  module CodeGiftExporter
9
- def self.export_all(codes)
10
- codes.each do |code|
11
- code.make_questions
12
- export code
13
- end
7
+ ##
8
+ # Export an Array of codes to gift format file
9
+ # @param codes (Array)
10
+ def self.export_all(codes, file)
11
+ codes.each { |code| export(code, file) }
14
12
  end
15
13
 
16
- def self.export(code)
14
+ ##
15
+ # Export 1 code to gift format file
16
+ # @param code (Code)
17
+ def self.export(code, file)
17
18
  return false unless code.process?
18
19
 
19
- file = Project.instance.outputfile
20
20
  file.write head(code)
21
-
22
21
  code.questions.each do |question|
23
22
  file.write QuestionGiftFormatter.to_s(question)
24
23
  end
25
24
  true
26
25
  end
27
26
 
28
- def self.head(code)
27
+ private_class_method def self.head(code)
29
28
  s = "\n"
30
29
  s += '// ' + '=' * 50 + "\n"
31
30
  s += "// Code #{code.type}: #{code.filename} (#{code.questions.size})\n"
@@ -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
- # Use to export data from ConceptIA to gift format
5
+ # Export ConceptIA data to gift to outputfile
7
6
  module ConceptAIGiftExporter
8
- def self.export_all(concepts_ai)
9
- concepts_ai.each { |concept_ai| export(concept_ai) }
7
+ ##
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) }
10
13
  end
11
-
12
- def self.export(concept_ai)
13
- return unless concept_ai.process?
14
14
 
15
- file = Project.instance.outputfile
16
- file.write head(concept_ai.name)
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?
17
21
 
18
- stages = Project.instance.stages
19
- 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"
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../formatter/question_moodle_formatter'
4
+
5
+ # Export ConceptIA data to gift to moodlefile
6
+ module ConceptAIMoodleExporter
7
+ ##
8
+ # Export an array of ConceptAI objects from Project into Moodle format file
9
+ # @param concepts_ai (Array)
10
+ # @param project (Project)
11
+ def self.export_all(concepts_ai, project)
12
+ file = File.open(project.get(:moodlepath), 'w')
13
+ file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
14
+ file.write("<quiz>\n")
15
+ file.write("<!--\n#{('=' * 50)}\n")
16
+ file.write(" Created by : #{Application::NAME}")
17
+ file.write(" (version #{Application::VERSION})\n")
18
+ file.write(" File : #{project.get(:moodlename)}\n")
19
+ file.write(" Time : #{Time.new}\n")
20
+ file.write(" Author : David Vargas Ruiz\n")
21
+ file.write("#{('=' * 50)}\n-->\n\n")
22
+
23
+ concepts_ai.each { |concept_ai| export(concept_ai, file) }
24
+
25
+ file.write("</quiz>\n")
26
+ file.close
27
+ end
28
+
29
+ ##
30
+ # Export 1 concept_ai from project
31
+ # @param concept_ai (ConceptAI)
32
+ # @param file (File)
33
+ # rubocop:disable Metrics/AbcSize
34
+ private_class_method def self.export(concept_ai, file)
35
+ return unless concept_ai.concept.process?
36
+
37
+ Application.instance.config['questions']['stages'].each do |stage|
38
+ concept_ai.questions[stage].each do |question|
39
+ file.write(QuestionMoodleFormatter.to_s(question))
40
+ end
41
+ end
42
+ end
43
+ # rubocop:enable Metrics/AbcSize
44
+ end
@@ -1,30 +1,35 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'yaml'
4
- require_relative '../project'
5
4
  require_relative '../formatter/question_hash_formatter'
6
5
 
7
6
  # Use to export data from ConceptIA to YAML format
8
7
  module ConceptAIYAMLExporter
9
- def self.export_all(concepts_ai)
8
+ ##
9
+ # Export array of ConceptAI objects from Project to YAML output file
10
+ # @param concepts_ai (Array)
11
+ # @param project (Project)
12
+ def self.export_all(concepts_ai, project)
10
13
  questions = []
11
14
  concepts_ai.each do |concept_ai|
12
15
  questions += get_questions_from concept_ai
13
16
  end
14
- project = Project.instance
15
17
  params = { lang: project.get(:lang) ,
16
18
  projectname: project.get(:projectname) }
17
19
  output = { params: params, questions: questions }
18
- project.yamlfile.write(output.to_yaml)
20
+
21
+ yamlfile = File.open(project.get(:yamlpath), 'w')
22
+ yamlfile.write(output.to_yaml)
23
+ yamlfile.close
19
24
  end
20
25
 
21
- def self.get_questions_from(concept_ai)
26
+ private_class_method def self.get_questions_from(concept_ai)
22
27
  data = []
23
- return data unless concept_ai.process?
24
- stages = Project.instance.stages
25
- stages.each_key do |stage|
28
+ return data unless concept_ai.concept.process?
29
+
30
+ Application.instance.config['questions']['stages'].each do |stage|
26
31
  concept_ai.questions[stage].each do |question|
27
- question.lang = concept_ai.lang
32
+ question.lang = concept_ai.concept.lang
28
33
  data << QuestionHashFormatter.to_hash(question)
29
34
  end
30
35
  end
@@ -1,21 +1,28 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require_relative '../project'
4
3
  require_relative '../formatter/concept_doc_formatter'
5
4
 
6
- class ConceptDocExporter
5
+ ##
6
+ # Export Concept to Doc file
7
+ module ConceptDocExporter
8
+ ##
9
+ # Export arrya of concepts to doc
10
+ # rubocop:disable Metrics/AbcSize
11
+ # rubocop:disable Metrics/MethodLength
12
+ def self.export_all(concepts, project)
13
+ file = File.new(project.get(:lessonpath), 'w')
14
+ file.write('=' * 50 + "\n")
15
+ file.write("Created by : #{Application::NAME} (version #{Application::VERSION})\n")
16
+ file.write("File : #{project.get(:lessonname)}\n")
17
+ file.write("Time : #{Time.new}\n")
18
+ file.write("Author : David Vargas Ruiz\n")
19
+ file.write('=' * 50 + "\n")
7
20
 
8
- def initialize(concepts)
9
- @concepts = concepts
10
- end
11
-
12
- def export
13
- file = Project.instance.lessonfile
14
- @concepts.each do |concept|
15
- if concept.process
16
- file.write(ConceptDocFormatter.to_s(concept))
17
- end
21
+ concepts.each do |concept|
22
+ file.write(ConceptDocFormatter.to_s(concept)) if concept.process
18
23
  end
24
+ file.close
19
25
  end
20
-
26
+ # rubocop:enable Metrics/AbcSize
27
+ # rubocop:enable Metrics/MethodLength
21
28
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'concept_ai_gift_exporter'
4
+ require_relative 'code_gift_exporter'
5
+
6
+ # Export Data (ConceptIA and Code) to gift to outputfile
7
+ module DataGiftExporter
8
+ ##
9
+ # Export an array of Data (ConceptAI and Code objects) into GIFT outpufile
10
+ # @param data (Hash)
11
+ # @param project (Project)
12
+ def self.export_all(data, project)
13
+ file = File.open(project.get(:outputpath), 'w')
14
+ file.write('// ' + ('=' * 50) + "\n")
15
+ file.write("// Created by : #{Application::NAME}")
16
+ file.write(" (version #{Application::VERSION})\n")
17
+ file.write("// File : #{project.get(:outputname)}\n")
18
+ file.write("// Time : #{Time.new}\n")
19
+ file.write("// Author : David Vargas Ruiz\n")
20
+ file.write('// ' + ('=' * 50) + "\n\n")
21
+ category = Application.instance.config['questions']['category']
22
+ file.write("$CATEGORY: $course$/#{category}\n") unless category.nil?
23
+
24
+ ConceptAIGiftExporter.export_all(data[:concepts_ai], file)
25
+ CodeGiftExporter.export_all(data[:codes_ai], file)
26
+
27
+ file.close
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ require_relative 'concept_ai_moodle_exporter'
2
+ require_relative 'concept_ai_yaml_exporter'
3
+ require_relative 'concept_doc_exporter'
4
+ require_relative 'data_gift_exporter'
5
+
6
+ # Export Output data:
7
+ # * Gift (ConceptAI, Code)
8
+ # * YAML
9
+ # * Doc (txt)
10
+ module OutputFileExporter
11
+ def self.export(data, project)
12
+ config = Application.instance.config
13
+ DataGiftExporter.export_all(data, project) if config['output']['gift'] == 'yes'
14
+ ConceptAIYAMLExporter.export_all(data[:concepts_ai], project) if config['output']['yaml'] == 'yes'
15
+ ConceptDocExporter.export_all(data[:concepts], project) if config['output']['doc'] == 'yes'
16
+ # ConceptAIGiftExporter.export_all(data[:concepts_ai], project) if config['output']['gift'] == 'yes'
17
+ # CodeGiftExporter.export_all(data[:codes_ai], project.get(:outputfile)) if config['output']['gift'] == 'yes'
18
+ # UNDER DEVELOPMENT
19
+ ConceptAIMoodleExporter.export_all(data[:concepts_ai], project) if config['output']['moodle'] == 'yes'
20
+ end
21
+ end