Selected work
Lavori selezionati
Projects
Progetti
Things I built to understand how they work from the inside - emulators, data structures, storage engines, API clients, desktop tooling. Filter by technology.
Cose che ho costruito per capirle da dentro - emulatori, strutture dati, motori di storage, client API, tool desktop. Filtra per tecnologia.
DESKTOP APP · TYPESCRIPT
the-annotator
Offline Windows desktop tool for YOLO object detection datasets: Electron, React and TypeScript, with a Fabric.js canvas for the bounding boxes. It edits the plain YOLO files in place (data.yaml, labels/*.txt), so the training pipeline stays untouched.
Tool desktop offline per Windows per dataset YOLO di object detection: Electron, React e TypeScript, con un canvas Fabric.js per le bounding box. Modifica direttamente i file YOLO (data.yaml, labels/*.txt), così la pipeline di training resta intatta.
- Bulk rename, merge, remap and reorder of classes across every label file
- Impact preview, backup before every bulk operation, rollback on failure
- Atomic writes (temp file, fsync, rename), autosave, per-image undo/redo, 30-day trash
- Context isolation and typed IPC between main and renderer; virtualised image list
- Vitest suites on parsers, bulk ops and rollback; NSIS installer and portable exe
- Rinomina, unione, rimappatura e riordino delle classi su tutti i file di label
- Anteprima dell'impatto, backup prima di ogni operazione bulk, rollback in caso di errore
- Scritture atomiche (file temporaneo, fsync, rename), autosave, undo/redo per immagine, cestino a 30 giorni
- Context isolation e IPC tipizzato tra main e renderer; lista immagini virtualizzata
- Suite Vitest su parser, operazioni bulk e rollback; installer NSIS ed exe portable
WEB APP · GEOSPATIAL
Criminal Geoprofiler
Geographic profiling estimates an offender's anchor point from the crime locations. Four models - Rossmo/CGT, Gaussian KDE, centre of gravity, journey-to-crime - rendered as a probability raster on a Leaflet map. Vanilla JavaScript in ES modules, no build step, Leaflet as the only dependency.
La geoprofilazione criminale stima il punto di ancoraggio di un autore di reati dai luoghi dei delitti. Quattro modelli - Rossmo/CGT, KDE gaussiana, centro di gravità, journey-to-crime - resi come raster di probabilità su una mappa Leaflet. JavaScript vanilla in moduli ES, nessuna build, Leaflet come unica dipendenza.
- Log-likelihood fields normalised once with log-sum-exp: a proper distribution, no underflow
- Grid in Web Mercator to match the map pixel for pixel; distances stay geodesic
- Bilinear resampling and area-percentile contours on a canvas overlay
- Peaks by non-maximum suppression, hit score against an anchor hypothesis, Weiszfeld geometric median
- Undo/redo, state shared via URL, CSV/GeoJSON import, IT/EN interface
- Campi di log-verosimiglianza normalizzati una volta sola con log-sum-exp: distribuzione vera, niente underflow
- Griglia in Web Mercator per coincidere pixel per pixel con la mappa; distanze geodetiche
- Ricampionamento bilineare e contorni per percentile d'area su un overlay canvas
- Picchi per soppressione dei non massimi, hit score contro un'ipotesi di ancoraggio, mediana geometrica di Weiszfeld
- Undo/redo, stato condiviso via URL, import CSV/GeoJSON, interfaccia IT/EN
FINTECH · API CLIENT · JAVA
Alpaca REST Client
Unofficial Java 21 client for Alpaca's Trading v2, Market Data v2 / v1beta3 and Broker v1 REST APIs. Every endpoint in a sync and an async variant on java.net.http.HttpClient, Jackson for JSON, Instant everywhere for time.
Client Java 21 non ufficiale per le API REST di Alpaca: Trading v2, Market Data v2 / v1beta3 e Broker v1. Ogni endpoint in variante sincrona e asincrona su java.net.http.HttpClient, Jackson per il JSON, Instant ovunque per il tempo.
- Retries with exponential backoff and jitter only on idempotent methods
- A timed-out POST /orders is never resent blindly: no duplicate orders
- Per-account rate-limit tracker (multiton) fed by the response headers, to throttle before a 429
- Tolerant JSON decoder for the timestamp formats the API mixes
- Configuration by precedence: system properties, environment, .env file
- Retry con backoff esponenziale e jitter solo sui metodi idempotenti
- Una POST /orders andata in timeout non viene mai reinviata alla cieca: niente ordini doppi
- Tracker del rate limit per account (multiton) alimentato dagli header di risposta, per rallentare prima di un 429
- Decoder JSON tollerante ai formati di timestamp che l'API mescola
- Configurazione per precedenza: system properties, ambiente, file .env
KEY-VALUE STORE · GO
Redis Go Clone
In-memory key-value store over TCP, written in Go with nothing but the standard library: a line-based protocol (GET, SET with optional TTL, DEL, SETEXP, PING), one goroutine per connection and a command-line client.
Key-value store in memoria su TCP, scritto in Go con la sola libreria standard: protocollo a righe (GET, SET con TTL opzionale, DEL, SETEXP, PING), una goroutine per connessione e un client a riga di comando.
- TTLs in a min-heap ordered by expiry: a background goroutine just peeks at the top, so the next key to drop is found in O(1)
- Snapshot every 3 s from a deep copy taken under read locks: clients are never blocked by disk I/O
- Compact binary snapshot (length-prefixed key and value, int64 expiry), flushed and fsynced; replayed on startup to rebuild map and heap
- Structure-aware tokenizer: SET accepts a quoted string or a whole JSON object as one value, tracking nesting and escapes
- Exactly one reply line per command, errors as ERR lines, and connect and I/O deadlines on the client: neither side ever hangs
- TTL in un min-heap ordinato per scadenza: una goroutine in background guarda solo la cima, così la prossima chiave da eliminare si trova in O(1)
- Snapshot ogni 3 s da una deep copy presa sotto read lock: i client non vengono mai bloccati dall'I/O su disco
- Snapshot binario compatto (chiave e valore length-prefixed, scadenza int64), flushato e fsyncato; rieseguito all'avvio per ricostruire map e heap
- Tokenizer consapevole della struttura: SET accetta una stringa tra virgolette o un intero oggetto JSON come singolo valore, gestendo annidamento ed escape
- Esattamente una riga di risposta per comando, errori come righe ERR, e deadline di connessione e I/O sul client: nessuno dei due lati resta mai appeso
TELEGRAM BOT · PYTHON
One Piece Chapter OUT
Telegram bot that announces new One Piece chapters. The release banner only exists in the rendered page, so a Playwright Chromium in stealth mode takes a screenshot and Tesseract OCR reads it.
Bot Telegram che annuncia i nuovi capitoli di One Piece. Il banner dell'uscita esiste solo nella pagina renderizzata, quindi un Chromium Playwright in modalità stealth fa uno screenshot e Tesseract OCR lo legge.
- Two loops in one process: long polling for /start and /stop, weekly notifier active from Thursday
- Subscribers, chapters and announcement cache in SQLite with in-place schema migrations
- First hit of the week is cached; later subscribers are served without re-scraping
- Docker container (Python 3.12, Tesseract, Chromium) on a Raspberry Pi 4, data on a bind mount
- Auto-deployed on every push to master by a self-hosted GitHub Actions runner; secrets via env_file
- Due loop in un processo: long polling per /start e /stop, notifier settimanale attivo dal giovedì
- Iscritti, capitoli e cache dell'annuncio in SQLite con migrazioni di schema in place
- Il primo riscontro della settimana finisce in cache; chi si iscrive dopo è servito senza ri-scraping
- Container Docker (Python 3.12, Tesseract, Chromium) su un Raspberry Pi 4, dati su bind mount
- Deploy automatico a ogni push su master con un runner GitHub Actions self-hosted; segreti via env_file
EMULATOR · GO
CHIP-8 Emulator
CHIP-8 interpreter written from scratch in Go on top of Ebiten: fetch/decode/execute loop, 4 KB of memory, 16 registers, call stack, delay and sound timers, 64×32 framebuffer. Runs the original ROMs: Pong, Tetris, Space Invaders, Breakout.
Interprete CHIP-8 scritto da zero in Go sopra Ebiten: ciclo fetch/decode/execute, 4 KB di memoria, 16 registri, stack delle chiamate, timer di delay e suono, framebuffer 64×32. Fa girare le ROM originali: Pong, Tetris, Space Invaders, Breakout.
- All 34 opcodes decoded from the instruction nibbles, one method each
- XOR sprite drawing with collision flag
- 10 instructions per 60 Hz frame (≈600 Hz CPU), timers ticking at 60 Hz
- 440 Hz beep as a PCM buffer generated once at start-up
- CPU and display dump on an invalid opcode; ~25 ROMs bundled with a terminal picker
- Tutti i 34 opcode decodificati dai nibble dell'istruzione, un metodo ciascuno
- Disegno degli sprite in XOR con flag di collisione
- 10 istruzioni per frame a 60 Hz (≈600 Hz di CPU), timer a 60 Hz
- Beep a 440 Hz come buffer PCM generato una volta all'avvio
- Dump di CPU e display su opcode non valido; ~25 ROM incluse con selettore da terminale
C11 library of the containers C does not ship with - linked list, hash map, binary search tree, matrix - plus string, byte and hashing helpers. Generic over void* payloads, with the ownership contract of every module in its header: who allocates, who frees, and when.
Libreria C11 dei container che il C non fornisce - lista concatenata, hash map, albero binario di ricerca, matrice - più helper per stringhe, byte e hashing. Generici su payload void*, con il contratto di ownership di ogni modulo nell'header: chi alloca, chi libera, e quando.
- Hash map on MurmurHash3 x64 with separate chaining over the linked list; keys always deep-copied, values owned only when a free callback is passed
- Matrix multiply in naive and cache-blocked variants, typed (f64, i64, u32, size_t, long double) and generic via a MatrixOps table
- BST that never copies payloads: deletion swaps them between nodes
- String helpers (copy, concat, trim, split), raw-byte utilities, distinct negative error codes per module
- Tests count frees through callbacks: a value freed twice or never fails the test
- Hash map su MurmurHash3 x64 con chaining sulla lista concatenata; chiavi sempre copiate in profondità, valori posseduti solo se si passa una callback di free
- Moltiplicazione di matrici naive e cache-blocked, tipizzata (f64, i64, u32, size_t, long double) e generica via tabella MatrixOps
- BST che non copia mai i payload: la cancellazione li scambia tra nodi
- Helper per stringhe (copy, concat, trim, split), utility sui byte grezzi, codici di errore negativi distinti per modulo
- I test contano le free tramite callback: un valore liberato due volte o mai fa fallire il test