asker-tool 2.7.2 → 2.9.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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/lib/asker/ai/problem/customizer.rb +36 -0
  3. data/lib/asker/ai/problem/problem_ai.rb +9 -239
  4. data/lib/asker/ai/problem/stage_answers.rb +104 -0
  5. data/lib/asker/ai/problem/stage_base.rb +34 -0
  6. data/lib/asker/ai/problem/stage_steps.rb +121 -0
  7. data/lib/asker/application.rb +1 -0
  8. data/lib/asker/check_input/check_haml_data.rb +2 -2
  9. data/lib/asker/cli.rb +2 -0
  10. data/lib/asker/data/concept.rb +5 -5
  11. data/lib/asker/data/problem.rb +10 -2
  12. data/lib/asker/data/project_data.rb +3 -2
  13. data/lib/asker/displayer/code_displayer.rb +2 -2
  14. data/lib/asker/displayer/concept_ai_displayer.rb +5 -3
  15. data/lib/asker/displayer/concept_displayer.rb +2 -2
  16. data/lib/asker/displayer/problem_displayer.rb +14 -7
  17. data/lib/asker/displayer/stats_displayer.rb +3 -3
  18. data/lib/asker/exporter/doc/format_code2doc.rb +17 -0
  19. data/lib/asker/exporter/doc/format_concept2doc.rb +30 -0
  20. data/lib/asker/exporter/doc/format_problem2doc.rb +41 -0
  21. data/lib/asker/exporter/export2doc.rb +41 -0
  22. data/lib/asker/exporter/{data_gift_exporter.rb → export2gift.rb} +8 -8
  23. data/lib/asker/exporter/{data_moodle_exporter.rb → export2moodle_xml.rb} +13 -11
  24. data/lib/asker/exporter/export2yaml.rb +70 -0
  25. data/lib/asker/exporter/export_action.rb +18 -0
  26. data/lib/asker/exporter/{code_gift_exporter.rb → gift/export_code2gift.rb} +7 -6
  27. data/lib/asker/exporter/{concept_ai_gift_exporter.rb → gift/export_concept2gift.rb} +7 -8
  28. data/lib/asker/exporter/{problem_gift_exporter.rb → gift/export_problem2gift.rb} +2 -2
  29. data/lib/asker/{formatter → exporter/gift}/question_gift_formatter.rb +0 -3
  30. data/lib/asker/formatter/concept_string_formatter.rb +0 -1
  31. data/lib/asker/formatter/{question_hash_formatter.rb → question2hash.rb} +15 -7
  32. data/lib/asker/formatter/{question_moodle_formatter.rb → question2moodle_xml.rb} +3 -5
  33. data/lib/asker/loader/code_loader.rb +1 -1
  34. data/lib/asker/loader/content_loader.rb +1 -0
  35. data/lib/asker/loader/embedded_file/loader.rb +114 -0
  36. data/lib/asker/loader/embedded_file/type.rb +51 -0
  37. data/lib/asker/loader/problem_loader.rb +2 -0
  38. data/lib/asker/logger.rb +1 -1
  39. data/lib/asker/start.rb +3 -3
  40. data/lib/asker/version.rb +1 -1
  41. metadata +22 -16
  42. data/lib/asker/deprecated/question_moodlexml_formatter.rb +0 -69
  43. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +0 -36
  44. data/lib/asker/exporter/concept_doc_exporter.rb +0 -24
  45. data/lib/asker/exporter/output_file_exporter.rb +0 -18
  46. data/lib/asker/formatter/concept_doc_formatter.rb +0 -33
  47. data/lib/asker/loader/embedded_file.rb +0 -133
@@ -11,7 +11,8 @@ class ProjectData
11
11
  end
12
12
 
13
13
  def reset
