xowf::test_item::Answer_manager method achieved_points (protected)

 <instance of xowf::test_item::Answer_manager[i]> achieved_points \
    [ -manual_grading manual_grading ] [ -submission submission ] \
    [ -exam_question_dict exam_question_dict ] \
    -answer_attributes answer_attributes 

Defined in packages/xowf/tcl/test-item-procs.tcl

Calculate the achieved_points dict for an exam submission. This function iterates of every question and sums up the achievable and achieved points of the questions. The per-question results are placed in the dict entry "details". This method has to be called after the instance was rendered, since it uses the produced form_fields.

Switches:
-manual_grading (optional)
-submission (optional, object)
-exam_question_dict (optional)
-answer_attributes (required)
Returns:
dict containing "achievedPoints", "achievablePoints" and "details"

Testcases:
No testcase defined.
Source code:
set all_form_fields [::xowiki::formfield::FormField info instances -closure]
set question_dict $exam_question_dict

if {[$submission property question] ne ""} {
  #
  # When the submission has a property "question" set then we
  # have a submission from a pool question. In this case, we
  # want - at least for the time being - the id of the pool
  # question and not the id of the replacement
  # question. Therefore, we have to create a dict for the
  # mapping of these values and to create a question_dict
  # (mapping from question_names to ids) updated with the id of
  # the pool question.
  #
  set question_ids_exam [lmap {k v} $exam_question_dict {set v}]
  set form_objs_submission [:QM load_question_objs $submission [$submission property question]]
  set question_ids_submission [lmap form_obj $form_objs_submission {$form_obj item_id}]
  #ns_log notice "=== achieved_points IDs examwf     <$question_ids_exam>"
  #ns_log notice "=== achieved_points IDs submission <$question_ids_submission>"
  set map ""
  foreach id_exam $question_ids_exam id_submission $question_ids_submission {
    if {$id_exam != $id_submission} {
      #ns_log notice "=== achieved_points must use $id_exam instead of $id_submission"
      dict set map $id_submission $id_exam
    }
  }
  set question_dict [:FL name_to_question_obj_dict $form_objs_submission]
  foreach {k v} $question_dict {
    if {[dict exists $map $v]} {
      dict set question_dict $k [dict get $map $v]
    }
  }
}

#ns_log notice "=== achieved_points question_dict <$question_dict>"

set totalPoints 0
set achievableTotalPoints 0
set details {}

foreach a [dict keys $answer_attributes] {
  set f [$submission lookup_form_field -name $a $all_form_fields]
  set points {}
  if {![$f exists test_item_points]} {
    ns_log warning "question $f [$f name] [$f info precedence] HAS NO POINTS"
    $f set test_item_points 0
  }
  set achievablePoints [$f set test_item_points]
  set achievableTotalPoints [expr {$achievableTotalPoints + $achievablePoints}]

  if {[$f exists correction_data]} {
    set auto_correct_achieved [:dict_value [$f set correction_data] points]
  } else {
    set auto_correct_achieved ""
  }
  #ns_log notice "=== achieved_points <$a> auto_correct_achieved $auto_correct_achieved"

  #
  # Manual grading has higher priority than autograding.
  #
  set achieved [:dict_value [:dict_value $manual_grading $a] achieved]
  if {$achieved eq ""} {
    set achieved $auto_correct_achieved
  }

  if {$achieved ne ""} {
    set totalPoints [expr {$totalPoints + $achieved}]
  } else {
    ns_log warning "$a: no points via automated or manual grading,"  "ignoring question in achieved points calculation"
  }
  lappend details [dict create  attributeName $a  question_id [:dict_value $question_dict $a]  achieved $achieved  auto_correct_achieved $auto_correct_achieved  achievable $achievablePoints]
}

#ns_log notice "final details <$details>"
return [list achievedPoints $totalPoints  details $details  achievablePoints $achievableTotalPoints]
XQL Not present:
Generic, PostgreSQL, Oracle
[ hide source ] | [ make this the default ]
Show another procedure: