asker-tool 2.5.9 → 2.7.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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -7
  3. data/lib/asker/ai/ai.rb +17 -22
  4. data/lib/asker/ai/ai_calculate.rb +10 -17
  5. data/lib/asker/ai/code/base_code_ai.rb +5 -30
  6. data/lib/asker/ai/code/code_ai_factory.rb +6 -12
  7. data/lib/asker/ai/code/javascript_code_ai.rb +33 -34
  8. data/lib/asker/ai/code/python_code_ai.rb +35 -36
  9. data/lib/asker/ai/code/ruby_code_ai.rb +33 -33
  10. data/lib/asker/ai/code/sql_code_ai.rb +20 -21
  11. data/lib/asker/ai/concept_ai.rb +12 -22
  12. data/lib/asker/ai/problem/problem_ai.rb +226 -0
  13. data/lib/asker/ai/question.rb +34 -45
  14. data/lib/asker/ai/stages/base_stage.rb +7 -7
  15. data/lib/asker/ai/stages/main.rb +6 -7
  16. data/lib/asker/ai/stages/stage_b.rb +62 -28
  17. data/lib/asker/ai/stages/stage_d.rb +10 -10
  18. data/lib/asker/ai/stages/stage_f.rb +17 -17
  19. data/lib/asker/ai/stages/stage_i.rb +8 -18
  20. data/lib/asker/ai/stages/stage_s.rb +28 -26
  21. data/lib/asker/ai/stages/stage_t.rb +54 -76
  22. data/lib/asker/application.rb +15 -14
  23. data/lib/asker/check_input/check_haml_data.rb +57 -51
  24. data/lib/asker/check_input/check_table.rb +26 -19
  25. data/lib/asker/check_input.rb +10 -22
  26. data/lib/asker/cli.rb +43 -24
  27. data/lib/asker/data/code.rb +10 -9
  28. data/lib/asker/data/column.rb +21 -17
  29. data/lib/asker/data/concept.rb +24 -37
  30. data/lib/asker/data/data_field.rb +2 -2
  31. data/lib/asker/data/problem.rb +112 -0
  32. data/lib/asker/data/project_data.rb +11 -15
  33. data/lib/asker/data/row.rb +25 -23
  34. data/lib/asker/data/table.rb +25 -46
  35. data/lib/asker/data/template.rb +7 -7
  36. data/lib/asker/data/world.rb +3 -3
  37. data/lib/asker/{formatter → deprecated}/question_moodlexml_formatter.rb +19 -21
  38. data/lib/asker/displayer/code_displayer.rb +10 -10
  39. data/lib/asker/displayer/concept_ai_displayer.erb +1 -1
  40. data/lib/asker/displayer/concept_ai_displayer.rb +22 -34
  41. data/lib/asker/displayer/concept_displayer.rb +9 -11
  42. data/lib/asker/displayer/problem_displayer.rb +45 -0
  43. data/lib/asker/displayer/stats_displayer.rb +7 -12
  44. data/lib/asker/exporter/code_gift_exporter.rb +2 -2
  45. data/lib/asker/exporter/concept_ai_gift_exporter.rb +4 -4
  46. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +7 -7
  47. data/lib/asker/exporter/concept_doc_exporter.rb +5 -5
  48. data/lib/asker/exporter/data_gift_exporter.rb +14 -15
  49. data/lib/asker/exporter/data_moodle_exporter.rb +51 -20
  50. data/lib/asker/exporter/output_file_exporter.rb +9 -8
  51. data/lib/asker/exporter/problem_gift_exporter.rb +30 -0
  52. data/lib/asker/files/language/ca/templates.yaml +6 -0
  53. data/lib/asker/files/language/du/templates.yaml +6 -0
  54. data/lib/asker/files/language/en/templates.yaml +7 -1
  55. data/lib/asker/files/language/es/templates.yaml +6 -0
  56. data/lib/asker/files/language/fr/templates.yaml +6 -0
  57. data/lib/asker/formatter/code_string_formatter.rb +5 -5
  58. data/lib/asker/formatter/concept_doc_formatter.rb +3 -3
  59. data/lib/asker/formatter/concept_string_formatter.rb +27 -24
  60. data/lib/asker/formatter/moodle/ddmatch.erb +40 -0
  61. data/lib/asker/formatter/moodle/gapfill.erb +57 -0
  62. data/lib/asker/formatter/moodle/ordering.erb +41 -0
  63. data/lib/asker/formatter/question_gift_formatter.rb +41 -14
  64. data/lib/asker/formatter/question_hash_formatter.rb +5 -6
  65. data/lib/asker/formatter/question_moodle_formatter.rb +14 -7
  66. data/lib/asker/formatter/rb2haml_formatter.rb +8 -7
  67. data/lib/asker/lang/lang.rb +16 -16
  68. data/lib/asker/lang/lang_factory.rb +13 -16
  69. data/lib/asker/lang/text_actions.rb +20 -18
  70. data/lib/asker/loader/code_loader.rb +10 -22
  71. data/lib/asker/loader/content_loader.rb +42 -49
  72. data/lib/asker/loader/directory_loader.rb +13 -16
  73. data/lib/asker/loader/embedded_file.rb +29 -24
  74. data/lib/asker/loader/file_loader.rb +7 -6
  75. data/lib/asker/loader/haml_loader.rb +6 -5
  76. data/lib/asker/loader/image_url_loader.rb +21 -18
  77. data/lib/asker/loader/input_loader.rb +27 -14
  78. data/lib/asker/loader/problem_loader.rb +88 -0
  79. data/lib/asker/loader/project_loader.rb +11 -28
  80. data/lib/asker/logger.rb +22 -13
  81. data/lib/asker/skeleton.rb +27 -43
  82. data/lib/asker/start.rb +44 -0
  83. data/lib/asker/version.rb +1 -1
  84. data/lib/asker.rb +7 -53
  85. metadata +12 -20
  86. data/lib/asker/ai/code/problem_code_ai.rb +0 -176
  87. data/lib/asker/exporter/code_moodle_exporter.rb +0 -15
  88. data/lib/asker/exporter/concept_ai_moodle_exporter.rb +0 -15
