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
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 0e5cbcd35b27392a56444a2bdae4036445ac8b7b8404c6601e006764fbe0dae8
         | 
| 4 | 
            +
              data.tar.gz: 04de6c0757edfba5abf31744d53844fd51f766c5287413d387c309fa3c95131e
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: b0305dfd9e98c0f92cf05cf567f1ab71b2522db32f930865e623dadc84fa9601623269a095fe590e4d7be9cc77c842590fd03848ad961c9047be786bfae6c7d6
         | 
| 7 | 
            +
              data.tar.gz: 833a34e6159b81f68919944a9fbc412c6870634d3d5eb6614e23c470c9d1bea5d4bf4a2c57bc70c836b06a75ad914f411710200cc2bde8070e5c8d32f04cb745
         | 
    
        data/README.md
    CHANGED
    
    | @@ -34,10 +34,10 @@ Let's see an example creating questions from ACDC input example file: | |
| 34 34 | 
             
            +--------------------+-----------+---------+---------+---+---+----+---+---+----+
         | 
| 35 35 | 
             
            | Concept            | Questions | Entries | xFactor | d | b | f  | i | s | t  |
         | 
| 36 36 | 
             
            +--------------------+-----------+---------+---------+---+---+----+---+---+----+
         | 
| 37 | 
            -
            | AC/DC              |  | 
| 37 | 
            +
            | AC/DC              | 46        | 18      | 2.5     | 7 | 0 | 15 | 0 | 4 | 20 |
         | 
| 38 38 | 
             
            | Excluded questions | 0         | -       | -       | 0 | 0 | 0  | 0 | 0 | 0  |
         | 
| 39 39 | 
             
            +--------------------+-----------+---------+---------+---+---+----+---+---+----+
         | 
| 40 | 
            -
            | 1 concept/s        |  | 
| 40 | 
            +
            | 1 concept/s        | 46        | 18      | 2.5     | 7 | 0 | 15 | 0 | 4 | 20 |
         | 
| 41 41 | 
             
            +--------------------+-----------+---------+---------+---+---+----+---+---+----+
         | 
