L
L
Lev Rozanov2020-04-17 21:00:13
PHP
Lev Rozanov, 2020-04-17 21:00:13

How to take into account questions that were not answered in the cycle?

Good day!

The code:

$answer = [
    1 => [2,3,4,5,52],
    2 => [7,8,9,52],
    3 => [10,11,12,25],
  ];

  $bd = [
    [
      'id' => 2,
      'id_question' => 1,
      'correct_answer' => 1,
    ],
    [
      'id' => 3,
      'id_question' => 1,
      'correct_answer' => 1,
    ],
    [
      'id' => 4,
      'id_question' => 1,
      'correct_answer' => 1,
    ],
    [
      'id' => 5,
      'id_question' => 1,
      'correct_answer' => 1,
    ],
    
    
    [
      'id' => 7,
      'id_question' => 2,
      'correct_answer' => 1,
    ],
    [
      'id' => 8,
      'id_question' => 2,
      'correct_answer' => 1,
    ],
    [
      'id' => 9,
      'id_question' => 2,
      'correct_answer' => 1,
    ],
    
    
    [
      'id' => 10,
      'id_question' => 3,
      'correct_answer' => 1,
    ],
    [
      'id' => 11,
      'id_question' => 3,
      'correct_answer' => 1,
    ],
    [
      'id' => 12,
      'id_question' => 3,
      'correct_answer' => 1,
    ],
    
    [
      'id' => 13,
      'id_question' => 4,
      'correct_answer' => 1,
    ],
    [
      'id' => 14,
      'id_question' => 4,
      'correct_answer' => 1,
    ],
    [
      'id' => 15,
      'id_question' => 4,
      'correct_answer' => 1,
    ],
  ];


  $quests = [];
  foreach ($bd as $bd_element) {
    $quests[$bd_element['id_question']][] = $bd_element['id'];
  }
  

  $a = 0;
  foreach ($quests as $id_quest => $ans) {
    $is = true;
    echo '<br><br>Вопрос: №'.$id_quest.'<br>';

    foreach ($ans as $an) {
      if (array_search($an, $answer[$id_quest]) === false) $is = false;
      echo 'Правильные ответы: '.$an.'<br>';
    }
    
    foreach ($answer[$id_quest] as $answer_give) {
      if (array_search($answer_give, $ans) === false) $is = false;
      echo 'Дан ответ: '.$answer_give.'<br>';
    }

  if ($is) $a++;
  }

  echo '<br><br>Правильных ответов: '.$a.'<br>';


Questions are being processed. A question can have multiple answers.
The code should:
- take into account only the correct answers
- if not all correct answers are selected - do not count the answer
- if correct and incorrect answers are selected - count the answer
- if there was no answer to the question - do not count the answer.

In the code above, all items work, except for taking into account questions that have not been answered.
Those. in the example there are 4 questions that were not answered, but the loop considers it as correct.
I can't find where to fix it.

Thanks in advance!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Maksim Fedorov, 2020-04-17
@MetisKot

$allAnswers = [
    1 => [2,3,4,5],      // верный, тк даны только верные ответы
    2 => [7,8,9,52],     // не верный, дан неверный 52
    3 => [10,11,12,25],  // не верный, дан неверный 25
    4 => [13],           // не верный, тк пропущены верные ответы 14 и 15
];
$dbAnswers = [
     // данные из БД
];

/** 
 *  Группирует любой массив  по любому полю $indexKey в качестве индекса, 
 *  и $columnKey в качестве группируемых значений
 */
function groupBy(array $input, string $indexKey, string $columnKey): array
{
    return array_reduce($input,  function($res, $data) use ($indexKey, $columnKey){
        if (!isset($data[$indexKey], $data[$columnKey])) {
             return $res;
        }
        
        $res[$data[$indexKey]][] = $data[$columnKey];
            
        return $res;
    }, []);
}

/** 
 *  Маппинг введенных ответов с верными ответами по каждому вопросу
 */
function computeAnswersResult(array $inputAnswers, array $questionsWithCorrectAnswers): array
{
    $correctAnswers = $questionsWithCorrectAnswers[$questIn] ?? [];

    $result = [];
    foreach($inputAnswers as $questIn => $answesrIn) {
        $errors = array_diff($answesrIn, $correctAnswers);
        $corrects = array_diff($answesrIn, $errors); // если бы не нужно было выводить, то код сильно бы сократился
        $correctDiff = array_diff($correctAnswers, $corrects);
    
        // Если нет лишних ответов и число  введенных верных ответов 
        // совпадает с числом верных в БД, то статус положительный
        $completed = \count($errors) === 0 && \count($correctDiff) === 0;
    
        $result[$questIn] = [
            'errors'    => $errors,
            'corrects'  => $corrects,
            'completed' => $completed,
        ];
    }
    
    return $result;
}

// Группируем верные ответы по каждому вопросу
$questionsWithCorrectAnswers = groupBy($dbAnswers, 'id_question', 'id');
// Маппим введенные ответы на правильные и получаем результат
$result = computeAnswersResult($allAnswers, $questionsWithCorrectAnswers);
// Посчитаем успешные
$completedCount = \count(
    array_filter($result, function($answer) {
        return $answer['completed'] ?? false;
    })
);

//  ОТОБРАЖЕНИЕ       
$html = '';
foreach ($result as $questId => $details) {
    $status = $details['completed'] ? 'верный' : 'не верный';
    
    $html .= 'Вопрос №:' . $questId . PHP_EOL;
    $html .= 'Правильные ответы: '  . implode(', ', $details['corrects']) . PHP_EOL;
    $html .= 'Результат вопроса: '  . $status . PHP_EOL;
    $html .= '-------------------'  .  PHP_EOL;
}
$html .= 'Всего верных: ' . $completedCount;

echo $html;

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question