@@ -1,21 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'erb'
4
- require 'terminal-table'
5
- require_relative '../application'
6
- require_relative '../logger'
3
+ require "erb"
4
+ require "rainbow"
5
+ require "terminal-table"
6
+ require_relative "../application"
7
+ require_relative "../logger"
7
8
 
8
- # Display ConceptAI stat on screen
9
9
  class ConceptAIDisplayer
10
10
  ##
11
11
  # Display ConceptAI stat on screen
12
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
13
  def self.show(concepts_ai)
18
- stages = Application.instance.config['questions']['stages']
14
+ stages = Application.instance.config["questions"]["stages"]
19
15
  # Create table HEAD
20
16
  screen_table = Terminal::Table.new do |st|
21
17
  title = %w[Concept Questions Entries xFactor]
@@ -52,10 +48,10 @@ class ConceptAIDisplayer
52
48
  st = concept_ai.questions[:t].size if stages.include? :t
53
49
  t = sd + sb + sf + si + ss + st
54
50
 
55
- factor = 'Unkown'
51
+ factor = "Unkown"
56
52
  factor = (t.to_f / e).round(2).to_s unless e.zero?
57
53
  screen_table.add_row [Rainbow(concept_ai.concept.name(:screen)).green.bright,
58
- t, e, factor, sd, sb, sf, si, ss, st]
54
+ t, e, factor, sd, sb, sf, si, ss, st]
59
55
 
60
56
  total[:q] += t
61
57
  total[:e] += e
@@ -75,21 +71,15 @@ class ConceptAIDisplayer
75
71
  # Create table TAIL
76
72
  screen_table.add_separator
77
73
  screen_table.add_row [Rainbow("#{total[:c]} concept/s").bright,
78
- Rainbow(total[:q].to_s).bright,
79
- Rainbow(total[:e].to_s).bright,
80
- Rainbow((total[:q].to_f / total[:e]).round(2)).bright,
81
- total[:sd], total[:sb], total[:sf],
82
- total[:si], total[:ss], total[:st]]
74
+ Rainbow(total[:q].to_s).bright,
75
+ Rainbow(total[:e].to_s).bright,
76
+ Rainbow((total[:q].to_f / total[:e]).round(2)).bright,
77
+ total[:sd], total[:sb], total[:sf],
78
+ total[:si], total[:ss], total[:st]]
83
79
  export_notes
84
- Logger.verboseln "#{screen_table}\n"
80
+ Logger.info "#{screen_table}\n"
85
81
  end
86
- # rubocop:enable Metrics/MethodLength
87
- # rubocop:enable Metrics/AbcSize
88
- # rubocop:enable Metrics/CyclomaticComplexity
89
- # rubocop:enable Metrics/PerceivedComplexity
90
82
 
91
- # rubocop:disable Metrics/MethodLength
92
- # rubocop:disable Metrics/AbcSize
93
83
  private_class_method def self.export_excluded_questions(screen_table, concepts_ai)
94
84
  # Create table BODY
95
85
  total = {}
@@ -117,18 +107,16 @@ class ConceptAIDisplayer
117
107
  total[:ss] += ss
118
108
  total[:st] += st
119
109
  end
