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.
- checksums.yaml +4 -4
- data/README.md +10 -7
- data/lib/asker/ai/ai.rb +17 -22
- data/lib/asker/ai/ai_calculate.rb +10 -17
- data/lib/asker/ai/code/base_code_ai.rb +5 -30
- data/lib/asker/ai/code/code_ai_factory.rb +6 -12
- data/lib/asker/ai/code/javascript_code_ai.rb +33 -34
- data/lib/asker/ai/code/python_code_ai.rb +35 -36
- data/lib/asker/ai/code/ruby_code_ai.rb +33 -33
- data/lib/asker/ai/code/sql_code_ai.rb +20 -21
- data/lib/asker/ai/concept_ai.rb +12 -22
- data/lib/asker/ai/problem/problem_ai.rb +226 -0
- data/lib/asker/ai/question.rb +34 -45
- data/lib/asker/ai/stages/base_stage.rb +7 -7
- data/lib/asker/ai/stages/main.rb +6 -7
- data/lib/asker/ai/stages/stage_b.rb +62 -28
- data/lib/asker/ai/stages/stage_d.rb +10 -10
- data/lib/asker/ai/stages/stage_f.rb +17 -17
- data/lib/asker/ai/stages/stage_i.rb +8 -18
- data/lib/asker/ai/stages/stage_s.rb +28 -26
- data/lib/asker/ai/stages/stage_t.rb +54 -76
- data/lib/asker/application.rb +15 -14
- data/lib/asker/check_input/check_haml_data.rb +57 -51
- data/lib/asker/check_input/check_table.rb +26 -19
- data/lib/asker/check_input.rb +10 -22
- data/lib/asker/cli.rb +43 -24
- data/lib/asker/data/code.rb +10 -9
- data/lib/asker/data/column.rb +21 -17
- data/lib/asker/data/concept.rb +24 -37
- data/lib/asker/data/data_field.rb +2 -2
- data/lib/asker/data/problem.rb +112 -0
- data/lib/asker/data/project_data.rb +11 -15
- data/lib/asker/data/row.rb +25 -23
- data/lib/asker/data/table.rb +25 -46
- data/lib/asker/data/template.rb +7 -7
- data/lib/asker/data/world.rb +3 -3
- data/lib/asker/{formatter → deprecated}/question_moodlexml_formatter.rb +19 -21
- data/lib/asker/displayer/code_displayer.rb +10 -10
- data/lib/asker/displayer/concept_ai_displayer.erb +1 -1
- data/lib/asker/displayer/concept_ai_displayer.rb +22 -34
- data/lib/asker/displayer/concept_displayer.rb +9 -11
- data/lib/asker/displayer/problem_displayer.rb +45 -0
- data/lib/asker/displayer/stats_displayer.rb +7 -12
- data/lib/asker/exporter/code_gift_exporter.rb +2 -2
- data/lib/asker/exporter/concept_ai_gift_exporter.rb +4 -4
- data/lib/asker/exporter/concept_ai_yaml_exporter.rb +7 -7
- data/lib/asker/exporter/concept_doc_exporter.rb +5 -5
- data/lib/asker/exporter/data_gift_exporter.rb +14 -15
- data/lib/asker/exporter/data_moodle_exporter.rb +51 -20
- data/lib/asker/exporter/output_file_exporter.rb +9 -8
- data/lib/asker/exporter/problem_gift_exporter.rb +30 -0
- data/lib/asker/files/language/ca/templates.yaml +6 -0
- data/lib/asker/files/language/du/templates.yaml +6 -0
- data/lib/asker/files/language/en/templates.yaml +7 -1
- data/lib/asker/files/language/es/templates.yaml +6 -0
- data/lib/asker/files/language/fr/templates.yaml +6 -0
- data/lib/asker/formatter/code_string_formatter.rb +5 -5
- data/lib/asker/formatter/concept_doc_formatter.rb +3 -3
- data/lib/asker/formatter/concept_string_formatter.rb +27 -24
- data/lib/asker/formatter/moodle/ddmatch.erb +40 -0
- data/lib/asker/formatter/moodle/gapfill.erb +57 -0
- data/lib/asker/formatter/moodle/ordering.erb +41 -0
- data/lib/asker/formatter/question_gift_formatter.rb +41 -14
- data/lib/asker/formatter/question_hash_formatter.rb +5 -6
- data/lib/asker/formatter/question_moodle_formatter.rb +14 -7
- data/lib/asker/formatter/rb2haml_formatter.rb +8 -7
- data/lib/asker/lang/lang.rb +16 -16
- data/lib/asker/lang/lang_factory.rb +13 -16
- data/lib/asker/lang/text_actions.rb +20 -18
- data/lib/asker/loader/code_loader.rb +10 -22
- data/lib/asker/loader/content_loader.rb +42 -49
- data/lib/asker/loader/directory_loader.rb +13 -16
- data/lib/asker/loader/embedded_file.rb +29 -24
- data/lib/asker/loader/file_loader.rb +7 -6
- data/lib/asker/loader/haml_loader.rb +6 -5
- data/lib/asker/loader/image_url_loader.rb +21 -18
- data/lib/asker/loader/input_loader.rb +27 -14
- data/lib/asker/loader/problem_loader.rb +88 -0
- data/lib/asker/loader/project_loader.rb +11 -28
- data/lib/asker/logger.rb +22 -13
- data/lib/asker/skeleton.rb +27 -43
- data/lib/asker/start.rb +44 -0
- data/lib/asker/version.rb +1 -1
- data/lib/asker.rb +7 -53
- metadata +12 -20
- data/lib/asker/ai/code/problem_code_ai.rb +0 -176
- data/lib/asker/exporter/code_moodle_exporter.rb +0 -15
- 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
|
|
4
|
-
require
|
|
5
|
-
|
|
6
|
-
require_relative
|
|
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[
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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.
|
|
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(
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
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[
|
|
131
|
-
renderer = ERB.new(File.read(File.join(File.dirname(__FILE__),
|
|
132
|
-
Logger.
|
|
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
|
|
2
|
-
require_relative
|
|
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
|
-
|
|
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
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
when "resume"
|
|
19
|
+
names = concepts.map { |c| c.name }
|
|
20
|
+
s = " * Concepts (#{names.count}): #{names.join(",")}"
|
|
21
21
|
Logger.verboseln s
|
|
22
|
-
when
|
|
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
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
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
|
-
#
|
|
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[
|
|
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 +=
|
|
26
|
+
s += "// " + "=" * 50 + "\n"
|
|
27
27
|
s += "// Code #{code.type}: #{code.filename} (#{code.questions.size})\n"
|
|
28
|
-
s +=
|
|
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
|
|
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[
|
|
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 +=
|
|
36
|
+
s += "// " + "=" * 50 + "\n"
|
|
37
37
|
s += "// Concept name: #{name}\n"
|
|
38
|
-
s +=
|
|
38
|
+
s += "// " + "=" * 50 + "\n"
|
|
39
39
|
s
|
|
40
40
|
end
|
|
41
41
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
require
|
|
2
|
-
require_relative
|
|
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 = {
|
|
16
|
-
|
|
17
|
-
output = {
|
|
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),
|
|
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[
|
|
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
|
|
4
|
-
require_relative
|
|
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),
|
|
13
|
-
file.write(
|
|
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(
|
|
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
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
6
|
-
require_relative
|
|
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 (
|
|
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),
|
|
16
|
-
file.write(
|
|
17
|
-
file.write("//
|
|
18
|
-
file.write("
|
|
19
|
-
file.write("//
|
|
20
|
-
file.write("//
|
|
21
|
-
|
|
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.
|
|
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#{
|
|
14
|
-
file.write("
|
|
15
|
-
file.write("
|
|
16
|
-
file.write("
|
|
17
|
-
file.write("
|
|
18
|
-
file
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
25
|
-
|
|
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
|
-
|
|
29
|
-
|
|
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
|
|
2
|
-
require_relative
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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: '
|
|
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
|
|
4
|
-
require
|
|
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(
|
|
12
|
-
t.add_row [Rainbow(
|
|
13
|
-
t.add_row [Rainbow(
|
|
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
|
|
4
|
-
require
|
|
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"
|