mdeck 2.3.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.
Files changed (268) hide show
  1. package/CHANGELOG.md +259 -0
  2. package/LICENSE +21 -0
  3. package/README.md +156 -0
  4. package/assets/base.css +196 -0
  5. package/assets/extensions/layouts/chapter/extension.toml +26 -0
  6. package/assets/extensions/layouts/chapter/layout.jsx +21 -0
  7. package/assets/extensions/layouts/chapter/starter.md +8 -0
  8. package/assets/extensions/layouts/focus/extension.toml +8 -0
  9. package/assets/extensions/layouts/focus/layout.jsx +10 -0
  10. package/assets/extensions/layouts/focus/starter.md +4 -0
  11. package/assets/extensions/layouts/full-bleed-image/extension.toml +31 -0
  12. package/assets/extensions/layouts/full-bleed-image/layout.jsx +19 -0
  13. package/assets/extensions/layouts/full-bleed-image/starter.md +6 -0
  14. package/assets/extensions/layouts/generic/extension.toml +8 -0
  15. package/assets/extensions/layouts/generic/layout.jsx +8 -0
  16. package/assets/extensions/layouts/generic/starter.md +4 -0
  17. package/assets/extensions/layouts/image-text/extension.toml +25 -0
  18. package/assets/extensions/layouts/image-text/layout.jsx +17 -0
  19. package/assets/extensions/layouts/image-text/starter.md +6 -0
  20. package/assets/extensions/layouts/split/extension.toml +25 -0
  21. package/assets/extensions/layouts/split/layout.jsx +19 -0
  22. package/assets/extensions/layouts/split/starter.md +14 -0
  23. package/assets/extensions/layouts/title/extension.toml +26 -0
  24. package/assets/extensions/layouts/title/layout.jsx +14 -0
  25. package/assets/extensions/layouts/title/starter.md +5 -0
  26. package/assets/extensions/palettes/brand/extension.toml +29 -0
  27. package/assets/extensions/palettes/cobalt/extension.toml +27 -0
  28. package/assets/extensions/palettes/ember/extension.toml +27 -0
  29. package/assets/extensions/palettes/forest/extension.toml +27 -0
  30. package/assets/extensions/palettes/graphite/extension.toml +27 -0
  31. package/assets/extensions/palettes/lagoon/extension.toml +27 -0
  32. package/assets/extensions/palettes/neon/extension.toml +27 -0
  33. package/assets/extensions/palettes/nordic/extension.toml +27 -0
  34. package/assets/extensions/palettes/pastel/extension.toml +30 -0
  35. package/assets/extensions/palettes/phosphor/extension.toml +27 -0
  36. package/assets/extensions/palettes/swiss/extension.toml +27 -0
  37. package/assets/extensions/palettes/terra/extension.toml +27 -0
  38. package/assets/extensions/themes/academic/extension.toml +53 -0
  39. package/assets/extensions/themes/academic/styles.css +631 -0
  40. package/assets/extensions/themes/aurora/extension.toml +37 -0
  41. package/assets/extensions/themes/aurora/styles.css +644 -0
  42. package/assets/extensions/themes/duet/extension.toml +46 -0
  43. package/assets/extensions/themes/duet/styles.css +573 -0
  44. package/assets/extensions/themes/editorial/extension.toml +46 -0
  45. package/assets/extensions/themes/editorial/styles.css +574 -0
  46. package/assets/extensions/themes/fhnw/extension.toml +61 -0
  47. package/assets/extensions/themes/fhnw/styles.css +604 -0
  48. package/assets/extensions/themes/neue/extension.toml +46 -0
  49. package/assets/extensions/themes/neue/styles.css +489 -0
  50. package/assets/extensions/themes/sketch/extension.toml +48 -0
  51. package/assets/extensions/themes/sketch/styles.css +633 -0
  52. package/assets/extensions/themes/terminal/extension.toml +38 -0
  53. package/assets/extensions/themes/terminal/styles.css +550 -0
  54. package/assets/logo/avatar.png +0 -0
  55. package/assets/logo/logo-dark.svg +10 -0
  56. package/assets/logo/logo-light.svg +10 -0
  57. package/assets/logo/mark.svg +15 -0
  58. package/bin/mdeck.js +2 -0
  59. package/docs/README.md +8 -0
  60. package/docs/reference/authoring.md +795 -0
  61. package/docs/reference/claude-skill.md +96 -0
  62. package/docs/reference/extensions.md +250 -0
  63. package/docs/reference/layouts.md +153 -0
  64. package/docs/reference/palettes.md +106 -0
  65. package/docs/reference/structured-slides.md +120 -0
  66. package/docs/reference/themes.md +133 -0
  67. package/docs/site/assets/favicon.svg +15 -0
  68. package/docs/site/assets/github-logo.svg +1 -0
  69. package/docs/site/assets/site.css +162 -0
  70. package/docs/site/assets/site.js +123 -0
  71. package/docs/site/build.js +148 -0
  72. package/docs/site/content/appearance.md +203 -0
  73. package/docs/site/content/audience.md +178 -0
  74. package/docs/site/content/commands.md +153 -0
  75. package/docs/site/content/components.md +134 -0
  76. package/docs/site/content/drawing.md +72 -0
  77. package/docs/site/content/editing.md +59 -0
  78. package/docs/site/content/getting-started.md +103 -0
  79. package/docs/site/content/layouts.md +126 -0
  80. package/docs/site/content/media.md +107 -0
  81. package/docs/site/content/more-content.md +130 -0
  82. package/docs/site/content/presenting.md +93 -0
  83. package/docs/site/content/reusable-layouts.md +74 -0
  84. package/docs/site/content/sharing.md +88 -0
  85. package/docs/site/content/theme-authoring.md +144 -0
  86. package/docs/site/content/theme-repository.md +76 -0
  87. package/docs/site/content/troubleshooting.md +92 -0
  88. package/docs/site/content/views.md +56 -0
  89. package/docs/site/content/welcome.md +71 -0
  90. package/docs/site/content/writing.md +121 -0
  91. package/docs/site/examples/first-talk.md +88 -0
  92. package/docs/site/examples/notebook.svg +58 -0
  93. package/docs/site/images/themes/academic-dark.webp +0 -0
  94. package/docs/site/images/themes/academic-light.webp +0 -0
  95. package/docs/site/images/themes/academic.webp +0 -0
  96. package/docs/site/images/themes/aurora-dark.webp +0 -0
  97. package/docs/site/images/themes/aurora-light.webp +0 -0
  98. package/docs/site/images/themes/aurora.webp +0 -0
  99. package/docs/site/images/themes/duet-dark.webp +0 -0
  100. package/docs/site/images/themes/duet-light.webp +0 -0
  101. package/docs/site/images/themes/duet.webp +0 -0
  102. package/docs/site/images/themes/editorial-dark.webp +0 -0
  103. package/docs/site/images/themes/editorial-light.webp +0 -0
  104. package/docs/site/images/themes/editorial.webp +0 -0
  105. package/docs/site/images/themes/fhnw.webp +0 -0
  106. package/docs/site/images/themes/neue-dark.webp +0 -0
  107. package/docs/site/images/themes/neue-light.webp +0 -0
  108. package/docs/site/images/themes/neue.webp +0 -0
  109. package/docs/site/images/themes/sketch-dark.webp +0 -0
  110. package/docs/site/images/themes/sketch-light.webp +0 -0
  111. package/docs/site/images/themes/sketch.webp +0 -0
  112. package/docs/site/images/themes/terminal-dark.webp +0 -0
  113. package/docs/site/images/themes/terminal-light.webp +0 -0
  114. package/docs/site/images/themes/terminal.webp +0 -0
  115. package/docs/site/package.json +9 -0
  116. package/docs/site/pages.js +27 -0
  117. package/docs/site/server.js +58 -0
  118. package/examples/custom-layouts/extensions/comparison/extension.toml +35 -0
  119. package/examples/custom-layouts/extensions/comparison/layout.jsx +15 -0
  120. package/examples/custom-layouts/extensions/comparison/starter.md +17 -0
  121. package/examples/custom-layouts/extensions/comparison/styles.css +4 -0
  122. package/examples/custom-layouts/slides.md +60 -0
  123. package/examples/poll/slides.md +127 -0
  124. package/examples/python/.mdeck-backups/slides.drawings-2026-10-06T08-36-47Z.json +19 -0
  125. package/examples/python/.mdeck-backups/slides.drawings-2026-10-06T11-27-30Z.json +6 -0
  126. package/examples/python/slides.drawings.json +6 -0
  127. package/examples/python/slides.md +493 -0
  128. package/examples/showcase/.mdeck-backups/slides.drawings-2026-10-06T08-08-30Z.json +10 -0
  129. package/examples/showcase/.mdeck-backups/slides.drawings-2026-10-06T11-41-35Z.json +13 -0
  130. package/examples/showcase/img/image.jpg +0 -0
  131. package/examples/showcase/img/mdeck.svg +66 -0
  132. package/examples/showcase/slides.drawings.json +11 -0
  133. package/examples/showcase/slides.md +427 -0
  134. package/package.json +75 -0
  135. package/skills/write-slides/SKILL.md +144 -0
  136. package/src/build/check.js +49 -0
  137. package/src/build/chrome.js +130 -0
  138. package/src/build/components.js +44 -0
  139. package/src/build/config.js +61 -0
  140. package/src/build/drawings.js +14 -0
  141. package/src/build/editorPlugin.js +272 -0
  142. package/src/build/editorServer.js +36 -0
  143. package/src/build/fonts.js +84 -0
  144. package/src/build/homePlugin.js +208 -0
  145. package/src/build/inkPlugin.js +192 -0
  146. package/src/build/ownWrites.js +18 -0
  147. package/src/build/pairing.js +81 -0
  148. package/src/build/pdf.js +34 -0
  149. package/src/build/relayAccess.js +85 -0
  150. package/src/build/slidesPlugin.js +371 -0
  151. package/src/build/themeCheck.js +151 -0
  152. package/src/build/tunnelClient.js +184 -0
  153. package/src/cli/args.js +76 -0
  154. package/src/cli/index.js +758 -0
  155. package/src/cli/migrate.js +123 -0
  156. package/src/cli/skill.js +40 -0
  157. package/src/cli/themes.js +140 -0
  158. package/src/components/CodeBlock.jsx +168 -0
  159. package/src/components/ConnectedViews.jsx +25 -0
  160. package/src/components/Icon.jsx +8 -0
  161. package/src/components/Poll.jsx +67 -0
  162. package/src/components/QrCode.jsx +29 -0
  163. package/src/components/QrCodeTag.jsx +27 -0
  164. package/src/components/Question.jsx +28 -0
  165. package/src/components/Scale.jsx +47 -0
  166. package/src/components/VideoPlayer.jsx +108 -0
  167. package/src/components/WordCloud.jsx +106 -0
  168. package/src/components/activity.jsx +35 -0
  169. package/src/components/callout.css +78 -0
  170. package/src/components/code-block.css +123 -0
  171. package/src/components/columns.css +11 -0
  172. package/src/components/poll.css +81 -0
  173. package/src/components/video-player.css +14 -0
  174. package/src/core/devPath.js +4 -0
  175. package/src/core/editDeck.js +230 -0
  176. package/src/core/icons.js +69 -0
  177. package/src/core/ink.js +221 -0
  178. package/src/core/labels.js +144 -0
  179. package/src/core/outline.js +33 -0
  180. package/src/core/parseSlides.js +152 -0
  181. package/src/core/source.js +137 -0
  182. package/src/core/urls.js +34 -0
  183. package/src/core/validateDeck.js +139 -0
  184. package/src/editor/api.js +67 -0
  185. package/src/editor/components/App.jsx +75 -0
  186. package/src/editor/components/ConflictBanner.jsx +10 -0
  187. package/src/editor/components/DeckSettings.jsx +108 -0
  188. package/src/editor/components/DesignApp.jsx +252 -0
  189. package/src/editor/components/Diagnostics.jsx +10 -0
  190. package/src/editor/components/ExtensionEditor.jsx +66 -0
  191. package/src/editor/components/ExtensionForms.jsx +134 -0
  192. package/src/editor/components/ExtensionsPanel.jsx +114 -0
  193. package/src/editor/components/Field.jsx +24 -0
  194. package/src/editor/components/Inspector.jsx +36 -0
  195. package/src/editor/components/LayoutPicker.jsx +23 -0
  196. package/src/editor/components/LayoutSelect.jsx +25 -0
  197. package/src/editor/components/LookThumbnail.jsx +8 -0
  198. package/src/editor/components/MetaFields.jsx +24 -0
  199. package/src/editor/components/Outline.jsx +28 -0
  200. package/src/editor/components/PalettePicker.jsx +32 -0
  201. package/src/editor/components/Preview.jsx +63 -0
  202. package/src/editor/components/PropsForm.jsx +46 -0
  203. package/src/editor/components/RawSlideEditor.jsx +9 -0
  204. package/src/editor/components/RegionEditor.jsx +15 -0
  205. package/src/editor/components/Resizer.jsx +18 -0
  206. package/src/editor/designLink.js +19 -0
  207. package/src/editor/editor.css +139 -0
  208. package/src/editor/extensions.js +86 -0
  209. package/src/editor/keyboard.js +21 -0
  210. package/src/editor/model.js +38 -0
  211. package/src/editor/sampleDeck.js +165 -0
  212. package/src/editor/saveQueue.js +47 -0
  213. package/src/editor/schema.js +36 -0
  214. package/src/editor/state.js +92 -0
  215. package/src/editor/useDeckDocument.js +67 -0
  216. package/src/extensions/appearance.js +79 -0
  217. package/src/extensions/contrast.js +57 -0
  218. package/src/extensions/discover.js +126 -0
  219. package/src/extensions/manifest.js +209 -0
  220. package/src/extensions/packs.js +268 -0
  221. package/src/extensions/tokens.js +25 -0
  222. package/src/home/Home.jsx +362 -0
  223. package/src/home/home.css +148 -0
  224. package/src/layouts/layoutApi.jsx +205 -0
  225. package/src/layouts/layoutProps.js +30 -0
  226. package/src/layouts/renderSlide.jsx +17 -0
  227. package/src/live/answer/answer.css +34 -0
  228. package/src/live/answer/answer.html +14 -0
  229. package/src/live/answer/answer.js +130 -0
  230. package/src/live/client.js +290 -0
  231. package/src/live/code.js +19 -0
  232. package/src/live/follow.js +17 -0
  233. package/src/live/pairing.js +34 -0
  234. package/src/live/presence.js +33 -0
  235. package/src/live/roomTag.js +38 -0
  236. package/src/live/rooms.js +249 -0
  237. package/src/live/server.js +82 -0
  238. package/src/live/tunnel.js +180 -0
  239. package/src/paths.js +9 -0
  240. package/src/runtime/ReaderView.jsx +193 -0
  241. package/src/runtime/SlideErrorBoundary.jsx +28 -0
  242. package/src/runtime/chrome.jsx +55 -0
  243. package/src/runtime/deck-stage.js +1533 -0
  244. package/src/runtime/design.html +12 -0
  245. package/src/runtime/design.jsx +5 -0
  246. package/src/runtime/editor.html +12 -0
  247. package/src/runtime/editor.jsx +5 -0
  248. package/src/runtime/editorBridge.js +58 -0
  249. package/src/runtime/fit.js +149 -0
  250. package/src/runtime/home.html +13 -0
  251. package/src/runtime/home.jsx +5 -0
  252. package/src/runtime/index.html +15 -0
  253. package/src/runtime/ink/InkLayer.jsx +17 -0
  254. package/src/runtime/ink/Toolbar.jsx +145 -0
  255. package/src/runtime/ink/attach.js +69 -0
  256. package/src/runtime/ink/bus.js +126 -0
  257. package/src/runtime/ink/controller.js +132 -0
  258. package/src/runtime/ink/room.js +101 -0
  259. package/src/runtime/ink/select.js +124 -0
  260. package/src/runtime/ink/server.js +75 -0
  261. package/src/runtime/ink/store.js +55 -0
  262. package/src/runtime/ink/toolbar.css +79 -0
  263. package/src/runtime/main.jsx +863 -0
  264. package/src/runtime/markedSetup.js +147 -0
  265. package/src/runtime/reader.css +59 -0
  266. package/src/runtime/registry.jsx +26 -0
  267. package/src/runtime/syncOrder.js +32 -0
  268. package/src/runtime/themeLoader.js +68 -0