14
- @default = {inputbasedir: FileUtils.pwd,
14
+ # @default = {inputbasedir: FileUtils.pwd,
15
+ @default = {inputbasedir: Dir.pwd,
15
16
  stages: {d: true, b: true, f: true, i: true, s: true, t: true},
16
17
  threshold: 0.5,
17
18
  outputdir: "output",
@@ -44,7 +45,7 @@ class ProjectData
44
45
  @param[:logname] = "#{@param[:projectname]}.log"
45
46
  @param[:outputname] = "#{@param[:projectname]}-gift.txt"
46
47
  @param[:lessonname] = "#{@param[:projectname]}.txt"
47
- @param[:yamlname] = "#{@param[:projectname]}-questions.yaml"
48
+ @param[:yamlname] = "#{@param[:projectname]}.yaml"
48
49
  @param[:moodlename] = "#{@param[:projectname]}-moodle.xml"
49
50
 
50
51
  outputdir = get(:outputdir)
@@ -1,11 +1,11 @@
1
1
  require "terminal-table"
2
2
  require_relative "../logger"
3
3
 
4
- module CodeDisplayer
4
+ class CodeDisplayer
5
5
  ##
6
6
  # Show all "code" data on screen
7
7
  # @param codes (Array) List of "code" data
8
- def self.show(codes)
8
+ def call(codes)
9
9
  return if codes.nil? || codes.size.zero?
10
10
 
11
11
  total_c = total_q = total_e = 0
@@ -10,7 +10,7 @@ class ConceptAIDisplayer
10
10
  ##
11
11
  # Display ConceptAI stat on screen
12
12
  # @param concepts_ai (Array)
13
- def self.show(concepts_ai)
13
+ def call(concepts_ai)
14
14
  stages = Application.instance.config["questions"]["stages"]
15
15
  # Create table HEAD
16
16
  screen_table = Terminal::Table.new do |st|
@@ -80,7 +80,9 @@ class ConceptAIDisplayer
80
80
  Logger.info "#{screen_table}\n"
81
81
  end
82
82
 
83
- private_class_method def self.export_excluded_questions(screen_table, concepts_ai)
83
+ private
84
+
85
+ def export_excluded_questions(screen_table, concepts_ai)
84
86
  # Create table BODY
85
87
  total = {}
86
88
  total[:q] = total[:c] = 0
@@ -114,7 +116,7 @@ class ConceptAIDisplayer
114
116
  total[:ss], total[:st]]
115
117
  end
116
118
 
117
- private_class_method def self.export_notes
119
+ def export_notes
118
120
  exclude_questions = Application.instance.config["questions"]["exclude"].to_s
119
121
  renderer = ERB.new(File.read(File.join(File.dirname(__FILE__), "concept_ai_displayer.erb")))
120
122
  Logger.info Rainbow(renderer.result(binding)).white
@@ -2,11 +2,11 @@ require_relative "../application"
2
2
  require_relative "../formatter/concept_string_formatter"
3
3
  require_relative "../logger"
4
4
 
5
- module ConceptDisplayer
5
+ class ConceptDisplayer
6
6
  ##
7
7
  # Show concepts on screen
8
8
  # @param concepts (Array) List of concept data
9
- def self.show(concepts)
9
+ def call(concepts)
10
10
  return if concepts.nil? || concepts.size.zero?
11
11
 
12
12
  show_mode = Application.instance.config["global"]["show_mode"]
@@ -1,16 +1,16 @@
1
1
  require "terminal-table"
2
2
  require_relative "../logger"
3
3
 
4
- module ProblemDisplayer
4
+ class ProblemDisplayer
5
5
  ##
6
6
  # Show all "problem" data on screen
7
7
  # @param problems (Array) List of "problems" data
8
- def self.show(problems)
8
+ def call(problems)
9
9
  return if problems.nil? || problems.size.zero?
10
10
 
11
- total_p = total_q = total_e = 0
11
+ total_p = total_q = total_e = total_a = total_s = 0
12
12
  my_screen_table = Terminal::Table.new do |st|
13
- st << %w[Problem Desc Questions Entries xFactor]
13
+ st << %w[Problem Desc Questions Entries xFactor a s]
14
14
  st << :separator
15
15
  end
16
16
 
@@ -23,14 +23,19 @@ module ProblemDisplayer
23
23
  e += 1 if !ask[:answer].nil?
24
24
  end
25
25
 
26
+ desc = Rainbow(problem.desc[0, 24]).green
26
27
  q = problem.questions.size
27
28
  factor = "Unknown"
28
29
  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]
