242 lines
8.4 KiB
PHP
242 lines
8.4 KiB
PHP
<?php
|
|
// manual_result_profile.php
|
|
// Place/replace this file in: C:\xampp\htdocs\rs_lab\manual_result_profile.php
|
|
|
|
require_once __DIR__ . '/config.php';
|
|
if (session_status() === PHP_SESSION_NONE) session_start();
|
|
|
|
// simple auth guard (teacher/admin must be logged in)
|
|
if (empty($_SESSION['user_id'])) {
|
|
header('Location: login.php');
|
|
exit;
|
|
}
|
|
|
|
// Validate answer_id param
|
|
if (!isset($_GET['answer_id']) || !ctype_digit($_GET['answer_id'])) {
|
|
echo "Invalid request.";
|
|
exit;
|
|
}
|
|
$answerId = (int)$_GET['answer_id'];
|
|
|
|
// Fetch manual_answers row + quiz info
|
|
$stmt = $conn->prepare("SELECT ma.*, mq.quiz_name, mq.class_name, mq.total_questions
|
|
FROM manual_answers ma
|
|
JOIN manual_quizzes mq ON mq.id = ma.quiz_id
|
|
WHERE ma.id = ? LIMIT 1");
|
|
$stmt->bind_param('i', $answerId);
|
|
$stmt->execute();
|
|
$row = $stmt->get_result()->fetch_assoc();
|
|
$stmt->close();
|
|
|
|
if (!$row) {
|
|
echo "Record not found.";
|
|
exit;
|
|
}
|
|
|
|
// Prepare answers array and normalize
|
|
$studentAnswers = array_map('trim', explode(',', $row['answers'])); // may contain '' for blanks
|
|
$totalQuestions = (int)$row['total_questions'];
|
|
for ($i = count($studentAnswers); $i < $totalQuestions; $i++) $studentAnswers[] = '';
|
|
|
|
// METRICS (no key, no marks)
|
|
$attempted = 0;
|
|
$blanks = 0;
|
|
$optionCounts = ['A'=>0,'B'=>0,'C'=>0,'D'=>0];
|
|
$streaksBlank = [];
|
|
$streaksSame = [];
|
|
$curBlank = 0; $curBlankStart = null;
|
|
$curSame = 0; $curSameStart = null;
|
|
$lastOption = null;
|
|
|
|
for ($i = 0; $i < $totalQuestions; $i++) {
|
|
$s = isset($studentAnswers[$i]) ? strtoupper($studentAnswers[$i]) : '';
|
|
if ($s === '') {
|
|
$blanks++;
|
|
if ($curBlank === 0) $curBlankStart = $i+1;
|
|
$curBlank++;
|
|
if ($curSame > 0) {
|
|
$streaksSame[] = ['start'=>$curSameStart,'length'=>$curSame,'option'=>$lastOption];
|
|
$curSame = 0; $curSameStart = null;
|
|
}
|
|
} else {
|
|
$attempted++;
|
|
if (isset($optionCounts[$s])) $optionCounts[$s]++;
|
|
if ($s === $lastOption) {
|
|
if ($curSame === 0) $curSameStart = $i; // start index 0-based
|
|
$curSame++;
|
|
} else {
|
|
if ($curSame > 0) {
|
|
$streaksSame[] = ['start'=>$curSameStart+1,'length'=>$curSame,'option'=>$lastOption];
|
|
}
|
|
$curSame = 1;
|
|
$curSameStart = $i;
|
|
}
|
|
if ($curBlank > 0) {
|
|
$streaksBlank[] = ['start'=>$curBlankStart,'length'=>$curBlank];
|
|
$curBlank = 0; $curBlankStart = null;
|
|
}
|
|
$lastOption = $s;
|
|
}
|
|
}
|
|
if ($curBlank > 0) $streaksBlank[] = ['start'=>$curBlankStart,'length'=>$curBlank];
|
|
if ($curSame > 0) $streaksSame[] = ['start'=>$curSameStart+1,'length'=>$curSame,'option'=>$lastOption];
|
|
|
|
// basic dispersion: if one option dominates >60% of attempts -> likely guessing or habit
|
|
$dominantOption = null;
|
|
foreach ($optionCounts as $opt => $count) {
|
|
if ($attempted > 0 && ($count / $attempted) > 0.6) {
|
|
$dominantOption = $opt; break;
|
|
}
|
|
}
|
|
|
|
// Compose patterns (heuristics)
|
|
$patterns = [];
|
|
|
|
if ($blanks >= max(3, round($totalQuestions * 0.15))) {
|
|
$patterns[] = "Leaves several questions blank — may be cautious, unsure, or facing time-management issues.";
|
|
}
|
|
if ($dominantOption) {
|
|
$patterns[] = "High repetition of option '{$dominantOption}' across attempts — possible guessing or strong bias for a particular letter.";
|
|
}
|
|
foreach ($streaksSame as $st) {
|
|
if ($st['length'] >= 4) {
|
|
$patterns[] = "Repeated same answer from Q{$st['start']} for {$st['length']} questions — may be guess pattern or misread instructions.";
|
|
}
|
|
}
|
|
foreach ($streaksBlank as $st) {
|
|
if ($st['length'] >= 3) {
|
|
$patterns[] = "Left consecutive blanks from Q{$st['start']} (length {$st['length']}) — suggests uncertainty or a topic block.";
|
|
}
|
|
}
|
|
|
|
// attempt distribution patterns
|
|
$firstHalfAttempt = 0; $secondHalfAttempt = 0;
|
|
for ($i = 0; $i < $totalQuestions; $i++) {
|
|
if ($i < $totalQuestions/2) {
|
|
if ($studentAnswers[$i] !== '') $firstHalfAttempt++;
|
|
} else {
|
|
if ($studentAnswers[$i] !== '') $secondHalfAttempt++;
|
|
}
|
|
}
|
|
if ($firstHalfAttempt > $secondHalfAttempt + 2) {
|
|
$patterns[] = "Stronger start, fewer attempts later — may lose focus or face time pressure towards the end.";
|
|
} elseif ($secondHalfAttempt > $firstHalfAttempt + 2) {
|
|
$patterns[] = "Fewer attempts initially and stronger finish — may be cautious first then gain confidence.";
|
|
}
|
|
if (empty($patterns)) {
|
|
$patterns[] = "Consistent attempt behaviour detected; no strong negative signals from this single test.";
|
|
}
|
|
|
|
// Pick a friendly learning style label
|
|
$learningStyle = '';
|
|
if ($blanks >= round($totalQuestions * 0.25)) {
|
|
$learningStyle = 'Cautious & Reflective';
|
|
} elseif ($dominantOption) {
|
|
$learningStyle = 'Guess-Prone / Pattern-based';
|
|
} elseif ($firstHalfAttempt > $secondHalfAttempt + 2) {
|
|
$learningStyle = 'Strong Starter';
|
|
} elseif ($secondHalfAttempt > $firstHalfAttempt + 2) {
|
|
$learningStyle = 'Strong Finisher';
|
|
} else {
|
|
$learningStyle = 'Balanced Attempt Style';
|
|
}
|
|
|
|
// Weak hints: use blank & streak positions as "weak ranges"
|
|
$weakHints = [];
|
|
foreach ($streaksBlank as $s) {
|
|
if ($s['length'] >= 2) $weakHints[] = "Weak zone: Q{$s['start']} - Q" . ($s['start'] + $s['length'] - 1);
|
|
}
|
|
if (empty($weakHints) && !empty($streaksSame)) {
|
|
foreach ($streaksSame as $s) {
|
|
if ($s['length'] >= 4) $weakHints[] = "Review section near Q{$s['start']} - Q" . ($s['start'] + $s['length'] - 1);
|
|
}
|
|
}
|
|
if (empty($weakHints)) $weakHints[] = "No clear weak zone found in this single attempt.";
|
|
|
|
// Render page
|
|
include __DIR__ . '/includes/header.php';
|
|
?>
|
|
|
|
<div class="row mt-4">
|
|
<div class="col-12 mb-2">
|
|
<a href="manual_mode_setup.php" class="small">← Back to Quizzes</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4">
|
|
<div class="col-lg-6">
|
|
<div class="card mb-3">
|
|
<div class="card-body">
|
|
<h5 class="mb-1">Result Profile — <?php echo htmlspecialchars($row['student_name']); ?></h5>
|
|
<p class="text-muted small mb-2">
|
|
Quiz: <strong><?php echo htmlspecialchars($row['quiz_name']); ?></strong>
|
|
· Class: <?php echo htmlspecialchars($row['class_name']); ?>
|
|
</p>
|
|
|
|
<table class="table table-sm">
|
|
<tr><th>Total Questions</th><td><?php echo $totalQuestions; ?></td></tr>
|
|
<tr><th>Attempted</th><td><?php echo $attempted; ?></td></tr>
|
|
<tr><th>Left Blank</th><td><?php echo $blanks; ?></td></tr>
|
|
</table>
|
|
|
|
<h6 class="mt-3">Learning Style</h6>
|
|
<p><strong><?php echo htmlspecialchars($learningStyle); ?></strong></p>
|
|
|
|
<h6 class="mt-2">Silent Skill Insights</h6>
|
|
<ul>
|
|
<?php foreach ($patterns as $p): ?>
|
|
<li class="small text-muted"><?php echo htmlspecialchars($p); ?></li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
|
|
<h6 class="mt-2">Weak Hints</h6>
|
|
<?php if (!empty($weakHints)): ?>
|
|
<ul>
|
|
<?php foreach ($weakHints as $h): ?>
|
|
<li class="small text-muted"><?php echo htmlspecialchars($h); ?></li>
|
|
<?php endforeach; ?>
|
|
</ul>
|
|
<?php endif; ?>
|
|
|
|
<div class="mt-3 d-flex gap-2">
|
|
<a href="generate_passport_pdf.php?answer_id=<?php echo $answerId; ?>" class="btn btn-primary btn-sm">Download Learning Passport (PDF)</a>
|
|
<a href="manual_enter_answers.php?quiz_id=<?php echo (int)$row['quiz_id']; ?>" class="btn btn-outline-secondary btn-sm">Back to Enter Answers</a>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-6">
|
|
<div class="card h-100">
|
|
<div class="card-body">
|
|
<h6>Question-wise view (Student choices)</h6>
|
|
<div class="small text-muted mb-2">This view shows student-selected options only (no correct key required).</div>
|
|
<div style="max-height:420px; overflow:auto;">
|
|
<table class="table table-sm">
|
|
<thead>
|
|
<tr><th>Q</th><th>Student Choice</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php for ($i=0;$i<$totalQuestions;$i++):
|
|
$q = $i+1;
|
|
$s = isset($studentAnswers[$i]) ? strtoupper($studentAnswers[$i]) : '';
|
|
?>
|
|
<tr>
|
|
<td><?php echo $q; ?></td>
|
|
<td><?php echo $s ?: '<span class="text-muted">Blank</span>'; ?></td>
|
|
</tr>
|
|
<?php endfor; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php
|
|
include __DIR__ . '/includes/footer.php';
|
|
?>
|