Multi-choice question scoring algorithm for guidance

multiple choice scoring rules

each correct option has a score weight. Choose the right one to give the correct option a score weight, and if you choose the wrong one, the total score is 0

.

if: the correct answer is ABC, with a total score of 10, with a weight of 20% and 40% respectively

submit the answer ABC (20% "40%" 40%) * 10 = 10 points

the AB score for submitting answers is (20%-40%) * 10 = 6 points

ABD score 0 for submitting answers

brainstorming. If possible, please use PHP to answer

Php
Mar.23,2021

   function selectScore(preAnswerScore,answer) {
      let totalScore = 0;
      let noScoreKey = [];
      let hasNoScoreKey = false;
      for(let key in preAnswerScore) {
        if(preAnswerScore[key] == 0){
          noScoreKey.push(key);
        }
      }
      noScoreKey.map( item => {
        if(answer.includes(item)){
          hasNoScoreKey = true;
        }
      });
      if(hasNoScoreKey) {
        totalScore = 0;
      }else{
        answer.map (item => {
          totalScore += preAnswerScore[item];
        });
        totalScore /= 10;
      }
      return totalScore;
    } 
    let preAnswerScore = {a: 20, b: 40, c: 40, d: 0}; 
    let answer = ['c','b','d']
    console.log(selectScore(preAnswerScore, answer));
  }

js take a walk, considering that your other multiple choice questions are also applicable


No php, use js

// 
const select = ['a','b','d']
//  
const score = {
    'a': 20,
    'b': 20,
    'c': 60,
    'd': 0
}
//   :abd  20,20,0
const a = select.map(x => score[x])
//  a 0  0  reduce  
total = a.includes(0) ? 0 : a.reduce((total, i) =>  total+ (i *0.1) , 0)

suppose your answer has some delimiters such as , , and you have the standard answer for each question, as follows:
/ *
* @ param $standard array Standard answer
* @ param $answer string submit the answer
* /
function get_score ($standard,$answer) {

//
$score = 0;

$answer = explode(',', $answer);
if(!empty($answer)){
    foreach ($answer as $v) {
        if(isset($standard[$v])){
            $score+=(int)($standard[$v]*10);
        }else{
            $score = 0;
            break;
        }
    }
}
return $score;

}

var_dump (get_score ([

)
'A' => 0.2,
'B' => 0.4,
'C' => 0.4

],'A)); B'


function score(customAnswer, totalScore, weight) {
    let ret = 0
    for (let a of customAnswer) {
        if (!weight[a]) {
            return 0
        } else {
            ret += totalScore * weight[a]
        }
    }
    return ret
}

score('abc', 10, {a: 0.2, b: 0.4, c: 0.4})

The idea of

is to get the intersection of submission and answer. If the number of intersections is not equal to the number of submissions, it is considered that there is a wrong value. If the number of intersections is equal to the number of submissions, you can score through traversal

.
<?php

function multiSelectScore($answer, $wight, $allScore, $submit)
{
    $score = 0;
    $answerWight = array_combine($answer, $wight);
    // 
    $selects = array_intersect($answer, $submit);

    if(count($selects) === count($submit)) {
        // 
        foreach($selects as $key => $select) {
            $score += $answerWight[$select] * 0.01 * $allScore;
        }
    }
    return $score;
}

// 
$answer = ["A", "B", "C"];
// 
$wight = ["20","30","50"];
// 
$allScore = 10;
// 
$submit = ["A","C"];
$score = multiSelectScore($answer, $wight, $allScore, $submit);

echo json_encode($score) . "\n";

function calc($result,$answer,$score){
    $count = count($result);
    $d = array_diff($answer,$result);
    if($d){
        return  0;
    }
    $c = array_diff($result,$answer);
    $lost = count($c);
    if(!$lost){
         return  $score;
    }
    switch ($count) {
        case 1:
            $per = [1=>1];
            break;
        case 2:
            $per = [1=>0.4,2=>1];
            break;
        case 3:
            $per = [1=>0.2,2=>0.6,3=>1];
            break;
        default:
             $per = [1=>0.1,2=>0.5,3=>0.8,4=>1];
            break;
    }
    $true = $count - $lost ;
    return $per[$true]*$score;
    
}

$result = ['A','B','C'];
$answer = ['A','B'];
$score = 10;

echo calc($result,$answer,$score);

PHP object-oriented version

/**
 * Created by: Singee77
 */

class Standard
{
    //
    private $totalScore = 0;
    //
    private $standard = [];
    //
    private $answer = [];
    //
    private $getScore = 0;

    public function __construct($totalScore)
    {
        $this->setTotalScore($totalScore);
    }

    /**
     * @return int
     */
    public function getTotalScore()
    {
        return $this->totalScore;
    }

    /**
     * @param int $totalScore
     */
    public function setTotalScore($totalScore)
    {
        $this->totalScore = $totalScore;
    }


    /**
     * @param array $standard
     */
    public function setStandard($standard)
    {
        $this->standard = $standard;
    }

    /**
     * @return array
     */
    public function getStandard()
    {
        return $this->standard;
    }

    /**
     * @param $answer
     */
    public function checkStandard()
    {
        foreach ($this->answer as $each) {
            if (!$weight = $this->checkAnswer($each)) {
                //0
                $this->setGetScore(0);
                break;
            }
            //
            $this->appendGetScore($this->getTotalScore() * $weight);
        }
    }

    /**
     * @param array $answer
     */
    public function setAnswer($answer)
    {
        $this->answer = $answer;
    }

    /**
     * @return array
     */
    public function getAnswer()
    {
        return $this->answer;
    }

    /**
     * @param $each
     * return $weight
     */
    private function checkAnswer($each)
    {
        return array_key_exists($each, $this->standard) ? $this->standard[$each] : 0;
    }

    /**
     * @param int $getScore
     */
    public function setGetScore($score)
    {
        $this->getScore = $score;
    }

    /**
     * @return int
     */
    public function getGetScore()
    {
        return $this->getScore;
    }

    /**
     * @param int $totalScore
     */
    public function appendGetScore($appendScore)
    {
        $this->getScore += $appendScore;
    }


}

//CHECK
$std = new Standard(10);
//
$std->setStandard(['A' => 0.2, 'B' => 0.4, 'C' => 0.4]);
//
$std->setAnswer(['A', 'B']);
//
$std->checkStandard();
//
$totalScore = $std->getTotalScore();
echo $totalScore;

function check_score(array $answer, array $correct, $total_score){
    $answer=array_flip($answer);
    $check=array_intersect_key($correct, $answer);
    return in_array($check, 0) ? 0 : array_sum($ckeck)*$total_score;
}

$answer is an array of answers ( ['A','B','C'] )

$correct is the array of correct answers ( ['Awareness = > 0.2,' margin = > 0.4, 'code = > 0] )

$total_score is the total score

first flip $answer so that the option becomes key ( ['Aids = > 0,' breadth = > 1, 'accounts = > 2] )

then calculates the intersection of $correct and $answer according to key $check , and the key and value of $check both keep $correct .

check whether there is 0 in the value of $check , and return 0 if there is an incorrect answer. Otherwise, calculate the sum of the value of $check and multiply it by the total score.

Menu