asker-tool 2.6.0 → 2.7.1
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 +5 -5
- data/lib/asker/ai/ai.rb +6 -6
- data/lib/asker/ai/ai_calculate.rb +3 -3
- 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/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 +40 -51
- data/lib/asker/application.rb +15 -14
- data/lib/asker/check_input/check_haml_data.rb +52 -51
- data/lib/asker/check_input/check_table.rb +17 -20
- data/lib/asker/check_input.rb +10 -23
- 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 +17 -17
- data/lib/asker/displayer/concept_displayer.rb +4 -2
- 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 +6 -6
- 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 +14 -14
- data/lib/asker/loader/file_loader.rb +5 -4
- data/lib/asker/loader/haml_loader.rb +4 -3
- data/lib/asker/loader/image_url_loader.rb +6 -5
- data/lib/asker/loader/input_loader.rb +24 -10
- data/lib/asker/loader/problem_loader.rb +88 -0
- data/lib/asker/loader/project_loader.rb +5 -12
- data/lib/asker/logger.rb +19 -10
- data/lib/asker/skeleton.rb +19 -35
- data/lib/asker/start.rb +44 -0
- data/lib/asker/version.rb +1 -1
- data/lib/asker.rb +7 -52
- metadata +12 -6
- 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
| @@ -10,7 +10,7 @@ class BaseStage | |
| 10 10 | 
             
              end
         | 
| 11 11 |  | 
| 12 12 | 
             
              def run
         | 
| 13 | 
            -
                raise  | 
| 13 | 
            +
                raise "Implement run method!"
         | 
| 14 14 | 
             
              end
         | 
| 15 15 |  | 
| 16 16 | 
             
              def concept
         | 
| @@ -22,7 +22,7 @@ class BaseStage | |
| 22 22 | 
             
              end
         | 
| 23 23 |  | 
| 24 24 | 
             
              def names
         | 
| 25 | 
            -
                raise  | 
| 25 | 
            +
                raise "Change names by concept.names"
         | 
| 26 26 | 
             
              end
         | 
| 27 27 |  | 
| 28 28 | 
             
              def num
         | 
| @@ -30,23 +30,23 @@ class BaseStage | |
| 30 30 | 
             
              end
         | 
| 31 31 |  | 
| 32 32 | 
             
              def lang
         | 
| 33 | 
            -
                raise  | 
| 33 | 
            +
                raise "Change lang by concept.lang"
         | 
| 34 34 | 
             
              end
         | 
| 35 35 |  | 
| 36 36 | 
             
              def type
         | 
| 37 | 
            -
                raise  | 
| 37 | 
            +
                raise "Change type by concept.type"
         | 
| 38 38 | 
             
              end
         | 
| 39 39 |  | 
| 40 40 | 
             
              def texts
         | 
| 41 | 
            -
                raise  | 
| 41 | 
            +
                raise "Change texts by cocept.texts"
         | 
| 42 42 | 
             
              end
         | 
| 43 43 |  | 
| 44 44 | 
             
              def images
         | 
| 45 | 
            -
                raise  | 
| 45 | 
            +
                raise "Change images by cocept.images"
         | 
| 46 46 | 
             
              end
         | 
| 47 47 |  | 
| 48 48 | 
             
              def neighbors
         | 
| 49 | 
            -
                raise  | 
| 49 | 
            +
                raise "Change neighbors by concept.neighbors"
         | 
| 50 50 | 
             
              end
         | 
| 51 51 |  | 
| 52 52 | 
             
              def random_image_for(option)
         | 
| @@ -1,7 +1,7 @@ | |
| 1 | 
            -
            require  | 
| 1 | 
            +
            require "set"
         | 
| 2 2 |  | 
| 3 | 
            -
            require_relative  | 
| 4 | 
            -
            require_relative  | 
| 3 | 
            +
            require_relative "base_stage"
         | 
| 4 | 
            +
            require_relative "../question"
         | 
| 5 5 |  | 
| 6 6 | 
             
            class StageB < BaseStage
         | 
| 7 7 | 
             
              ##
         | 
| @@ -14,7 +14,7 @@ class StageB < BaseStage | |
| 14 14 | 
             
                questions = []
         | 
| 15 15 | 
             
                return questions if table.fields.count < 2
         | 
| 16 16 |  | 
| 17 | 
            -
                return questions unless concept.type ==  | 
| 17 | 
            +
                return questions unless concept.type == "text"
         | 
| 18 18 |  | 
| 19 19 | 
             
                if table.fields.count == 2
         | 
| 20 20 | 
             
                  questions += process_table_match2fields(table, list1, list2, 0, 1)
         | 
| @@ -49,8 +49,18 @@ class StageB < BaseStage | |
| 49 49 | 
             
                    e.shuffle!
         | 
| 50 50 | 
             
                    q = Question.new(:match)
         | 
| 51 51 | 
             
                    q.name = "#{name}-#{num}-b1match4x4-#{p_table.name}"
         | 
| 52 | 
            -
                    q.tags <<  | 
| 53 | 
            -
                    q.tags <<  | 
| 52 | 
            +
                    q.tags << "match"
         | 
| 53 | 
            +
                    q.tags << "random"
         | 
| 54 | 
            +
                    q.text = random_image_for(name) \
         | 