120
- screen_table.add_row [Rainbow('Excluded questions').yellow.bright,
121
- total[:q], '-', '-',
122
- total[:sd], total[:sb],
123
- total[:sf], total[:si],
124
- total[:ss], total[:st]]
110
+ screen_table.add_row [Rainbow("Excluded questions").yellow.bright,
111
+ total[:q], "-", "-",
112
+ total[:sd], total[:sb],
113
+ total[:sf], total[:si],
114
+ total[:ss], total[:st]]
125
115
  end
126
- # rubocop:enable Metrics/MethodLength
127
- # rubocop:enable Metrics/AbcSize
128
116
 
129
117
  private_class_method def self.export_notes
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)
118
+ exclude_questions = Application.instance.config["questions"]["exclude"].to_s
119
+ renderer = ERB.new(File.read(File.join(File.dirname(__FILE__), "concept_ai_displayer.erb")))
120
+ Logger.info Rainbow(renderer.result(binding)).white
133
121
  end
134
122
  end
@@ -1,31 +1,29 @@
1
- require_relative '../application'
2
- require_relative '../formatter/concept_string_formatter'
1
+ require_relative "../application"
2
+ require_relative "../formatter/concept_string_formatter"
3
3
  require_relative "../logger"
4
4
 
5
5
  module ConceptDisplayer
6
6
  ##
7
7
  # Show concepts on screen
8
8
  # @param concepts (Array) List of concept data
9
- # rubocop:disable Metrics/AbcSize
10
- # rubocop:disable Metrics/MethodLength
11
9
  def self.show(concepts)
12
- show_mode = Application.instance.config['global']['show_mode']
10
+ return if concepts.nil? || concepts.size.zero?
11
+
12
+ show_mode = Application.instance.config["global"]["show_mode"]
13
13
  return unless show_mode
14
14
 
15
15
  msg = "\n[INFO] Showing concept data (#{Rainbow(show_mode).bright})"
16
16
  Logger.verboseln msg
17
17
  case show_mode
18
- when 'resume'
19
- s = "* Concepts (#{concepts.count}): "
20
- concepts.each { |c| s += c.name + ', ' }
18
+ when "resume"
19
+ names = concepts.map { |c| c.name }
20
+ s = " * Concepts (#{names.count}): #{names.join(",")}"
21
21
  Logger.verboseln s
22
- when 'default'
22
+ when "default"
23
23
  # Only show Concepts with process attr true
24
24
  concepts.each do |c|
25
25
  Logger.verboseln ConceptStringFormatter.to_s(c) if c.process?
26
26
  end
27
27
  end
28
28
  end
29
- # rubocop:enable Metrics/AbcSize
30
- # rubocop:enable Metrics/MethodLength
31
29
  end
@@ -0,0 +1,45 @@
1
+ require "terminal-table"
2
+ require_relative "../logger"
3
+
4
+ module ProblemDisplayer
5
+ ##
6
+ # Show all "problem" data on screen
7
+ # @param problems (Array) List of "problems" data
8
+ def self.show(problems)
9
+ return if problems.nil? || problems.size.zero?
10
+
11
+ total_p = total_q = total_e = 0
12
+ my_screen_table = Terminal::Table.new do |st|
13
+ st << %w[Problem Desc Questions Entries xFactor]
14
+ st << :separator
15
+ end
16
+
17
+ problems.each do |problem|
18
+ next unless problem.process?
19
+
20
+ e = problem.cases.size
21
+ problem.asks.each do |ask|
22
+ e += ask[:steps].size
23
+ e += 1 if !ask[:answer].nil?
24
+ end
25
+
26
+ q = problem.questions.size
27
+ factor = "Unkown"
28
+ factor = (q.to_f / e).round(2).to_s unless e.zero?
29
+ desc = Rainbow(problem.desc[0, 24]).green
30
+ my_screen_table.add_row [problem.name, desc, q, e, factor]
31
+ total_p += 1
32
+ total_q += q
33
+ total_e += e
34
+ end
35
+ return unless total_p.positive?
36
+
37
+ my_screen_table.add_separator
38
+ my_screen_table.add_row [Rainbow("TOTAL = #{total_p}").bright, "",
39
+ Rainbow(total_q.to_s).bright,
40
+ Rainbow(total_e.to_s).bright,
41
+ Rainbow((total_q / total_e.to_f).round(2)).bright]
42
+ Logger.verboseln Rainbow("\n[INFO] Showing PROBLEMs statistics").white
43
+ Logger.verboseln my_screen_table.to_s
44
+ end
45
+ end
@@ -1,22 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../application'
4
- require_relative 'concept_ai_displayer'
5
- require_relative 'code_displayer'
3
+ require_relative "../application"
4
+ require_relative "concept_ai_displayer"
5
+ require_relative "code_displayer"
6
+ require_relative "problem_displayer"
6
7
 
7
- # Display Stats on screen.
8
- # * Display all "Concept AI"
9
- # * Display all "Code"
10
8
  module StatsDisplayer