30
+ a = problem.stats[:answer]
31
+ s = problem.stats[:steps]
32
+
33
+ my_screen_table.add_row [problem.name, desc, q, e, factor, a, s]
31
34
  total_p += 1
32
35
  total_q += q
33
36
  total_e += e
37
+ total_a += a
38
+ total_s += s
34
39
  end
35
40
  return unless total_p.positive?
36
41
 
@@ -38,7 +43,9 @@ module ProblemDisplayer
38
43
  my_screen_table.add_row [Rainbow("TOTAL = #{total_p}").bright, "",
39
44
  Rainbow(total_q.to_s).bright,
40
45
  Rainbow(total_e.to_s).bright,
41
- Rainbow((total_q / total_e.to_f).round(2)).bright]
46
+ Rainbow((total_q / total_e.to_f).round(2)).bright,
47
+ Rainbow(total_a.to_s).bright,
48
+ Rainbow(total_s.to_s).bright]
42
49
  Logger.verboseln Rainbow("\n[INFO] Showing PROBLEMs statistics").white
43
50
  Logger.verboseln my_screen_table.to_s
44
51
  end
@@ -10,8 +10,8 @@ module StatsDisplayer
10
10
  def self.show(data)
11
11
  return unless Application.instance.config["global"]["show_mode"]
12
12
 
13
- ConceptAIDisplayer.show(data[:concepts_ai])
14
- CodeDisplayer.show(data[:codes_ai])
15
- ProblemDisplayer.show(data[:problems])
13
+ ConceptAIDisplayer.new.call(data[:concepts_ai])
14
+ CodeDisplayer.new.call(data[:codes_ai])
15
+ ProblemDisplayer.new.call(data[:problems])
16
16
  end
17
17
  end
