建置紀錄與疑難排解

這份是給老師的

記錄整個過程碰到的問題、原因、解法,以及最終的檔案結構。
給同學的版本是桌面上的 ITS-Python-給同學.zip,裡面不含這份。


🧩 碰到的問題與解法

1. PDF 讀不出文字(掃描檔)

症狀2024 ITS PYTHON 出85趴.pdf 擷取出來是亂碼;轉成圖片後整頁全黑或反白
原因這是 MRC 分層壓縮掃描檔(背景層 + JBIG2 遮罩前景層),一般工具只取到單一圖層
解法改用 PyMuPDF 整頁重新渲染(會自動合成三層),61 頁才完整讀出
備註另一份 PYTHON_202412_OK_15趴.pdf 是純文字 PDF,直接擷取即可

2. 課本解答表有 7 處印錯

來源python修正.txt
影響照課本背會直接失分
解法整理成勘誤表,並加上「課本頁碼 ↔ PDF 頁數」對照 → 01-模擬題庫解答與勘誤速查
注意其中 CH06 第 6 題 (B) 是真爭議題,官方答 Yes 但實際執行會回傳 1000。文件裡兩邊論據都寫了

3. 筆記出現 Dataview 紅字錯誤

症狀`==` 的地方跑出 PARSING FAILED 大紅字
原因Dataview 的「行內查詢」前綴預設是 =,反引號包住以 = 開頭的字就會被當成查詢
範圍全 vault 25 處、8 個檔案(不只 ITS 資料夾)
解法改 Dataview 前綴:inlineQueryPrefix= 改成 dv=(先確認過 vault 內 0 條行內查詢,無副作用)
教訓Python 的 == 運算子跟 Dataview 前綴撞號,這是巧合但會一直復發

4. 改了設定檔卻沒生效

症狀data.json 明明改好了,畫面還是舊行為
原因Obsidian 執行中,記憶體裡是舊設定;而且它關閉時會把記憶體內容寫回檔案,蓋掉外部修改
證據設定檔寫入 22:29,但 Obsidian 程序 19:13 就啟動了
解法一律在 UI 裡改設定。真要改檔案,必須先完全關閉 Obsidian

5. 說明文字被誤判成閃卡

症狀07-填空打字卡(自動比對) 開頭的說明區塊自己長出 <!--SR:...--> 排程註解
原因說明裡寫了字面上的大括號範例,被外掛當成填空題
解法說明文字改用「大括號」中文描述,不寫實際符號;並刪掉誤產生的排程註解
通則在有 #flashcards 標籤的檔案裡,不要寫出填空語法的實際符號

6. 找不到「Convert cloze patterns to input fields」

症狀在「卡片」設定頁翻遍了都找不到
原因這一項屬於 UIPreferencesPage,在「User Interface」分頁,不在「卡片」分頁
加重該字串沒有繁中翻譯,在中文介面裡仍顯示英文,更難找
解法分頁位置與中文對應寫進 06-閃卡使用說明

7. 高亮語法不能當填空符號

