學生成績系統、綜合評價模型常需計算加權平均分。本文提供完整的三頁式實現:課程數輸入 → 成績權重錄入 → 結果展示,涵蓋 Session 狀態管理與數據驗證。
<form action="step2.php" method="post">
課程數量: <input type="number" name="course_number" min="1" max="50" required>
<button type="submit">下一步</button>
</form>
<?php
session_start();
$n = (int)($_POST['course_number'] ?? 0);
if ($n < 1 || $n > 50) die('課程數量異常');
$_SESSION['course_number'] = $n;
?>
<form action="result.php" method="post">
<?php for ($i = 0; $i < $n; $i++): ?>
<div class="course-row">
<label>課程 :</label>
<input type="number" name="score[]" step="0.1" min="0" max="100" placeholder="分數" required>
<input type="number" name="credit[]" step="0.1" min="0" max="10" placeholder="學分/權重" required>
</div>
<?php endfor; ?>
<button type="submit">計算加權平均</button>
</form>
<?php
session_start();
$n = $_SESSION['course_number'] ?? 0;
$scores = $_POST['score'] ?? [];
$credits = $_POST['credit'] ?? [];
if (count($scores) !== $n || count($credits) !== $n) {
die('數據不完整,請重新提交');
}
$totalWeight = 0;
$weightedSum = 0;
for ($i = 0; $i < $n; $i++) {
$score = (float)$scores[$i];
$credit = (float)$credits[$i];
// 基礎驗證
if ($score < 0 || $score > 100) die("第 {$i+1} 門課分數超出範圍");
if ($credit <= 0) die("第 {$i+1} 門課學分必須大於 0");
$weightedSum += $score * $credit;
$totalWeight += $credit;
}
$gpa = $totalWeight > 0 ? round($weightedSum / $totalWeight, 2) : 0;
?>
<h2>計算結果</h2>
<table>
<tr><th>課程</th><th>分數</th><th>權重</th><th>加權分</th></tr>
<?php for ($i = 0; $i < $n; $i++):
$w = round($scores[$i] * $credits[$i], 2);
?>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<?php endfor; ?>
<tr class="total">
<td colspan="2">總計</td>
<td></td>
<td></td>
</tr>
</table>
<h3>加權平均分: <strong></strong></h3>
<a href="index.php">重新計算</a>
function calculateWeightedAverage(array $scores, array $credits): float {
if (count($scores) !== count($credits)) {
throw new InvalidArgumentException('分數與權重數量不匹配');
}
$sum = 0;
$totalWeight = 0;
foreach ($scores as $i => $score) {
$weight = $credits[$i];
if ($weight <= 0) continue; // 或拋出異常
$sum += $score * $weight;
$totalWeight += $weight;
}
return $totalWeight > 0 ? $sum / $totalWeight : 0;
}
function scoreToGradePoint(float $score): float {
if ($score >= 90) return 4.0;
if ($score >= 85) return 3.7;
if ($score >= 82) return 3.3;
if ($score >= 78) return 3.0;
if ($score >= 75) return 2.7;
if ($score >= 72) return 2.3;
if ($score >= 68) return 2.0;
if ($score >= 64) return 1.5;
if ($score >= 60) return 1.0;
return 0.0;
}
class GPACalculator {
private array $courses = [];
public function addCourse(string $name, float $score, float $credit, string $semester): self {
$this->courses[] = compact('name', 'score', 'credit', 'semester');
return $this;
}
public function getGPA(?string $semester = null): float {
$filtered = $semester
? array_filter($this->courses, fn($c) => $c['semester'] === $semester)
: $this->courses;
return calculateWeightedAverage(
array_column($filtered, 'score'),
array_column($filtered, 'credit')
);
}
public function getReport(): array {
$semesters = array_unique(array_column($this->courses, 'semester'));
return array_map(fn($s) => [
'semester' => $s,
'gpa' => $this->getGPA($s),
'credits' => array_sum(array_filter($this->courses, fn($c) => $c['semester'] === $s))
], $semesters);
}
}
input[type=number] step="0.1" 支持小數oninput="updateWeighted(this)"localStorage 防止誤刷新丟失這套方案結構清晰,易於擴展為完整的教務管理子系統。