dsh-aha-tutor 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "format": "aha-tutor.coursepack",
3
3
  "version": 1,
4
- "exportedAt": "2026-10-19T05:41:04.608Z",
4
+ "exportedAt": "2026-10-22T07:38:00.045Z",
5
5
  "app": {
6
6
  "name": "dsh-aha-tutor",
7
7
  "version": "sample"
@@ -16,7 +16,7 @@
16
16
  "goal": "不需要高深数学,从掷骰子和人数表格出发,理解条件概率、基础比率和贝叶斯公式,最后亲手写一个会“学习”的垃圾短信过滤器。",
17
17
  "units": [
18
18
  {
19
- "id": "unt_mvettalbbn2kda",
19
+ "id": "unt_mvj8b7qkxzap73",
20
20
  "title": "条件概率的直觉",
21
21
  "summary": "新信息会把世界变小,概率要在小世界里重新计算。",
22
22
  "objectives": [
@@ -25,12 +25,12 @@
25
25
  ],
26
26
  "lectures": [
27
27
  {
28
- "id": "lec_mvettalbqgcijj",
28
+ "id": "lec_mvj8b7qk199u3n",
29
29
  "title": "条件概率",
30
30
  "summary": "",
31
31
  "lessons": [
32
32
  {
33
- "id": "les_mvettalb3489i1",
33
+ "id": "les_mvj8b7qkl4u2t0",
34
34
  "title": "条件概率:知道一点之后",
35
35
  "summary": "在信息划定的小世界里重新数一遍。",
36
36
  "objectives": [
@@ -39,19 +39,20 @@
39
39
  ],
40
40
  "concepts": [
41
41
  {
42
- "id": "cpt_mvettalbr7booh",
42
+ "id": "cpt_mvj8b7qkt07w9q",
43
43
  "name": "条件概率"
44
44
  },
45
45
  {
46
- "id": "cpt_mvettalbf883xz",
46
+ "id": "cpt_mvj8b7qkh92r21",
47
47
  "name": "P(A|B) 与 P(B|A)"
48
48
  }
49
49
  ],
50
50
  "estMinutes": 12,
51
- "kind": "lesson"
51
+ "kind": "lesson",
52
+ "depth": "intuition"
52
53
  },
53
54
  {
54
- "id": "les_mvettalb5cl7sw",
55
+ "id": "les_mvj8b7qk387ppx",
55
56
  "title": "独立与不独立",
56
57
  "summary": "什么时候一个信息完全不改变另一个事件的概率。",
57
58
  "objectives": [
@@ -60,22 +61,23 @@
60
61
  ],
61
62
  "concepts": [
62
63
  {
63
- "id": "cpt_mvettalbvpbysf",
64
+ "id": "cpt_mvj8b7qk2om3g5",
64
65
  "name": "独立事件"
65
66
  }
66
67
  ],
67
68
  "estMinutes": 12,
68
- "kind": "lesson"
69
+ "kind": "lesson",
70
+ "depth": "definition"
69
71
  }
70
72
  ]
71
73
  },
72
74
  {
73
- "id": "lec_mvettalbgfqiuc",
75
+ "id": "lec_mvj8b7qk16yq1q",
74
76
  "title": "全概率",
75
77
  "summary": "",
76
78
  "lessons": [
77
79
  {
78
- "id": "les_mvettalbfzwku4",
80
+ "id": "les_mvj8b7qk7lrwi2",
79
81
  "title": "把世界切成几块:全概率公式",
80
82
  "summary": "分情况讨论,再把各部分加起来。",
81
83
  "objectives": [
@@ -84,19 +86,20 @@
84
86
  ],
85
87
  "concepts": [
86
88
  {
87
- "id": "cpt_mvettalb90l4hz",
89
+ "id": "cpt_mvj8b7qkes1npo",
88
90
  "name": "全概率公式"
89
91
  }
90
92
  ],
91
93
  "estMinutes": 15,
92
- "kind": "lesson"
94
+ "kind": "lesson",
95
+ "depth": "derivation"
93
96
  }
94
97
  ]
95
98
  }
96
99
  ]
97
100
  },
98
101
  {
99
- "id": "unt_mvettalbhn9nwv",
102
+ "id": "unt_mvj8b7qko13f4j",
100
103
  "title": "贝叶斯公式",
101
104
  "summary": "从结果反推原因,用证据更新信念。",
102
105
  "objectives": [
@@ -105,12 +108,12 @@
105
108
  ],
106
109
  "lectures": [
107
110
  {
108
- "id": "lec_mvettalbrgha10",
111
+ "id": "lec_mvj8b7qkrebgtb",
109
112
  "title": "贝叶斯",
110
113
  "summary": "",
111
114
  "lessons": [
112
115
  {
113
- "id": "les_mvettalb0yqhx7",
116
+ "id": "les_mvj8b7qkqxxu37",
114
117
  "title": "医学检测悖论:基础比率的力量",
115
118
  "summary": "准确率 99% 的检测,阳性也未必意味着得病。",
116
119
  "objectives": [
@@ -119,19 +122,20 @@
119
122
  ],
120
123
  "concepts": [
121
124
  {
122
- "id": "cpt_mvettalbb84add",
125
+ "id": "cpt_mvj8b7qkf072gp",
123
126
  "name": "基础比率"
124
127
  },
125
128
  {
126
- "id": "cpt_mvettalbh8eot6",
129
+ "id": "cpt_mvj8b7qkid7qhf",
127
130
  "name": "贝叶斯公式"
128
131
  }
129
132
  ],
130
133
  "estMinutes": 15,
131
- "kind": "lesson"
134
+ "kind": "lesson",
135
+ "depth": "application"
132
136
  },
133
137
  {
134
- "id": "les_mvettalb6i1vvh",
138
+ "id": "les_mvj8b7qkck2pka",
135
139
  "title": "先验、似然与后验",
136
140
  "summary": "贝叶斯公式里每一项的含义。",
137
141
  "objectives": [
@@ -140,26 +144,27 @@
140
144
  ],
141
145
  "concepts": [
142
146
  {
143
- "id": "cpt_mvettalbx5h9qc",
147
+ "id": "cpt_mvj8b7qkepj9pp",
144
148
  "name": "先验与后验"
145
149
  },
146
150
  {
147
- "id": "cpt_mvettalbfgnoeb",
151
+ "id": "cpt_mvj8b7qkk18djq",
148
152
  "name": "似然"
149
153
  }
150
154
  ],
151
155
  "estMinutes": 12,
152
- "kind": "lesson"
156
+ "kind": "lesson",
157
+ "depth": "definition"
153
158
  }
154
159
  ]
155
160
  },
156
161
  {
157
- "id": "lec_mvettalb8j0rl9",
162
+ "id": "lec_mvj8b7qkpsplfw",
158
163
  "title": "用起来",
159
164
  "summary": "",
160
165
  "lessons": [
161
166
  {
162
- "id": "les_mvettalbpsslfv",
167
+ "id": "les_mvj8b7qkrlzttw",
163
168
  "title": "一次次更新你的判断",
164
169
  "summary": "每一个新证据,都让昨天的后验变成今天的先验。",
165
170
  "objectives": [
@@ -168,12 +173,13 @@
168
173
  ],
169
174
  "concepts": [
170
175
  {
171
- "id": "cpt_mvettalb03n28y",
176
+ "id": "cpt_mvj8b7qk3r6ppf",
172
177
  "name": "贝叶斯更新"
173
178
  }
174
179
  ],
175
180
  "estMinutes": 12,
176
- "kind": "lesson"
181
+ "kind": "lesson",
182
+ "depth": "extension"
177
183
  }
178
184
  ]
179
185
  }
@@ -182,7 +188,7 @@
182
188
  ],
183
189
  "projects": [
184
190
  {
185
- "id": "prj_mvettalb98jgu4",
191
+ "id": "prj_mvj8b7qkni92wg",
186
192
  "title": "写一个会学习的垃圾短信过滤器",
187
193
  "kind": "code",
188
194
  "brief": "用朴素贝叶斯的思路,统计正常短信和垃圾短信里各个词出现的频率,对一条新短信计算它是垃圾短信的后验概率。完成后,试着输入几条你自己的短信,看看过滤器的判断是否合理。",
@@ -253,12 +259,12 @@
253
259
  "content": "import csv\nimport math\nfrom collections import Counter\n\nrows = list(csv.DictReader(open(\"messages.csv\", encoding=\"utf-8\")))\n\n# TODO 1:分别统计 spam 和 ham 中每个词出现的次数\nspam_words, ham_words = Counter(), Counter()\n\n# TODO 2:计算先验 P(spam) 和 P(ham)\np_spam = None\np_ham = None\n\ndef score(text):\n \"\"\"返回 log P(spam|text) - log P(ham|text)。大于 0 判为垃圾短信。\"\"\"\n # TODO 3:对每个词累加 log 似然,记得做拉普拉斯平滑(每个词的计数 +1)\n return 0.0\n\nfor text in [\"恭喜 中奖 点击 领取\", \"明天 一起 吃饭\"]:\n print(text, \"->\", \"垃圾\" if score(text) > 0 else \"正常\")\n"
254
260
  }
255
261
  ],
256
- "unitId": "unt_mvettalbhn9nwv"
262
+ "unitId": "unt_mvj8b7qko13f4j"
257
263
  }
258
264
  ]
259
265
  },
