From 4a69fb5e622c6affe632caa7bc106b6bcd82c56c Mon Sep 17 00:00:00 2001 From: LordBaryhobal Date: Sun, 23 Aug 2026 23:24:21 +0200 Subject: [PATCH] fix(presentation): finishing touches add progress bar, tweak animations, adjust spacing, add conclusion --- poster/figs/qr_docs.svg | 2 + poster/figs/qrs.py | 8 +- presentation/presentation.typ | 33 ++++- presentation/requirements.typ | 113 +++++++++++++++++- presentation/sections/01_introduction.typ | 19 ++- presentation/sections/02_state_of_the_art.typ | 14 ++- presentation/sections/03_midas.typ | 13 +- .../sections/04_status_and_future.typ | 72 ++++++----- presentation/sections/05_conclusion.typ | 38 ++++++ presentation/sections/06_appendix.typ | 3 + 10 files changed, 260 insertions(+), 55 deletions(-) create mode 100644 poster/figs/qr_docs.svg create mode 100644 presentation/sections/05_conclusion.typ create mode 100644 presentation/sections/06_appendix.typ diff --git a/poster/figs/qr_docs.svg b/poster/figs/qr_docs.svg new file mode 100644 index 0000000..2790a61 --- /dev/null +++ b/poster/figs/qr_docs.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/poster/figs/qrs.py b/poster/figs/qrs.py index 8030a5c..70fa99d 100644 --- a/poster/figs/qrs.py +++ b/poster/figs/qrs.py @@ -4,14 +4,18 @@ from qrcode.image.svg import SvgPathImage def main(): - urls: dict[str, str] = { + urls: dict[str, str | tuple[str, int | None]] = { "gitea": "https://git.kb28.ch/HEL/midas", "github": "https://github.com/LordBaryhobal/midas", + "docs": "https://git.kb28.ch/HEL/TB-Docs", } factory = SvgPathImage for name, url in urls.items(): - qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_Q, version=4) + version: int | None = 4 + if isinstance(url, tuple): + url, version = url + qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_Q, version=version) qr.add_data(url) qr.make() img = qr.make_image(image_factory=factory) diff --git a/presentation/presentation.typ b/presentation/presentation.typ index f6b10a9..2a589c7 100644 --- a/presentation/presentation.typ +++ b/presentation/presentation.typ @@ -2,6 +2,7 @@ #import "../meta.typ" #import codly: codly-init, codly #import "@preview/codly-languages:0.1.10": codly-languages +#import "@preview/tiaoma:0.3.0" #pdfpc.config( start-time: datetime(hour: 13, minute: 15, second: 0), @@ -43,14 +44,38 @@ //subtitle: meta.subtitle, //short-title: [Midas], //short-subtitle: [Hybrid Type Checking for Python], - logo: image("figs/isc_logo.svg"), + //logo: image("figs/isc_logo.svg"), + logo: { + image("figs/isc_logo.svg") + place( + left + horizon, + dx: 100% + 1em, + clearance: 0pt, + //scale(80%, tiaoma.qrcode("https://url.kb28.ch/nws0")) + scale(80%, tiaoma.qrcode("https://git.kb28.ch/HEL/TB-Docs/releases/download/official/presentation_handout.pdf")) + ) + }, ), config-common( enable-pdfpc: true, + handout: sys.inputs.at("handout", default: "false") == "true", + slide-fn: slide, ), config-store( - font: "Source Sans Pro" - ) + footer-appendix-label: "A", + show-header: { + place( + top + left, + utils.touying-progress( + ratio => box( + width: ratio * 100%, + height: 6pt, + fill: orange.C + ) + ) + ) + } + ), ) #title-slide( @@ -64,3 +89,5 @@ #include "sections/02_state_of_the_art.typ" #include "sections/03_midas.typ" #include "sections/04_status_and_future.typ" +#include "sections/05_conclusion.typ" +#include "sections/06_appendix.typ" \ No newline at end of file diff --git a/presentation/requirements.typ b/presentation/requirements.typ index 45f8a0f..7d5a0aa 100644 --- a/presentation/requirements.typ +++ b/presentation/requirements.typ @@ -1,3 +1,114 @@ #import "@preview/touying:0.7.4": * #import "@preview/touying-unistra-pristine:1.4.3": * -#import "@local/codly:1.3.1" \ No newline at end of file +#import "@local/codly:1.3.1" + +// Adapted from: +// https://github.com/spidersouris/touying-unistra-pristine/blob/67084e00529991bfbd12152c0f074c582cba0093/src/unistra.typ#L22-L126 +#let slide( + config: (:), + repeat: auto, + setting: body => body, + composer: auto, + ..bodies, +) = touying-slide-wrapper(self => { + let footer(self) = { + let cell(body) = rect( + width: 100%, + height: 100%, + inset: 0mm, + outset: 0mm, + fill: none, + stroke: none, + text(size: 0.5em, fill: self.colors.black, body), + ) + + let author = self.info.author + let date = self.info.date + if self.store.footer-hide.contains("author") { + author = none + } + + if self.store.footer-hide.contains("date") { + date = none + } + + set align(center + horizon) + block(width: 101%, height: -25%, stroke: (top: 0.5pt + self.colors.black), { + set text(size: 1.5em) + + // give priority to short, since long is also used in title slide + let title = self.info.title + if (self.info.short-title != auto) { + title = self.info.short-title + } + + let first-col-width = 15% + let second-col-width = 75% + + grid( + columns: (first-col-width, second-col-width, 10%), + rows: 0.5em, + stroke: (x: 1pt + self.colors.black), + cell(box(self.info.logo, height: 100%)), + cell(box( + width: 100%, + text( + title, // either title or short-title + weight: "bold", + ) + + self.store.footer-first-sep + + if _is(author) { author } + + if _is(date) and _is(author) { + self.store.footer-second-sep + } else { "" } + + if _is(date) { date }, + )), + cell(utils.call-or-display(self, context { + let current = int(utils.slide-counter.display()) + let last = int(utils.last-slide-counter.display()) + if current > last { + ( + text(self.store.footer-appendix-label, style: "italic") + + str(current) + ) + } else { + str(current) + } + } + + " / " + + utils.last-slide-number)), + ) + }) + } + + let store-header = self.store.show-header + let store-footer = self.store.show-footer + + let self = utils.merge-dicts(self, config-page( + header: if store-header == true { + unistra-nav-bar(self) + } else if store-header == false { + none + } else { + store-header + }, + footer: if store-footer == true { + footer + } else if store-footer == false { + none + } else { + store-footer + }, + // todo: change if no footer/header, etc. + margin: (x: 3em, y: 2em), + )) + + touying-slide( + self: self, + config: config, + repeat: repeat, + setting: setting, + composer: composer, + ..bodies, + ) +}) \ No newline at end of file diff --git a/presentation/sections/01_introduction.typ b/presentation/sections/01_introduction.typ index 63935c0..1edb906 100644 --- a/presentation/sections/01_introduction.typ +++ b/presentation/sections/01_introduction.typ @@ -1,16 +1,21 @@ #import "../requirements.typ": * #focus-slide(theme: "berry")[The Issue] -// = The issue += The issue == A popular language #align(center, image("../figs/python-logo.svg")) Python is a widely used language, especially in data science: -- Easy to learn -- Simple syntax -- Vast and thriving ecosystem +#item-by-item[ + + - Easy to learn + + - Simple syntax + + - Vast and thriving ecosystem +] == It can bite @@ -21,11 +26,13 @@ transactions = load_transactions() mean_amount = np.mean(transactions) ``` -// Il y a comme un couac -> duck-typing +#speaker-note[ + Il y a comme un couac -> duck-typing +] #pause -Until its not +Until it's not ```python def load_transactions(): diff --git a/presentation/sections/02_state_of_the_art.typ b/presentation/sections/02_state_of_the_art.typ index 279a81e..aa1ff67 100644 --- a/presentation/sections/02_state_of_the_art.typ +++ b/presentation/sections/02_state_of_the_art.typ @@ -1,15 +1,19 @@ #import "../requirements.typ": * #focus-slide(theme: "mandarine")[What's Out There?] -// = What's out there? += What's out there? -#gallery( +== Existing Type Checkers + +#v(1fr) +#grid( + columns: (1fr, 1fr), + column-gutter: 3em, + align: center + horizon, image("../figs/mypy_logo.svg"), image("../figs/pyright-logo.png"), - title: [Existing Type Checkers], - columns: 2, - gutter: 3em, ) +#v(1fr) == Community Packages for Pandas diff --git a/presentation/sections/03_midas.typ b/presentation/sections/03_midas.typ index 1cabcbc..6a32b06 100644 --- a/presentation/sections/03_midas.typ +++ b/presentation/sections/03_midas.typ @@ -7,7 +7,7 @@ #import "@preview/conch:0.1.0" #focus-slide(theme: "forest")[Making Python Better] -// = Making Python Better += Making Python Better == Strict Typing Rules @@ -428,15 +428,15 @@ Steps: unknown = fetch_data() speed = cast(Meter, unknown) ```, - rotate(-90deg, reflow: true)[*Generated*], - ```python + uncover("2-", rotate(-90deg, reflow: true)[*Generated*]), + uncover("2-", ```python from lib import fetch_data unknown = fetch_data() __midas_a0__ = unknown assert isinstance(__midas_a0__, float), f'script.py:L3:9: CastError: Cannot cast {type(__midas_a0__).__name__} to float' speed = __midas_a0__ del __midas_a0__ - ``` + ```) ) } @@ -519,10 +519,7 @@ Generates runtime checks #figure( align( left + top, - alternatives( - make-cast-error(python-outputs.data1), - make-cast-error(python-outputs.data2), - ) + make-cast-error(python-outputs.data2), ) ) diff --git a/presentation/sections/04_status_and_future.typ b/presentation/sections/04_status_and_future.typ index 24e1514..df32a0d 100644 --- a/presentation/sections/04_status_and_future.typ +++ b/presentation/sections/04_status_and_future.typ @@ -2,49 +2,60 @@ #import codly: codly #focus-slide(theme: "neon")[Current Status and Future] -// = Current Status and Future += Current Status and Future == What Midas offers -- Working *static type checking* of a good subset of Python (including dataframes) +#v(-0.5em) +#item-by-item[ -- *Custom type* definition language for domain-specific usages (supports generics, method overloads, dependent types, frame schemas, named predicates and more) + - Working *static type checking* of a good subset of Python (including dataframes) -- Toolbox *CLI* with useful debug features + - *Custom type* definition language for domain-specific usages (supports generics, method overloads, dependent types, frame schemas, named predicates and more) -- Generation of *runtime assertions* + - Toolbox *CLI* with useful debug features -- Stubs for *seamless integration* with other type checkers + - Generation of *runtime assertions* + + - Stubs for *seamless integration* with other type checkers +] == What needs work -- Reference types (side effects) - ```python - def modify_column(df: pd.DataFrame): - df["col"] = df["col"].astype(float) - ``` -- Reverse operators - ```python - a = 1.0 + 1 # float.__add__(int) - b = 1 + 1.0 # float.__radd__(int) - ``` -- Logical short-circuit bypass - #codly( - highlights: ( - ( - line: 1, - start: 15, - tag: box(inset: (x: 0.5em))[_Always evaluated_ ], - fill: std.red.lighten(20%) - ), - ) - ) - ```python - value = v1 or cast(Type, v2) - ``` +#{ + show raw: set text(size: 0.85em) + item-by-item[ + - Reference types (side effects) + ```python + def modify_column(df: pd.DataFrame): + df["col"] = df["col"].astype(float) + ``` + - Reverse operators + ```python + a = 1.0 + 1 # float.__add__(int) + b = 1 + 1.0 # float.__radd__(int) + ``` + - Logical short-circuit bypass + #codly( + highlights: ( + ( + line: 1, + start: 15, + tag: box(inset: (x: 0.5em))[_Always evaluated_ ], + fill: std.red.lighten(20%) + ), + ) + ) + ```python + value = v1 or cast(Type, v2) + ``` + ] +} == Possible extensions +#item-by-item[ + - Visitor pattern $->$ easy to extend supported Python syntax - Multi-file projects (```python import``` statements) @@ -53,3 +64,4 @@ $ v in [1; 6] => v > 0 $ +] \ No newline at end of file diff --git a/presentation/sections/05_conclusion.typ b/presentation/sections/05_conclusion.typ new file mode 100644 index 0000000..956370d --- /dev/null +++ b/presentation/sections/05_conclusion.typ @@ -0,0 +1,38 @@ +#import "../requirements.typ": * + +#focus-slide(theme: "smoke")[Thanks for listening !] += Thanks for listening ! + +== Repositories + +#let repos = ( + ([Code], path("../../poster/figs/qr_gitea.svg"), "https://git.kb28.ch/HEL/midas"), + ([Code (mirror)], path("../../poster/figs/qr_github.svg"), "https://github.com/LordBaryhobal/midas"), + ([Docs], path("../../poster/figs/qr_docs.svg"), "https://git.kb28.ch/HEL/TB-Docs"), +) + +#let repo(name, code, url) = { + stack( + dir: ttb, + spacing: 0.2em, + strong(text(size: 0.8em, name)), + image(code, width: 3cm), + { + set text(size: 0.6em) + link(url) + } + ) +} + +#v(1fr) + +#grid( + columns: (1fr, 1fr), + align: center + horizon, + row-gutter: 2em, + repo(..repos.at(0)), + repo(..repos.at(1)), + grid.cell(colspan: 2, repo(..repos.at(2))) +) + +#v(1fr) \ No newline at end of file diff --git a/presentation/sections/06_appendix.typ b/presentation/sections/06_appendix.typ new file mode 100644 index 0000000..fc4d2c3 --- /dev/null +++ b/presentation/sections/06_appendix.typ @@ -0,0 +1,3 @@ +#import "../requirements.typ": * + +#show: appendix