class Qti::V2::Models::Interactions::GapMatchInteraction

Public Class Methods

matches(node, parent) click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 6
def self.matches(node, parent)
  matches = node.xpath('.//xmlns:gapMatchInteraction')
  return false if matches.count != 1
  new(node, parent)
end

Public Instance Methods

answers() click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 81
def answers
  @answers ||= answer_nodes.map do |node|
    V2::Models::Choices::GapMatchChoice.new(node, self)
  end
end
blanks() click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 75
def blanks
  node.xpath('.//xmlns:gapText').map do |blank|
    { id: blank.attributes['identifier'].value }
  end
end
choices() click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 100
def choices
  @node.xpath('.//xmlns:gapText')
end
clean_stem_items() click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 16
def clean_stem_items
  @clean_stem_items ||= begin
    node = @node.dup
    gap_node = node.xpath('.//xmlns:gapMatchInteraction')
    gap_node.children.filter('gapText').each(&:remove)

    gap_node.children.each do |child|
      child.remove if child.inner_text.strip.empty?
    end

    gap_node
  end
end
prompt() click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 30
def prompt
  clean_stem_items.children.filter('prompt')
end
prompt_hash() click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 52
def prompt_hash
  {
    type: 'text',
    value: prompt.first.text
  }
end
scoring_data_structs() click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 87
def scoring_data_structs
  mapping = question_response_id_mapping
  answer_nodes.map do |value_node|
    node_id = value_node.attributes['identifier']&.value
    ScoringData.new(
      answer_choice(choices, mapping[node_id]).content,
      'directedPair',
      id: node_id,
      case: false
    )
  end
end
shuffled?() click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 12
def shuffled?
  @node.at_xpath('.//xmlns:gapMatchInteraction').attributes['shuffle']&.value.try(:downcase) == 'true'
end
stem_items() click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 34
def stem_items
  if prompt.present?
    stem_text_with_prompt = stem_text.unshift(prompt_hash)
    stem_items_with_id_and_position(stem_text_with_prompt)
  else
    stem_items_with_id_and_position(stem_text)
  end
end
stem_items_with_id_and_position(stem_text) click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 43
def stem_items_with_id_and_position(stem_text)
  stem_text.map.with_index do |stem_item, index|
    stem_item.merge(
      id: "stem_#{index}",
      position: index + 1
    )
  end
end
stem_text() click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 59
def stem_text
  clean_stem_items.search('p').children.map do |stem_item|
    if stem_item.name == 'gap'
      {
        type: 'blank',
        blank_id: stem_item.attributes['identifier'].value
      }
    else
      {
        type: 'text',
        value: stem_item.text.empty? ? ' ' : stem_item.text
      }
    end
  end
end

Private Instance Methods

answer_choice(choices, response) click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 110
def answer_choice(choices, response)
  choices.find do |choice|
    choice.attributes['identifier']&.value == response
  end
end
answer_nodes() click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 106
def answer_nodes
  @node.xpath('.//xmlns:gap')
end
question_response_id_mapping() click to toggle source
# File lib/qti/v2/models/interactions/gap_match_interaction.rb, line 116
def question_response_id_mapping
  question_response_pairs = node.xpath('.//xmlns:correctResponse//xmlns:value').map do |value|
    value.content.split
  end
  question_response_pairs.map!(&:reverse)
  Hash[question_response_pairs]
end