各位資訊老師們,期末考週又到了,你是否正面臨這樣的惡夢?
看著電腦資料夾裡躺著 300 個 .sb3 檔案(全校五年級生每人交一份),你必須一個一個點開、等待 Scratch 讀取、按下綠旗檢查、然後打分數。假設一個檔案花 3 分鐘,改完這些作業需要整整 15 個小時!
「有沒有辦法像改考卷一樣,機器掃過去分數就出來了?」
答案是有的!今天這篇文章就要教大家一個 「黑科技」:利用 Python 腳本,不用打開 Scratch 編輯器,就能在幾秒鐘內「透視」學生的作業結構,並自動產生成績報表。
原理大解密:.sb3 其實就是 ZIP 檔
首先,我們要了解 Scratch 3.0 的存檔格式。雖然副檔名是 .sb3,但它本質上是一個 ZIP 壓縮檔。
如果你把 .sb3 改名為 .zip 並解壓縮,你會發現裡面有一個核心檔案叫做 project.json。這個 JSON 檔紀錄了所有的程式積木(Blocks)、角色(Sprites)、變數與邏輯。
因此,我們不需要打開圖形化介面,只需要寫一個小程式去讀取這個 project.json,算出「積木總數」和「角色數量」,就能初步判斷這份作業的豐富度與完成度。
實作教學:Python 自動評分腳本
不需要很高深的程式技巧,請跟著以下步驟操作:
- 環境準備:請確保你的電腦已安裝 Python 以及 Pandas 套件。
(在終端機輸入pip install pandas即可安裝) - 準備腳本:請複製以下的程式碼,並存檔為
grade_scratch.py。 - 執行:將這個
.py檔放在跟學生作業(一堆 .sb3 檔案)同一個資料夾中,點兩下執行。
import os
import zipfile
import json
import pandas as pd
# --- 設定評分標準區域 ---
def calculate_score(data):
"""
這裡可以依照老師的需求修改評分邏輯
"""
score = 60 # 基本分:只要交作業就有60分
# 1. 努力度:根據積木數量加分 (每10個積木+1分,上限20分)
score += min(data['block_count'] // 10, 20)
# 2. 豐富度:角色數量 (每個角色+2分,上限10分)
score += min(data['sprite_count'] * 2, 10)
# 3. 邏輯運用:有無使用特定功能 (各加5分)
if data['has_loop']: score += 5
if data['has_variable']: score += 5
# 滿分不超過100
return min(score, 100)
def analyze_sb3(filename):
try:
# 嘗試將 sb3 當作 zip 讀取
with zipfile.ZipFile(filename, 'r') as z:
# 讀取核心檔案 project.json
with z.open('project.json') as f:
project_data = json.load(f)
targets = project_data.get('targets', [])
# 扣除舞台(Stage),剩下的就是角色數量
sprite_count = len(targets) - 1
block_count = 0
has_loop = False
has_variable = False
# 掃描所有角色與舞台的程式碼
for target in targets:
blocks = target.get('blocks', {})
block_count += len(blocks)
# 檢查每個積木的種類 (OpCode)
for block_id, block in blocks.items():
if isinstance(block, dict):
opcode = block.get('opcode', '')
# 檢查是否包含重複迴圈
if 'control_repeat' in opcode or 'control_forever' in opcode:
has_loop = True
# 檢查是否包含變數操作
if 'data_setvariableto' in opcode or 'data_changevariableby' in opcode:
has_variable = True
return {
'檔名': filename,
'角色數': sprite_count,
'積木總數': block_count,
'使用迴圈': '是' if has_loop else '否',
'使用變數': '是' if has_variable else '否',
'has_loop': has_loop, # 供計算用
'has_variable': has_variable # 供計算用
}
except Exception as e:
return {'檔名': filename, '備註': f'讀取錯誤: {str(e)}'}
# --- 主程式開始 ---
files = [f for f in os.listdir('.') if f.endswith('.sb3')]
results = []
print(f"找到 {len(files)} 個作業,開始批改...")
for file in files:
data = analyze_sb3(file)
if '備註' not in data:
data['預估分數'] = calculate_score(data)
results.append(data)
# 輸出成 Excel (CSV格式)
output_file = 'Scratch作業成績單.csv'
df = pd.DataFrame(results)
# 移除計算用的欄位,只留給老師看的
if 'has_loop' in df.columns: del df['has_loop']
if 'has_variable' in df.columns: del df['has_variable']
df.to_csv(output_file, index=False, encoding='utf-8-sig')
print(f"完成!已輸出 '{output_file}',請用 Excel 開啟。")
這樣做有什麼優缺點?
雖然自動化很迷人,但身為教育者,我們必須誠實面對工具的限制。這套方法不是完美的,請務必了解以下幾點:
⭕ 優點
- 極速效率:幾百個檔案只需 3-5 秒,這在期末結算成績時是救命稻草。
- 檔名檢核:一眼就能在 Excel 表中看出誰亂存檔名(例如沒寫班級座號)。
- 找出缺交/低完成度:積木數只有 0 或 個位數的,通常就是只開了檔案沒做作業。
❌ 缺點(盲點)
- 無法判斷美感與創意:程式只看得懂「數量」。A同學畫了精美的自創角色但程式簡單,B同學拉了一堆亂七八糟的積木,程式可能會判 B 比較高分。
- 無法偵測 Bug:學生如果寫了「無限迴圈」導致當機,或是程式邏輯根本跑不動,腳本是看不出來的。
- 未組裝積木也算分:如果學生把積木拉出來丟在旁邊沒有組裝,腳本依然會計算數量。
老師建議的最佳使用策略:混合式評分法
建議的 SOP 如下:
-
Step 1. 跑腳本 (佔總分 60%)
利用程式快速篩出「努力程度」。積木多、角色多,基本分就有。 -
Step 2. 抓頭尾 (人工複查)
打開 Excel 表:檢查低分群(確認是否沒做)與高分群(抽查前 5 名給予嘉獎)。 -
Step 3. 看檔名
利用 Excel 排序,快速找出檔名不符規範的同學。
科技來自於人性,也來自於想早點下班的老師們(笑)。希望這個小工具能幫助各位資訊老師從改作業的地獄中解脫出來,把時間花在更有意義的課程設計上!
免責聲明:
本文所提供的程式碼與教學僅供學習與參考之用。實際評分標準應依據教學現場狀況進行調整,作者不對因使用本程式碼而導致的成績計算錯誤或檔案損毀負擔任何責任。請在執行前務必備份原始作業檔案。
本文所提供的程式碼與教學僅供學習與參考之用。實際評分標準應依據教學現場狀況進行調整,作者不對因使用本程式碼而導致的成績計算錯誤或檔案損毀負擔任何責任。請在執行前務必備份原始作業檔案。
文章標籤
全站熱搜