11
- # Display Stats on screen.
12
- # * Display all "Concept AI"
13
- # * Display all "Code"
14
- # @param data (Hash) With concept_ai list and code list
9
+ # @param data (Hash) With concept_ai, code and problem list
15
10
  def self.show(data)
16
- return unless Application.instance.config['global']['show_mode']
11
+ return unless Application.instance.config["global"]["show_mode"]
17
12
 
18
- # show_final_results
19
13
  ConceptAIDisplayer.show(data[:concepts_ai])
20
14
  CodeDisplayer.show(data[:codes_ai])
15
+ ProblemDisplayer.show(data[:problems])
21
16
  end
22
17
  end
@@ -23,9 +23,9 @@ module CodeGiftExporter
23
23
 
24
24
  private_class_method def self.head(code)
25
25
  s = "\n"
26
- s += '// ' + '=' * 50 + "\n"
26
+ s += "// " + "=" * 50 + "\n"
27
27
  s += "// Code #{code.type}: #{code.filename} (#{code.questions.size})\n"
28
- s += '// ' + '=' * 50 + "\n"
28
+ s += "// " + "=" * 50 + "\n"
29
29
  s
30
30
  end
31
31
  end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../formatter/question_gift_formatter'
3
+ require_relative "../formatter/question_gift_formatter"
4
4
 
5
5
  # Export ConceptIA data to gift to outputfile
6
6
  module ConceptAIGiftExporter
@@ -20,7 +20,7 @@ module ConceptAIGiftExporter
20
20
  return unless concept_ai.concept.process?
21
21
 
22
22
  file.write head(concept_ai.concept.name)
23
- Application.instance.config['questions']['stages'].each do |stage|
23
+ Application.instance.config["questions"]["stages"].each do |stage|
24
24
  concept_ai.questions[stage].each do |question|
25
25
  file.write(QuestionGiftFormatter.to_s(question))
26
26
  end
@@ -33,9 +33,9 @@ module ConceptAIGiftExporter
33
33
  # @return String
34
34
  private_class_method def self.head(name)
35
35
  s = "\n"
36
- s += '// ' + '=' * 50 + "\n"
36
+ s += "// " + "=" * 50 + "\n"
37
37
  s += "// Concept name: #{name}\n"
38
- s += '// ' + '=' * 50 + "\n"
38
+ s += "// " + "=" * 50 + "\n"
39
39
  s
40
40
  end
41
41
  end
@@ -1,5 +1,5 @@
1
- require 'yaml'
2
- require_relative '../formatter/question_hash_formatter'
1
+ require "yaml"
2
+ require_relative "../formatter/question_hash_formatter"
3
3
 
4
4
  # Use to export data from ConceptIA to YAML format
5
5
  module ConceptAIYAMLExporter
@@ -12,11 +12,11 @@ module ConceptAIYAMLExporter
12
12
  concepts_ai.each do |concept_ai|
13
13
  questions += get_questions_from concept_ai
14
14
  end
15
- params = { lang: project.get(:lang) ,
16
- projectname: project.get(:projectname) }
17
- output = { params: params, questions: questions }
15
+ params = {lang: project.get(:lang),
16
+ projectname: project.get(:projectname)}
17
+ output = {params: params, questions: questions}
18
18
 
19
- yamlfile = File.open(project.get(:yamlpath), 'w')
19
+ yamlfile = File.open(project.get(:yamlpath), "w")
20
20
  yamlfile.write(output.to_yaml)
21
21
  yamlfile.close
22
22
  end
@@ -25,7 +25,7 @@ module ConceptAIYAMLExporter
25
25
  data = []
26
26
  return data unless concept_ai.concept.process?
27
27
 
28
- Application.instance.config['questions']['stages'].each do |stage|
28
+ Application.instance.config["questions"]["stages"].each do |stage|
29
29
  concept_ai.questions[stage].each do |question|
30
30
  question.lang = concept_ai.concept.lang
31
31
  data << QuestionHashFormatter.to_hash(question)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../formatter/concept_doc_formatter'
4
- require_relative '../version'
3
+ require_relative "../formatter/concept_doc_formatter"
4
+ require_relative "../version"
5
5
 
6
6
  ##
7
7
  # Export Concept to Doc file
@@ -9,12 +9,12 @@ module ConceptDocExporter
9
9
  ##
10
10
  # Export array of concepts to doc
11
11
  def self.export_all(concepts, project)
12
- file = File.new(project.get(:lessonpath), 'w')
13
- file.write('=' * 50 + "\n")
12
+ file = File.new(project.get(:lessonpath), "w")
13
+ file.write("=" * 50 + "\n")
14
14
  file.write("Created by : #{Asker::NAME} (version #{Asker::VERSION})\n")
15
15
  file.write("File : #{project.get(:lessonname)}\n")
16
16
  file.write("Time : #{Time.new}\n")
