asker-tool 2.7.2 → 2.9.0

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