Class: Senkyoshi::Question

Inherits:
Resource show all
Defined in:
lib/senkyoshi/models/question.rb

Constant Summary collapse

QUESTION_TYPE =
{
  "True/False" => "true_false_question",
  "Numeric" => "numerical_question",
  "Multiple Choice" => "multiple_choice_question",
  "Multiple Answer" => "multiple_answers_question",
  "Matching" => "matching_question",
  "Fill in the Blank" => "short_answer_question",
  "Fill in the Blank Plus" => "fill_in_multiple_blanks_question",
  "File Upload" => "file_upload_question",
  "Essay" => "essay_question",
  "Calculated" => "calculated_question",
  "Jumbled Sentence" => "multiple_dropdowns_question",
  "Either/Or" => "multiple_choice_question",
  "Hot Spot" => "text_only_question",
  "Opinion Scale" => "multiple_answers_question",
  "Ordering" => "matching_question",
  "Quiz Bowl" => "text_only_question",
  "Short Response" => "essay_question",
}.freeze
ITEM_FUNCTION =
{
  "True/False" => "TrueFalse",
  "Numeric" => "NumericalQuestion",
  "Multiple Choice" => "MultipleChoice",
  "Multiple Answer" => "MultipleAnswer",
  "Matching" => "Matching",
  "Fill in the Blank" => "FillInBlank",
  "Fill in Multiple Blanks" => "FillInMultipleBlanks",
  "Fill in the Blank Plus" => "FillInBlankPlus",
  "File Upload" => "FileUpload",
  "Essay" => "Essay",
  "Calculated" => "Calculated",
  "Jumbled Sentence" => "JumbledSentence",
  "Either/Or" => "EitherOr",
  "Hot Spot" => "HotSpot",
  "Opinion Scale" => "OpinionScale",
  "Ordering" => "Ordering",
  "Quiz Bowl" => "QuizBowl",
  "Short Response" => "ShortResponse",
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Resource

#_find_directories, #_fix_path, #_matches_directory_xid?, #_search_and_replace, #cleanup, #fix_html, get_pre_data, #matches_xid?, #strip_xid

Constructor Details

#initializeQuestion

Returns a new instance of Question.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/senkyoshi/models/question.rb', line 70

def initialize
  @original_identifier = ""
  @question = nil
  @question_type = ""
  @points_possible = ""
  @title = "Question"
  @material = ""
  @answers = []
  @general_feedback = ""
  @general_correct_feedback = ""
  @general_incorrect_feedback = ""
  @blackboard_type = ""
  @correct_answers = {}
  @incorrect_answers = {}
  @max_score = 1
end

Instance Attribute Details

#answersObject (readonly)

Returns the value of attribute answers.



20
21
22
# File 'lib/senkyoshi/models/question.rb', line 20

def answers
  @answers
end

Class Method Details

.from(item) ⇒ Object



63
64
65
66
67
68
# File 'lib/senkyoshi/models/question.rb', line 63

def self.from(item)
  type = item.at("bbmd_questiontype").children.text
  item_class = Senkyoshi.const_get ITEM_FUNCTION[type]
  question = item_class.new
  question.iterate_xml(item)
end

Instance Method Details

#canvas_conversion(_, resources) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/senkyoshi/models/question.rb', line 99

def canvas_conversion(_, resources)
  @question.identifier = Senkyoshi.create_random_hex
  @question.title = @title
  @question.original_identifier = @original_identifier
  @question.points_possible = @points_possible
  @question.material = fix_html(@material, resources)
  @question.general_feedback = fix_html(@general_feedback, resources)
  @general_correct_feedback =
    fix_html(@general_correct_feedback, resources)
  @question.general_correct_feedback = @general_correct_feedback
  @general_incorrect_feedback =
    fix_html(@general_incorrect_feedback, resources)
  @question.general_incorrect_feedback = @general_incorrect_feedback
  @question.answers = []
  @answers.each do |answer|
    @question = answer.canvas_conversion(@question, resources)
  end
  @question
end

#get_fraction(answer_text) ⇒ Object



119
120
121
122
123
124
125
# File 'lib/senkyoshi/models/question.rb', line 119

def get_fraction(answer_text)
  if @correct_answers && answer_text.to_s == @correct_answers["name"].to_s
    @correct_answers["fraction"].to_f
  else
    @incorrect_answers["fraction"].to_f
  end
end

#iterate_item(data) ⇒ Object



165
166
167
168
169
170
171
# File 'lib/senkyoshi/models/question.rb', line 165

def iterate_item(data)
  @general_correct_feedback = set_feedback(data, "correct")
  @general_incorrect_feedback = set_feedback(data, "incorrect")
  @material = set_material(data)
  resprocessing = data.at("resprocessing")
  @max_score = set_max_score(resprocessing)
end

#iterate_xml(data) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
# File 'lib/senkyoshi/models/question.rb', line 87

def iterate_xml(data)
  @original_identifier = data.at("bbmd_asi_object_id").text
  @blackboard_type = data.at("bbmd_questiontype").text
  @question_type = QUESTION_TYPE[@blackboard_type]
  @question = CanvasCc::CanvasCC::Models::Question.create(@question_type)
  @points_possible = data.at("qmd_absolutescore_max").text
  title = data.attributes["title"]
  @title = title ? title.value : ""
  iterate_item(data)
  self
end

#set_answers(resprocessing) ⇒ Object



127
128
129
130
# File 'lib/senkyoshi/models/question.rb', line 127

def set_answers(resprocessing)
  set_correct_answers(resprocessing)
  set_incorrect_answers(resprocessing)
end

#set_correct_answers(resprocessing) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/senkyoshi/models/question.rb', line 132

def set_correct_answers(resprocessing)
  correct = resprocessing.at("respcondition[title=correct]")
  if correct
    if correct.at("varequal")
      @correct_answers["name"] = correct.at("varequal").text
    end
    score = correct.at("setvar") ? correct.at("setvar").text : 0
    score_number = score == "SCORE.max" ? @max_score.to_f : score.to_f
    if score_number > 0
      @correct_answers["fraction"] = score_number.to_f / @max_score.to_f
    else
      # mark as correct when there is no score for the answer
      @correct_answers["fraction"] = 1
    end
  end
end

#set_feedback(data, type) ⇒ Object



173
174
175
176
177
178
179
180
# File 'lib/senkyoshi/models/question.rb', line 173

def set_feedback(data, type)
  feedback = data.at("itemfeedback[ident=#{type}]")
  if feedback && feedback.at("mat_formattedtext")
    feedback.at("mat_formattedtext").text
  else
    ""
  end
end

#set_incorrect_answers(resprocessing) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/senkyoshi/models/question.rb', line 149

def set_incorrect_answers(resprocessing)
  incorrect = resprocessing.at("respcondition[title=incorrect]")
  if incorrect
    if incorrect.at("varequal")
      @incorrect_answers["name"] = incorrect.at("varequal").text
    end
    score = incorrect.at("setvar") ? incorrect.at("setvar").text : 0
    score_number = score == "SCORE.max" ? @max_score.to_f : score.to_f
    if score_number > 0
      @incorrect_answers["fraction"] = score_number.to_f / @max_score.to_f
    else
      @incorrect_answers["fraction"] = 0
    end
  end
end

#set_material(data) ⇒ Object



182
183
184
185
186
187
188
# File 'lib/senkyoshi/models/question.rb', line 182

def set_material(data)
  if (question_block = data.at("flow[@class=QUESTION_BLOCK]"))
    question_block.at("mat_formattedtext").text
  else
    ""
  end
end

#set_max_score(resprocessing) ⇒ Object



190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/senkyoshi/models/question.rb', line 190

def set_max_score(resprocessing)
  no_score = "0.0"
  outcomes = resprocessing.at("outcomes")
  if outcomes && !outcomes.at("decvar").nil?
    if outcomes.at("decvar").attributes["maxvalue"]
      outcomes.at("decvar").attributes["maxvalue"].value
    else
      no_score
    end
  else
    no_score
  end
end