17
- file.write('=' * 50 + "\n")
17
+ file.write("=" * 50 + "\n")
18
18
 
19
19
  concepts.each do |concept|
20
20
  file.write(ConceptDocFormatter.to_s(concept)) if concept.process
@@ -1,30 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'concept_ai_gift_exporter'
4
- require_relative 'code_gift_exporter'
5
- require_relative '../version'
6
- require_relative '../application'
3
+ require_relative "concept_ai_gift_exporter"
4
+ require_relative "code_gift_exporter"
5
+ require_relative "problem_gift_exporter"
6
+ require_relative "../application"
7
+ require_relative "../version"
7
8
 
8
- # Export Data (ConceptIA and Code) to gift to outputfile
9
9
  module DataGiftExporter
10
10
  ##
11
- # Export an array of Data (ConceptAI and Code objects) into GIFT outpufile
11
+ # Export an array of Data (ConceptAIs, Codes and Problems objects) into GIFT file
12
12
  # @param data (Hash)
13
13
  # @param project (Project)
14
14
  def self.export_all(data, project)
15
- file = File.open(project.get(:outputpath), 'w')
16
- file.write('// ' + ('=' * 50) + "\n")
17
- file.write("// Created by : #{Asker::NAME}")
18
- file.write(" (version #{Asker::VERSION})\n")
19
- file.write("// File : #{project.get(:outputname)}\n")
20
- file.write("// Time : #{Time.new}\n")
21
- file.write('// ' + ('=' * 50) + "\n\n")
22
- category = Application.instance.config['questions']['category']
15
+ file = File.open(project.get(:outputpath), "w")
16
+ file.write("// " + ("=" * 50) + "\n")
17
+ file.write("// #{Asker::NAME} : version #{Asker::VERSION}\n")
18
+ file.write("// Filename : #{project.get(:outputname)}\n")
19
+ file.write("// Datetime : #{Time.new}\n")
20
+ file.write("// " + ("=" * 50) + "\n\n")
21
+ category = Application.instance.config["questions"]["category"]
23
22
  file.write("$CATEGORY: $course$/#{category}\n") unless category.nil?
24
23
 
25
24
  ConceptAIGiftExporter.export_all(data[:concepts_ai], file)
26
25
  CodeGiftExporter.export_all(data[:codes_ai], file)
27
-
26
+ ProblemGiftExporter.new.call(data[:problems], file)
28
27
  file.close
29
28
  end
30
29
  end
@@ -1,31 +1,62 @@
1
+ require_relative "../application"
2
+ require_relative "../version"
3
+ require_relative "../formatter/question_moodle_formatter"
1
4
 
2
- require_relative '../version'
3
- require_relative 'concept_ai_moodle_exporter'
4
- require_relative 'code_moodle_exporter'
5
-
6
- # Export data to MoodleXML file
7
5
  module DataMoodleExporter
6
+ def self.call(data, project)
7
+ file = File.open(project.get(:moodlepath), "w")
8
+ add_header(file, project)
9
+
10
+ export_concepts(concepts: data[:concepts_ai], file: file)
11
+ export_codes(codes: data[:codes_ai], file: file)
12
+ export_problems(problems: data[:problems], file: file)
13
+
14
+ close(file)
15
+ end
8
16
 
9
- def self.export_all(data, project)
10
- file = File.open(project.get(:moodlepath), 'w')
17
+ def self.add_header(file, project)
11
18
  file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
12
19
  file.write("<quiz>\n")
13
- file.write("<!--\n#{('=' * 50)}\n")
14
- file.write(" Created by : #{Asker::NAME}")
15
- file.write(" (version #{Asker::VERSION})\n")
16
- file.write(" File : #{project.get(:moodlename)}\n")
17
- file.write(" Time : #{Time.new}\n")
18
- file.write("#{('=' * 50)}\n-->\n\n")
19
-
20
- data[:concepts_ai].each do |concept_ai|
21
- ConceptAIMoodleExporter.run(concept_ai, file)
20
+ file.write("<!--\n#{"=" * 50}\n")
21
+ file.write(" #{Asker::NAME} : version #{Asker::VERSION}\n")
22
+ file.write(" Filename : #{project.get(:moodlename)}\n")
23
+ file.write(" Datetime : #{Time.new}\n")
24
+ file.write("#{"=" * 50}\n-->\n\n")
25
+ file
26
+ end
27
+
28
+ def self.close(file)
29
+ file.write("</quiz>\n")
30
+ file.close
31
+ end
32
+
33
+ def self.export_concepts(concepts:, file:)
34
+ concepts.each do |concept_ai|
35
+ next 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
22
42
  end
43
+ end
23
44
 
