asker-tool 2.1.5 → 2.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/{LICENSE → LICENSE.txt} +0 -0
  3. data/README.md +2 -3
  4. data/bin/asker +1 -0
  5. data/lib/asker.rb +10 -6
  6. data/lib/asker/ai/ai.rb +4 -0
  7. data/lib/asker/ai/code/base_code_ai.rb +104 -0
  8. data/lib/asker/{code/ai → ai/code}/code_ai_factory.rb +11 -1
  9. data/lib/asker/{code/ai → ai/code}/javascript_code_ai.rb +2 -5
  10. data/lib/asker/ai/code/problem_code_ai.rb +176 -0
  11. data/lib/asker/{code/ai → ai/code}/python_code_ai.rb +2 -5
  12. data/lib/asker/{code/ai → ai/code}/ruby_code_ai.rb +14 -7
  13. data/lib/asker/{code/ai → ai/code}/sql_code_ai.rb +2 -5
  14. data/lib/asker/ai/concept_ai.rb +1 -0
  15. data/lib/asker/ai/stages/stage_t.rb +76 -76
  16. data/lib/asker/application.rb +18 -2
  17. data/lib/asker/checker.rb +112 -30
  18. data/lib/asker/cli.rb +12 -25
  19. data/lib/asker/data/code.rb +73 -0
  20. data/lib/asker/data/column.rb +31 -21
  21. data/lib/asker/data/concept.rb +42 -45
  22. data/lib/asker/data/data_field.rb +14 -0
  23. data/lib/asker/data/row.rb +75 -52
  24. data/lib/asker/data/table.rb +89 -42
  25. data/lib/asker/data/world.rb +57 -33
  26. data/lib/asker/displayer/concept_ai_displayer.rb +56 -37
  27. data/lib/asker/displayer/concept_displayer.rb +7 -5
  28. data/lib/asker/displayer/stats_displayer.rb +4 -3
  29. data/lib/asker/exporter/concept_ai_gift_exporter.rb +5 -3
  30. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +7 -3
  31. data/lib/asker/exporter/output_file_exporter.rb +1 -1
  32. data/lib/asker/files/config.ini +37 -0
  33. data/lib/asker/files/example-concept.haml +0 -1
  34. data/lib/asker/{lang/locales → files/language}/du/templates.yaml +0 -0
  35. data/lib/asker/{lang/locales → files/language}/en/connectors.yaml +0 -0
  36. data/lib/asker/{lang/locales → files/language}/en/mistakes.yaml +0 -0
  37. data/lib/asker/{lang/locales → files/language}/en/templates.yaml +0 -0
  38. data/lib/asker/{lang/locales → files/language}/es/connectors.yaml +0 -0
  39. data/lib/asker/{lang/locales → files/language}/es/mistakes.yaml +0 -0
  40. data/lib/asker/{lang/locales → files/language}/es/templates.yaml +0 -0
  41. data/lib/asker/{lang/locales → files/language}/fr/connectors.yaml +0 -0
  42. data/lib/asker/{lang/locales → files/language}/fr/mistakes.yaml +0 -0
  43. data/lib/asker/{lang/locales → files/language}/fr/templates.yaml +0 -0
  44. data/lib/asker/{lang/locales → files/language}/javascript/connectors.yaml +0 -0
  45. data/lib/asker/{lang/locales → files/language}/javascript/mistakes.yaml +0 -0
  46. data/lib/asker/{lang/locales → files/language}/javascript/templates.yaml +0 -0
  47. data/lib/asker/{lang/locales → files/language}/math/connectors.yaml +0 -0
  48. data/lib/asker/{lang/locales → files/language}/math/mistakes.yaml +0 -0
  49. data/lib/asker/{lang/locales → files/language}/math/templates.yaml +0 -0
  50. data/lib/asker/{lang/locales → files/language}/python/connectors.yaml +0 -0
  51. data/lib/asker/{lang/locales → files/language}/python/mistakes.yaml +0 -0
  52. data/lib/asker/{lang/locales → files/language}/python/templates.yaml +0 -0
  53. data/lib/asker/{lang/locales → files/language}/ruby/connectors.yaml +0 -0
  54. data/lib/asker/{lang/locales → files/language}/ruby/mistakes.yaml +0 -0
  55. data/lib/asker/{lang/locales → files/language}/ruby/templates.yaml +0 -0
  56. data/lib/asker/{lang/locales → files/language}/sql/connectors.yaml +0 -0
  57. data/lib/asker/{lang/locales → files/language}/sql/mistakes.yaml +0 -0
  58. data/lib/asker/{lang/locales → files/language}/sql/templates.yaml +0 -0
  59. data/lib/asker/lang/lang.rb +17 -10
  60. data/lib/asker/lang/lang_factory.rb +26 -5
  61. data/lib/asker/lang/text_actions.rb +87 -69
  62. data/lib/asker/loader/code_loader.rb +3 -3
  63. data/lib/asker/loader/content_loader.rb +9 -5
  64. data/lib/asker/loader/file_loader.rb +2 -11
  65. data/lib/asker/loader/haml_loader.rb +15 -0
  66. data/lib/asker/loader/image_url_loader.rb +5 -8
  67. data/lib/asker/loader/input_loader.rb +8 -9
  68. data/lib/asker/loader/project_loader.rb +10 -8
  69. data/lib/asker/logger.rb +3 -3
  70. data/lib/asker/project.rb +24 -50
  71. data/lib/asker/skeleton.rb +22 -13
  72. metadata +39 -37
  73. data/lib/asker/code/ai/base_code_ai.rb +0 -48
  74. data/lib/asker/code/code.rb +0 -53
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 39bc74c80c6c83d62fb43bee32e10d3c3503880132cbaaa81f5e14115c9286d7
4
- data.tar.gz: b60194338ffb8429c665d726b62f784c7a0787efb79db4a079b4c13bcbcd6fe8
3
+ metadata.gz: 31954f483d7ed78c542d50fcbfd3ce9419d49cca87a89a6dd717e9832e870386
4
+ data.tar.gz: 2dc8133f935ec289cafa318392d2575542f3083c165d0e86b6902ef7fbc2a427
5
5
  SHA512:
