36459-vm/manual_result_profile.php
2026-05-27 14:29:58 +05:30

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">&larr; 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>
&middot; 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';
?>