24
- data[:codes_ai].each do |code|
25
- CodeMoodleExporter.run(code, file)
45
+ def self.export_codes(codes:, file:)
46
+ codes.each do |code|
47
+ next unless code.process?
48
+ code.questions.each do |question|
49
+ file.write QuestionMoodleFormatter.to_s(question)
50
+ end
26
51
  end
52
+ end
27
53
 
28
- file.write("</quiz>\n")
29
- file.close
54
+ def self.export_problems(problems:, file:)
55
+ problems.each do |problem|
56
+ next unless problem.process?
57
+ problem.questions.each do |question|
58
+ file.write QuestionMoodleFormatter.to_s(question)
59
+ end
60
+ end
30
61
  end
31
62
  end
@@ -1,7 +1,7 @@
1
- require_relative 'concept_ai_yaml_exporter'
2
- require_relative 'concept_doc_exporter'
3
- require_relative 'data_gift_exporter'
4
- require_relative 'data_moodle_exporter'
1
+ require_relative "concept_ai_yaml_exporter"
2
+ require_relative "concept_doc_exporter"
3
+ require_relative "data_gift_exporter"
4
+ require_relative "data_moodle_exporter"
5
5
 
6
6
  ##
7
7
  # Export Output data files
@@ -9,9 +9,10 @@ require_relative 'data_moodle_exporter'
9
9
  module OutputFileExporter
10
10
  def self.export(data, project)
11
11
  config = Application.instance.config
12
- ConceptAIYAMLExporter.export_all(data[:concepts_ai], project) if config['output']['yaml'] == 'yes'
13
- ConceptDocExporter.export_all(data[:concepts], project) if config['output']['doc'] == 'yes'
14
- DataGiftExporter.export_all(data, project) if config['output']['gift'] == 'yes'
15
- DataMoodleExporter.export_all(data, project) if config['output']['moodle'] == 'yes'
12
+
13
+ ConceptAIYAMLExporter.export_all(data[:concepts_ai], project) if config["output"]["yaml"] == "yes"
14
+ ConceptDocExporter.export_all(data[:concepts], project) if config["output"]["doc"] == "yes"
15
+ DataGiftExporter.export_all(data, project) if config["output"]["gift"] == "yes"
16
+ DataMoodleExporter.call(data, project) if config["output"]["moodle"] == "yes"
16
17
  end
17
18
  end
@@ -0,0 +1,30 @@
1
+ require_relative "../formatter/question_gift_formatter"
2
+
3
+ class ProblemGiftExporter
4
+ ##
5
+ # Export an Array of problems to gift format file
6
+ # @param problems (Array)
7
+ def call(problems, file)
8
+ problems.each { |problem| export_one(problem, file) }
9
+ end
10
+
11
+ private
12
+
13
+ def export_one(problem, file)
14
+ return false unless problem.process?
15
+
16
+ file.write head(problem)
17
+ problem.questions.each do |question|
18
+ file.write QuestionGiftFormatter.to_s(question)
19
+ end
20
+ true
21
+ end
22
+
23
+ def head(problem)
24
+ s = "\n"
25
+ s += "// " + "=" * 50 + "\n"
26
+ s += "// Problem: #{problem.name} (#{problem.questions.size} questions)\n"
27
+ s += "// " + "=" * 50 + "\n"
28
+ s
29
+ end
30
+ end
@@ -27,3 +27,9 @@
27
27
  :t8table: 'Concepte <b><%=text1%></b><br/>Completa la següent associació:<br/><ul><li><%=text2%>: "<%=text3%>"</li><li><%=text4%>: [*]</li></ul>Escriu una paraula.<br/>'
28
28
  :t9table: 'Concepte <b><%=text1%></b><br/>Completa la següent associació:<br/><ul><li><%=text2%>: "<%=text3%>"</li><li><%=text4%>: <%=text5%></li></ul>Escriu <%=text6%> paraules.<br/>'
29
29
  :code1: '<pre><%=text1%></pre><br/><p>Escriu el número de línia hi ha el primer error. Escriu 0 si no hi ha cap error.</p>'
30
+ :pa1: '<p><%=text1%></p><p><b>Pregunta:</b> <%=text2%></p><p><b>Resposta:</b > <%=text3%></p>'
31
+ :pa2: '<p><%=text1%></p><p><b>Pregunta:</b> <%=text2%></p>'
32
+ :ps3: '<p><%=text1%></p><p><b>Pregunta:</b> <%=text2%></p><p><b>Resposta:</b ></p><pre><%=text3%></pre><br/><i>(Escriure el número de línia on hi ha el primer error. Escriure 0 si no hi ha cap error)</i>'
33
+ :ps4: 'Canvia el pas <%=text1%> pel pas <%=text2%>'
34
+ :ps5: '<p><%=text1%></p><p><b>Pregunta:</b> <%=text2%></p><p><b>Resposta:</b ></p><pre><%=text3%></pre><br/><i>(Col·loca cada pas en la seva posició correcta dins de la seqüència)</i>'
35
+ :ps6: '<p><%=text1%></p><p><b>Pregunta:</b> <%=text2%></p><br/><i>(Posa cada pas en la posició correcta dins de la seqüència)</i>'
@@ -27,3 +27,9 @@
27
27
  :t8table: 'Begriff <b><%=text1%></b><br/>Vervollständigen Sie / Schreiben Sie einen Begriff:<br/><ul><li><%=text2%>: "<%=text3%>"</li><li><%=text4%>: [*]</li></ul>Escribir una palabra.<br/>'
