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.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -7
  3. data/lib/asker/ai/ai.rb +17 -22
  4. data/lib/asker/ai/ai_calculate.rb +10 -17
  5. data/lib/asker/ai/code/base_code_ai.rb +5 -30
  6. data/lib/asker/ai/code/code_ai_factory.rb +6 -12
  7. data/lib/asker/ai/code/javascript_code_ai.rb +33 -34
  8. data/lib/asker/ai/code/python_code_ai.rb +35 -36
  9. data/lib/asker/ai/code/ruby_code_ai.rb +33 -33
  10. data/lib/asker/ai/code/sql_code_ai.rb +20 -21
  11. data/lib/asker/ai/concept_ai.rb +12 -22
  12. data/lib/asker/ai/problem/problem_ai.rb +226 -0
  13. data/lib/asker/ai/question.rb +34 -45
  14. data/lib/asker/ai/stages/base_stage.rb +7 -7
  15. data/lib/asker/ai/stages/main.rb +6 -7
  16. data/lib/asker/ai/stages/stage_b.rb +62 -28
  17. data/lib/asker/ai/stages/stage_d.rb +10 -10
  18. data/lib/asker/ai/stages/stage_f.rb +17 -17
  19. data/lib/asker/ai/stages/stage_i.rb +8 -18
  20. data/lib/asker/ai/stages/stage_s.rb +28 -26
  21. data/lib/asker/ai/stages/stage_t.rb +54 -76
  22. data/lib/asker/application.rb +15 -14
  23. data/lib/asker/check_input/check_haml_data.rb +57 -51
  24. data/lib/asker/check_input/check_table.rb +26 -19
  25. data/lib/asker/check_input.rb +10 -22
  26. data/lib/asker/cli.rb +43 -24
  27. data/lib/asker/data/code.rb +10 -9
  28. data/lib/asker/data/column.rb +21 -17
  29. data/lib/asker/data/concept.rb +24 -37
  30. data/lib/asker/data/data_field.rb +2 -2
  31. data/lib/asker/data/problem.rb +112 -0
  32. data/lib/asker/data/project_data.rb +11 -15
  33. data/lib/asker/data/row.rb +25 -23
  34. data/lib/asker/data/table.rb +25 -46
  35. data/lib/asker/data/template.rb +7 -7
  36. data/lib/asker/data/world.rb +3 -3
  37. data/lib/asker/{formatter → deprecated}/question_moodlexml_formatter.rb +19 -21
  38. data/lib/asker/displayer/code_displayer.rb +10 -10
  39. data/lib/asker/displayer/concept_ai_displayer.erb +1 -1
  40. data/lib/asker/displayer/concept_ai_displayer.rb +22 -34
  41. data/lib/asker/displayer/concept_displayer.rb +9 -11
  42. data/lib/asker/displayer/problem_displayer.rb +45 -0
  43. data/lib/asker/displayer/stats_displayer.rb +7 -12
  44. data/lib/asker/exporter/code_gift_exporter.rb +2 -2
  45. data/lib/asker/exporter/concept_ai_gift_exporter.rb +4 -4
  46. data/lib/asker/exporter/concept_ai_yaml_exporter.rb +7 -7
  47. data/lib/asker/exporter/concept_doc_exporter.rb +5 -5
  48. data/lib/asker/exporter/data_gift_exporter.rb +14 -15
  49. data/lib/asker/exporter/data_moodle_exporter.rb +51 -20
  50. data/lib/asker/exporter/output_file_exporter.rb +9 -8
  51. data/lib/asker/exporter/problem_gift_exporter.rb +30 -0
  52. data/lib/asker/files/language/ca/templates.yaml +6 -0
  53. data/lib/asker/files/language/du/templates.yaml +6 -0
  54. data/lib/asker/files/language/en/templates.yaml +7 -1
  55. data/lib/asker/files/language/es/templates.yaml +6 -0
  56. data/lib/asker/files/language/fr/templates.yaml +6 -0
  57. data/lib/asker/formatter/code_string_formatter.rb +5 -5
  58. data/lib/asker/formatter/concept_doc_formatter.rb +3 -3
  59. data/lib/asker/formatter/concept_string_formatter.rb +27 -24
  60. data/lib/asker/formatter/moodle/ddmatch.erb +40 -0
  61. data/lib/asker/formatter/moodle/gapfill.erb +57 -0
  62. data/lib/asker/formatter/moodle/ordering.erb +41 -0
  63. data/lib/asker/formatter/question_gift_formatter.rb +41 -14
  64. data/lib/asker/formatter/question_hash_formatter.rb +5 -6
  65. data/lib/asker/formatter/question_moodle_formatter.rb +14 -7
  66. data/lib/asker/formatter/rb2haml_formatter.rb +8 -7
  67. data/lib/asker/lang/lang.rb +16 -16
  68. data/lib/asker/lang/lang_factory.rb +13 -16
  69. data/lib/asker/lang/text_actions.rb +20 -18
  70. data/lib/asker/loader/code_loader.rb +10 -22
  71. data/lib/asker/loader/content_loader.rb +42 -49
  72. data/lib/asker/loader/directory_loader.rb +13 -16
  73. data/lib/asker/loader/embedded_file.rb +29 -24
  74. data/lib/asker/loader/file_loader.rb +7 -6
  75. data/lib/asker/loader/haml_loader.rb +6 -5
  76. data/lib/asker/loader/image_url_loader.rb +21 -18
  77. data/lib/asker/loader/input_loader.rb +27 -14
  78. data/lib/asker/loader/problem_loader.rb +88 -0
  79. data/lib/asker/loader/project_loader.rb +11 -28
  80. data/lib/asker/logger.rb +22 -13
  81. data/lib/asker/skeleton.rb +27 -43
  82. data/lib/asker/start.rb +44 -0
  83. data/lib/asker/version.rb +1 -1
  84. data/lib/asker.rb +7 -53
  85. metadata +12 -20
  86. data/lib/asker/ai/code/problem_code_ai.rb +0 -176
  87. data/lib/asker/exporter/code_moodle_exporter.rb +0 -15
  88. data/lib/asker/exporter/concept_ai_moodle_exporter.rb +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 211d45e28562281dbadb99c156ae2e630d28bae27d4314f74771c7637de889b7