6
- metadata.gz: 11b8da624fedb21e507ec7f015e8e921d8d2a85efd613e1a85646114e4b505a73f303b96b2a76ce77653cf511143f495dffcb6477959eb43ad139446547e55ae
7
- data.tar.gz: f6c64ac247cada2b4099385e77b2e86b953f60d4250a01f2907ff811b92d10d50628ffeb0c1f8921bef5900be3f46bec18f664276e03441e8af7ae7183965f28
6
+ metadata.gz: c107cb11e05e15e635d4fd8e6c8ba04389a2fd70a1e0f03e4f468d61d8bb01b5b45083a9f162c2e0221359fefef14fa96f02f78af32b74a074fb7f673fceb0a1
7
+ data.tar.gz: 7f7e4305c1c2ec88e81245d3402f27f5ae1590b87ddfa45932cc19dfcf8c4d3d6d9d6326cbf6e03941194e71ceb65922bf85ca15f5dce6d1abc97293295ac6d5
File without changes
data/README.md CHANGED
@@ -7,7 +7,7 @@ Generate a lot of questions from an _input file_ base on your own _definitions_.
7
7
 
8
8
  ASKER helps trainers to create a huge amount of questions, from a definitions (_conceptual entities_) input file.
9
9
 
10
- * Free Software [LICENSE](https://github.com/dvarrui/asker/blob/devel/LICENSE).
10
+ * Free Software [LICENSE](https://github.com/dvarrui/asker/blob/devel/LICENSE.txt).
11
11
  * Multiplatform.
12
12
  * Ruby program.
13
13
 
@@ -25,14 +25,13 @@ Steps:
25
25
  1. Create an input file with your definitions (_conceptual entities_).
26
26
  1. Run _asker_ and get the results into `output` directory.
27
27
 
28
- Run `asker` with our example input file as argument (`jedi.haml`):
28
+ Example: Running `asker` with our example input file as argument (`jedi.haml`):
29
29
 
30
30
  ```
31
31
  asker docs/examples/starwars/jedi.haml
32
32
  ```
33
33
 
34
34
  * Output files created into the `output` folder.
35
- * This example use an example input definition file `docs/examples/starwars/jedi.haml`, with concepts about _"Jedi's"_. ;-)
36
35
  * More [example input files](https://github.com/dvarrui/asker/tree/devel/docs/examples).
37
36
  * More asker input files at `github/dvarrui/asker-inputs` repository.
38
37
 
data/bin/asker CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/ruby
2
2
  require 'asker/cli'
3
+
3
4
  # Start Asker command line interface
4
5
  CLI.start(ARGV)
data/lib/asker.rb CHANGED
@@ -17,8 +17,14 @@ class Asker
17
17
  ##
18
18
  # Create asker input demo files
19
19
  # @param dirpath (String)
20
- def self.create_skeleton(dirpath)
21
- Skeleton.create(dirpath)
20
+ def self.create_input(dirpath)
21
+ Skeleton.create_input(dirpath)
22
+ end
23
+
24
+ ##
25
+ # Create asker configuration files
26
+ def self.create_configuration
27
+ Skeleton.create_configuration
22
28
  end
23
29
 
24
30
  ##
@@ -33,7 +39,7 @@ class Asker
33
39
  # @param filepath (String) HAML or XML filepath
34
40
  def self.start(filepath)
35
41
  project, data = load_input(filepath)
36
- ConceptDisplayer.show(data[:concepts], project.get(:show_mode))
42
+ ConceptDisplayer.show(data[:concepts])
37
43
  create_output(project, data)
38
44
  end
39
45
 
@@ -50,7 +56,6 @@ class Asker
50
56
  ##
51
57
  # Create output files: Gift, YAML, TXT Doc
52
58
  # rubocop:disable Metrics/AbcSize
53
- # rubocop:disable Metrics/MethodLength
54
59
  private_class_method def self.create_output(project, data)
55
60
  Logger.verbose "\n[INFO] Creating output files"
56
61
  Logger.verbose ' ├── Gift questions file => ' +
@@ -60,9 +65,8 @@ class Asker
60
65
  Logger.verbose ' └── Lesson file => ' +
61
66
  Rainbow(project.get(:lessonpath)).bright
62
67
  OutputFileExporter.export(data, project)
63
- StatsDisplayer.show(data, project.get(:show_mode))
68
+ StatsDisplayer.show(data)
64
69
  project.close # Logger use Project.get(:logfile) until the end
65
70
  end
66
71
  # rubocop:enable Metrics/AbcSize
67
- # rubocop:enable Metrics/MethodLength
68
72
  end
data/lib/asker/ai/ai.rb CHANGED
@@ -46,6 +46,8 @@ module AI
46
46
  end
47
47
  end
48
48
 
49
+ # rubocop:disable Metrics/AbcSize
50
+ # rubocop:disable Metrics/MethodLength
49
51
  def exclude_questions
50
52
  param = Application.instance.config['questions']['exclude']
51
53
  return if param.nil?
@@ -61,6 +63,8 @@ module AI
61
63
  @questions = input
62
64
  @excluded_questions = output
63
65
  end
66
+ # rubocop:enable Metrics/AbcSize
67
+ # rubocop:enable Metrics/MethodLength
64
68
 
65
69
  def string_has_this_tags?(input, tags)
66
70
  flag = false
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: false
2
+
3
+ require_relative '../../lang/lang_factory'
4
+ require_relative '../../ai/question'
5
+
6
+ ##
7
+ # BaseCodeAI class
8
+ class BaseCodeAI
9
+ attr_reader :questions
10
+
11
+ ##
12
+ # Create CodeAI object from Code data
13
+ # @param code (Code)
14
+ def initialize(code)
15
+ @code = code
16
+ @lines = code.lines
17
+ @num = 0
18
+ @questions = []
19
+ make_questions
20
+ end
21
+
22
+ ##
23
+ # Return the name of code
24
+ # @return String
25
+ def name
26
+ File.basename(@code.filename)
27
+ end
28
+
29
+ def process?
30
+ @code.process?
31
+ end
32
+
33
+ def type
34
+ @code.type
35
+ end
36
+
37
+ def filename
38
+ @code.filename
39
+ end
40
+
41
+ def lines
42
+ @code.lines
43
+ end
44
+
45
+ ##
46
+ # Counter
47
+ # @return count
48
+ def num
49
+ @num += 1
50
+ end
51
+
52
+ ##
53
+ # Clone array
54
+ # @param array (Array)
55
+ # @return Array
56
+ def clone_array(array)
57
+ out = []
58
+ array.each { |item| out << item.dup }
59
+ out
60
+ end
61
+
62
+ ##
63
+ # Convert an array of lines into one String
64
+ # @param lines (Array)
65
+ # @return String
66
+ # rubocop:disable Style/FormatString
67
+ def lines_to_s(lines)
68
+ out = ''
69
+ lines.each_with_index do |line, index|
70
+ out << "%2d: #{line}\n" % (index + 1)
71
+ end
72
+ out
73
+ end
74
+
75
+ ##
76
+ # Convert an array of lines into one HTML String
77
+ # @param lines (Array)
78
+ # @return String
79
+ def lines_to_html(lines)
80
+ out = ''
81
+ lines.each_with_index do |line, index|
82
+ out << "%2d: #{line}</br>" % (index + 1)
83
+ end
84
+ out
85
+ end
86
+ # rubocop:enable Style/FormatString
87
+
88
+ ##
89
+ # Make questions
90
+ def make_questions
91
+ list = find_make_methods
92
+ list.each { |m| @questions += send m }
93
+ @questions
94
+ end
95
+
96
+ private
97
+
98
+ def find_make_methods
99
+ list = public_methods.sort
100
+ list.select! { |name| name.to_s.start_with? 'make_' }
101
+ list.delete(:make_questions)
102
+ list
103
+ end
104
+ end
@@ -1,15 +1,25 @@
1
1
 
2
+ require 'rainbow'
2
3
  require_relative 'javascript_code_ai'
4
+ require_relative 'problem_code_ai'
3
5
  require_relative 'python_code_ai'
4
6
  require_relative 'ruby_code_ai'
5
7
  require_relative 'sql_code_ai'
6
8
 
9
+ ##
10
+ # CodeAI factory
7
11
  module CodeAIFactory
12
+ ##
13
+ # Return CodeAI associated to Code.type
14
+ # @param code (Code)
15
+ # @return CodeAI
8
16
  def self.get(code)
9
17
  type = code.type
10
18
  case type
11
19
  when :javascript
12
20
  return JavascriptCodeAI.new(code)
21
+ when :problem
22
+ return ProblemCodeAI.new(code)
13
23
  when :python
14
24
  return PythonCodeAI.new(code)
15
25
  when :ruby
@@ -19,7 +29,7 @@ module CodeAIFactory
19
29
  when :vagrantfile
20
30
  return RubyCodeAI.new(code)
21
31
  else
22
- puts "[ERROR] <#{type}> is not valid type"
32
+ puts Rainbow("[ERROR] <#{type}> is not valid type").red.bright
23
33
  end
24
34
  nil
25
35
  end
@@ -4,12 +4,9 @@ require_relative '../../ai/question'
4
4
  require_relative 'base_code_ai'
5
5
 
6
6
  class JavascriptCodeAI < BaseCodeAI
7
- def initialize(data_object)
8
- @data_object = data_object
9
- @lines = data_object.lines
7
+ def initialize(code)
10
8
  @lang = LangFactory.instance.get('javascript')
11
- @num = 0
12
- @questions = []
9
+ super code
13
10
  end
14
11
 
15
12
  def make_comment_error
@@ -0,0 +1,176 @@
1
+
2
+ require_relative '../../lang/lang_factory'
3
+ require_relative '../../ai/question'
4
+ require_relative 'base_code_ai'
5
+
6
+ ##
7
+ # Class for RubyCodeAI objects
8
+ class ProblemCodeAI < BaseCodeAI
9
+ def initialize(code)
10
+ @reduce = 1
11
+ @reduce = 4 if code.lines.size > 25
12
+ @lang = LangFactory.instance.get('es')
13
+ super code
14
+ end
15
+
16
+ ##
17
+ # Make errors about comments
18
+ def make_comment_error
19
+ questions = []
20
+ error_lines = []
21
+ @lines.each_with_index do |line,index|
22
+ if line.strip.start_with?('#')
23
+ lines = clone_array @lines
24
+ lines[index].sub!('#','').strip!
25
+
26
+ q = Question.new(:short)
27
+ q.name = "#{name}-#{num}-uncomment"
28
+ q.text = @lang.text_for(:code1,lines_to_html(lines))
29
+ q.shorts << (index+1)
30
+ q.feedback = 'Comment symbol removed'
31
+ questions << q
32
+ elsif line.strip.size>0
33
+ lines = clone_array @lines
34
+ lines[index]='# ' + lines[index]
35
+
36
+ q = Question.new(:short)
37
+ q.name = "#{name}-#{num}-comment"
38
+ q.text = @lang.text_for(:code1,lines_to_html(lines))
39
+ q.shorts << (index+1)
40
+ q.feedback = 'Comment symbol added'
41
+ questions << q
42
+ end
43
+ end
44
+ questions.shuffle[0,@lines.size/@reduce]
45
+ end
46
+
47
+ ##
48
+ # Make questions without errors
49
+ def make_no_error_changes
50
+ questions = []
51
+ empty_lines = []
52
+ used_lines = []
53
+ @lines.each_with_index do |line,index|
54
+ if line.strip.size.zero?
55
+ empty_lines << index
56
+ else
57
+ used_lines << index
58
+ end
59
+ end
60
+
61
+ used_lines.each do |index|
62
+ lines = clone_array(@lines)
63
+ lines.insert(index, ' ' * (rand(4).to_i + 1))
64
+ if @lines.size < 4 || rand(2) == 0
65
+ q = Question.new(:short)
66
+ q.name = "#{name}-#{num}-codeok"
67
+ q.text = @lang.text_for(:code1,lines_to_html(lines))
68
+ q.shorts << '0'
69
+ q.feedback = 'Code is OK'
70
+ questions << q
71
+ else
72
+ q = Question.new(:choice)
73
+ q.name = "#{name}-#{num}-codeok"
74
+ q.text = @lang.text_for(:code2,lines_to_html(lines))
75
+ others = (1..@lines.size).to_a.shuffle!
76
+ q.good = '0'
77
+ q.bads << others[0].to_s
78
+ q.bads << others[1].to_s
79
+ q.bads << others[2].to_s
80
+ q.feedback = 'Code is OK'
81
+ end
82
+ end
83
+
84
+ questions.shuffle[0,@lines.size/@reduce]
85
+ end
86
+
87
+ ##
88
+ # Make questions with syntax errors
89
+ def make_syntax_error
90
+ questions = []
91
+
92
+ @lang.mistakes.each_pair do |key,values|
93
+ error_lines = []
94
+ @lines.each_with_index do |line,index|
95
+ error_lines << index if line.include?(key.to_s)
96
+ end
97
+
98
+ v = values.split(',')
99
+ v.each do |value|
100
+ error_lines.each do |index|
101
+ lines = clone_array(@lines)
102
+ lines[index].sub!(key.to_s, value)
103
+ if @lines.size < 4 || rand(2) == 0
104
+ q = Question.new(:short)
105
+ q.name = "#{name}-#{num}-syntaxerror"
106
+ q.text = @lang.text_for(:code1,lines_to_html(lines))
107
+ q.shorts << (index+1)
108
+ q.feedback = "Syntax error: '#{value}' must be '#{key}'"
109
+ else
110
+ q = Question.new(:choice)
111
+ q.name = "#{name}-#{num}-syntaxerror"
112
+ q.text = @lang.text_for(:code2,lines_to_html(lines))
113
+ others = (1..@lines.size).to_a.shuffle!
114
+ others.delete(index+1)
115
+ q.good = (index + 1).to_s
116
+ q.bads << others[0].to_s
117
+ q.bads << others[1].to_s
118
+ q.bads << others[2].to_s
119
+ q.feedback = "Syntax error: '#{value}' must be '#{key}'"
120
+ end
121
+ questions << q
122
+ end
123
+ end
124
+ end
125
+ questions.shuffle[0,@lines.size/@reduce]
126
+ end
127
+
128
+ ##
129
+ # Make questions with variable errors
130
+ def make_variable_error
131
+ questions = []
132
+ error_lines = []
133
+ @lines.each_with_index do |line, index|
134
+ # Search Variable assignment
135
+ m = /\s*(\w*)\s*\=\w*/.match(line)
136
+ i = []
137
+ unless m.nil?
138
+ varname = (m.values_at 1)[0]
139
+ # Search used Variable
140
+ @lines.each_with_index do |line2, index2|
141
+ next if index >= index2
142
+ i << index2 if line2.include?(varname)
143
+ end
144
+ end
145
+ next if i.size == 0
146
+ i.shuffle!
147
+ i.each do |k|
148
+ lines = clone_array @lines
149
+ temp = lines[index]
150
+ lines[index] = lines[k]
151
+ lines[k] = temp
152
+
153
+ if rand(2) == 0
154
+ q = Question.new(:short)
155
+ q.name = "#{name}-#{num}-variable"
156
+ q.text = @lang.text_for(:code1, lines_to_html(lines))
157
+ q.shorts << (index + 1)
158
+ q.feedback = "Variable error! Swapped lines #{(index+1)} with #{(k+1)}"
159
+ else
160
+ q = Question.new(:choice)
161
+ q.name = "#{name}-#{num}-variable"
162
+ q.text = @lang.text_for(:code2, lines_to_html(lines))
163
+ others = (1..@lines.size).to_a.shuffle!
164
+ others.delete(index+1)
165
+ q.good = (index + 1).to_s
166
+ q.bads << others[0].to_s
167
+ q.bads << others[1].to_s
168
+ q.bads << others[2].to_s
169
+ q.feedback = "Variable error! Swapped lines #{(index+1)} with #{(k+1)}"
170
+ end
171
+ questions << q
172
+ end
173
+ end
174
+ questions.shuffle[0,@lines.size/@reduce]
175
+ end
176
+ end
@@ -4,12 +4,9 @@ require_relative '../../ai/question'
4
4
  require_relative 'base_code_ai'
5
5
 
6
6
  class PythonCodeAI < BaseCodeAI
7
- def initialize(data_object)
8
- @data_object = data_object
9
- @lines = data_object.lines
7
+ def initialize(code)
10
8
  @lang = LangFactory.instance.get('python')
11
- @num = 0
12
- @questions = []
9
+ super code
13
10
  end
14
11
 
15
12
  def make_comment_error