@@ -0,0 +1,17 @@
1
+ class FormatCode2Doc
2
+ def call(code)
3
+ out = ""
4
+ title = "#{code.filename} (#{code.type})"
5
+ out << ("-" * title.size + "\n")
6
+ out << "#{title}\n"
7
+ if code.features.size.positive?
8
+ out << "* features: #{code.features.join(", ")}"
9
+ end
10
+ out << "\n"
11
+ code.lines.each_with_index do |line, index|
12
+ out << "#{index} | #{line}\n"
13
+ end
14
+ out << "\n"
15
+ out
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ require "terminal-table"
2
+
3
+ class FormatConcept2Doc
4
+ def call(concept)
5
+ out = ""
6
+ title = concept.names.join(", ")
7
+ out << ("-" * title.size + "\n")
8
+ out << "#{title}\n"
9
+ concept.texts.each { |text| out << "* #{text}\n" }
10
+ concept.images.each do |data|
11
+ out << "* (#{data[:type]}) #{data[:url]}\n"
12
+ end
13
+ out << "\n"
14
+ concept.tables.each do |table|
15
+ out << format_table(table)
16
+ end
17
+ out
18
+ end
19
+
20
+ private
21
+
22
+ def format_table(table)
23
+ my_screen_table = Terminal::Table.new do |st|
24
+ st << table.fields
25
+ st << :separator
26
+ table.rows.each { |r| st.add_row r }
27
+ end
28
+ "#{my_screen_table}\n"
29
+ end
30
+ end
@@ -0,0 +1,41 @@
1
+ class FormatProblem2Doc
2
+ def initialize(problem)
3
+ @problem = problem
4
+ end
5
+
6
+ def call
7
+ # attr_accessor :varnames
8
+ # attr_accessor :cases
9
+ out = ""
10
+ title = "Problem: #{@problem.name}"
11
+ out << ("-" * title.size + "\n")
12
+ out << "#{title}\n"
13
+ desc = replace_case_values(@problem.desc)
14
+ out << "#{desc}\n"
15
+ @problem.asks.each_with_index do |ask, index|
16
+ text = replace_case_values(ask[:text])
17
+ out << "#{index + 1}) #{text}\n"
18
+ if ask[:answer]
19
+ answer = replace_case_values(ask[:answer])
20
+ out << " #{answer}\n"
21
+ else
22
+ ask[:steps].each do |step|
23
+ step = replace_case_values(step)
24
+ out << " #{step}\n"
25
+ end
26
+ end
27
+ end
28
+ out << "\n"
29
+ out << "\n"
30
+ out
31
+ end
32
+
33
+ private
34
+
35
+ def replace_case_values(text)
36
+ output = text.clone
37
+ keyvalues = @problem.varnames.zip @problem.cases[0]
38
+ keyvalues.each { |varname, value | output.gsub!(varname, value) }
39
+ output
40
+ end
41
+ end
@@ -0,0 +1,41 @@
1
+ require_relative "doc/format_code2doc"
2
+ require_relative "doc/format_concept2doc"
3
+ require_relative "doc/format_problem2doc"
4
+ require_relative "../version"
5
+
6
+ class Export2Doc
7
+ def call(data, project)
8
+ file_open(project)
9
+ export_codes(data[:codes])
10
+ export_concepts(data[:concepts])
11
+ export_problems(data[:problems])
12
+ @file.close
13
+ end
14
+
15
+ private
16
+
17
+ def file_open(project)
18
+ @file = File.new(project.get(:lessonpath), "w")
19
+ @file.write("Asker : version #{Asker::VERSION}\n")
20
+ @file.write("Filename : #{project.get(:lessonname)}\n")
21
+ @file.write("Datetime : #{Time.new}\n\n")
22
+ end
23
+
24
+ def export_codes(codes)
25
+ codes.each do |code|
26
+ @file.write(FormatCode2Doc.new.call(code)) if code.process
27
+ end
28
+ end
29
+
30
+ def export_concepts(concepts)
31
+ concepts.each do |concept|
32
+ @file.write(FormatConcept2Doc.new.call(concept)) if concept.process
33
+ end
34
+ end
35
+
36
+ def export_problems(problems)
37
+ problems.each do |problem|
38
+ @file.write(FormatProblem2Doc.new(problem).call) if problem.process
39
+ end
40
+ end
41
+ end
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "concept_ai_gift_exporter"
4
- require_relative "code_gift_exporter"
5
- require_relative "problem_gift_exporter"
3
+ require_relative "gift/export_code2gift"
4
+ require_relative "gift/export_concept2gift"
5
+ require_relative "gift/export_problem2gift"
6
6
  require_relative "../application"
7
7
  require_relative "../version"
8
8
 
9
- module DataGiftExporter
9
+ class Export2Gift
10
10
  ##
11
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
- def self.export_all(data, project)
14
+ def call(data, project)
15
15
  file = File.open(project.get(:outputpath), "w")
16
16
  file.write("// " + ("=" * 50) + "\n")
17
17
  file.write("// #{Asker::NAME} : version #{Asker::VERSION}\n")
@@ -21,9 +21,9 @@ module DataGiftExporter
21
21
  category = Application.instance.config["questions"]["category"]
22
22
  file.write("$CATEGORY: $course$/#{category}\n") unless category.nil?
23
23
 
24
- ConceptAIGiftExporter.export_all(data[:concepts_ai], file)
25
- CodeGiftExporter.export_all(data[:codes_ai], file)
26
- ProblemGiftExporter.new.call(data[:problems], file)
24
+ ExportConcept2Gift.new.call(data[:concepts_ai], file)
25
+ ExportCode2Gift.new.call(data[:codes_ai], file)
26
+ ExportProblem2Gift.new.call(data[:problems], file)
27
27
  file.close
28
28
  end
29
29
  end
@@ -1,9 +1,9 @@
1
1
  require_relative "../application"
2
2
  require_relative "../version"
3
- require_relative "../formatter/question_moodle_formatter"
3
+ require_relative "../formatter/question2moodle_xml"
4
4
 
5
- module DataMoodleExporter
6
- def self.call(data, project)
5
+ class Export2MoodleXML
6
+ def call(data, project)
7
7
  file = File.open(project.get(:moodlepath), "w")
8
8
  add_header(file, project)
9
9
 
@@ -14,7 +14,9 @@ module DataMoodleExporter
14
14
  close(file)
15
15
  end
16
16
 
17
- def self.add_header(file, project)
17
+ private
18
+
19
+ def add_header(file, project)
18
20
  file.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
19
21
  file.write("<quiz>\n")
20
22
  file.write("<!--\n#{"=" * 50}\n")
@@ -25,37 +27,37 @@ module DataMoodleExporter
25
27
  file
26
28
  end
27
29
 
28
- def self.close(file)
30
+ def close(file)
29
31
  file.write("</quiz>\n")
30
32
  file.close
31
33
  end
32
34
 
33
- def self.export_concepts(concepts:, file:)
35
+ def export_concepts(concepts:, file:)
34
36
  concepts.each do |concept_ai|
35
37
  next unless concept_ai.concept.process?
36
38
 
37
39
  Application.instance.config["questions"]["stages"].each do |stage|
38
40
  concept_ai.questions[stage].each do |question|
39
- file.write(QuestionMoodleFormatter.to_s(question))
41
+ file.write(Question2MoodleXML.new.format(question))
40
42
  end
41
43
  end
42
44
  end
43
45
  end
44
46
 
45
- def self.export_codes(codes:, file:)
47
+ def export_codes(codes:, file:)
46
48
  codes.each do |code|
47
49
  next unless code.process?
48
50
  code.questions.each do |question|
49
- file.write QuestionMoodleFormatter.to_s(question)
51
+ file.write Question2MoodleXML.new.format(question)
50
52
  end
51
53
  end
52
54
  end
53
55
 
54
- def self.export_problems(problems:, file:)
56
+ def export_problems(problems:, file:)
55
57
  problems.each do |problem|
56
58
  next unless problem.process?
57
59
  problem.questions.each do |question|
58
- file.write QuestionMoodleFormatter.to_s(question)
60
+ file.write Question2MoodleXML.new.format(question)
59
61
  end
60
62
  end
61
63
  end
@@ -0,0 +1,70 @@
1
+ require "yaml"
2
+ require_relative "../formatter/question2hash"
3
+
4
+ class Export2YAML
5
+ ##
6
+ # Export array of ConceptAI objects from Project to YAML output file
7
+ # @param concepts_ai (Array)
8
+ # @param project (Project)
9
+ def call(data, project)
10
+ questions = []
11
+ questions += get_questions_from_codes(data)
12
+ questions += get_questions_from_concepts(data)
13
+ questions += get_questions_from_problems(data)
14
+
15
+ output = {
16
+ lang: project.get(:lang_code),
17
+ projectname: project.get(:projectname),
18
+ questions: questions
19
+ }
20
+
21
+ yamlfile = File.open(project.get(:yamlpath), "w")
22
+ yamlfile.write(output.to_yaml)
23
+ yamlfile.close
24
+ end
25
+
26
+ private
27
+
28
+ def get_questions_from_codes(data)
29
+ questions = []
30
+ data[:codes].each do |code|
31
+ next unless code.process
32
+ code.questions.each do |question|
33
+ questions << Question2Hash.new.format(question)
34
+ end
35
+ end
36
+ questions
37
+ end
38
+
39
+ def get_questions_from_concepts(data)
40
+ questions = []
41
+ data[:concepts_ai].each do |concept_ai|
42
+ questions += get_questions_from_concept concept_ai
43
+ end
44
+ questions
45
+ end
46
+
47
+ def get_questions_from_concept(concept_ai)
48
+ questions = []
49
+ return questions unless concept_ai.concept.process?
50
+
51
+ Application.instance.config["questions"]["stages"].each do |stage|
52
+ concept_ai.questions[stage].each do |question|
53
+ question.lang = concept_ai.concept.lang
54
+ questions << Question2Hash.new.format(question)
55
+ end
56
+ end
57
+ questions
58
+ end
59
+
60
+ def get_questions_from_problems(data)
61
+ questions = []
62
+ data[:problems].each do |problem|
63
+ next unless problem.process
64
+ problem.questions.each do |question|
65
+ questions << Question2Hash.new.format(question)
66
+ end
67
+ end
68
+ questions
69
+ end
70
+ end
@@ -0,0 +1,18 @@
1
+ require_relative "export2doc"
2
+ require_relative "export2gift"
3
+ require_relative "export2moodle_xml"
4
+ require_relative "export2yaml"
5
+
6
+ ##
7
+ # Export Output data files
8
+ # * YAML, Doc (txt), Gift (ConceptAI, Code) and Moodle XML (ConceptAI, Code)
9
+ class ExportAction
10
+ def call(data, project)
11
+ output = Application.instance.config["output"]
12
+
13
+ Export2Doc.new.call(data, project) if output["doc"] == "yes"
14
+ Export2Gift.new.call(data, project) if output["gift"] == "yes"
15
+ Export2MoodleXML.new.call(data, project) if output["moodle"] == "yes"
16
+ Export2YAML.new.call(data, project) if output["yaml"] == "yes"
17
+ end
18
+ end
@@ -1,17 +1,18 @@
1
- require_relative "../formatter/question_gift_formatter"
1
+ require_relative "question_gift_formatter"
2
2
 