260
266
  "boards": {
261
- "les_mvettalb3489i1": {
267
+ "les_mvj8b7qkl4u2t0": {
262
268
  "title": "条件概率:知道一点之后",
263
269
  "steps": [
264
270
  {
@@ -342,7 +348,7 @@
342
348
  "hints": [],
343
349
  "difficulty": 2,
344
350
  "conceptIds": [
345
- "cpt_mvettalbr7booh"
351
+ "cpt_mvj8b7qkt07w9q"
346
352
  ],
347
353
  "options": [
348
354
  {
@@ -455,7 +461,7 @@
455
461
  "hints": [],
456
462
  "difficulty": 2,
457
463
  "conceptIds": [
458
- "cpt_mvettalbr7booh"
464
+ "cpt_mvj8b7qkt07w9q"
459
465
  ],
460
466
  "answer": 0.25,
461
467
  "tolerance": 0.005,
@@ -516,7 +522,7 @@
516
522
  "hints": [],
517
523
  "difficulty": 2,
518
524
  "conceptIds": [
519
- "cpt_mvettalbf883xz"
525
+ "cpt_mvj8b7qkh92r21"
520
526
  ],
521
527
  "options": [
522
528
  {
@@ -540,9 +546,9 @@
540
546
  }
541
547
  }
542
548
  ],
543
- "lessonId": "les_mvettalb3489i1"
549
+ "lessonId": "les_mvj8b7qkl4u2t0"
544
550
  },
545
- "les_mvettalb0yqhx7": {
551
+ "les_mvj8b7qkqxxu37": {
546
552
  "title": "医学检测悖论:基础比率的力量",
547
553
  "steps": [
548
554
  {
@@ -578,7 +584,7 @@
578
584
  "hints": [],
579
585
  "difficulty": 2,
580
586
  "conceptIds": [
581
- "cpt_mvettalbb84add"
587
+ "cpt_mvj8b7qkf072gp"
582
588
  ],
583
589
  "options": [
584
590
  {
@@ -739,8 +745,8 @@
739
745
  "hints": [],
740
746
  "difficulty": 2,
741
747
  "conceptIds": [
742
- "cpt_mvettalbh8eot6",
743
- "cpt_mvettalbb84add"
748
+ "cpt_mvj8b7qkid7qhf",
749
+ "cpt_mvj8b7qkf072gp"
744
750
  ],
745
751
  "answer": 50,
746
752
  "tolerance": 1,
@@ -804,7 +810,7 @@
804
810
  "hints": [],
805
811
  "difficulty": 2,
806
812
  "conceptIds": [
807
- "cpt_mvettalbh8eot6"
813
+ "cpt_mvj8b7qkid7qhf"
808
814
  ],
809
815
  "options": [
810
816
  {
@@ -828,12 +834,12 @@
828
834
  }
829
835
  }
830
836
  ],
831
- "lessonId": "les_mvettalb0yqhx7"
837
+ "lessonId": "les_mvj8b7qkqxxu37"
832
838
  }
833
839
  },
834
840
  "practice": {
835
- "les_mvettalb3489i1": {
836
- "lessonId": "les_mvettalb3489i1",
841
+ "les_mvj8b7qkl4u2t0": {
842
+ "lessonId": "les_mvj8b7qkl4u2t0",
837
843
  "items": [
838
844
  {
839
845
  "id": "i1",
@@ -845,7 +851,7 @@
845
851
  ],
846
852
  "difficulty": 1,
847
853
  "conceptIds": [
848
- "cpt_mvettalbr7booh"
854
+ "cpt_mvj8b7qkt07w9q"
849
855
  ],
850
856
  "options": [
851
857
  {
@@ -877,7 +883,7 @@
877
883
  ],
878
884
  "difficulty": 1,
879
885
  "conceptIds": [
880
- "cpt_mvettalbr7booh"
886
+ "cpt_mvj8b7qkt07w9q"
881
887
  ],
882
888
  "answer": 0.3,
883
889
  "tolerance": 0.001,
@@ -893,7 +899,7 @@
893
899
  ],
894
900
  "difficulty": 2,
895
901
  "conceptIds": [
896
- "cpt_mvettalbf883xz"
902
+ "cpt_mvj8b7qkh92r21"
897
903
  ],
898
904
  "options": [
899
905
  {
@@ -923,7 +929,7 @@
923
929
  "hints": [],
924
930
  "difficulty": 1,
925
931
  "conceptIds": [
926
- "cpt_mvettalbr7booh"
932
+ "cpt_mvj8b7qkt07w9q"
927
933
  ],
928
934
  "answer": [
929
935
  "P(B)",
@@ -939,7 +945,7 @@
939
945
  "hints": [],
940
946
  "difficulty": 2,
941
947
  "conceptIds": [
942
- "cpt_mvettalbf883xz"
948
+ "cpt_mvj8b7qkh92r21"
943
949
  ],
944
950
  "answer": "例如:P(会游泳 | 是游泳运动员) 接近 100%,但 P(是游泳运动员 | 会游泳) 很小,因为会游泳的人里只有极少数是运动员。",
945
951
  "rubric": [
@@ -950,8 +956,8 @@
950
956
  }
951
957
  ]
952
958
  },
953
- "les_mvettalb0yqhx7": {
954
- "lessonId": "les_mvettalb0yqhx7",
959
+ "les_mvj8b7qkqxxu37": {
960
+ "lessonId": "les_mvj8b7qkqxxu37",
955
961
  "items": [
956
962
  {
957
963
  "id": "i1",
@@ -963,7 +969,7 @@
963
969
  ],
964
970
  "difficulty": 1,
965
971
  "conceptIds": [
966
- "cpt_mvettalbb84add"
972
+ "cpt_mvj8b7qkf072gp"
967
973
  ],
968
974
  "answer": 999,
969
975
  "tolerance": 1,
@@ -979,7 +985,7 @@
979
985
  ],
980
986
  "difficulty": 2,
981
987
  "conceptIds": [
982
- "cpt_mvettalbb84add"
988
+ "cpt_mvj8b7qkf072gp"
983
989
  ],
984
990
  "options": [
985
991
  {
@@ -1011,7 +1017,7 @@
1011
1017
  ],
1012
1018
  "difficulty": 2,
1013
1019
  "conceptIds": [
1014
- "cpt_mvettalbh8eot6"
1020
+ "cpt_mvj8b7qkid7qhf"
1015
1021
  ],
1016
1022
  "answer": 0.2687,
1017
1023
  "tolerance": 0.01,
@@ -1025,7 +1031,7 @@
1025
1031
  "hints": [],
1026
1032
  "difficulty": 1,
1027
1033
  "conceptIds": [
1028
- "cpt_mvettalbh8eot6"
1034
+ "cpt_mvj8b7qkid7qhf"
1029
1035
  ],
1030
1036
  "options": [
1031
1037
  {
@@ -1055,8 +1061,8 @@
1055
1061
  "hints": [],
1056
1062
  "difficulty": 3,
1057
1063
  "conceptIds": [
1058
- "cpt_mvettalbh8eot6",
1059
- "cpt_mvettalbb84add"
1064
+ "cpt_mvj8b7qkid7qhf",
1065
+ "cpt_mvj8b7qkf072gp"
1060
1066
  ],
1061
1067
  "answer": "一次阳性后,患病的后验概率从很低升到较高(如从 0.1% 到约 9%);复查时这个后验成为新的先验,若再次阳性,患病概率会大幅提高(约 91%),判断更可靠。",
1062
1068
  "rubric": [