asker-tool 2.5.9 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
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"