@@ -0,0 +1,493 @@
1
+ ---
2
+ theme: sketch
3
+ meta:
4
+ title: "Introduction to Python"
5
+ author: "Tilman Schieber"
6
+ organization: "FHNW"
7
+ date: "2026-05-19"
8
+ palette: graphite
9
+ ---
10
+
11
+ ---
12
+ :::meta
13
+ layout: title
14
+ id: python-for-life-sciences
15
+ :::
16
+ # Python for Life Sciences.
17
+ ## A step-by-step introduction for Master's students.
18
+
19
+ :::notes
20
+ Welcome to the Python module. This session assumes no prior programming experience.
21
+
22
+ - We'll move step by step — don't hesitate to interrupt with questions
23
+ - All code runs live in the browser — no installation needed today
24
+ - Goal: by the end you'll be able to load, inspect, and plot a dataset
25
+ :::
26
+
27
+ ---
28
+ :::meta
29
+ layout: focus
30
+ eyebrow: Why Python?
31
+ id: the-tools-your-field-uses-are-written-in
32
+ :::
33
+ # The tools your field uses are *written in Python*.
34
+
35
+ :::notes
36
+ Python is the dominant language in both academia and industry for data-heavy work.
37
+ Life sciences is no exception — bioinformatics, imaging, and clinical data analysis all run on Python.
38
+
39
+ The ecosystem (NumPy, Pandas, Matplotlib, scikit-learn, BioPython) is unmatched.
40
+ Point out that R is still common in statistics, but Python has largely converged as the lingua franca.
41
+ :::
42
+
43
+ ---
44
+ :::meta
45
+ layout: chapter
46
+ number: 1
47
+ part: Getting Started
48
+ description: Variables, types, and your first lines of code.
49
+ id: variables-and-data-types
50
+ :::
51
+ # Variables and data types.
52
+
53
+ :::notes
54
+ Start here even if students have seen some Python before. We build from the ground up.
55
+ Estimated time for this chapter: 20 minutes.
56
+ :::
57
+
58
+ ---
59
+ :::meta
60
+ layout: split
61
+ section: Variables
62
+ id: variables-store-data
63
+ props:
64
+ ratio: [3, 2]
65
+ :::
66
+ # A variable is a name for a value.
67
+ :::slot left
68
+ ```python live editable copy
69
+ name = "E. coli"
70
+ genome_size = 4_641_652 # base pairs
71
+ gc_content = 0.506 # fraction
72
+
73
+ print(name, genome_size, gc_content)
74
+ print(f"GC content: {gc_content:.1%}")
75
+ ```
76
+ :::
77
+ :::slot right
78
+ No declarations: Python sees the type from the value.
79
+
80
+ **Try it:** change `gc_content` to `0.65` and run again.
81
+ :::
82
+
83
+ :::notes
84
+ A variable is just a name attached to a value. Python figures out the type automatically.
85
+
86
+ Point out: no semicolons, no type declarations, no boilerplate. The `f"…"` string formats a value inside text; `:.1%` shows a fraction as a percentage.
87
+ Encourage students to change the values and re-run — that's the point of the live block.
88
+ :::
89
+
90
+ ---
91
+ :::meta
92
+ section: Data Types
93
+ id: four-types-cover-most-biology-data
94
+ :::
95
+ # Four types cover most biology data.
96
+
97
+ :::steps
98
+ - **`int`** — whole numbers: counts, positions, indices
99
+ - **`float`** — decimals: concentrations, p-values, fold changes
100
+ - **`str`** — text: gene names, sequences, sample IDs
101
+ - **`bool`** — True or False: significance flags, quality filters
102
+ :::
103
+
104
+ :::notes
105
+ Reveal one type at a time and ask for an example from the lab before showing the next.
106
+
107
+ Emphasise that booleans typically come from comparisons, not literal True/False. The next slide asks the room.
108
+ :::
109
+
110
+ ---
111
+ :::meta
112
+ section: Data Types
113
+ title: "Poll: the type of a p-value"
114
+ id: poll-the-type-of-a-p-value
115
+ :::
116
+ # What type is a p-value?
117
+
118
+ <poll room="p-value" options="int|float|str|bool" answer="float" />
119
+
120
+ :::notes
121
+ A quick check before moving on. Phones join with the QR code; start the deck with `mdeck run slides.md --network` so they can reach this computer.
122
+
123
+ Answer: `float`; the tick button under the bars marks it. If many chose `bool`, they are thinking of the *significance flag* computed from it (`p < 0.05`): a good moment to show that comparisons produce booleans.
124
+ :::
125
+
126
+ ---
127
+ :::meta
128
+ layout: split
129
+ section: Strings
130
+ props:
131
+ ratio: [3, 2]
132
+ :::
133
+ # Strings behave like sequences.
134
+ :::slot left
135
+ ```python live editable copy
136
+ dna = "ATGCGTAAGCTTGAC"
137
+
138
+ print("Length: ", len(dna))
139
+ print("First codon:", dna[:3])
140
+ print("A count: ", dna.count("A"))
141
+ print("Reversed: ", dna[::-1])
142
+ print("As RNA: ", dna.replace("T", "U"))
143
+ ```
144
+ :::
145
+ :::slot right
146
+ Slicing, counting and replacing work the same on any text.
147
+
148
+ **Try it:** print the last codon with `dna[-3:]`.
149
+ :::
150
+
151
+ :::notes
152
+ Strings are sequences — you can slice them just like a nucleotide sequence.
153
+ `replace("T", "U")` is transcription in one line. The concepts transfer directly to BioPython later.
154
+ :::
155
+
156
+ ---
157
+ :::meta
158
+ layout: chapter
159
+ number: 2
160
+ part: Collections
161
+ description: Storing and accessing multiple values at once.
162
+ :::
163
+ # Lists and dictionaries.
164
+
165
+ :::notes
166
+ Most real data is not a single value. Lists and dictionaries are the two workhorse collections.
167
+ Estimated time for this chapter: 25 minutes.
168
+ :::
169
+
170
+ ---
171
+ :::meta
172
+ layout: split
173
+ section: Lists
174
+ props:
175
+ ratio: [3, 2]
176
+ :::
177
+ # A list holds values in order.
178
+ :::slot left
179
+ ```python live editable copy
180
+ conc = [0.12, 0.45, 0.33, 0.78, 0.21]
181
+
182
+ print("Samples:", len(conc))
183
+ print("First: ", conc[0])
184
+ print("Last: ", conc[-1])
185
+ print("Sorted: ", sorted(conc))
186
+ print("Mean: ", sum(conc) / len(conc))
187
+ ```
188
+ :::
189
+ :::slot right
190
+ Counting starts at zero: `conc[0]` is the first item, `conc[-1]` the last.
191
+
192
+ **Try it:** add a sixth value and watch the mean change.
193
+ :::
194
+
195
+ :::notes
196
+ Lists maintain order and allow duplicates. Index from 0. Negative indices count from the end.
197
+ Great for: time series, replicate measurements, ordered processing steps.
198
+
199
+ Common mistake: students try index 1 for the first element. Drill 0-indexing early.
200
+ :::
201
+
202
+ ---
203
+ :::meta
204
+ layout: split
205
+ section: Dictionaries
206
+ props:
207
+ ratio: [3, 2]
208
+ :::
209
+ # A dictionary looks values up by name.
210
+ :::slot left
211
+ ```python live editable copy
212
+ sample = {
213
+ "id": "S042",
214
+ "organism": "Mus musculus",
215
+ "tissue": "liver",
216
+ "weight_mg": 312,
217
+ }
218
+
219
+ print(sample["organism"])
220
+ sample["weight_mg"] = 318 # update a field
221
+ print(sample)
222
+ ```
223
+ :::
224
+ :::slot right
225
+ One dictionary describes one sample: no column numbers to remember.
226
+
227
+ **Try it:** add `"treated": True`.
228
+ :::
229
+
230
+ :::notes
231
+ Dictionaries map keys to values. Perfect for structured records — one dictionary = one sample.
232
+ Later, a list of dictionaries becomes a Pandas DataFrame. Plant that seed now.
233
+ :::
234
+
235
+ ---
236
+ :::meta
237
+ layout: chapter
238
+ number: 3
239
+ part: Control Flow
240
+ description: Making decisions and repeating operations across your data.
241
+ :::
242
+ # Decisions and loops.
243
+
244
+ :::notes
245
+ These two constructs — if and for — cover the vast majority of logic in data processing scripts.
246
+ Estimated time for this chapter: 25 minutes.
247
+ :::
248
+
249
+ ---
250
+ :::meta
251
+ layout: split
252
+ section: Conditions
253
+ props:
254
+ ratio: [3, 2]
255
+ :::
256
+ # `if` chooses a path.
257
+ :::slot left
258
+ ```python live editable copy
259
+ p_value = 0.023
260
+ fold_change = 2.4
261
+
262
+ if p_value < 0.05 and fold_change > 2:
263
+ print("Significant upregulation")
264
+ elif p_value < 0.05:
265
+ print("Significant, modest effect")
266
+ else:
267
+ print("Not significant")
268
+ ```
269
+ :::
270
+ :::slot right
271
+ The indentation is the block: Python uses whitespace, not braces.
272
+
273
+ **Try it:** set `fold_change = 1.5`.
274
+ :::
275
+
276
+ :::notes
277
+ if / elif / else covers all branching. Indentation is not stylistic in Python — it is syntax.
278
+ This trips up students from other languages or R. The colon and the indent are mandatory.
279
+ Show what happens if you forget the colon: Python gives a SyntaxError.
280
+ :::
281
+
282
+ ---
283
+ :::meta
284
+ layout: split
285
+ section: Loops
286
+ props:
287
+ ratio: [3, 2]
288
+ :::
289
+ # `for` repeats an action for every item.
290
+ :::slot left
291
+ ```python live editable copy
292
+ values = [1.2, 0.8, 2.1, 1.5, 0.9, 2.8]
293
+
294
+ above = []
295
+ for value in values:
296
+ if value > 1.0:
297
+ above.append(value)
298
+
299
+ print(len(above), "of", len(values))
300
+ print(above)
301
+ ```
302
+ :::
303
+ :::slot right
304
+ Loop, test, collect: the core pattern of filtering data.
305
+
306
+ **Try it:** count the values below 1.0 instead.
307
+ :::
308
+
309
+ :::notes
310
+ for loops iterate over any collection. This pattern — loop, test, collect — is at the heart of
311
+ almost every data processing script students will write.
312
+
313
+ Press **D** and trace one value through the loop on the slide: into `value`, through the `if`, into `above`. Escape stops drawing; the drawing stays with the slide.
314
+ :::
315
+
316
+ ---
317
+ :::meta
318
+ layout: chapter
319
+ number: 4
320
+ part: Functions
321
+ description: Packaging logic so you can reuse and test it.
322
+ :::
323
+ # Functions package logic for reuse.
324
+
325
+ :::notes
326
+ Functions are the first step toward reusable, testable code.
327
+ Motivate with: "you'll run this same calculation on 200 samples — write it once, call it 200 times."
328
+ Estimated time for this chapter: 20 minutes.
329
+ :::
330
+
331
+ ---
332
+ :::meta
333
+ layout: split
334
+ section: Functions
335
+ props:
336
+ ratio: [3, 2]
337
+ :::
338
+ # A function turns inputs into an output.
339
+ :::slot left
340
+ ```python live editable copy
341
+ def gc_content(seq):
342
+ """Return the GC fraction of a sequence."""
343
+ gc = seq.count("G") + seq.count("C")
344
+ return gc / len(seq)
345
+
346
+ for seq in ["ATGCGC", "AATTAA", "GCGCGC"]:
347
+ print(seq, f"{gc_content(seq):.0%}")
348
+ ```
349
+ :::
350
+ :::slot right
351
+ Write it once, then call it on every sample.
352
+
353
+ **Try it:** add your own sequence to the list.
354
+ :::
355
+
356
+ :::notes
357
+ def, parameters, return — that's the whole syntax.
358
+ Walk through: define once, call many times with different inputs.
359
+ The docstring (triple-quoted string after def) is best practice — introduce it early.
360
+ :::
361
+
362
+ ---
363
+ :::meta
364
+ layout: chapter
365
+ number: 5
366
+ part: Scientific Python
367
+ description: NumPy, Pandas, and Matplotlib — the three pillars.
368
+ :::
369
+ # The scientific stack.
370
+
371
+ :::notes
372
+ These three libraries are what make Python the dominant language in data science.
373
+ Students won't write much pure Python in practice — they'll use these.
374
+ Estimated time for this chapter: 30 minutes.
375
+ :::
376
+
377
+ ---
378
+ :::meta
379
+ section: Scientific Python
380
+ :::
381
+ # Three libraries cover most life sciences workflows.
382
+
383
+ :::steps
384
+ - **NumPy** — fast arrays: calculate on a whole dataset at once
385
+ - **Pandas** — tables: load, filter, group and summarise spreadsheet data
386
+ - **Matplotlib** — plots, with control over every element
387
+ :::
388
+
389
+ :::notes
390
+ Brief overview before diving in. The key message: these libraries handle the heavy lifting
391
+ so students write less code and get faster, more reliable results than with pure Python loops.
392
+ :::
393
+
394
+ ---
395
+ :::meta
396
+ layout: split
397
+ section: NumPy
398
+ props:
399
+ ratio: [3, 2]
400
+ :::
401
+ # NumPy calculates on whole arrays.
402
+ :::slot left
403
+ ```python live copy
404
+ import numpy as np
405
+
406
+ m = np.array([1.2, 0.8, 2.1, 1.5, 0.9, 2.8])
407
+
408
+ print("Mean: ", m.mean().round(3))
409
+ print("Std: ", m.std().round(3))
410
+ print("Median:", np.median(m))
411
+ print("> 1.5: ", m[m > 1.5])
412
+ ```
413
+ :::
414
+ :::slot right
415
+ `m[m > 1.5]` filters without a loop.
416
+
417
+ Compare it with the `for` loop two chapters ago.
418
+ :::
419
+
420
+ :::notes
421
+ NumPy operations apply to the whole array at once — no loops. This is both faster and more readable.
422
+ The vectorised style takes getting used to but is worth learning early.
423
+ Demo: ask students to predict what `m > 1.5` returns before running it.
424
+ :::
425
+
426
+ ---
427
+ :::meta
428
+ layout: focus
429
+ eyebrow: Key insight
430
+ :::
431
+ # Write operations on *arrays*, not on single values.
432
+
433
+ :::notes
434
+ This is the most important mental model shift from pure Python to scientific Python.
435
+ Repeat it, let it sink in. Students who internalise this early write much cleaner code later.
436
+ :::
437
+
438
+ ---
439
+ :::meta
440
+ layout: chapter
441
+ number: 6
442
+ part: Next Steps
443
+ description: Where to go from here.
444
+ id: keep-going
445
+ :::
446
+ # Keep going.
447
+
448
+ :::notes
449
+ Close with a roadmap. Students often feel lost after an intro — give them concrete next steps
450
+ and point them to the best free resources.
451
+ :::
452
+
453
+ ---
454
+ :::meta
455
+ section: Next Steps
456
+ :::
457
+ # What to learn next.
458
+
459
+ - **Pandas** — load a CSV, filter rows, compute group statistics
460
+ - **Matplotlib and Seaborn** — scatter plots, heatmaps, volcano plots
461
+ - **scikit-learn** — classification, clustering, dimensionality reduction
462
+ - **BioPython** — sequences, BLAST, GenBank and PDB files
463
+
464
+ :::notes
465
+ For self-study: the official Python tutorial for syntax, Pandas documentation for data work.
466
+ Kaggle's free Python and Pandas courses are excellent and self-paced.
467
+ For life sciences specifically: BioPython docs, and the Python for Bioinformatics textbook (Bassi).
468
+ :::
469
+
470
+ ---
471
+ :::meta
472
+ layout: focus
473
+ eyebrow: Remember
474
+ :::
475
+ # The best way to learn to code is to *write code*.
476
+
477
+ :::notes
478
+ Close on this. Programming is a skill — it takes practice. The first few weeks feel slow,
479
+ then things click. Encourage daily practice, even small scripts. Point to the exercises.
480
+ :::
481
+
482
+ ---
483
+ :::meta
484
+ layout: title
485
+ :::
486
+ # Questions?
487
+ ## Thank you — now open your laptops.
488
+
489
+ :::notes
490
+ Leave time for questions.
491
+ Remind students where to find the course materials and how to reach you.
492
+ The next session will cover Pandas and loading real datasets.
493
+ :::
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 1,
3
+ "width": 1920,
4
+ "height": 1080,
5
+ "slides": {
6
+ "draw-on-any-slide": [
7
+ {"id":"pkpb2b:muw89tng0","tool":"pen","color":"#e11d48","size":6,"points":[[1247,286,0.5]]}
8
+ ]
9
+ }
10
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "version": 1,
3
+ "width": 1920,
4
+ "height": 1080,
5
+ "slides": {
6
+ "draw-on-any-slide": [
7
+ {"id":"pkpb2b:muw89tng0","tool":"pen","color":"#e11d48","size":6,"points":[[1247,286,0.5]]}
8
+ ],
9
+ "give-the-talk": [
10
+ {"id":"pkpb2b:muwectdg0","tool":"pen","color":"#e11d48","size":6,"points":[[950,358,0.5],[917,358,0.5],[899,362,0.5],[877,369,0.5],[861,381,0.5],[851,391,0.5],[845,403,0.5],[838,421,0.5],[833,439,0.5],[831,453,0.5],[831,490,0.5],[833,506,0.5],[839,517,0.5],[849,525,0.5],[868,532,0.5],[895,536,0.5],[958,537,0.5],[998,533,0.5],[1043,522,0.5],[1087,505,0.5],[1132,483,0.5],[1181,452,0.5],[1207,433,0.5],[1235,409,0.5],[1257,386,0.5],[1275,364,0.5],[1287,341,0.5],[1294,318,0.5],[1297,295,0.5],[1297,270,0.5],[1290,245,0.5],[1270,214,0.5],[1241,186,0.5],[1205,169,0.5],[1142,159,0.5],[1061,157,0.5],[975,179,0.5],[878,227,0.5],[793,283,0.5],[709,354,0.5],[637,423,0.5],[587,486,0.5],[544,556,0.5],[519,618,0.5],[508,672,0.5],[510,716,0.5],[527,752,0.5],[558,779,0.5],[601,798,0.5],[653,809,0.5],[712,812,0.5],[775,810,0.5],[843,797,0.5],[961,744,0.5],[1006,711,0.5],[1055,668,0.5],[1095,620,0.5],[1126,571,0.5],[1141,534,0.5],[1147,501,0.5],[1149,467,0.5],[1146,443,0.5],[1130,424,0.5],[1094,413,0.5],[1047,420,0.5],[995,450,0.5],[953,487,0.5],[917,531,0.5],[886,571,0.5],[872,599,0.5],[856,633,0.5],[846,662,0.5],[843,691,0.5],[844,722,0.5],[856,739,0.5],[893,745,0.5],[949,740,0.5],[1015,717,0.5],[1093,675,0.5],[1174,620,0.5],[1232,574,0.5],[1261,543,0.5],[1292,508,0.5],[1313,480,0.5],[1341,420,0.5],[1339,409,0.5],[1318,400,0.5],[1254,406,0.5],[1155,442,0.5],[1035,512,0.5],[932,585,0.5],[836,667,0.5],[758,743,0.5],[724,785,0.5],[704,814,0.5],[686,843,0.5],[666,887,0.5],[659,916,0.5],[685,915,0.5],[767,878,0.5],[884,801,0.5],[977,728,0.5],[1051,667,0.5],[1140,590,0.5],[1218,521,0.5],[1260,481,0.5],[1325,417,0.5],[1334,405,0.5],[1334,399,0.5],[1306,412,0.5],[1172,492,0.5],[1112,530,0.5],[1079,553,0.5],[1039,582,0.5],[1016,601,0.5]]}
11
+ ]
12
+ }
13
+ }
Binary file
@@ -0,0 +1,66 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="960" height="800" viewBox="0 0 960 800">
2
+ <!-- A Markdown file becoming a stack of slides. The colours come from the
3
+ deck's palette (var(--accent) …), so the picture follows the theme;
4
+ the fallbacks apply where it is shown as a plain image. -->
5
+ <style>
6
+ .mdk-paper { fill: var(--surface, #eef1fb); stroke: var(--rule, #d5dbf0); stroke-width: 3; }
7
+ .mdk-fold { fill: var(--rule, #d5dbf0); }
8
+ .mdk-shadow { fill: var(--ink, #0c1033); opacity: .12; }
9
+ .mdk-code { font-family: ui-monospace, 'JetBrains Mono', Menlo, Consolas, monospace; font-size: 30px; fill: var(--ink-soft, #2a2f55); }
10
+ .mdk-mark { fill: var(--accent, #1f3fd1); font-weight: 700; }
11
+ .mdk-quiet { fill: var(--muted, #5b6080); }
12
+ .mdk-slide { fill: var(--bg, #ffffff); stroke: var(--ink, #0c1033); stroke-width: 3; }
13
+ .mdk-accent { fill: var(--accent, #1f3fd1); }
14
+ .mdk-accent-2 { fill: var(--accent-2, #e8590c); }
15
+ .mdk-rule { fill: var(--rule, #d5dbf0); }
16
+ .mdk-on-accent { fill: var(--on-accent, #ffffff); font-family: var(--font-display, sans-serif); font-weight: 800; font-size: 96px; }
17
+ .mdk-title { fill: var(--ink, #0c1033); font-family: var(--font-display, sans-serif); font-weight: 800; font-size: 46px; }
18
+ .mdk-arrow { fill: none; stroke: var(--accent-2, #e8590c); stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; }
19
+ </style>
20
+
21
+ <!-- The text file -->
22
+ <g transform="rotate(-5 230 400)">
23
+ <rect class="mdk-shadow" x="56" y="146" width="370" height="510" rx="18"/>
24
+ <path class="mdk-paper" d="M58 130 h290 l62 62 v438 a18 18 0 0 1 -18 18 h-316 a18 18 0 0 1 -18 -18 v-482 a18 18 0 0 1 18 -18 z"/>
25
+ <path class="mdk-fold" d="M348 130 v44 a18 18 0 0 0 18 18 h44 z"/>
26
+ <text class="mdk-code" x="84" y="232"><tspan class="mdk-mark">#</tspan> A talk</text>
27
+ <text class="mdk-code" x="84" y="300"><tspan class="mdk-mark">-</tspan> one idea</text>
28
+ <text class="mdk-code" x="84" y="344"><tspan class="mdk-mark">-</tspan> an example</text>
29
+ <text class="mdk-code mdk-mark" x="84" y="412">---</text>
30
+ <text class="mdk-code mdk-quiet" x="84" y="480">:::notes</text>
31
+ <text class="mdk-code mdk-quiet" x="84" y="524">pause here</text>
32
+ <text class="mdk-code mdk-quiet" x="84" y="568">:::</text>
33
+ </g>
34
+
35
+ <!-- From text to slides -->
36
+ <path class="mdk-arrow" d="M300 112 C 380 20, 560 22, 640 150" stroke-dasharray="2 16"/>
37
+ <path class="mdk-arrow" d="M612 138 l30 16 l4 -34"/>
38
+ <path class="mdk-accent" d="M470 60 l7 17 l17 7 l-17 7 l-7 17 l-7 -17 l-17 -7 l17 -7 z"/>
39
+ <path class="mdk-accent-2" d="M760 210 l5 12 l12 5 l-12 5 l-5 12 l-5 -12 l-12 -5 l12 -5 z"/>
40
+
41
+ <!-- The slides: a chapter, a statement, and a content slide in front -->
42
+ <g transform="rotate(9 680 330)">
43
+ <rect class="mdk-accent-2" x="440" y="200" width="480" height="270" rx="14"/>
44
+ </g>
45
+ <g transform="rotate(3 660 420)">
46
+ <rect class="mdk-accent" x="420" y="290" width="480" height="270" rx="14"/>
47
+ <text class="mdk-on-accent" x="452" y="386">2</text>
48
+ <rect class="mdk-accent-2" x="512" y="350" width="80" height="10" rx="5"/>
49
+ </g>
50
+ <g transform="rotate(-3 640 540)">
51
+ <rect class="mdk-shadow" x="412" y="420" width="480" height="270" rx="14"/>
52
+ <rect class="mdk-slide" x="400" y="404" width="480" height="270" rx="14"/>
53
+ <text class="mdk-title" x="432" y="470">A talk</text>
54
+ <rect class="mdk-accent" x="432" y="486" width="88" height="8" rx="4"/>
55
+ <rect class="mdk-accent" x="432" y="524" width="14" height="14" rx="3"/>
56
+ <rect class="mdk-rule" x="458" y="525" width="150" height="12" rx="6"/>
57
+ <rect class="mdk-accent" x="432" y="562" width="14" height="14" rx="3"/>
58
+ <rect class="mdk-rule" x="458" y="563" width="120" height="12" rx="6"/>
59
+ <rect class="mdk-accent" x="432" y="600" width="14" height="14" rx="3"/>
60
+ <rect class="mdk-rule" x="458" y="601" width="136" height="12" rx="6"/>
61
+ <rect class="mdk-accent-2" x="682" y="580" width="34" height="62" rx="4"/>
62
+ <rect class="mdk-accent" x="726" y="530" width="34" height="112" rx="4"/>
63
+ <rect class="mdk-accent-2" x="770" y="556" width="34" height="86" rx="4"/>
64
+ <rect class="mdk-accent" x="814" y="500" width="34" height="142" rx="4"/>
65
+ </g>
66
+ </svg>
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 1,
3
+ "width": 1920,
4
+ "height": 1080,
5
+ "slides": {
6
+ "draw-on-any-slide": [
7
+ {"id":"tour:underline","tool":"pen","color":"#e11d48","size":7,"points":[[120,462,0.45],[135,464,0.48],[150,466,0.52],[165,467,0.55],[180,468,0.58],[195,469,0.61],[210,469,0.64],[225,468,0.66],[240,467,0.68],[255,465,0.7],[270,464,0.72],[285,462,0.73],[300,460,0.74],[315,459,0.75],[330,458,0.75],[345,458,0.75],[360,459,0.74],[375,460,0.73],[390,461,0.72],[405,463,0.71],[420,465,0.69],[435,467,0.67],[450,469,0.64],[465,470,0.62],[480,471,0.59],[495,472,0.56],[510,472,0.53],[525,471,0.49],[540,470,0.46],[555,468,0.43],[570,467,0.39],[585,465,0.36],[600,464,0.33],[615,462,0.3],[630,462,0.27],[645,461,0.25],[660,462,0.22],[675,462,0.2],[690,464,0.19],[705,466,0.17],[720,468,0.16]]},
8
+ {"id":"tour:circle","tool":"pen","color":"#e11d48","size":6,"points":[[226,491,0.5],[230,491,0.54],[235,491,0.57],[239,492,0.6],[243,494,0.64],[247,497,0.66],[250,500,0.69],[252,504,0.71],[254,508,0.73],[255,512,0.74],[256,516,0.75],[255,520,0.75],[254,524,0.75],[252,528,0.74],[250,532,0.73],[247,534,0.71],[244,537,0.69],[240,539,0.66],[237,541,0.63],[233,542,0.6],[229,543,0.57],[225,543,0.54],[221,543,0.5],[217,543,0.46],[213,541,0.43],[209,540,0.4],[206,538,0.36],[203,535,0.34],[200,531,0.31],[198,528,0.29],[196,523,0.27],[196,519,0.26],[196,515,0.25],[197,510,0.25],[199,506,0.25],[201,503,0.26],[204,500,0.27],[207,497,0.29],[211,495,0.31],[215,494,0.34],[219,493,0.37],[223,493,0.4],[227,493,0.43],[231,493,0.47],[235,495,0.5],[239,496,0.54]]}
9
+ ]
10
+ }
11
+ }