28
28
  :t9table: 'Begriff <b><%=text1%></b><br/>Verbinden Sie / Schreiben Sie fogende Begriffe:<br/><ul><li><%=text2%>: "<%=text3%>"</li><li><%=text4%>: <%=text5%></li></ul>Escribir <%=text6%> palabras.<br/>'
29
29
  :code1: '<pre><%=text1%></pre><br/><p>Nennen Sie die Nummer der Zeile, in der sich der erste Fehler befindet / Wenn es keinen Fehler gibt, setzen Sie 0 ein.</p>'
30
+ :pa1: '<p><%=text1%></p><p><b>Frage:</b> <%=text2%></p><p><b>Antwort:</b > <%=text3%></p>'
31
+ :pa2: '<p><%=text1%></p><p><b>Frage:</b> <%=text2%></p>'
32
+ :ps3: '<p><%=text1%></p><p><b>Frage:</b> <%=text2%></p><p><b>Antwort:</b ></p><pre><%=text3%></pre><br/><i>(Schreiben Sie die Zeilennummer, in der sich der erste Fehler befindet. Schreiben Sie 0, wenn kein Fehler vorliegt)</i>'
33
+ :ps4: 'Ändere Schritt <%=text1%> in Schritt <%=text2%>'
34
+ :ps5: '<p><%=text1%></p><p><b>Frage:</b> <%=text2%></p><p><b>Antwort:</b ></p><pre><%=text3%></pre><br/><i>(Platzieren Sie jeden Schritt an der richtigen Position innerhalb der Sequenz)</i>'
35
+ :ps6: '<p><%=text1%></p><p><b>Frage:</b> <%=text2%></p><br/><i>(Platzieren Sie jeden Schritt an der richtigen Position innerhalb der Sequenz)</i>'
@@ -1,5 +1,5 @@
1
1
  ---
2
- :none: 'No correct'
2
+ :none: 'None correct'
3
3
  :error: 'Error'
4
4
  :misspelling: 'Misspelling'
5
5
  :true: 'True'
@@ -27,3 +27,9 @@
27
27
  :t8table: '<b>Concept <%=text1%></b><br/>Complete the next association:<br/><ul><li><%=text2%>: "<%=text3%>"</li><li><%=text4%>: [*]</li></ul>Write only one word.<br/>'
28
28
  :t9table: '<b>Concept <%=text1%></b><br/>Complete the next association:<br/><ul><li><%=text2%>: "<%=text3%>"</li><li><%=text4%>: <%=text5%></li></ul>Write <%=text6%> words.<br/>'
29
29
  :code1: '<pre><%=text1%></pre><br/><p>Write the number of the first wrong line. Write 0 if there is no fail.</p>'
30
+ :pa1: '<p><%=text1%></p><p><b>Question:</b> <%=text2%></p><p><b>Answer:</b> <%=text3%></p>'
31
+ :pa2: '<p><%=text1%></p><p><b>Question:</b> <%=text2%></p>'
32
+ :ps3: '<p><%=text1%></p><p><b>Question:</b> <%=text2%></p><p><b>Answer:</b></p><pre><%=text3%></pre><br/><i>(Write the number of the first wrong line. Write 0 if there is no fail)</i>'
33
+ :ps4: 'Change step <%=text1%> by step <%=text2%>'
34
+ :ps5: '<p><%=text1%></p><p><b>Question:</b> <%=text2%></p><p><b>Answer:</b></p><pre><%=text3%></pre><br/><i>(Place each step in its correct position within the sequence)</i>'
35
+ :ps6: '<p><%=text1%></p><p><b>Question:</b> <%=text2%></p><br/><i>(Place each step in its correct position within the sequence)</i>'
@@ -27,3 +27,9 @@
27
27
  :t8table: 'Concepto <b><%=text1%></b><br/>Completa la siguiente asociación:<br/><ul><li><%=text2%>: "<%=text3%>"</li><li><%=text4%>: [*]</li></ul>Escribir una palabra.<br/>'
28
28
  :t9table: 'Concepto <b><%=text1%></b><br/>Completa la siguiente asociación:<br/><ul><li><%=text2%>: "<%=text3%>"</li><li><%=text4%>: <%=text5%></li></ul>Escribir <%=text6%> palabras.<br/>'