3
- module CodeGiftExporter
3
+ class ExportCode2Gift
4
4
  ##
5
5
  # Export an Array of codes to gift format file
6
6
  # @param codes (Array)
7
- def self.export_all(codes, file)
7
+ def call(codes, file)
8
8
  codes.each { |code| export(code, file) }
9
9
  end
10
10
 
11
+ private
12
+
11
13
  ##
12
14
  # Export 1 code to gift format file
13
- # @param code (Code)
14
- def self.export(code, file)
15
+ def export(code, file)
15
16
  return false unless code.process?
16
17
 
17
18
  file.write head(code)
@@ -21,7 +22,7 @@ module CodeGiftExporter
21
22
  true
22
23
  end
23
24
 
24
- private_class_method def self.head(code)
25
+ def head(code)
25
26
  s = "\n"
26
27
  s += "// " + "=" * 50 + "\n"
27
28
  s += "// Code #{code.type}: #{code.filename} (#{code.questions.size})\n"
@@ -1,22 +1,21 @@
1
- # frozen_string_literal: true
1
+ require_relative "question_gift_formatter"
2
2
 
3
- require_relative "../formatter/question_gift_formatter"
4
-
5
- # Export ConceptIA data to gift to outputfile
6
- module ConceptAIGiftExporter
3
+ class ExportConcept2Gift
7
4
  ##
8
5
  # Export an array of ConceptAI objects from Project into GIFT outpufile
9
6
  # @param concepts_ai (Array)
10
7
  # @param file (File)
11
- def self.export_all(concepts_ai, file)
8
+ def call(concepts_ai, file)
12
9
  concepts_ai.each { |concept_ai| export(concept_ai, file) }
13
10
  end
14
11
 
12
+ private
13
+
15
14
  ##
16
15
  # Export 1 concept_ai from project
17
16
  # @param concept_ai (ConceptAI)
18
17
  # @param file (File)
19
- private_class_method def self.export(concept_ai, file)
18
+ def export(concept_ai, file)
20
19
  return unless concept_ai.concept.process?
21
20
 
22
21
  file.write head(concept_ai.concept.name)
@@ -31,7 +30,7 @@ module ConceptAIGiftExporter
31
30
  # Convert Concept name into gift format head
32
31
  # @param name (String)
33
32
  # @return String
34
- private_class_method def self.head(name)
33
+ def head(name)
35
34
  s = "\n"
36
35
  s += "// " + "=" * 50 + "\n"
37
36
  s += "// Concept name: #{name}\n"
@@ -1,6 +1,6 @@
1
- require_relative "../formatter/question_gift_formatter"
1
+ require_relative "question_gift_formatter"
2
2
 
3
- class ProblemGiftExporter
3
+ class ExportProblem2Gift
4
4
  ##
5
5
  # Export an Array of problems to gift format file
6
6
  # @param problems (Array)
