Compare commits

...
5 Commits
Author SHA1 Message Date
HEL 873dc440b8 fix(report): correct T-Assign
thanks @sjrd and @kyouko-taiga
2026-08-24 14:01:29 +02:00
HEL 123a65addf fix: minor typo
missing 'r' in 'Programming'
thanks @pmudry
2026-08-24 13:59:44 +02:00
HEL c5b703efe8 fix(presentation): minor tweaks 2026-08-24 01:10:58 +02:00
HEL 4a69fb5e62 fix(presentation): finishing touches
add progress bar, tweak animations, adjust spacing, add conclusion
2026-08-23 23:24:21 +02:00
HEL 908ae6b779 feat(presentation): present and future 2026-08-23 23:06:25 +02:00
14 changed files with 295 additions and 32 deletions
+7 -3
View File
@@ -8,6 +8,7 @@ report_out_path := outdir / "report.pdf"
summary_out_path := outdir / "summary.pdf" summary_out_path := outdir / "summary.pdf"
poster_out_path := outdir / "poster.pdf" poster_out_path := outdir / "poster.pdf"
presentation_out_path := outdir / "presentation.pdf" presentation_out_path := outdir / "presentation.pdf"
presentation_handout_path := outdir / "presentation_handout.pdf"
presentation_pdfpc_path := outdir / "presentation.pdfpc" presentation_pdfpc_path := outdir / "presentation.pdfpc"
default: all default: all
@@ -45,7 +46,10 @@ presentation: _setup
typst c --root . presentation/presentation.typ {{presentation_out_path}} typst c --root . presentation/presentation.typ {{presentation_out_path}}
typst eval --root . 'query(<pdfpc-file>).first().value' --in presentation/presentation.typ > {{presentation_pdfpc_path}} typst eval --root . 'query(<pdfpc-file>).first().value' --in presentation/presentation.typ > {{presentation_pdfpc_path}}
present: presentation presentation-handout: _setup
pympress {{presentation_out_path}} typst c --root . --input handout=true presentation/presentation.typ {{presentation_handout_path}}
all: report summary poster presentation present: presentation
pdfpc {{presentation_out_path}}
all: report summary poster presentation presentation-handout
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.5 KiB