29
29
  :code1: '<pre><%=text1%></pre><br/><p>Escribir el número de línea donde está el primer error. Escribir 0 si no hay ningún error.</p>'
30
+ :pa1: '<p><%=text1%></p><p><b>Pregunta:</b> <%=text2%></p><p><b>Respuesta:</b> <%=text3%></p>'
31
+ :pa2: '<p><%=text1%></p><p><b>Pregunta:</b> <%=text2%></p>'
32
+ :ps3: '<p><%=text1%></p><p><b>Pregunta:</b> <%=text2%></p><p><b>Respuesta:</b></p><pre><%=text3%></pre><br/><i>(Escribir el número de línea donde está el primer error. Escribir 0 si no hay ningún error)</i>'
33
+ :ps4: 'Cambia el paso <%=text1%> por el paso <%=text2%>'
34
+ :ps5: '<p><%=text1%></p><p><b>Pregunta:</b> <%=text2%></p><p><b>Respuesta:</b></p><pre><%=text3%></pre><br/><i>(Coloca cada paso en su posición correcta dentro de la secuencia)</i>'
35
+ :ps6: '<p><%=text1%></p><p><b>Pregunta:</b> <%=text2%></p><br/><i>(Coloca cada paso en su posición correcta dentro de la secuencia)</i>'
@@ -27,3 +27,9 @@
27
27
  :t8table: "Concept <b><%=text1%></b><br/>Complétez l'association suivante:<br/><ul><li><%=text2%>: \"<%=text3%>\"</li><li><%=text4%>: [*]</li></ul>Écrire un mot.<br/>"
28
28
  :t9table: "Concept <b><%=text1%></b><br/>Complétez l'association suivante:<br/><ul><li><%=text2%>: \"<%=text3%>\"</li><li><%=text4%>: <%=text5%></li></ul>Écrire<%=text6%> mots.<br/>"
29
29
  :code1: "<pre><%=text1%></pre><br/><p>Écrire le numéro de ligne où se trouve la première erreur. Écrire 0 s'il n'y a aucune erreur.</p>"
30
+ :pa1 : "<p><%=text1%></p><p><b>Question :</b> <%=text2%></p><p><b>Réponse :</b > <%=text3%></p>"
31
+ :pa2 : "<p><%=text1%></p><p><b>Question :</b> <%=text2%></p>"
32
+ :ps3 : "<p><%=text1%></p><p><b>Question :</b> <%=text2%></p><p><b>Réponse :</b ></p><pre><%=text3%></pre><br/><i>(Écrivez le numéro de ligne où se trouve la première erreur. Écrivez 0 s'il n'y a pas d'erreur)</i>"
33
+ :ps4: "Changer l'étape <%=text1%> en étape <%=text2%>"
34
+ :ps5 : "<p><%=text1%></p><p><b>Question :</b> <%=text2%></p><p><b>Réponse :</b ></p><pre><%=text3%></pre><br/><i>(Placez chaque étape dans sa position correcte dans la séquence)</i>"
35
+ :ps6 : "<p><%=text1%></p><p><b>Question :</b> <%=text2%></p><br/><i>(Placez chaque étape dans sa position correcte dans la séquence)</i>"
@@ -1,16 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'rainbow'
4
- require 'terminal-table'
3
+ require "rainbow"
4
+ require "terminal-table"
5
5
 
6
6
  # Define methods to trasnforme Code object into String
7
7
  module CodeStringFormatter
8
8
  def self.to_s(code)
9
9
  t = Terminal::Table.new
10
10
  msg = Rainbow(code.filename).white.bg(:blue).bright
11
- t.add_row [Rainbow('Code').bright, msg]
12
- t.add_row [Rainbow('Type').blue, code.type.to_s]
13
- t.add_row [Rainbow('Lines').blue, code.lines_to_s(code.lines)]
11
+ t.add_row [Rainbow("Code").bright, msg]
12
+ t.add_row [Rainbow("Type").blue, code.type.to_s]
13
+ t.add_row [Rainbow("Lines").blue, code.lines_to_s(code.lines)]
14
14
  "#{t}\n"
15
15
  end
16
16
  end
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: false
2
2
 
3
- require 'rainbow'
4
- require 'terminal-table'
3
+ require "rainbow"
4
+ require "terminal-table"
5
5
 
6
6
  module ConceptDocFormatter
7
7
  ##
8
8
  # Formatter Concept into Doc
9
9
  # @param concept (Concept)
10
10
  def self.to_s(concept)
11
- out = ''
11
+ out = ""
12
12
  out << "\n#{Rainbow(concept.name).bg(:blue).bright}\n\n"
13
13
  concept.texts.each { |i| out << "* #{i}\n" }
14
14
  out << "\n"