原因外掛預設 convertHighlightsToClozes = true,會把 ==...== 當填空。但 Python 教材滿是 == 比較運算子,會大量誤判
解法關閉高亮、改用大括號語法(convertCurlyBracketsToClozes = true
附帶粗體那項也必須保持關閉 —— 講義答案大量使用粗體,開了會產生上百張垃圾卡

8. 速查表列印溢頁、表格被切斷

原因03-考前速查表(A4列印用) 內容持續增補,早已超出原訂 2 頁(實測約 4.5 頁),且分頁點隨機落下,會把「檔案模式」等對照表切成兩半
解法① 壓縮兩處冗餘表格(math 函式、try/finally 規則)改為單行條列,省約 16 行;② 插入 <div style="page-break-after: always;"></div> 固定分頁點,四頁份量配平(57.5/55.2/60.4/47.4 行當量)
通則標榜「可列印」的文件每次增補後都要重估頁數,並用固定分頁點保護表格不被切斷

9. 發放包出現資料夾自我巢狀

症狀zip 從 1.18 MB 暴增為 2.37 MB、檔案數 30 → 73
原因打包腳本重跑時,make_archive 把已存在的輸出資料夾又收進自己裡面(ITS-Python-給同學/ITS-Python-給同學/),所有檔案被收錄兩次
解法壓縮前先刪除巢狀層與舊 zip 再重壓
通則重新打包前一律先清空輸出目標;壓完用 zipfile.namelist() 檢查有無重複路徑

10. 內容技術查核(全 3147 行逐條實測)

用 Python 3.14 實際執行所有可驗證的斷言(型態、切片、隨機範圍、例外型別、格式化輸出、追蹤題輸出行數),共抓到 2 個實質錯誤

錯誤根因影響檔案
A優先序表把 not 放在 +x -x 那一層,並標為「反位元」混淆了 not(邏輯否定)與 ~(位元反轉)。not 的優先序其實低於比較運算子00 / 03 / 04 / 05
B'{:%B-%d-%y}' 標為輸出 APRIL-07-17%B 實際回傳 April(首字大寫)。官方選項印成全大寫00 / 02 / 04 / 05

A 的驗證方式(AST 最直接):

import ast
ast.dump(ast.parse('not a == b', mode='eval').body)
# UnaryOp(op=Not(), operand=Compare(...))  → not 包住整個比較,故優先序較低
a, b = 2, True
not a == b      # True   ← 實際
(not a) == b    # False  ← 若照原表理解會得到的錯誤結果

B 的處理:官方答案保留(考試仍選該選項),但四份文件都加註「實際輸出是 April-07-17」,避免同學誤記 %B 會給全大寫。

查核通過:切片六種寫法、randint/randrange 五組邊界、math 三函式、七種例外型別、format/% 格式規格、追蹤題輸出行數、字串與清單方法存在性、os.path.existfile.add 等干擾項確認不存在。

一則易混點(非錯誤)

教材 CH05-17 是 if grade <= 100:,新題 Q16 是 if grade < 100: —— 兩題確實不同(已回頭調原始 PDF 逐字比對)。已在 02-2024新增考題重點解析 加註,避免抄筆記時互相污染。


✅ 最終成果

檔案清單

檔案內容對象
00-ITS Python 考照重點總整理CH01–08 觀念、對照表、必考陷阱、速記卡主講義
01-模擬題庫解答與勘誤速查全部答案 + 7 處勘誤 + 頁碼對照訂正課本
02-2024新增考題重點解析新題 44 題逐題解析新題型
03-考前速查表(A4列印用)濃縮 4 頁(雙面 2 張)列印發放
04-易錯題自我測驗卡46 張摺疊問答自我檢測
05-SR閃卡-ITS Python47 張問答閃卡每日複習
06-閃卡使用說明安裝 + 操作完整教學發給同學
07-填空打字卡(自動比對)48 張打字填空卡練精確記憶
本檔建置紀錄老師留存(不發放)
09-同學安裝步驟(A4列印)一頁式安裝步驟課堂列印發放

閃卡總數:95 張

牌組張數型態
ITS-Python(6 個子牌組)47問答,自己想答案
ITS-Python-填空(6 個子牌組)48打字,自動比對對錯

環境設定

Dataview

inlineQueryPrefix   = "dv="
inlineJsQueryPrefix = "dv$="

Spaced Repetition 1.15.4

convertClozePatternsToInputs = true    ← User Interface 分頁
convertCurlyBracketsToClozes = true    ← 卡片分頁
convertHighlightsToClozes    = false   ← 必須關(Python 的 == )
convertBoldTextToClozes      = false   ← 必須關(講義大量粗體)

📤 發給同學

桌面上已產生:

C:\Users\allen\Desktop\ITS-Python-給同學.zip   (1.07 MB,25 個檔案)

包含:9 份 .md(00–07 + 09 列印版)、10 張說明用截圖、外掛本體三個檔、設定範本 data.jsonpython修正.txt、獨立的 00-請先讀我.md 安裝指南。

不包含:本檔(08 建置紀錄)為老師專用,已排除。

已處理

  • ✅ 清除 5 筆老師個人的複習排程紀錄(同學從零開始)
  • ✅ 剔除 5 張未被任何筆記引用的孤兒截圖(1.18 → 1.07 MB)
  • ✅ 附上調好的 data.json,同學不必自己摸設定
  • ⚠️ 未收錄兩份 PDF(教材掃描檔,版權考量)—— 要不要放請自行決定

發放方式:直接給 zip 檔即可(LINE 群組 / Google Drive / USB 皆可)。同學照 00-請先讀我.md 操作,約 10 分鐘完成。


🔄 之後要更新卡片時

  1. 直接編輯 05-SR閃卡-ITS Python07-填空打字卡(自動比對)
  2. 卡片之間空一行,卡片內部不可有空行
  3. 不要動句尾的 <!--SR:...-->(那是排程紀錄)

每次重新發放前一定要做這一步

只要老師自己複習過卡片,排程註解就會重新長回來。 這不是一次性清乾淨就沒事的 —— 本次重新打包時就又出現了 5 筆(05 一筆、07 四筆)。
忘記清的話,同學一打開會看到某些卡片「已排到 8/21」而不出現,還以為裝壞了。

清除方式(只改發放包,不要動 vault 原檔):

import re
PAT = re.compile(r'[ \t]*<!--SR:!\d{4}-\d{2}-\d{2},\d+,\d+-->[ \t]*\n?')
# 對發放包內每個 .md 做 PAT.subn('', text)

註:只比對「! + 日期」格式,這樣 06 說明檔裡當範例用的 <!--SR:!...--> 文字不會被誤刪。


🔗 06-閃卡使用說明 00-ITS Python 考照重點總整理