4
- data.tar.gz: 16625618a4b4a26753727abbe6f1c59e51bd63eb99573fd929a3d98b06cdcd39
3
+ metadata.gz: 1baeb7aed03362eef9980d237bfa0fbd9b260c356fc11b96c88d870e970260ec
4
+ data.tar.gz: 67ed271bf5e6979643e7d63eed43fbb9659428b66a3f67522d8acc5bb4ea14ba
5
5
  SHA512:
6
- metadata.gz: e2ac75d61319e1c833d72dc8224da00df81f57636fa5f1f61e887cc5ddff47a98bd6f2e389de58c142c77c224ea1dd87ad3971479c50b1024a691626bae13a8e
7
- data.tar.gz: 34aa413ffac40f922b18ec07ecefec8fe7d2132bd2f20f3929ae87f7666958adefd75cc3bd6c67c12078f004a1ce61e743837a46e55c78c85a454e13d073e184
6
+ metadata.gz: 9bf4fd2e2ca703548c1a5fdeca6d12bf05549e76423d5ce82f094ca5aaea455499632ae5926ae8ac2e9072ff748a1c74f68908fce8e8cca0ba51220802c97d30
7
+ data.tar.gz: bd150d797993fd3708c254f03fb227e04dc33789854f71b548d3cf27663288ea61c5b62be2a5242f43f8ac449a571675c889cb106e072e0709603642f3ed8d51
data/README.md CHANGED
@@ -21,11 +21,10 @@ gem install asker-tool
21
21
 
22
22
  # Usage
23
23
 
