asker-tool 2.5.9 → 2.7.0

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