| 55 | 
            +
                             + lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
         | 
| 56 | 
            +
                    q.matching << [e[0][:data][index1], e[0][:data][index2]]
         | 
| 57 | 
            +
                    q.matching << [e[1][:data][index1], e[1][:data][index2]]
         | 
| 58 | 
            +
                    q.matching << [e[2][:data][index1], e[2][:data][index2]]
         | 
| 59 | 
            +
                    q.matching << [e[3][:data][index1], e[3][:data][index2]]
         | 
| 60 | 
            +
                    questions << q
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    q = Question.new(:ddmatch)
         | 
| 63 | 
            +
                    q.name = "#{name}-#{num}-b1ddmatch4x4-#{p_table.name}"
         | 
| 54 64 | 
             
                    q.text = random_image_for(name) \
         | 
| 55 65 | 
             
                             + lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
         | 
| 56 66 | 
             
                    q.matching << [e[0][:data][index1], e[0][:data][index2]]
         | 
| @@ -64,29 +74,29 @@ class StageB < BaseStage | |
| 64 74 | 
             
                      e.shuffle!
         | 
| 65 75 | 
             
                      q = Question.new(:match)
         | 
| 66 76 | 
             
                      q.name = "#{name}-#{num}-b1match4x5-#{p_table.name}"
         | 
| 67 | 
            -
                      q.tags <<  | 
| 68 | 
            -
                      q.tags <<  | 
| 77 | 
            +
                      q.tags << "match"
         | 
| 78 | 
            +
                      q.tags << "random"
         | 
| 69 79 | 
             
                      q.text = random_image_for(name) \
         | 
| 70 80 | 
             
                               + lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
         | 
| 71 81 | 
             
                      q.matching << [e[0][:data][index1], e[0][:data][index2]]
         | 
| 72 82 | 
             
                      q.matching << [e[1][:data][index1], e[1][:data][index2]]
         | 
| 73 83 | 
             
                      q.matching << [e[2][:data][index1], e[2][:data][index2]]
         | 
| 74 84 | 
             
                      q.matching << [e[3][:data][index1], e[3][:data][index2]]
         | 
