Experience
-
Sigma
Software Engineer Intern, New York, NY
- Built the Manual AI Columns feature end to end and shipped it to production.
- Added a caching layer and a schema-level index that cut query latency by 75%.
- Designed a system that tracks model deprecations across Snowflake and Databricks and alerts the team in Slack.
-
Zwilling J.A. Henckels
Data Science Intern, New York, NY
- Built a pipeline that audits shipment reports automatically, keeping data integrity at 99.9%.
- Made a dashboard for monitoring KPIs and tuning slow SQL queries.
-
Bucherer 1888
Data Management Intern, New York, NY
- Wrote validation scripts covering 100,000+ records with no downstream errors.
- Reconciled invoice and product data across legacy systems, cutting review time by 90%.
-
Lowe’s
Software Engineer Intern, Charlotte, NC
- Built and deployed ProRange, a platform used in more than 1,700 stores.
- Improved backend API performance by 25% and reduced scheduling errors.
-
Vassar College
Cognitive Science Programmer, Poughkeepsie, NY
- Built browser-based experiments that ran with more than 100 participants.
- Automated data processing for 10,000+ trials, cutting preprocessing time by 40%.
-
Sponsors for Educational Opportunity
Tech Developer Intern, New York, NY
- Built internal tools used daily by more than 50 staff.
- Set up CI/CD and a test suite with 90% coverage.
Projects
-
Receipts
A query engine in Rust, compiled to WebAssembly, that lets you click any number computed from NYC 311 data and see the rows behind it.
- Runs over content-addressed Arrow IPC snapshots in 64Ki-row chunks. The browser re-derives every BLAKE3 hash on load and refuses data that doesn’t match.
- Captures lineage at every operator (selection vectors, CSR group membership) for backward and forward tracing, adding about 6% to execution time on 7.1M rows.
- Computes exact counterfactuals: it re-derives a result without chosen rows, recomputing only the affected groups when it can, and matches a full re-run bit for bit.
- The Rayon-parallel WASM build loads and verifies all 7.1M rows in under 2 seconds. Nine workspace crates, property tests, and a pyarrow differential oracle.
-
Chapter
An offline-first RSVP speed reader for EPUB, PDF, and text files, installable as a PWA.
- Parses EPUBs with JSZip and DOMParser (OPF manifest and spine) and PDFs with pdf.js in Web Workers, reading pages in parallel on multi-core machines and stripping running headers.
- Times each word against performance.now() deadlines so playback doesn’t drift, weighting length, punctuation, rare words, and first mentions of names, then normalizing so the chosen WPM is the true average.
- Full-text search runs in a Web Worker over an Int32Array inverted index, with stemming, prefix matching, and an edit-distance fallback for typos.
- Books, progress, and bookmarks persist in IndexedDB. CI runs 196 Vitest unit tests and 67 Playwright tests on desktop and mobile.
-
Music Generation
A PyTorch melody model that continues a musical prompt, with a demo that runs the trained Transformer in your browser.
- A decoder-only Transformer with rotary position embeddings, pre-LayerNorm, and a sliding-window KV cache, compared against token and piano-roll LSTM baselines.
- A REMI-style event tokenizer with tempo-aware quantization. Sampling supports temperature, top-k, and nucleus sampling, a grammar mask, and key constraints estimated with Krumhansl–Schmuckler.
- The demo reimplements the forward pass in JavaScript over 1.6 MB of float16 weights in a Web Worker, parity-tested against the PyTorch logits.
- Trained with AdamW, warm-up and cosine decay, and early stopping, and evaluated with perplexity and Yang & Lerch musical metrics. 84 pytest cases run on Python 3.10–3.12 in CI.
-
Does Morality Pop Out?
An EEG replication of Gantman et al. (2020) with 34 participants, published as an interactive page that refits the statistics in the browser.
- Found a bug in the original analysis: R’s gee() only clusters contiguous rows, so the published models fit about 5,000 one-trial clusters instead of 34 participants. Fixing it changes one conclusion.
- Ported the gee package’s exchangeable-correlation GEE with sandwich variance to JavaScript, matching 66 reference fits from R to about 1e-12.
- Compressed 1.5 GB of EEG data into 2.3 MB of per-participant moments in 25 ms bins, so any time window can be refit in about 0.35 ms.
- Includes a one-minute version of the masked word task with requestAnimationFrame timing. The full report is written in Quarto and R.
Visit site: Does Morality Pop Out? Source code: Does Morality Pop Out?
-
Brightness Perception
A jsPsych experiment, run on Prolific, testing whether a word’s emotional valence biases how bright a gray square looks.
- A custom jsPsych plugin sequences fixation, word, and probe with requestAnimationFrame, logging measured display durations and reaction times on the performance clock.
- Seeded, reproducible randomization of 80 trials, with a repeat-detection cover task, an accuracy-gated practice block, and a valence-rating manipulation check.
- Analysis runs in the browser and in Node: response rates by valence and cover-task d′ with the Hautus log-linear correction. Results export as CSV.
- CI verifies the subresource-integrity hashes of CDN scripts, then runs node:test unit tests and Playwright end-to-end tests.
Visit site: Brightness Perception Source code: Brightness Perception