Add variable question distractor pools
This commit is contained in:
@@ -30,6 +30,8 @@ func start_block(selected_system: String, block_size: int, selected_mode: String
|
||||
mode = selected_mode
|
||||
session_kind = "block"
|
||||
active_questions = QuestionBankService.build_block(selected_system, block_size)
|
||||
for index in range(active_questions.size()):
|
||||
active_questions[index] = _prepare_question_choices(active_questions[index])
|
||||
answers.clear()
|
||||
answers.resize(active_questions.size())
|
||||
current_index = 0
|
||||
@@ -293,10 +295,38 @@ func _draw_core_question() -> Dictionary:
|
||||
var candidate: Dictionary = core_question_pool[index]
|
||||
if str(candidate.get("id", "")) != last_id or core_question_pool.size() == 1:
|
||||
core_question_pool.remove_at(index)
|
||||
return candidate.duplicate(true)
|
||||
return _prepare_question_choices(candidate.duplicate(true))
|
||||
return {}
|
||||
|
||||
|
||||
func _prepare_question_choices(question: Dictionary) -> Dictionary:
|
||||
var existing: Array = question.get("presented_choices", [])
|
||||
if not existing.is_empty():
|
||||
return question
|
||||
|
||||
var all_choices: Array = question.get("choices", []).duplicate(true)
|
||||
var correct_id := str(question.get("correct_choice_id", ""))
|
||||
var correct_choice: Dictionary = {}
|
||||
var distractors: Array = []
|
||||
for choice in all_choices:
|
||||
if typeof(choice) != TYPE_DICTIONARY:
|
||||
continue
|
||||
if str(choice.get("id", "")) == correct_id:
|
||||
correct_choice = choice
|
||||
else:
|
||||
distractors.append(choice)
|
||||
|
||||
distractors.shuffle()
|
||||
var presented: Array = distractors.slice(0, min(4, distractors.size()))
|
||||
if not correct_choice.is_empty():
|
||||
presented.append(correct_choice)
|
||||
elif not all_choices.is_empty():
|
||||
presented = all_choices.slice(0, min(5, all_choices.size()))
|
||||
presented.shuffle()
|
||||
question["presented_choices"] = presented
|
||||
return question
|
||||
|
||||
|
||||
func _build_core_question_pool() -> Array:
|
||||
var pool: Array = []
|
||||
var profile := ProfileService.get_profile()
|
||||
|
||||
@@ -103,7 +103,8 @@ func load_questions_from_api(reset_retry: bool = true) -> void:
|
||||
"Authorization: Bearer %s" % AuthState.access_token
|
||||
])
|
||||
var payload := {
|
||||
"limit": 80
|
||||
"limit": 80,
|
||||
"supportsChoicePools": true
|
||||
}
|
||||
var err := request.request(questions_api_url, headers, HTTPClient.METHOD_POST, JSON.stringify(payload))
|
||||
if err != OK:
|
||||
@@ -177,10 +178,10 @@ func clear_questions() -> void:
|
||||
ratings_changed.emit()
|
||||
|
||||
|
||||
func record_first_attempt(question_id: String, choice_id: String) -> void:
|
||||
func record_first_attempt(question_id: String, choice_id: String, presented_choice_ids: Array = []) -> void:
|
||||
if AuthState.access_token.is_empty() or question_id == "" or choice_id == "":
|
||||
return
|
||||
_enqueue_attempt("answer", question_id, choice_id)
|
||||
_enqueue_attempt("answer", question_id, choice_id, presented_choice_ids)
|
||||
|
||||
|
||||
func skip_question(question_id: String) -> void:
|
||||
@@ -294,7 +295,7 @@ func _on_retry_timer_timeout() -> void:
|
||||
load_questions_from_api(false)
|
||||
|
||||
|
||||
func _enqueue_attempt(kind: String, question_id: String, choice_id: String) -> void:
|
||||
func _enqueue_attempt(kind: String, question_id: String, choice_id: String, presented_choice_ids: Array = []) -> void:
|
||||
var account := AuthState.username.strip_edges()
|
||||
if account == "":
|
||||
return
|
||||
@@ -306,6 +307,7 @@ func _enqueue_attempt(kind: String, question_id: String, choice_id: String) -> v
|
||||
"kind": kind,
|
||||
"question_id": question_id,
|
||||
"choice_id": choice_id,
|
||||
"presented_choice_ids": presented_choice_ids.duplicate(),
|
||||
"retry_count": 0
|
||||
})
|
||||
_save_attempt_queue()
|
||||
@@ -335,7 +337,8 @@ func _process_attempt_queue() -> void:
|
||||
var url := question_attempt_api_url
|
||||
var body := JSON.stringify({
|
||||
"questionExternalId": question_id,
|
||||
"choiceId": str(queued.get("choice_id", ""))
|
||||
"choiceId": str(queued.get("choice_id", "")),
|
||||
"presentedChoiceIds": queued.get("presented_choice_ids", [])
|
||||
})
|
||||
if str(queued.get("kind", "answer")) == "skip":
|
||||
url = "%s/%s/skip" % [question_api_base_url.rstrip("/"), question_id.uri_encode()]
|
||||
@@ -457,6 +460,7 @@ func _load_attempt_queue() -> void:
|
||||
"kind": kind,
|
||||
"question_id": question_id,
|
||||
"choice_id": str(item.get("choice_id", "")),
|
||||
"presented_choice_ids": item.get("presented_choice_ids", []).duplicate(),
|
||||
"retry_count": max(0, int(item.get("retry_count", 0)))
|
||||
})
|
||||
|
||||
|
||||
@@ -442,8 +442,7 @@ func _load_question() -> void:
|
||||
lead_label.text = question.get("lead_in", "")
|
||||
_refresh_labs_button()
|
||||
|
||||
presented_choices = question.get("choices", []).duplicate(true)
|
||||
presented_choices.shuffle()
|
||||
presented_choices = question.get("presented_choices", question.get("choices", [])).duplicate(true)
|
||||
var choices := presented_choices
|
||||
for index in range(choice_buttons.size()):
|
||||
var button := choice_buttons[index]
|
||||
@@ -613,7 +612,11 @@ func _submit_or_next() -> void:
|
||||
_collapse_resolved_followups()
|
||||
var attempted_choice := selected_choice
|
||||
var attempted_question_id := str(BlockSessionService.get_current_question().get("id", ""))
|
||||
QuestionBankService.record_first_attempt(attempted_question_id, attempted_choice)
|
||||
QuestionBankService.record_first_attempt(
|
||||
attempted_question_id,
|
||||
attempted_choice,
|
||||
_presented_choice_ids()
|
||||
)
|
||||
var result := BlockSessionService.submit_core_attempt(selected_choice, eliminated, flagged)
|
||||
if result.is_empty():
|
||||
return
|
||||
@@ -632,6 +635,12 @@ func _submit_or_next() -> void:
|
||||
_trigger_wrong_feedback()
|
||||
_apply_saved_choice_state()
|
||||
return
|
||||
var attempted_question_id := str(BlockSessionService.get_current_question().get("id", ""))
|
||||
QuestionBankService.record_first_attempt(
|
||||
attempted_question_id,
|
||||
selected_choice,
|
||||
_presented_choice_ids()
|
||||
)
|
||||
current_answer = BlockSessionService.answer_current(selected_choice, eliminated, flagged)
|
||||
if BlockSessionService.mode == "Tutor":
|
||||
_show_explanation()
|
||||
@@ -1871,6 +1880,14 @@ func _get_presented_choices() -> Array:
|
||||
return BlockSessionService.get_current_question().get("choices", [])
|
||||
|
||||
|
||||
func _presented_choice_ids() -> Array:
|
||||
var ids: Array = []
|
||||
for choice in _get_presented_choices():
|
||||
if typeof(choice) == TYPE_DICTIONARY:
|
||||
ids.append(str(choice.get("id", "")))
|
||||
return ids
|
||||
|
||||
|
||||
func _display_label_for_index(index: int) -> String:
|
||||
return String.chr(65 + index)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user