@@ -1,6 +1,3 @@
1
- # frozen_string_literal: false
2
-
3
- # Transform Questions into Gift format
4
1
  module QuestionGiftFormatter
5
2
  ##
6
3
  # Convert question object into gift formatted string
@@ -3,7 +3,6 @@
3
3
  require "rainbow"
4
4
  require "terminal-table"
5
5
 
6
- # Define methods to transform Concept into String
7
6
  module ConceptStringFormatter
8
7
  ##
9
8
  # Formatter Concept to String
@@ -1,6 +1,7 @@
1
- # Transform Questions into YAML format
2
- module QuestionHashFormatter
3
- def self.to_hash(question)
1
+ require_relative "../logger"
2
+
3
+ class Question2Hash
4
+ def format(question)
4
5
  @question = question
5
6
  # Return question using YAML format
6
7
  s = {}
@@ -9,23 +10,30 @@ module QuestionHashFormatter
9
10
  s[:text] = sanitize(@question.text)
10
11
  s[:type] = @question.type
11
12
  s[:feedback] = sanitize(@question.feedback.to_s)
12
- s[:lang] = @question.lang.code.to_sym
13
13
  case @question.type
14
+ when :boolean
15
+ s[:answer] = @question.good
14
16
  when :choice
15
17
  s[:answer] = sanitize(@question.good)
16
18
  s[:options] = (@question.bads + [@question.good]).shuffle
17
- when :boolean
18
- s[:answer] = @question.good
19
+ when :ddmatch
20
+ s[:answer] = @question.matching
19
21
  when :match
20
22
  s[:answer] = @question.matching
23
+ when :ordering
24
+ s[:answer] = @question.ordering
21
25
  when :short
22
26
  @question.shorts.uniq!
23
27
  s[:answer] = @question.shorts
28
+ else
29
+ Logger.warn "[WARN] Question2Hash: Unkown type (#{@question.type})"
24
30
  end
25
31
  s
26
32
  end
27
33
 
28
- def self.sanitize(input = "")
34
+ private
35
+
36
+ def sanitize(input = "")
29
37
  output = input.dup
30
38
  output.gsub!("#", "\\#")
31
39
  output.tr!("\n", " ")
@@ -1,15 +1,13 @@
1
- # frozen_string_literal: false
2
-
3
1
  require "erb"
4
2
  require_relative "../application"
5
3
 
6
4
  # Transform Questions into Gift format
7
- class QuestionMoodleFormatter
5
+ class Question2MoodleXML
8
6
  ##
9
7
  # Convert question object into gift formatted string
10
8
  # @param question (Question)
11
9
  # @return String
12
- def self.to_s(question)
10
+ def format(question)
13
11
  case question.type
14
12
  when :choice
15
13
  fractions = Application.instance.config["questions"]["fractions"]
@@ -31,7 +29,7 @@ class QuestionMoodleFormatter
31
29
  when :short
32
30
  template = File.read(File.join(File.dirname(__FILE__), "moodle", "shortanswer.erb"))
33
31
  else
34
- warn "[ERROR] QuestionMoodleFormatter: Unknown type (#{question.type})"
32
+ warn "[ERROR] Question2MoodleXML: Unknown type (#{question.type})"
35
33
  exit 1
36
34
  end
37
35
  renderer = ERB.new(template)
@@ -13,7 +13,7 @@ module CodeLoader
13
13
  def self.call(xmldata, filepath)
14
14
  data = read_codedata_from_xml(xmldata, File.basename(filepath))
15
15
  code = Code.new(File.dirname(filepath), data[:path], data[:type])
16
- code.features << data[:features]
16
+ code.features = data[:features]
17
17
  code
18
18
  end
19
19
 
@@ -48,6 +48,7 @@ class ContentLoader
48
48
  lang_code = ProjectData.instance.lang
49
49
  Logger.warn "ContentLoader: Applying default lang (#{lang_code})"
50
50
  end
51
+ ProjectData.instance.set(:lang_code, lang_code)
51
52
  LangFactory.instance.get(lang_code)
52
53
  end
53
54