+6 -2
View File
@@ -4,14 +4,18 @@ from qrcode.image.svg import SvgPathImage
def main(): def main():
urls: dict[str, str] = { urls: dict[str, str | tuple[str, int | None]] = {
"gitea": "https://git.kb28.ch/HEL/midas", "gitea": "https://git.kb28.ch/HEL/midas",
"github": "https://github.com/LordBaryhobal/midas", "github": "https://github.com/LordBaryhobal/midas",
"docs": "https://git.kb28.ch/HEL/TB-Docs",
} }
factory = SvgPathImage factory = SvgPathImage
for name, url in urls.items(): 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.add_data(url)
qr.make() qr.make()
img = qr.make_image(image_factory=factory) img = qr.make_image(image_factory=factory)
+1 -1
View File
@@ -121,7 +121,7 @@
caption: [Implementation architecture overview] caption: [Implementation architecture overview]
) <fig:architecture> ) <fig:architecture>
First, typing rules were formally defined, drawing heavily on _Types and Progamming Languages_@tapl. First, typing rules were formally defined, drawing heavily on _Types and Programming Languages_@tapl.
The implementation of the parser for the definition language follows R. Nystrom's _Crafting Interpreters_@Nystrom2021. The whole system is itself implemented in Python, leveraging the language's own `ast` module to parse and manipulate source code. The implementation of the parser for the definition language follows R. Nystrom's _Crafting Interpreters_@Nystrom2021. The whole system is itself implemented in Python, leveraging the language's own `ast` module to parse and manipulate source code.
The type checker also includes some machinery to infer the result types of several *dataframe operations* and *aggregation methods*. The type checker also includes some machinery to infer the result types of several *dataframe operations* and *aggregation methods*.
] ]
+30 -3
View File
@@ -2,11 +2,12 @@
#import "../meta.typ" #import "../meta.typ"
#import codly: codly-init, codly #import codly: codly-init, codly
#import "@preview/codly-languages:0.1.10": codly-languages #import "@preview/codly-languages:0.1.10": codly-languages
#import "@preview/tiaoma:0.3.0"
#pdfpc.config( #pdfpc.config(
start-time: datetime(hour: 13, minute: 15, second: 0), start-time: datetime(hour: 13, minute: 15, second: 0),
end-time: datetime(hour: 13, minute: 55, second: 0),
duration-minutes: 20, duration-minutes: 20,
last-minutes: 3
) )
#show raw.where(block: true): set text(size: 0.8em) #show raw.where(block: true): set text(size: 0.8em)
@@ -43,14 +44,38 @@
//subtitle: meta.subtitle, //subtitle: meta.subtitle,
//short-title: [Midas], //short-title: [Midas],
//short-subtitle: [Hybrid Type Checking for Python], //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( config-common(
enable-pdfpc: true, enable-pdfpc: true,
handout: sys.inputs.at("handout", default: "false") == "true",
slide-fn: slide,
), ),
config-store( 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( #title-slide(
@@ -64,3 +89,5 @@
#include "sections/02_state_of_the_art.typ" #include "sections/02_state_of_the_art.typ"
#include "sections/03_midas.typ" #include "sections/03_midas.typ"
#include "sections/04_status_and_future.typ" #include "sections/04_status_and_future.typ"
#include "sections/05_conclusion.typ"
#include "sections/06_appendix.typ"
+111
View File
@@ -1,3 +1,114 @@
#import "@preview/touying:0.7.4": * #import "@preview/touying:0.7.4": *
#import "@preview/touying-unistra-pristine:1.4.3": * #import "@preview/touying-unistra-pristine:1.4.3": *
#import "@local/codly:1.3.1" #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,
)
})
+14 -4
View File
@@ -1,13 +1,21 @@
#import "../requirements.typ": * #import "../requirements.typ": *
#focus-slide(theme: "berry")[The Issue] #focus-slide(theme: "berry")[The Issue]
// = The issue = The issue
== A popular language == A popular language
#align(center, image("../figs/python-logo.svg")) #align(center, image("../figs/python-logo.svg"))
Python is a widely used language, especially in data science Python is a widely used language, especially in data science:
#item-by-item[
- Easy to learn
- Simple syntax
- Vast and thriving ecosystem
]
== It can bite == It can bite
@@ -18,11 +26,13 @@ transactions = load_transactions()
mean_amount = np.mean(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 #pause
Until its not Until it's not
```python ```python
def load_transactions(): def load_transactions():
@@ -1,15 +1,19 @@
#import "../requirements.typ": * #import "../requirements.typ": *
#focus-slide(theme: "mandarine")[What's Out There?] #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/mypy_logo.svg"),
image("../figs/pyright-logo.png"), image("../figs/pyright-logo.png"),
title: [Existing Type Checkers],
columns: 2,
gutter: 3em,
) )
#v(1fr)
== Community Packages for Pandas == Community Packages for Pandas
+5 -8
View File
@@ -7,7 +7,7 @@
#import "@preview/conch:0.1.0" #import "@preview/conch:0.1.0"
#focus-slide(theme: "forest")[Making Python Better] #focus-slide(theme: "forest")[Making Python Better]
// = Making Python Better = Making Python Better
== Strict Typing Rules == Strict Typing Rules
@@ -428,22 +428,22 @@ Steps:
unknown = fetch_data() unknown = fetch_data()
speed = cast(Meter, unknown) speed = cast(Meter, unknown)
```, ```,
rotate(-90deg, reflow: true)[*Generated*], uncover("2-", rotate(-90deg, reflow: true)[*Generated*]),
```python uncover("2-", ```python
from lib import fetch_data from lib import fetch_data
unknown = fetch_data() unknown = fetch_data()
__midas_a0__ = unknown __midas_a0__ = unknown
assert isinstance(__midas_a0__, float), f'script.py:L3:9: CastError: Cannot cast {type(__midas_a0__).__name__} to float' assert isinstance(__midas_a0__, float), f'script.py:L3:9: CastError: Cannot cast {type(__midas_a0__).__name__} to float'
speed = __midas_a0__ speed = __midas_a0__
del __midas_a0__ del __midas_a0__
``` ```)
) )
} }
== Customization == Customization
#{ #{
show raw: set text(size: 0.69em) show raw: set text(size: 0.8em)
item-by-item()[ item-by-item()[
- Domain Specific Types (e.g. units, scores, transformed data) - Domain Specific Types (e.g. units, scores, transformed data)
```midas ```midas
@@ -519,11 +519,8 @@ Generates runtime checks
#figure( #figure(
align( align(
left + top, left + top,
alternatives(
make-cast-error(python-outputs.data1),
make-cast-error(python-outputs.data2), make-cast-error(python-outputs.data2),
) )
)
) )
--- ---
+64 -1
View File
@@ -1,4 +1,67 @@
#import "../requirements.typ": * #import "../requirements.typ": *
#import codly: codly
#focus-slide(theme: "neon")[Current Status and Future] #focus-slide(theme: "neon")[Current Status and Future]
// = Current Status and Future = Current Status and Future
== What Midas offers
#v(-0.5em)
#item-by-item[
- Working *static type checking* of a good subset of Python (including dataframes)
- *Custom type* definition language for domain-specific usages (supports generics, method overloads, dependent types, frame schemas, named predicates and more)
- Toolbox *CLI* with useful debug features
- Generation of *runtime assertions*
- Stubs for *seamless integration* with other type checkers
]
== What needs work
#{
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)
- Constraint solver
$
v in [1; 6] => v > 0
$
]
+38
View File
@@ -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)
+3
View File
@@ -0,0 +1,3 @@
#import "../requirements.typ": *
#show: appendix
+1 -1
View File
@@ -1,7 +1,7 @@
#import "@preview/acrostiche:0.7.0": * #import "@preview/acrostiche:0.7.0": *
#let acronyms = ( #let acronyms = (
"TaPL": ([Types and Progamming Languages@tapl],), "TaPL": ([Types and Programming Languages@tapl],),
"LSP": (link("https://en.wikipedia.org/wiki/Liskov_substitution_principle")[Liskov substitution principle],), "LSP": (link("https://en.wikipedia.org/wiki/Liskov_substitution_principle")[Liskov substitution principle],),
"AST": ([Abstract Syntax Tree],), "AST": ([Abstract Syntax Tree],),
"LUB": ([Least Upper Bound],), "LUB": ([Least Upper Bound],),
+1 -1
View File
@@ -103,7 +103,7 @@
), ),
rule( rule(
"T-Assign", "T-Assign",
$Gamma tack "x": "T"$, $"x": "T" in Gamma$,
$Gamma tack "t": "T"$, $Gamma tack "t": "T"$,
$Gamma tack "x" = "t" tack.l Gamma$, $Gamma tack "x" = "t" tack.l Gamma$,
```py x = t```, ```py x = t```,