| 42 42 | 
             
            ```
         | 
| 43 43 |  | 
| @@ -46,15 +46,15 @@ Let's see an example creating questions from ACDC input example file: | |
| 46 46 | 
             
            * [Free Software License](LICENSE).
         | 
| 47 47 | 
             
            * Multiplatform.
         | 
| 48 48 | 
             
            * Input files formats: XML, HAML.
         | 
| 49 | 
            -
            * Output formats: GIFT, Moodle XML.
         | 
| 50 | 
            -
            * Question types: true/false, multiple choice, short answer, matching.
         | 
| 49 | 
            +
            * Output formats: GIFT, Moodle XML, YAML.
         | 
| 50 | 
            +
            * Question types: true/false, multiple choice, short answer, matching and ordering.
         | 
| 51 51 | 
             
            * Embeded files: mp3, ogg, wav, jpg, jpeg, png, mp4, ogv and plain text files.
         | 
| 52 52 |  | 
| 53 53 | 
             
            # Documentation
         | 
| 54 54 |  | 
| 55 55 | 
             
            * [Installation](docs/install/README.md)
         | 
| 56 56 | 
             
            * [Videos](docs/videos.md)
         | 
| 57 | 
            -
            * [ | 
| 57 | 
            +
            * [Get started](docs/inputs/README.md)
         | 
| 58 58 | 
             
            * [Usage](docs/usage.md)
         | 
| 59 59 | 
             
            * [Reference](docs/reference.md)
         | 
| 60 60 | 
             
            * [Contributions](docs/contributions.md)
         | 
    
        data/lib/asker/ai/ai.rb
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require_relative  | 
| 4 | 
            -
            require_relative  | 
| 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
         | 
| @@ -49,12 +49,12 @@ module AI | |
| 49 49 | 
             
              end
         | 
| 50 50 |  | 
| 51 51 | 
             
              def exclude_questions
         | 
| 52 | 
            -
                param = Application.instance.config[ | 
| 52 | 
            +
                param = Application.instance.config["questions"]["exclude"]
         | 
| 53 53 | 
             
                return if param.nil?
         | 
| 54 54 |  | 
| 55 | 
            -
                tags = param.split( | 
| 56 | 
            -
                input = { | 
| 57 | 
            -
                output = { | 
| 55 | 
            +
                tags = param.split(",").each(&:strip!)
         | 
| 56 | 
            +
                input = {d: [], b: [], f: [], i: [], s: [], t: []}
         | 
| 57 | 
            +
                output = {d: [], b: [], f: [], i: [], s: [], t: []}
         | 
| 58 58 |  | 
| 59 59 | 
             
                @questions.each_pair do |key, qlist|
         | 
| 60 60 | 
             
                  output[key] = qlist.select { |q| string_has_this_tags?(q.name, tags) }
         | 
| @@ -12,7 +12,7 @@ module AICalculate | |
| 12 12 | 
             
                list1 = []
         | 
| 13 13 | 
             
                count = 1
         | 
| 14 14 | 
             
                p_table.rows.each do |i|
         | 
| 15 | 
            -
                  list1 << { | 
| 15 | 
            +
                  list1 << {id: count, weight: 0, data: i}
         | 
| 16 16 | 
             
                  count += 1
         | 
| 17 17 | 
             
                end
         | 
| 18 18 |  | 
| @@ -23,7 +23,7 @@ module AICalculate | |
| 23 23 | 
             
                    next if t2.name != p_table.name
         | 
| 24 24 |  | 
| 25 25 | 
             
                    t2.rows.each do |i|
         | 
| 26 | 
            -
                      list2 << { | 
| 26 | 
            +
                      list2 << {id: count, weight: 0, data: i}
         | 
| 27 27 | 
             
                      count += 1
         | 
| 28 28 | 
             
                    end
         | 
| 29 29 | 
             
                  end
         | 
| @@ -34,7 +34,7 @@ module AICalculate | |
| 34 34 | 
             
              def calculate_nearness_between_texts(text1, text2)
         | 
| 35 35 | 
             
                return 0.0 if text2.nil? || text2.empty?
         | 
| 36 36 |  | 
| 37 | 
            -
                words = text1.split( | 
| 37 | 
            +
                words = text1.split(" ")
         | 
| 38 38 | 
             
                count = 0
         | 
| 39 39 | 
             
                words.each { |w| count += 1 if text2.include?(w) }
         | 
| 40 40 | 
             
                (count * 100 / words.count)
         | 
| @@ -1,16 +1,13 @@ | |
| 1 1 | 
             
            # frozen_string_literal: false
         | 
| 2 2 |  | 
| 3 | 
            -
            require_relative  | 
| 4 | 
            -
            require_relative  | 
| 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?  | 
| 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 | 
            -
                   | 
| 26 | 
            +
                  Logger.warn "CodeAIFactory: Invalid type (#{type})"
         | 
| 33 27 | 
             
                end
         | 
| 34 28 | 
             
                nil
         | 
| 35 29 | 
             
              end
         | 
| @@ -1,7 +1,6 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
            require_relative  | 
| 3 | 
            -
            require_relative  | 
| 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!( | 
| 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 =  | 
| 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]= | 
| 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 =  | 
| 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,  | 
| 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 <<  | 
| 61 | 
            -
                    q.feedback =  | 
| 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 =  | 
| 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 =  | 
| 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 #{ | 
| 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 #{ | 
| 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  | 
| 3 | 
            -
            require_relative  | 
| 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( | 
| 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!( | 
| 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 =  | 
| 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]= | 
| 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 =  | 
| 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,  | 
| 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 <<  | 
| 61 | 
            -
                    q.feedback =  | 
| 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 =  | 
| 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 =  | 
| 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 | 
| 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 #{ | 
| 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 #{ | 
| 156 | 
            +
                      q.feedback = "Variable error! Swapped lines #{index + 1} with #{k + 1}"
         | 
| 158 157 | 
             
                    end
         | 
| 159 158 | 
             
                    questions << q
         | 
| 160 159 | 
             
                  end
         |