| 75 | 
            -
                      q.matching << [ | 
| 85 | 
            +
                      q.matching << ["", list2[0][:data][index2]]
         | 
| 76 86 | 
             
                      questions << q
         | 
| 77 87 | 
             
                    else
         | 
| 78 88 | 
             
                      e.shuffle!
         | 
| 79 89 | 
             
                      q = Question.new(:match)
         | 
| 80 90 | 
             
                      q.name = "#{name}-#{num}-b1match4x5_1misspelled-#{p_table.name}"
         | 
| 81 | 
            -
                      q.tags <<  | 
| 82 | 
            -
                      q.tags <<  | 
| 91 | 
            +
                      q.tags << "match"
         | 
| 92 | 
            +
                      q.tags << "random"
         | 
| 83 93 | 
             
                      q.text = random_image_for(name) \
         | 
| 84 94 | 
             
                               + lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
         | 
| 85 95 | 
             
                      q.matching << [e[0][:data][index1], e[0][:data][index2]]
         | 
| 86 96 | 
             
                      q.matching << [e[1][:data][index1], e[1][:data][index2]]
         | 
| 87 97 | 
             
                      q.matching << [e[2][:data][index1], e[2][:data][index2]]
         | 
| 88 98 | 
             
                      q.matching << [e[3][:data][index1], e[3][:data][index2]]
         | 
| 89 | 
            -
                      q.matching << [ | 
| 99 | 
            +
                      q.matching << ["", lang.do_mistake_to(e[0][:data][index2])]
         | 
| 90 100 | 
             
                      questions << q
         | 
| 91 101 | 
             
                    end
         | 
| 92 102 |  | 
| @@ -94,8 +104,20 @@ class StageB < BaseStage | |
| 94 104 | 
             
                    e.shuffle!
         | 
| 95 105 | 
             
                    q = Question.new(:match)
         | 
| 96 106 | 
             
                    q.name = "#{name}-#{num}-b1match4x4_1misspelled-#{p_table.name}"
         | 
| 97 | 
            -
                    q.tags <<  | 
| 98 | 
            -
                    q.tags <<  | 
| 107 | 
            +
                    q.tags << "match"
         | 
| 108 | 
            +
                    q.tags << "random"
         | 
| 109 | 
            +
                    q.text = random_image_for(name) \
         | 
| 110 | 
            +
                             + lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
         | 
| 111 | 
            +
                    q.matching << [e[0][:data][index1], e[0][:data][index2]]
         | 
| 112 | 
            +
                    q.matching << [e[1][:data][index1], e[1][:data][index2]]
         | 
| 113 | 
            +
                    q.matching << [e[2][:data][index1], e[2][:data][index2]]
         | 
| 114 | 
            +
                    q.matching << [lang.do_mistake_to(e[3][:data][index1]), lang.text_for(:misspelling)]
         | 
| 115 | 
            +
                    questions << q
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                    q = Question.new(:ddmatch)
         | 
| 118 | 
            +
                    q.name = "#{name}-#{num}-b1ddmatch4x4_1misspelled-#{p_table.name}"
         | 
| 119 | 
            +
                    q.tags << "match"
         | 
| 120 | 
            +
                    q.tags << "random"
         | 
| 99 121 | 
             
                    q.text = random_image_for(name) \
         | 
| 100 122 | 
             
                             + lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
         | 
| 101 123 | 
             
                    q.matching << [e[0][:data][index1], e[0][:data][index2]]
         | 
| @@ -109,31 +131,31 @@ class StageB < BaseStage | |
| 109 131 | 
             
                      e.shuffle!
         | 
| 110 132 | 
             
                      q = Question.new(:match)
         | 
| 111 133 | 
             
                      q.name = "#{name}-#{num}-b1match4x5_1misspelled_1error-#{p_table.name}"
         | 
| 112 | 
            -
                      q.tags <<  | 
| 113 | 
            -
                      q.tags <<  | 
| 134 | 
            +
                      q.tags << "match"
         | 
| 135 | 
            +
                      q.tags << "random"
         | 
| 114 136 | 
             
                      q.text = random_image_for(name) \
         | 
| 115 137 | 
             
                               + lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
         | 
| 116 138 | 
             
                      q.matching << [e[0][:data][index1], e[0][:data][index2]]
         | 
| 117 139 | 
             
                      q.matching << [e[1][:data][index1], e[1][:data][index2]]
         | 
| 118 140 | 
             
                      q.matching << [e[2][:data][index1], e[2][:data][index2]]
         | 
| 119 141 | 
             
                      q.matching << [lang.do_mistake_to(e[3][:data][index1]), lang.text_for(:misspelling)]
         | 
| 120 | 
            -
                      q.matching << [ | 
| 142 | 
            +
                      q.matching << ["", list2[0][:data][index2]]
         | 
| 121 143 | 
             
                      questions << q
         | 
| 122 144 | 
             
                    else
         | 
| 123 145 | 
             
                      # Add an extra line misspelled
         | 
| 124 146 | 
             
                      e.shuffle!
         | 
| 125 147 | 
             
                      q = Question.new(:match)
         | 
| 126 148 | 
             
                      q.name = "#{name}-#{num}-b1match4x5_2misspelled-#{p_table.name}"
         | 
| 127 | 
            -
                      q.tags <<  | 
| 128 | 
            -
                      q.tags <<  | 
| 129 | 
            -
                      q.tags <<  | 
| 149 | 
            +
                      q.tags << "match"
         | 
| 150 | 
            +
                      q.tags << "random"
         | 
| 151 | 
            +
                      q.tags << "misspelled"
         | 
| 130 152 | 
             
                      q.text = random_image_for(name) \
         | 
| 131 153 | 
             
                               + lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
         | 
| 132 154 | 
             
                      q.matching << [e[0][:data][index1], e[0][:data][index2]]
         | 
| 133 155 | 
             
                      q.matching << [e[1][:data][index1], e[1][:data][index2]]
         | 
| 134 156 | 
             
                      q.matching << [e[2][:data][index1], e[2][:data][index2]]
         | 
| 135 157 | 
             
                      q.matching << [lang.do_mistake_to(e[3][:data][index1]), lang.text_for(:misspelling)]
         | 
| 136 | 
            -
                      q.matching << [ | 
| 158 | 
            +
                      q.matching << ["", lang.do_mistake_to(e[0][:data][index2])]
         | 
| 137 159 | 
             
                      questions << q
         | 
| 138 160 | 
             
                    end
         | 
| 139 161 | 
             
                  end
         | 
| @@ -142,16 +164,28 @@ class StageB < BaseStage | |
| 142 164 | 
             
                if list1.count > 2 && list2.count.positive?
         | 
| 143 165 | 
             
                  s = Set.new
         | 
| 144 166 | 
             
                  list1.each do |i|
         | 
| 145 | 
            -
                    s.add(i[:data][index1] +  | 
| 167 | 
            +
                    s.add(i[:data][index1] + "<=>" + i[:data][index2])
         | 
| 146 168 | 
             
                  end
         | 
| 147 | 
            -
                  s.add(list2[0][:data][index1] +  | 
| 169 | 
            +
                  s.add(list2[0][:data][index1] + "<=>" + list2[0][:data][index2])
         | 
| 148 170 |  | 
| 149 171 | 
             
                  # Question 3 items from table-A, and 1 item from table-B
         | 
| 150 172 | 
             
                  if s.count > 3
         | 
| 151 173 | 
             
                    q = Question.new(:match)
         | 
| 152 174 | 
             
                    q.name = "#{name}-#{num}-b1match4x4_1error-#{p_table.name}"
         | 
| 153 | 
            -
                    q.tags <<  | 
| 154 | 
            -
                    q.tags <<  | 
| 175 | 
            +
                    q.tags << "match"
         | 
| 176 | 
            +
                    q.tags << "random"
         | 
| 177 | 
            +
                    q.text = random_image_for(name) \
         | 
| 178 | 
            +
                             + lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
         | 
| 179 | 
            +
                    q.matching << [list1[0][:data][index1], list1[0][:data][index2]]
         | 
| 180 | 
            +
                    q.matching << [list1[1][:data][index1], list1[1][:data][index2]]
         | 
| 181 | 
            +
                    q.matching << [list1[2][:data][index1], list1[2][:data][index2]]
         | 
| 182 | 
            +
                    q.matching << [list2[0][:data][index1], lang.text_for(:error)]
         | 
| 183 | 
            +
                    questions << q
         | 
| 184 | 
            +
             | 
| 185 | 
            +
                    q = Question.new(:ddmatch)
         | 
| 186 | 
            +
                    q.name = "#{name}-#{num}-b1ddmatch4x4_1error-#{p_table.name}"
         | 
| 187 | 
            +
                    q.tags << "match"
         | 
| 188 | 
            +
                    q.tags << "random"
         | 
| 155 189 | 
             
                    q.text = random_image_for(name) \
         | 
| 156 190 | 
             
                             + lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
         | 
| 157 191 | 
             
                    q.matching << [list1[0][:data][index1], list1[0][:data][index2]]
         | 
| @@ -162,15 +196,15 @@ class StageB < BaseStage | |
| 162 196 |  | 
| 163 197 | 
             
                    q = Question.new(:match)
         | 
| 164 198 | 
             
                    q.name = "#{name}-#{num}-b1match4x5_1error_1misspelled-#{p_table.name}"
         | 
| 165 | 
            -
                    q.tags <<  | 
| 166 | 
            -
                    q.tags <<  | 
| 199 | 
            +
                    q.tags << "match"
         | 
| 200 | 
            +
                    q.tags << "random"
         | 
| 167 201 | 
             
                    q.text = random_image_for(name) \
         | 
| 168 202 | 
             
                             + lang.text_for(:b1, name, p_table.fields[index1].capitalize, p_table.fields[index2].capitalize)
         | 
| 169 203 | 
             
                    q.matching << [list1[0][:data][index1], list1[0][:data][index2]]
         | 
| 170 204 | 
             
                    q.matching << [list1[1][:data][index1], list1[1][:data][index2]]
         | 
| 171 205 | 
             
                    q.matching << [list1[2][:data][index1], list1[2][:data][index2]]
         | 
| 172 206 | 
             
                    q.matching << [list2[0][:data][index1], lang.text_for(:error)]
         | 
| 173 | 
            -
                    q.matching << [ | 
| 207 | 
            +
                    q.matching << ["", lang.do_mistake_to(list1[0][:data][index2])]
         | 
| 174 208 | 
             
                    questions << q
         | 
| 175 209 | 
             
                  end
         | 
| 176 210 | 
             
                end
         | 
| @@ -1,9 +1,9 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require  | 
| 3 | 
            +
            require "set"
         | 
| 4 4 |  | 
| 5 | 
            -
            require_relative  | 
| 6 | 
            -
            require_relative  | 
| 5 | 
            +
            require_relative "base_stage"
         | 
| 6 | 
            +
            require_relative "../question"
         | 
| 7 7 |  | 
| 8 8 | 
             
            ##
         | 
| 9 9 | 
             
            # range d1-d4: d1choice, d1none-misspelled, d1none
         | 
| @@ -11,7 +11,7 @@ class StageD < BaseStage | |
| 11 11 | 
             
              def run
         | 
| 12 12 | 
             
                # Stage D: process every definition, I mean every <def> tag
         | 
| 13 13 | 
             
                questions = []
         | 
| 14 | 
            -
                return questions unless concept.type ==  | 
| 14 | 
            +
                return questions unless concept.type == "text"
         | 
| 15 15 |  | 
| 16 16 | 
             
                lang = concept.lang
         | 
| 17 17 | 
             
                # for every <text> do this
         | 
| @@ -85,7 +85,7 @@ class StageD < BaseStage | |
| 85 85 | 
             
                  q = Question.new(:choice)
         | 
| 86 86 | 
             
                  q.name = "#{name(:id)}-#{num}-d2true-misspelled"
         | 
| 87 87 | 
             
                  q.text = random_image_for(name(:raw)) + lang.text_for(:d2, name(:raw), t)
         | 
| 88 | 
            -
                  q.good = | 
| 88 | 
            +
                  q.good = lang.text_for(:true)
         | 
| 89 89 | 
             
                  q.bads << lang.text_for(:misspelling)
         | 
| 90 90 | 
             
                  q.bads << lang.text_for(:false)
         | 
| 91 91 | 
             
                  questions << q
         | 
| @@ -94,7 +94,7 @@ class StageD < BaseStage | |
| 94 94 | 
             
                  q = Question.new(:boolean)
         | 
| 95 95 | 
             
                  q.name = "#{name(:id)}-#{num}-d2true"
         | 
| 96 96 | 
             
                  q.text = random_image_for(name(:raw)) + lang.text_for(:d2, name(:raw), t)
         | 
| 97 | 
            -
                  q.good =  | 
| 97 | 
            +
                  q.good = "TRUE"
         | 
| 98 98 | 
             
                  questions << q
         | 
| 99 99 |  | 
| 100 100 | 
             
                  # Question choice => false
         | 
| @@ -102,7 +102,7 @@ class StageD < BaseStage | |
| 102 102 | 
             
                    q = Question.new(:choice)
         | 
| 103 103 | 
             
                    q.name = "#{name(:id)}-#{num}-d2false-misspelled"
         | 
| 104 104 | 
             
                    q.text = random_image_for(name(:raw)) + lang.text_for(:d2, a[1], t)
         | 
| 105 | 
            -
                    q.good = | 
| 105 | 
            +
                    q.good = lang.text_for(:false)
         | 
| 106 106 | 
             
                    q.bads << lang.text_for(:misspelling)
         | 
| 107 107 | 
             
                    q.bads << lang.text_for(:true)
         | 
| 108 108 | 
             
                    questions << q
         | 
| @@ -111,7 +111,7 @@ class StageD < BaseStage | |
| 111 111 | 
             
                    q = Question.new(:boolean)
         | 
| 112 112 | 
             
                    q.name = "#{name(:id)}-#{num}-d2false"
         | 
| 113 113 | 
             
                    q.text = random_image_for(name(:raw)) + lang.text_for(:d2, a[1], t)
         | 
| 114 | 
            -
                    q.good =  | 
| 114 | 
            +
                    q.good = "FALSE"
         | 
| 115 115 | 
             
                    questions << q
         | 
| 116 116 | 
             
                  end
         | 
| 117 117 |  | 
| @@ -120,7 +120,7 @@ class StageD < BaseStage | |
| 120 120 | 
             
                  q.name = "#{name(:id)}-#{num}-d3hidden"
         | 
| 121 121 | 
             
                  q.text = random_image_for(name(:raw)) + lang.text_for(:d3, lang.hide_text(name(:raw)), t)
         | 
| 122 122 | 
             
                  q.shorts << name(:raw)
         | 
| 123 | 
            -
                  q.shorts << name(:raw). | 
| 123 | 
            +
                  q.shorts << name(:raw).tr("-", " ").tr("_", " ")
         | 
| 124 124 | 
             
                  concept.names.each { |n| q.shorts << n if n != name }
         | 
| 125 125 | 
             
                  questions << q
         | 
| 126 126 |  | 
| @@ -140,7 +140,7 @@ class StageD < BaseStage | |
| 140 140 | 
             
                    e.each_with_index do |value, index|
         | 
| 141 141 | 
             
                      q.matching << [(index + 1).to_s, filtered[:words][value][:word].downcase]
         | 
| 142 142 | 
             
                    end
         | 
| 143 | 
            -
                    questions << q
         | 
| 143 | 
            +
                    questions << q        
         | 
| 144 144 | 
             
                  end
         | 
| 145 145 | 
             
                end
         | 
| 146 146 |  | 
| @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require_relative  | 
| 4 | 
            -
            require_relative  | 
| 3 | 
            +
            require_relative "base_stage"
         | 
| 4 | 
            +
            require_relative "../question"
         | 
| 5 5 |  | 
| 6 6 | 
             
            class StageF < BaseStage
         | 
| 7 7 | 
             
              ##
         | 
| @@ -43,7 +43,7 @@ class StageF < BaseStage | |
| 43 43 | 
             
                    indexes = filtered[:indexes]
         | 
| 44 44 |  | 
| 45 45 | 
             
                    groups = indexes.combination(4).to_a.shuffle
         | 
| 46 | 
            -
                    max | 
| 46 | 
            +
                    max = (indexes.size / 4).to_i
         | 
| 47 47 | 
             
                    groups[0, max].each do |i|
         | 
| 48 48 | 
             
                      i.sort!
         | 
| 49 49 | 
             
                      q = Question.new(:match)
         | 
| @@ -55,7 +55,7 @@ class StageF < BaseStage | |
| 55 55 | 
             
                      i.each_with_index do |value, index|
         | 
| 56 56 | 
             
                        q.matching << [(index + 1).to_s, filtered[:words][value][:word].downcase]
         | 
| 57 57 | 
             
                      end
         | 
| 58 | 
            -
                      q.matching << [ | 
| 58 | 
            +
                      q.matching << ["", lang.do_mistake_to(filtered[:words][rand(filtered[:words].size)][:word].downcase)]
         | 
| 59 59 | 
             
                      # questions << q
         | 
| 60 60 | 
             
                      # TODO: Revise this type of questions
         | 
| 61 61 | 
             
                    end
         | 
| @@ -75,19 +75,19 @@ class StageF < BaseStage | |
| 75 75 | 
             
                q = Question.new(:choice)
         | 
| 76 76 | 
             
                q.name = "#{name(:id)}-#{num}-f1true#{values.size}-#{table.name}"
         | 
| 77 77 | 
             
                q.text = random_image_for(name(:raw))
         | 
| 78 | 
            -
                q.text += lang.text_for(:f1, name(:decorated), table.fields[0].capitalize, values.join( | 
| 79 | 
            -
                q.good = | 
| 78 | 
            +
                q.text += lang.text_for(:f1, name(:decorated), table.fields[0].capitalize, values.join("</li><li>"))
         | 
| 79 | 
            +
                q.good = lang.text_for(:true)
         | 
| 80 80 | 
             
                q.bads << lang.text_for(:misspelling)
         | 
| 81 81 | 
             
                q.bads << lang.text_for(:false)
         | 
| 82 82 |  | 
| 83 | 
            -
                if concept.type ==  | 
| 83 | 
            +
                if concept.type == "text"
         | 
| 84 84 | 
             
                  values.shuffle!
         | 
| 85 85 | 
             
                  q = Question.new(:short)
         | 
| 86 86 | 
             
                  q.name = "#{name(:id)}-#{num}-f1short#{values.size}-#{table.name}"
         | 
| 87 87 | 
             
                  q.text = random_image_for(name(:raw))
         | 
| 88 | 
            -
                  q.text += lang.text_for(:f1, lang.hide_text(name(:raw)), table.fields[0].capitalize, values.join( | 
| 88 | 
            +
                  q.text += lang.text_for(:f1, lang.hide_text(name(:raw)), table.fields[0].capitalize, values.join("</li><li>"))
         | 
| 89 89 | 
             
                  q.shorts << name(:raw)
         | 
| 90 | 
            -
                  q.shorts << name(:raw).tr( | 
| 90 | 
            +
                  q.shorts << name(:raw).tr("-_", " ")
         | 
| 91 91 | 
             
                  questions << q
         | 
| 92 92 |  | 
| 93 93 | 
             
                  values.shuffle!
         | 
| @@ -96,9 +96,9 @@ class StageF < BaseStage | |
| 96 96 | 
             
                  q = Question.new(:choice)
         | 
| 97 97 | 
             
                  q.name = "#{name(:id)}-#{num}-f1name-misspelled#{values.size}-#{table.name}"
         | 
| 98 98 | 
             
                  q.text = random_image_for(name(:raw))
         | 
| 99 | 
            -
                  q.text += lang.text_for(:f1, lang.do_mistake_to(name(:decorated)), | 
| 100 | 
            -
             | 
| 101 | 
            -
                  q.good = | 
| 99 | 
            +
                  q.text += lang.text_for(:f1, lang.do_mistake_to(name(:decorated)),
         | 
| 100 | 
            +
                    table.fields[0].capitalize, values.join("</li><li>"))
         | 
| 101 | 
            +
                  q.good = lang.text_for(:misspelling)
         | 
| 102 102 | 
             
                  q.bads << lang.text_for(:true)
         | 
| 103 103 | 
             
                  q.bads << lang.text_for(:false)
         | 
| 104 104 | 
             
                  q.feedback = "Concept name #{name(:raw)} misspelled!"
         | 
| @@ -112,8 +112,8 @@ class StageF < BaseStage | |
| 112 112 | 
             
                q = Question.new(:choice)
         | 
| 113 113 | 
             
                q.name = "#{name(:id)}-#{num}-f1true-misspelled#{values.size}-#{table.name}"
         | 
| 114 114 | 
             
                q.text = random_image_for(name(:raw))
         | 
| 115 | 
            -
                q.text += lang.text_for(:f1, name(:decorated), table.fields[0].capitalize, values.join( | 
| 116 | 
            -
                q.good = | 
| 115 | 
            +
                q.text += lang.text_for(:f1, name(:decorated), table.fields[0].capitalize, values.join("</li><li>"))
         | 
| 116 | 
            +
                q.good = lang.text_for(:misspelling)
         | 
| 117 117 | 
             
                q.bads << lang.text_for(:true)
         | 
| 118 118 | 
             
                q.bads << lang.text_for(:false)
         | 
| 119 119 | 
             
                q.feedback = "Text #{save} misspelled!"
         | 
| @@ -143,8 +143,8 @@ class StageF < BaseStage | |
| 143 143 | 
             
                  q = Question.new(:choice)
         | 
| 144 144 | 
             
                  q.name = "#{name(:id)}-#{num}-f1false-#{table.name}"
         | 
| 145 145 | 
             
                  q.text = random_image_for(name(:raw))
         | 
| 146 | 
            -
                  q.text += concept.lang.text_for(:f1, name(:decorated), table.fields[0].capitalize, e.join( | 
| 147 | 
            -
                  q.good = | 
| 146 | 
            +
                  q.text += concept.lang.text_for(:f1, name(:decorated), table.fields[0].capitalize, e.join("</li><li>"))
         | 
| 147 | 
            +
                  q.good = concept.lang.text_for(:false)
         | 
| 148 148 | 
             
                  q.bads << concept.lang.text_for(:misspelling)
         | 
| 149 149 | 
             
                  q.bads << concept.lang.text_for(:true)
         | 
| 150 150 | 
             
                  questions << q
         | 
| @@ -154,7 +154,7 @@ class StageF < BaseStage | |
| 154 154 | 
             
                  q.name = "#{name(:id)}-#{num}-f2outsider-#{table.name}"
         | 
| 155 155 | 
             
                  q.text = random_image_for(name(:raw))
         | 
| 156 156 | 
             
                  q.text += concept.lang.text_for(:f2, name(:decorated), table.fields[0].capitalize)
         | 
| 157 | 
            -
                  q.good = | 
| 157 | 
            +
                  q.good = f4
         | 
| 158 158 | 
             
                  q.bads << e1
         | 
| 159 159 | 
             
                  q.bads << e2
         | 
| 160 160 | 
             
                  q.bads << e3
         | 
| @@ -1,21 +1,16 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require  | 
| 3 | 
            +
            require "set"
         | 
| 4 4 |  | 
| 5 | 
            -
            require_relative  | 
| 6 | 
            -
            require_relative  | 
| 5 | 
            +
            require_relative "base_stage"
         | 
| 6 | 
            +
            require_relative "../question"
         | 
| 7 7 |  | 
| 8 8 | 
             
            # range i1, i2, i3, i4
         | 
| 9 9 | 
             
            class StageI < BaseStage
         | 
| 10 10 | 
             
              # Stage I: process every image from <def> tag
         | 
| 11 | 
            -
              # rubocop:disable Metrics/BlockLength
         | 
| 12 | 
            -
              # rubocop:disable Metrics/MethodLength
         | 
| 13 | 
            -
              # rubocop:disable Metrics/AbcSize
         | 
| 14 | 
            -
              # rubocop:disable Metrics/CyclomaticComplexity
         | 
| 15 | 
            -
              # rubocop:disable Metrics/PerceivedComplexity
         | 
| 16 11 | 
             
              def run
         | 
| 17 12 | 
             
                questions = []
         | 
| 18 | 
            -
                return questions unless concept.type ==  | 
| 13 | 
            +
                return questions unless concept.type == "text"
         | 
| 19 14 |  | 
| 20 15 | 
             
                lang = concept.lang
         | 
| 21 16 | 
             
                # for every <image> do this
         | 
| @@ -72,7 +67,7 @@ class StageI < BaseStage | |
| 72 67 | 
             
                  q.name = "#{name}-#{num}-i2true"
         | 
| 73 68 | 
             
                  q.text = lang.text_for(:i2, url, name)
         | 
| 74 69 | 
             
                  q.encode = image[:file]
         | 
| 75 | 
            -
                  q.good =  | 
| 70 | 
            +
                  q.good = "TRUE"
         | 
| 76 71 | 
             
                  questions << q
         | 
| 77 72 |  | 
| 78 73 | 
             
                  # Question type <i2>: boolean => FALSE
         | 
| @@ -81,7 +76,7 @@ class StageI < BaseStage | |
| 81 76 | 
             
                    q.name = "#{name}-#{num}-i2false"
         | 
| 82 77 | 
             
                    q.text = lang.text_for(:i2, url, concept.neighbors[0][:concept].name)
         | 
| 83 78 | 
             
                    q.encode = image[:file]
         | 
| 84 | 
            -
                    q.good =  | 
| 79 | 
            +
                    q.good = "FALSE"
         | 
| 85 80 | 
             
                    questions << q
         | 
| 86 81 | 
             
                  end
         | 
| 87 82 |  | 
| @@ -91,7 +86,7 @@ class StageI < BaseStage | |
| 91 86 | 
             
                  q.text = lang.text_for(:i3, url, lang.hide_text(name))
         | 
| 92 87 | 
             
                  q.encode = image[:file]
         | 
| 93 88 | 
             
                  q.shorts << name
         | 
| 94 | 
            -
                  q.shorts << name. | 
| 89 | 
            +
                  q.shorts << name.tr("-", " ").tr("_", " ")
         | 
| 95 90 | 
             
                  questions << q
         | 
| 96 91 |  | 
| 97 92 | 
             
                  # Question filtered text questions
         | 
| @@ -101,7 +96,7 @@ class StageI < BaseStage | |
| 101 96 |  | 
| 102 97 | 
             
                    indexes = filtered[:indexes]
         | 
| 103 98 | 
             
                    groups = indexes.combination(4).to_a.shuffle
         | 
| 104 | 
            -
                    max | 
| 99 | 
            +
                    max = (indexes.size / 4).to_i
         | 
| 105 100 | 
             
                    groups[0, max].each do |e|
         | 
| 106 101 | 
             
                      q = Question.new(:match)
         | 
| 107 102 | 
             
                      q.shuffle_off
         | 
| @@ -119,9 +114,4 @@ class StageI < BaseStage | |
| 119 114 | 
             
                end
         | 
| 120 115 | 
             
                questions
         | 
| 121 116 | 
             
              end
         | 
| 122 | 
            -
              # rubocop:enable Metrics/BlockLength
         | 
| 123 | 
            -
              # rubocop:enable Metrics/MethodLength
         | 
| 124 | 
            -
              # rubocop:enable Metrics/AbcSize
         | 
| 125 | 
            -
              # rubocop:enable Metrics/CyclomaticComplexity
         | 
| 126 | 
            -
              # rubocop:enable Metrics/PerceivedComplexity
         | 
| 127 117 | 
             
            end
         | 
| @@ -1,57 +1,59 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require_relative  | 
| 4 | 
            -
            require_relative  | 
| 3 | 
            +
            require_relative "base_stage"
         | 
| 4 | 
            +
            require_relative "../question"
         | 
| 5 5 |  | 
| 6 | 
            -
            # process_sequence
         | 
| 7 6 | 
             
            class StageS < BaseStage
         | 
| 8 7 | 
             
              # process_sequence
         | 
| 9 | 
            -
              # rubocop:disable Metrics/MethodLength
         | 
| 10 | 
            -
              # rubocop:disable Metrics/AbcSize
         | 
| 11 | 
            -
              # rubocop:disable Metrics/CyclomaticComplexity
         | 
| 12 | 
            -
              # rubocop:disable Metrics/PerceivedComplexity
         | 
| 13 8 | 
             
              def run(table, list1, _list2)
         | 
| 14 9 | 
             
                questions = []
         | 
| 15 | 
            -
                return questions unless table.fields.count == 1 && table.sequence? && table.sequence[0] !=  | 
| 10 | 
            +
                return questions unless table.fields.count == 1 && table.sequence? && table.sequence[0] != ""
         | 
| 16 11 |  | 
| 17 12 | 
             
                lang = concept.lang
         | 
| 18 | 
            -
                # Question  | 
| 13 | 
            +
                # Question: items are part of a sequence
         | 
| 19 14 | 
             
                if list1.count > 3
         | 
| 20 15 | 
             
                  a = 0..(list1.count - 4)
         | 
| 21 16 | 
             
                  a.each_entry do |i|
         | 
| 22 17 | 
             
                    q = Question.new(:match)
         | 
| 23 18 | 
             
                    q.name = "#{name}-#{num}-s1sequence-#{table.name}"
         | 
| 24 19 | 
             
                    q.text = random_image_for(name) + lang.text_for(:s1, name, table.fields[0].capitalize, table.sequence[0])
         | 
| 25 | 
            -
                    q.matching << [list1[i + 0][:data][0],  | 
| 26 | 
            -
                    q.matching << [list1[i + 1][:data][0],  | 
| 27 | 
            -
                    q.matching << [list1[i + 2][:data][0],  | 
| 28 | 
            -
                    q.matching << [list1[i + 3][:data][0],  | 
| 29 | 
            -
                    q.matching << [ | 
| 20 | 
            +
                    q.matching << [list1[i + 0][:data][0], "1º"]
         | 
| 21 | 
            +
                    q.matching << [list1[i + 1][:data][0], "2º"]
         | 
| 22 | 
            +
                    q.matching << [list1[i + 2][:data][0], "3º"]
         | 
| 23 | 
            +
                    q.matching << [list1[i + 3][:data][0], "4º"]
         | 
| 24 | 
            +
                    q.matching << ["", lang.text_for(:error)]
         | 
| 30 25 | 
             
                    questions << q
         | 
| 31 26 | 
             
                  end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                  q = Question.new(:ordering)
         | 
| 29 | 
            +
                  q.name = "#{name}-#{num}-s1sequence-#{table.name}"
         | 
| 30 | 
            +
                  q.text = random_image_for(name) + lang.text_for(:s1, name, table.fields[0].capitalize, table.sequence[0])
         | 
| 31 | 
            +
                  list1.each { |item| q.ordering << item[:data][0] }
         | 
| 32 | 
            +
                  questions << q
         | 
| 32 33 | 
             
                end
         | 
| 33 34 |  | 
| 34 | 
            -
                # Question  | 
| 35 | 
            +
                # Question: items are part of a reverse sequence
         | 
| 35 36 | 
             
                if list1.count > 3 && table.sequence.size > 1
         | 
| 36 37 | 
             
                  a = 0..(list1.count - 4)
         | 
| 37 38 | 
             
                  a.each_entry do |i|
         | 
| 38 | 
            -
                    q = Question.new
         | 
| 39 | 
            -
                    q.set_match
         | 
| 39 | 
            +
                    q = Question.new(:match)
         | 
| 40 40 | 
             
                    q.name = "#{name}-#{num}-s2sequence-#{table.name}"
         | 
| 41 41 | 
             
                    q.text = random_image_for(name) + lang.text_for(:s1, name, table.fields[0].capitalize, table.sequence[1])
         | 
| 42 | 
            -
                    q.matching << [list1[i + 3][:data][0],  | 
| 43 | 
            -
                    q.matching << [list1[i + 2][:data][0],  | 
| 44 | 
            -
                    q.matching << [list1[i + 1][:data][0],  | 
| 45 | 
            -
                    q.matching << [list1[i + 0][:data][0],  | 
| 46 | 
            -
                    q.matching << [ | 
| 42 | 
            +
                    q.matching << [list1[i + 3][:data][0], "1º"]
         | 
| 43 | 
            +
                    q.matching << [list1[i + 2][:data][0], "2º"]
         | 
| 44 | 
            +
                    q.matching << [list1[i + 1][:data][0], "3º"]
         | 
| 45 | 
            +
                    q.matching << [list1[i + 0][:data][0], "4º"]
         | 
| 46 | 
            +
                    q.matching << ["", lang.text_for(:error)]
         | 
| 47 47 | 
             
                    questions << q
         | 
| 48 48 | 
             
                  end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                  q = Question.new(:ordering)
         | 
| 51 | 
            +
                  q.name = "#{name}-#{num}-s2sequence-#{table.name}"
         | 
| 52 | 
            +
                  q.text = random_image_for(name) + lang.text_for(:s1, name, table.fields[0].capitalize, table.sequence[1])
         | 
| 53 | 
            +
                  list1.reverse.to_a.each { |item| q.ordering << item[:data][0] }
         | 
| 54 | 
            +
                  questions << q
         | 
| 49 55 | 
             
                end
         | 
| 50 56 |  | 
| 51 57 | 
             
                questions
         | 
| 52 58 | 
             
              end
         | 
| 53 | 
            -
              # rubocop:enable Metrics/MethodLength
         | 
| 54 | 
            -
              # rubocop:enable Metrics/AbcSize
         | 
| 55 | 
            -
              # rubocop:enable Metrics/CyclomaticComplexity
         | 
| 56 | 
            -
              # rubocop:enable Metrics/PerceivedComplexity
         | 
| 57 59 | 
             
            end
         |