24
- | Step | Action | Description |
25
- | ---: | --------------------- | ----------- |
26
- | 1 | Create your **input file** | Create input file with your contents (_conceptual map_). Here are some [examples](./docs/examples). And more examples at this [repository](https://github.com/dvarrui/asker-inputs).
27
- | 2 | **Run `asker`** | `asker PATH/TO/INPUT` |
28
- | 3 | Choose your **output files** | Output files saved into the `output` folder |
24
+ | Step | Action | Tool | Description |
25
+ | ---: | --------------------- | ---- | ----------- |
26
+ | 1 | Define your concepts | Text plain editor | Create input file with your contents (_conceptual map_). Here are some [examples](./docs/examples). And more examples at this [repository](https://github.com/dvarrui/asker-inputs).
27
+ | 2 | Generate questions | `asker PATH/TO/INPUT` | **Run `asker`** to process input file. Output files are saved into the `output` folder |
29
28
 
30
29
  Let's see an example creating questions from ACDC input example file:
31
30
 
@@ -35,10 +34,10 @@ Let's see an example creating questions from ACDC input example file:
35
34
  +--------------------+-----------+---------+---------+---+---+----+---+---+----+
36
35
  | Concept | Questions | Entries | xFactor | d | b | f | i | s | t |
37
36
  +--------------------+-----------+---------+---------+---+---+----+---+---+----+
38
- | AC/DC | 45 | 18 | 2.5 | 7 | 0 | 15 | 0 | 3 | 20 |
37
+ | AC/DC | 46 | 18 | 2.5 | 7 | 0 | 15 | 0 | 4 | 20 |
39
38
  | Excluded questions | 0 | - | - | 0 | 0 | 0 | 0 | 0 | 0 |
40
39
  +--------------------+-----------+---------+---------+---+---+----+---+---+----+
41
- | 1 concept/s | 45 | 18 | 2.5 | 7 | 0 | 15 | 0 | 3 | 20 |
40
+ | 1 concept/s | 46 | 18 | 2.5 | 7 | 0 | 15 | 0 | 4 | 20 |
42
41
  +--------------------+-----------+---------+---------+---+---+----+---+---+----+
43
42
  ```
44
43
 
@@ -46,6 +45,10 @@ Let's see an example creating questions from ACDC input example file:
46
45
 
47
46
  * [Free Software License](LICENSE).
48
47
  * Multiplatform.
48
+ * Input files formats: XML, HAML.
49
+ * Output formats: GIFT, Moodle XML, YAML.
50
+ * Question types: true/false, multiple choice, short answer, matching and ordering.
51
+ * Embeded files: mp3, ogg, wav, jpg, jpeg, png, mp4, ogv and plain text files.
49
52
 
50
53
  # Documentation
51
54
 
data/lib/asker/ai/ai.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'stages/main'
4
- require_relative 'ai_calculate'
3
+ require_relative "stages/main"
4
+ require_relative "ai_calculate"
5
5
 
6
6
  # Description: Method to be included into every ConceptAI instance.
7
7
  # * make_questions: use AI to fill @questions Array
@@ -13,13 +13,13 @@ module AI
13
13
 
14
14
  make_questions_stages_di
15
15
  # Process every table of this concept
16
- concept.tables.each do |tab|
17
- list1, list2 = get_list1_and_list2_from(tab)
18
- make_questions_stages_bsf(tab, list1, list2)
19
- make_questions_stages_t(tab, list1, list2)
16
+ concept.tables.each do |table|
17
+ list1, list2 = get_list1_and_list2_from(table)
18
+ make_questions_stages_bsf(table, list1, list2)
19
+ make_questions_stages_t(table, list1, list2)
20
20
  end
21
21
  # -------------------------------------------------------
22
- # Exclude questions as is defined into config.ini params
22
+ # Exclude questions as is defined into asker.ini params
23
23
  exclude_questions
24
24
  end
25
25
 
@@ -30,34 +30,31 @@ module AI
30
30
  end
31
31
 
32
32
  # Make questions for stages B, S and F
33
- def make_questions_stages_bsf(tab, list1, list2)
33
+ def make_questions_stages_bsf(table, list1, list2)
34
34
  # Stage B: process table to make match questions
35
- @questions[:b] += StageB.new(self).run(tab, list1, list2)
35
+ @questions[:b] += StageB.new(self).run(table, list1, list2)
36
36
  # Stage S: process tables with sequences
37
- @questions[:s] += StageS.new(self).run(tab, list1, list2)
37
+ @questions[:s] += StageS.new(self).run(table, list1, list2)
38
38
  # Stage F: process tables with only 1 field
39
- @questions[:f] += StageF.new(self).run(tab, list1, list2)
39
+ @questions[:f] += StageF.new(self).run(table, list1, list2)
40
40
  end
41
41
 
42
- # Make questions for stage T
43
- def make_questions_stages_t(tab, list1, list2)
42
+ def make_questions_stages_t(table, list1, list2)
44
43
  # Stage T: process_tableXfields
45
44
  list3 = list1 + list2
46
45
  list1.each do |row|
47
46
  reorder_list_with_row(list3, row)
48
- @questions[:t] += StageT.new(self).run(tab, row, list3)
47
+ @questions[:t] += StageT.new(self).run(table, row, list3)
49
48
  end
50
49
  end
51
50
 
52
- # rubocop:disable Metrics/AbcSize
53
- # rubocop:disable Metrics/MethodLength
54
51
  def exclude_questions
55
- param = Application.instance.config['questions']['exclude']
52
+ param = Application.instance.config["questions"]["exclude"]
56
53
  return if param.nil?
57
54
 
58
- tags = param.split(',').each(&:strip!)
59
- input = { d: [], b: [], f: [], i: [], s: [], t: [] }
60
- output = { d: [], b: [], f: [], i: [], s: [], t: [] }
55
+ tags = param.split(",").each(&:strip!)
56
+ input = {d: [], b: [], f: [], i: [], s: [], t: []}
57
+ output = {d: [], b: [], f: [], i: [], s: [], t: []}
61
58
 
62
59
  @questions.each_pair do |key, qlist|
63
60
  output[key] = qlist.select { |q| string_has_this_tags?(q.name, tags) }
@@ -66,8 +63,6 @@ module AI
66
63
  @questions = input
67
64
  @excluded_questions = output
68
65
  end
69
- # rubocop:enable Metrics/AbcSize
70
- # rubocop:enable Metrics/MethodLength
71
66
 
72
67
  def string_has_this_tags?(input, tags)
73
68
  flag = false
@@ -7,14 +7,12 @@ module AICalculate
7
7
  # * return list1 (Array) List with all the rows from the table
8
8
  # * return list2 (Array) List with similar rows (same table name) from the neighbours tables
9
9
  # @param p_table (Table)
10
- # rubocop:disable Metrics/MethodLength
11
- # rubocop:disable Metrics/AbcSize
12
10
  def get_list1_and_list2_from(p_table)
13
11
  # create <list1> with all the rows from the table
14
12
  list1 = []
15
13
  count = 1
16
14
  p_table.rows.each do |i|
17
- list1 << { id: count, weight: 0, data: i }
15
+ list1 << {id: count, weight: 0, data: i}
18
16
  count += 1
19
17
  end
20
18
 
@@ -25,45 +23,40 @@ module AICalculate
25
23
  next if t2.name != p_table.name
26
24
 
27
25
  t2.rows.each do |i|
28
- list2 << { id: count, weight: 0, data: i }
26
+ list2 << {id: count, weight: 0, data: i}
29
27
  count += 1
30
28
  end
31
29
  end
32
30
  end
33
31
  [list1, list2]
34
32
  end
35
- # rubocop:enable Metrics/MethodLength
36
- # rubocop:enable Metrics/AbcSize
37
33
 
38
34
  def calculate_nearness_between_texts(text1, text2)
39
35
  return 0.0 if text2.nil? || text2.empty?
40
36
 
41
- words = text1.split(' ')
37
+ words = text1.split(" ")
42
38
  count = 0
43
39
  words.each { |w| count += 1 if text2.include?(w) }
44
40
  (count * 100 / words.count)
45
41
  end
46
42
 
47
- # rubocop:disable Metrics/MethodLength
48
- # rubocop:disable Metrics/AbcSize
49
43
  def reorder_list_with_row(list, row)
50
- # evaluate every row of the list2
44
+ # evaluate every row of the list, and calculate weight
45
+ magic_number = -300
51
46
  list.each do |r|
52
47
  if r[:id] == row[:id]
53
- r[:weight] = -300
48
+ r[:weight] = magic_number
54
49
  else
55
- val = 0
50
+ value = 0
56
51
  s = row[:data].count
57
52
  s.times do |i|
58
- val += calculate_nearness_between_texts(row[:data][i], r[:data][i])
53
+ value += calculate_nearness_between_texts(row[:data][i], r[:data][i])
59
54
  end
60
- val /= s
61
- r[:weight] = val
55
+ value /= s
56
+ r[:weight] = value
62
57
  end
63
58
  end
64
59
  list.sort! { |a, b| a[:weight] <=> b[:weight] }
65
60
  list.reverse!
66
61
  end
67
- # rubocop:enable Metrics/MethodLength
68
- # rubocop:enable Metrics/AbcSize
69
62
  end
@@ -1,16 +1,13 @@
1
1
  # frozen_string_literal: false
2
2
 
3
- require_relative '../../lang/lang_factory'
4
- require_relative '../../ai/question'
3
+ require_relative "../../lang/lang_factory"
4
+ require_relative "../../ai/question"
5
5
 
6
6
  ##
7
7
  # BaseCodeAI class
8
8
  class BaseCodeAI
9
9
  attr_reader :questions
10
10
 
11
- ##
12
- # Create CodeAI object from Code data
13
- # @param code (Code)
14
11
  def initialize(code)
15
12
  @code = code
16
13
  @lines = code.lines
@@ -19,9 +16,6 @@ class BaseCodeAI
19
16
  make_questions
20
17
  end
21
18
 
22
- ##
23
- # Return the name of code
24
- # @return String
25
19
  def name
26
20
  File.basename(@code.filename)
27
21
  end
@@ -42,51 +36,32 @@ class BaseCodeAI
42
36
  @code.lines
43
37
  end
44
38
 
45
- ##
46
- # Counter
47
- # @return count
48
39
  def num
49
40
  @num += 1
50
41
  end
51
42
 
52
- ##
53
- # Clone array
54
- # @param array (Array)
55
- # @return Array
56
43
  def clone_array(array)
57
44
  out = []
58
45
  array.each { |item| out << item.dup }
59
46
  out
60
47
  end
61
48
 
62
- ##
63
- # Convert an array of lines into one String
64
- # @param lines (Array)
65
- # @return String
66
- # rubocop:disable Style/FormatString
67
49
  def lines_to_s(lines)
68
- out = ''
50
+ out = ""
69
51
  lines.each_with_index do |line, index|
70
52
  out << "%2d: #{line}\n" % (index + 1)
71
53
  end
72
54
  out
73
55
  end
74
56
 
75
- ##
76
- # Convert an array of lines into one HTML String
77
- # @param lines (Array)
78
- # @return String
79
57
  def lines_to_html(lines)
80
- out = ''
58
+ out = ""
81
59
  lines.each_with_index do |line, index|
82
60
  out << "%2d: #{line}</br>" % (index + 1)
83
61
  end
84
62
  out
85
63
  end
86
- # rubocop:enable Style/FormatString
87
64
 
88
- ##
89
- # Make questions
90
65
  def make_questions
91
66
  list = find_make_methods
92
67
  list.each { |m| @questions += send m }
@@ -97,7 +72,7 @@ class BaseCodeAI
97
72
 
98
73
  def find_make_methods
99
74
  list = public_methods.sort
100
- list.select! { |name| name.to_s.start_with? 'make_' }
75
+ list.select! { |name| name.to_s.start_with? "make_" }
101
76
  list.delete(:make_questions)
102
77
  list
103
78
  end
@@ -1,13 +1,9 @@
1
+ require_relative "javascript_code_ai"
2
+ require_relative "python_code_ai"
3
+ require_relative "ruby_code_ai"
4
+ require_relative "sql_code_ai"
5
+ require_relative "../../logger"
1
6
 
2
- require 'rainbow'
3
- require_relative 'javascript_code_ai'
4
- require_relative 'problem_code_ai'
5
- require_relative 'python_code_ai'
6
- require_relative 'ruby_code_ai'
7
- require_relative 'sql_code_ai'
8
-
9
- ##
10
- # CodeAI factory
11
7
  module CodeAIFactory
12
8
  ##
13
9
  # Return CodeAI associated to Code.type
@@ -18,8 +14,6 @@ module CodeAIFactory
18
14
  case type
19
15
  when :javascript
20
16
  return JavascriptCodeAI.new(code)
21
- when :problem
22
- return ProblemCodeAI.new(code)
23
17
  when :python
24
18
  return PythonCodeAI.new(code)
25
19
  when :ruby
@@ -29,7 +23,7 @@ module CodeAIFactory
29
23
  when :vagrantfile
30
24
  return RubyCodeAI.new(code)
31
25
  else
32
- puts Rainbow("[ERROR] <#{type}> is not valid type").red.bright
26
+ Logger.warn "CodeAIFactory: Invalid type (#{type})"
33
27
  end
34
28
  nil
35
29
  end
@@ -1,7 +1,6 @@
1
-
2
- require_relative '../../lang/lang_factory'
3
- require_relative '../../ai/question'
4
- require_relative 'base_code_ai'
1
+ require_relative "../../lang/lang_factory"
2
+ require_relative "../../ai/question"
3
+ require_relative "base_code_ai"
5
4
 
6
5
  class JavascriptCodeAI < BaseCodeAI
7
6
  def initialize(code)
@@ -13,25 +12,25 @@ class JavascriptCodeAI < BaseCodeAI
13
12
  questions = []
14
13
  # error_lines = []
15
14
  @lines.each_with_index do |line, index|
16
- if line.strip.start_with?('//')
15
+ if line.strip.start_with?("//")
17
16
  lines = clone_array @lines
18
- lines[index].sub!('//','').strip!
17
+ lines[index].sub!("//", "").strip!
19
18
 
20
19
  q = Question.new(:short)
21
20
  q.name = "#{name}-#{num}-uncomment"
22
- q.text = @lang.text_for(:code1,lines_to_html(lines))
23
- q.shorts << (index+1)
24
- q.feedback = 'Comment symbol removed'
21
+ q.text = @lang.text_for(:code1, lines_to_html(lines))
22
+ q.shorts << (index + 1)
23
+ q.feedback = "Comment symbol removed"
25
24
  questions << q
26
- elsif line.strip.size>0
25
+ elsif line.strip.size > 0
27
26
  lines = clone_array @lines
28
- lines[index]='// ' + lines[index]
27
+ lines[index] = "// " + lines[index]
29
28
 
30
29
  q = Question.new(:short)
31
30
  q.name = "#{name}-#{num}-comment"
32
- q.text = @lang.text_for(:code1,lines_to_html(lines))
33
- q.shorts << (index+1)
34
- q.feedback = 'Comment symbol added'
31
+ q.text = @lang.text_for(:code1, lines_to_html(lines))
32
+ q.shorts << (index + 1)
33
+ q.feedback = "Comment symbol added"
35
34
  questions << q
36
35
  end
37
36
  end
@@ -42,7 +41,7 @@ class JavascriptCodeAI < BaseCodeAI
42
41
  questions = []
43
42
  empty_lines = []
44
43
  used_lines = []
45
- @lines.each_with_index do |line,index|
44
+ @lines.each_with_index do |line, index|
46
45
  if line.strip.size.zero?
47
46
  empty_lines << index
48
47
  else
@@ -52,24 +51,24 @@ class JavascriptCodeAI < BaseCodeAI
52
51
 
53
52
  used_lines.each do |index|
54
53
  lines = clone_array(@lines)
55
- lines.insert(index, ' ' * (rand(4).to_i + 1))
54
+ lines.insert(index, " " * (rand(4).to_i + 1))
56
55
  if @lines.size < 4 || rand(2) == 0
57
56
  q = Question.new(:short)
58
57
  q.name = "#{name}-#{num}-codeok"
59
- q.text = @lang.text_for(:code1,lines_to_html(lines))
60
- q.shorts << '0'
61
- q.feedback = 'Code is OK'
58
+ q.text = @lang.text_for(:code1, lines_to_html(lines))
59
+ q.shorts << "0"
60
+ q.feedback = "Code is OK"
62
61
  questions << q
63
62
  else
64
63
  q = Question.new(:choice)
65
64
  q.name = "#{name}-#{num}-codeok"
66
- q.text = @lang.text_for(:code2,lines_to_html(lines))
65
+ q.text = @lang.text_for(:code2, lines_to_html(lines))
67
66
  others = (1..@lines.size).to_a.shuffle!
68
- q.good = '0'
67
+ q.good = "0"
69
68
  q.bads << others[0].to_s
70
69
  q.bads << others[1].to_s
71
70
  q.bads << others[2].to_s
72
- q.feedback = 'Code is OK'
71
+ q.feedback = "Code is OK"
73
72
  end
74
73
  end
75
74
 
@@ -79,13 +78,13 @@ class JavascriptCodeAI < BaseCodeAI
79
78
  def make_syntax_error
80
79
  questions = []
81
80
 
82
- @lang.mistakes.each_pair do |key,values|
81
+ @lang.mistakes.each_pair do |key, values|
83
82
  error_lines = []
84
- @lines.each_with_index do |line,index|
83
+ @lines.each_with_index do |line, index|
85
84
  error_lines << index if line.include?(key.to_s)
86
85
  end
87
86
 
88
- v = values.split(',')
87
+ v = values.split(",")
89
88
  v.each do |value|
90
89
  error_lines.each do |index|
91
90
  lines = clone_array(@lines)
@@ -93,15 +92,15 @@ class JavascriptCodeAI < BaseCodeAI
93
92
  if @lines.size < 4 || rand(2) == 0
94
93
  q = Question.new(:short)
95
94
  q.name = "#{name}-#{num}-syntaxerror"
96
- q.text = @lang.text_for(:code1,lines_to_html(lines))
97
- q.shorts << (index+1)
95
+ q.text = @lang.text_for(:code1, lines_to_html(lines))
96
+ q.shorts << (index + 1)
98
97
  q.feedback = "Syntax error: '#{value}' must be '#{key}'"
99
98
  else
100
99
  q = Question.new(:choice)
101
100
  q.name = "#{name}-#{num}-syntaxerror"
102
- q.text = @lang.text_for(:code2,lines_to_html(lines))
101
+ q.text = @lang.text_for(:code2, lines_to_html(lines))
103
102
  others = (1..@lines.size).to_a.shuffle!
104
- others.delete(index+1)
103
+ others.delete(index + 1)
105
104
  q.good = (index + 1).to_s
106
105
  q.bads << others[0].to_s
107
106
  q.bads << others[1].to_s
@@ -141,20 +140,20 @@ class JavascriptCodeAI < BaseCodeAI
141
140
  if rand(2) == 0
142
141
  q = Question.new(:short)
143
142
  q.name = "#{name}-#{num}-variable"
144
- q.text = @lang.text_for(:code1,lines_to_html(lines))
143
+ q.text = @lang.text_for(:code1, lines_to_html(lines))
145
144
  q.shorts << (index + 1)
146
- q.feedback = "Variable error! Swapped lines #{(index+1)} with #{(k+1)}"
145
+ q.feedback = "Variable error! Swapped lines #{index + 1} with #{k + 1}"
147
146
  else
148
147
  q = Question.new(:choice)
149
148
  q.name = "#{name}-#{num}-variable"
150
- q.text = @lang.text_for(:code2,lines_to_html(lines))
149
+ q.text = @lang.text_for(:code2, lines_to_html(lines))
151
150
  others = (1..@lines.size).to_a.shuffle!
152
- others.delete(index+1)
151
+ others.delete(index + 1)
153
152
  q.good = (index + 1).to_s
154
153
  q.bads << others[0].to_s
155
154
  q.bads << others[1].to_s
156
155
  q.bads << others[2].to_s
157
- q.feedback = "Variable error! Swapped lines #{(index+1)} with #{(k+1)}"
156
+ q.feedback = "Variable error! Swapped lines #{index + 1} with #{k + 1}"
158
157
  end
159
158
  questions << q
160
159
  end
@@ -1,11 +1,10 @@
1
-
2
- require_relative '../../lang/lang_factory'
3
- require_relative '../../ai/question'
4
- require_relative 'base_code_ai'
1
+ require_relative "../../lang/lang_factory"
2
+ require_relative "../../ai/question"
3
+ require_relative "base_code_ai"
5
4
 
6
5
  class PythonCodeAI < BaseCodeAI
7
6
  def initialize(code)
8
- @lang = LangFactory.instance.get('python')
7
+ @lang = LangFactory.instance.get("python")
9
8
  super code
10
9
  end
11
10
 
@@ -13,25 +12,25 @@ class PythonCodeAI < BaseCodeAI
13
12
  questions = []
14
13
  # error_lines = []
15
14
  @lines.each_with_index do |line, index|
16
- if line.strip.start_with?('#')
15
+ if line.strip.start_with?("#")
17
16
  lines = clone_array @lines
18
- lines[index].sub!('#','').strip!
17
+ lines[index].sub!("#", "").strip!
19
18
 
20
19
  q = Question.new(:short)
21
20
  q.name = "#{name}-#{num}-uncomment"
22
- q.text = @lang.text_for(:code1,lines_to_html(lines))
23
- q.shorts << (index+1)
24
- q.feedback = 'Comment symbol removed'
21
+ q.text = @lang.text_for(:code1, lines_to_html(lines))
22
+ q.shorts << (index + 1)
23
+ q.feedback = "Comment symbol removed"
25
24
  questions << q
26
- elsif line.strip.size>0
25
+ elsif line.strip.size > 0
27
26
  lines = clone_array @lines
28
- lines[index]='# ' + lines[index]
27
+ lines[index] = "# " + lines[index]
29
28
 
30
29
  q = Question.new(:short)
31
30
  q.name = "#{name}-#{num}-comment"
32
- q.text = @lang.text_for(:code1,lines_to_html(lines))
33
- q.shorts << (index+1)
34
- q.feedback = 'Comment symbol added'
31
+ q.text = @lang.text_for(:code1, lines_to_html(lines))
32
+ q.shorts << (index + 1)
33
+ q.feedback = "Comment symbol added"
35
34
  questions << q
36
35
  end
37
36
  end
@@ -42,7 +41,7 @@ class PythonCodeAI < BaseCodeAI
42
41
  questions = []
43
42
  empty_lines = []
44
43
  used_lines = []
45
- @lines.each_with_index do |line,index|
44
+ @lines.each_with_index do |line, index|
46
45
  if line.strip.size.zero?
47
46
  empty_lines << index
48
47
  else
@@ -52,24 +51,24 @@ class PythonCodeAI < BaseCodeAI
52
51
 
53
52
  used_lines.each do |index|
54
53
  lines = clone_array(@lines)
55
- lines.insert(index, ' ' * (rand(4).to_i + 1))
54
+ lines.insert(index, " " * (rand(4).to_i + 1))
56
55
  if @lines.size < 4 || rand(2) == 0
57
56
  q = Question.new(:short)
58
57
  q.name = "#{name}-#{num}-codeok"
59
- q.text = @lang.text_for(:code1,lines_to_html(lines))
60
- q.shorts << '0'
61
- q.feedback = 'Code is OK'
58
+ q.text = @lang.text_for(:code1, lines_to_html(lines))
59
+ q.shorts << "0"
60
+ q.feedback = "Code is OK"
62
61
  questions << q
63
62
  else
64
63
  q = Question.new(:choice)
65
64
  q.name = "#{name}-#{num}-codeok"
66
- q.text = @lang.text_for(:code2,lines_to_html(lines))
65
+ q.text = @lang.text_for(:code2, lines_to_html(lines))
67
66
  others = (1..@lines.size).to_a.shuffle!
68
- q.good = '0'
67
+ q.good = "0"
69
68
  q.bads << others[0].to_s
70
69
  q.bads << others[1].to_s
71
70
  q.bads << others[2].to_s
72
- q.feedback = 'Code is OK'
71
+ q.feedback = "Code is OK"
73
72
  end
74
73
  end
75
74
 
@@ -79,13 +78,13 @@ class PythonCodeAI < BaseCodeAI
79
78
  def make_syntax_error
80
79
  questions = []
81
80
 
82
- @lang.mistakes.each_pair do |key,values|
81
+ @lang.mistakes.each_pair do |key, values|
83
82
  error_lines = []
84
- @lines.each_with_index do |line,index|
83
+ @lines.each_with_index do |line, index|
85
84
  error_lines << index if line.include?(key.to_s)
86
85
  end
87
86
 
88
- v = values.split(',')
87
+ v = values.split(",")
89
88
  v.each do |value|
90
89
  error_lines.each do |index|
91
90
  lines = clone_array(@lines)
@@ -93,15 +92,15 @@ class PythonCodeAI < BaseCodeAI
93
92
  if @lines.size < 4 || rand(2) == 0
94
93
  q = Question.new(:short)
95
94
  q.name = "#{name}-#{num}-syntaxerror"
96
- q.text = @lang.text_for(:code1,lines_to_html(lines))
97
- q.shorts << (index+1)
95
+ q.text = @lang.text_for(:code1, lines_to_html(lines))
96
+ q.shorts << (index + 1)
98
97
  q.feedback = "Syntax error: '#{value}' must be '#{key}'"
99
98
  else
100
99
  q = Question.new(:choice)
101
100
  q.name = "#{name}-#{num}-syntaxerror"
102
- q.text = @lang.text_for(:code2,lines_to_html(lines))
101
+ q.text = @lang.text_for(:code2, lines_to_html(lines))
103
102
  others = (1..@lines.size).to_a.shuffle!
104
- others.delete(index+1)
103
+ others.delete(index + 1)
105
104
  q.good = (index + 1).to_s
106
105
  q.bads << others[0].to_s
107
106
  q.bads << others[1].to_s
@@ -120,7 +119,7 @@ class PythonCodeAI < BaseCodeAI
120
119
  # error_lines = []
121
120
  @lines.each_with_index do |line, index|
122
121
  # Search Variable assignment
123
- m = /\s*(\w*)\s*\=\w*/.match(line)
122
+ m = /\s*(\w*)\s*=\w*/.match(line)
124
123
  i = []
125
124
  unless m.nil?
126
125
  varname = (m.values_at 1)[0]
@@ -141,20 +140,20 @@ class PythonCodeAI < BaseCodeAI
141
140
  if rand(2) == 0
142
141
  q = Question.new(:short)
143
142
  q.name = "#{name}-#{num}-variable"
144
- q.text = @lang.text_for(:code1,lines_to_html(lines))
143
+ q.text = @lang.text_for(:code1, lines_to_html(lines))
145
144
  q.shorts << (index + 1)
146
- q.feedback = "Variable error! Swapped lines #{(index+1)} with #{(k+1)}"
145
+ q.feedback = "Variable error! Swapped lines #{index + 1} with #{k + 1}"
147
146
  else
148
147
  q = Question.new(:choice)
149
148
  q.name = "#{name}-#{num}-variable"
150
- q.text = @lang.text_for(:code2,lines_to_html(lines))
149
+ q.text = @lang.text_for(:code2, lines_to_html(lines))
151
150
  others = (1..@lines.size).to_a.shuffle!
152
- others.delete(index+1)
151
+ others.delete(index + 1)
153
152
  q.good = (index + 1).to_s
154
153
  q.bads << others[0].to_s
155
154
  q.bads << others[1].to_s
156
155
  q.bads << others[2].to_s
157
- q.feedback = "Variable error! Swapped lines #{(index+1)} with #{(k+1)}"
156
+ q.feedback = "Variable error! Swapped lines #{index + 1} with #{k + 1}"
158
157
  end
159
158
  questions << q
160
159
  end