A realtime rundown and remote event timer in the browser, where the timekeeper changes the rundown and runs the clock from a laptop, the presenters see the time left on a screen in front of them, and the crew and the participants waiting their turn follow the same rundown on their phones, seeing who is on now, how long is left, and when their turn comes. It is for anyone who wants an event to run on time, smoothly, and clearly. Running late is one problem, but not knowing what changed is a bigger one, so even when a session runs over or the rundown shifts, the live rundown is the one schedule everyone trusts.
- Kind
- app
- Field
- Product design, UX design, system design, software architecture, real-time systems, web development, backend engineering, serverless infrastructure, DevOps, product management, market research, pricing
- Stack
- TypeScript, SvelteKit, Bun, Cloud Run, Cloudflare, Firebase Realtime Database, Firebase Auth
- Language
- Bahasa
- Status
- Live at waktumu.com





















Two apps for an apartment tower under construction in Indonesia, one on iOS for residents to enter the building, run the lights, curtains and air conditioning in their unit, order services and pay, and one on the web for the staff who run the building. Underneath sits a smart system platform that knows the building's spaces and devices but never its people, so the apartment keeps its residents to itself and sends over only what each of them may do.
- Kind
- app
- Field
- Product design, UI/UX design, system design, software architecture, mobile development, iOS development, web development, platform development, DevOps, IoT, smart home, access control, integrated building management system, property management
- Stack
- SwiftUI, SvelteKit, Svelte 5, TypeScript, Tailwind CSS, Bun, Go, Tuya Cloud, Cloud Run, Cloudflare, Neon, Postgres, Firebase, Xendit
- Language
- English
- Status
- Building is still under construction
- Your code using this library calls client.UserDevices(ctx, "ay1762310745982Kq7Ts")
- Then this library signed the request with the project's Access Secret (HMAC-SHA256)
- Then this library sent it to the project's data center (openapi-sg.iotbing.com)
- Then this library had its cached access token refused by Tuya (1010 token invalid)
- Then this library fetched a new token, signed the request again, and resent it (8a2d6f0c4e9b1735d8a0c6e2f4b97d13)
- Then this library decoded Tuya's answer into Go types
- The code results in Bedroom lights, Desk lamp, and Kitchen switch ([]tuya.UserDevice, err nil)
- Your code using this library calls app.Devices(ctx, "abraham")
- Then this library looked up the user's linked Tuya account in the store (0 rows in tuya_app_accounts)
- Then this library stopped before anything was sent to Tuya
- The code results in a named error, ready for errors.Is (appaccount.ErrNotLinked)
An open source Go library, go.trueardian.com/tuya, for the Tuya Cloud API, the service that lets software read and switch the lights, plugs, curtains, and other devices built on Tuya, a platform many smart device brands use. Without it, every app that controls those devices writes the same plumbing again, signing every request, fetching and renewing an access token, finding the right data center, and remembering which Tuya account belongs to which of its users. With that in one library, an app imports it and keeps its code about what it does, whether it switches a few devices of its own, runs the rooms of a building, or acts for each of its users.
- Kind
- library
- Field
- Internet of Things, smart home, software engineering, backend engineering, API integration, databases
- Stack
- Go, Tuya Cloud, Postgres, Firestore







- Human: music!
- Ava: sure, something calm, or anything goes?
- Human: anything
- Ava: @yori play what the human's been into lately
- Yori: on it! lately the human keeps listening to Never Is Enough by Iann Dior, it's playing now
- Human: @rafal any important email today? any events? I don't think so
- Rafal: right, nothing, just emails that don't matter, and no events today either
- Human: ok, a slow day then. please open the curtains a little
- Ava: @zee
- Zee: opened them a quarter!!
- Human: oh, I'm picking up Nay at 5 later
- Ava: got it, I'll remind you at 4:30 so you have time to get ready
- 16:30
- Ava: it's 4:30, half an hour until you pick up Nay (woken by Postera)
- 16:45
- Ava: 15 minutes left, time to head out for Nay (woken by Postera)
- 17:00
- Ava: it's 5, Nay is waiting. are you on your way? (woken by Postera)
- Human: yes, I'm already on the way
- Ava: great, I've cancelled your 5:10 reminder. drive safe!
A group chat of AI assistants on web and iOS for people in Indonesia. Unlike popular AI agents and multi-agent systems, which answer in one voice and hide which agent did the work, every agent here is a member of the chat and speaks under its own name. People talk to the main agent, Ava, and she hands the work to the agent who handles it, Zee for the smart home, Yori for music, and Rafal for email, calendar, and contacts. Every agent reads and writes the same chat, so a request is never retold in a summary, and people can see which agent did what or mention one to ask it directly. The agents also remember what was said and what they have learned about each person. When a task belongs to later, Ava wakes herself up when it is due and carries it out on her own, through Postera, my open source Go library that lets an AI agent wake itself at any moment in the future.
- Kind
- app
- Field
- Agentic AI, multi-agent systems, AI engineering, prompt engineering, knowledge graphs, system design, software architecture, backend engineering, web development, iOS development, voice interfaces, API integration, serverless infrastructure, DevOps, smart home, double-entry accounting
- Stack
- Go, Google ADK, Zep, SvelteKit, Bun, SwiftUI, Cloud Run, Cloud Tasks, Neon, Postgres, Firestore, Firebase
- Language
- Bahasa
- Status
- Paused
- Human: put on Cigarettes by Juice WRLD
- Ava to Yori: put on Cigarettes by Juice WRLD
- Yori to Ava: it's playing
- Ava: Cigarettes is playing
- Human: turn the AC off at 4
- Ava: okay, I'll turn it off at 4
- 16:00
- Ava to Zee: turn the AC off
- Zee to Ava: done, the AC is off
- Ava: it's 4, the AC is off
Ava is the lead of the Avagenc agents, an AI agent that ships as a Go module any Avagenc product can import. She takes what a person asks and either answers it herself or hands it to a specialist, and to her each specialist is one more tool. When a task belongs to later, she wakes herself up when it is due and carries it out on her own, through Postera, my open source Go library that lets an AI agent wake itself at any moment in the future. To Avagenc users she is simply Ava, a woman who remembers, and never a system with machinery behind her.
- Kind
- agent
- Field
- Agentic AI, multi-agent systems, AI engineering, prompt engineering, conversation design, software engineering
- Stack
- Go, Google ADK, agentkit, Postera
- Human: close the bedroom curtains
- Zee:
- Tool list_devices: {"devices":[{"id":"bf7e21c94d0a3c5f8e1kqx","category":"cl","name":"Bedroom curtain","status":[{"code":"control","value":"stop"},{"code":"percent_control","value":0}],"code_name_mapping":[]}]}
- Tool send_commands with {"device_id":"bf7e21c94d0a3c5f8e1kqx","commands":[{"code":"percent_control","value":100}]}: {"ok":true}
- let's say user opened curtain manually
- Human: are the bedroom curtains closed?
- Zee:
- Tool device_status with {"device_id":"bf7e21c94d0a3c5f8e1kqx"}: {"status":[{"code":"control","value":"stop"},{"code":"percent_control","value":0}]}
- Human: turn off the living room lamp
- Zee:
- Tool list_devices: {"error":"the human hasn't linked their Tuya account yet — they need to link it before I can see or control any device"}
Zee is an AI agent for homes that run on Tuya, a cloud that many smart home brands build on, and it ships as a Go module any Avagenc product can import. A language model cannot see the room. It only reads and writes text, while curtains move by hand and by app without it knowing, so Zee asks the device instead of trusting what was said before. It turns a message like "close the bedroom curtains" into the exact value the curtain understands, sends it, and says what happened only after Tuya has answered.
- Kind
- agent
- Field
- Agentic AI, AI engineering, prompt engineering, Internet of Things, software engineering, API integration
- Stack
- Go, Google ADK, agentkit, tuya
- Human: put on Cigarettes by Juice WRLD
- Yori:
- Tool search_tracks with {"query":"Cigarettes Juice WRLD"}: {"tracks":[{"id":"…","name":"Cigarettes","artists":["Juice WRLD"],"uri":"spotify:track:…"}, …]}
- Tool play with {"uri":"spotify:track:…"}: no active Spotify device — ask the human to open Spotify somewhere, or check my_devices, then try again
- Tool my_devices: {"devices":[{"id":"…","name":"Web Player (Safari)","is_active":false, …}]}
- Tool play with {"uri":"spotify:track:…","device_id":"…"}: {"ok":true}
- Human: play Flaws and Sins from my azardian playlist, and keep the playlist going after
- Yori:
- Tool my_playlists: {"playlists":[…, {"id":"…","name":"azardian","url":"https://open.spotify.com/playlist/…"}, …]}
- Tool playlist_tracks with {"playlist_id":"…"}: {"tracks":[…, {"id":"…","name":"Flaws and Sins","uri":"spotify:track:…"}, …]}
- Tool play with {"context_uri":"spotify:playlist:…","uri":"spotify:track:…"}: {"ok":true}
Yori is an AI agent for music, a Go module any Avagenc product can import. It searches Spotify, reads a person's playlists and devices, and controls playback, choosing among eleven tools and reading what each one returns until the music is actually playing. It is for someone who would rather ask for a song than look for it and press play. In July 2026, tracing real conversations showed it saying it could not do things Spotify allows, and what that took to fix is the center of this notebook.
- Kind
- agent
- Field
- Agentic AI, AI engineering, prompt engineering, software engineering, API integration
- Stack
- Go, Google ADK, agentkit, spotify
- Human: invite Abraham to swim in Falajawa Beach at 5 pm
- Rafal:
- Tool get_contacts: {"contacts": [{"name": "Abraham", "emails": ["abraham@avagenc.com"]}, {"name": "Ishmael", "emails": ["ishmael@avagenc.com", "ishmaelhasan@gmail.com"]}]}
- Tool get_events with time_min 2026-11-10T17:00:00+07:00, time_max 2026-11-10T18:00:00+07:00: {"events": []}
- Tool add_event with summary Swim with Abraham, location Falajawa Beach, start 2026-11-10T17:00:00+07:00, end 2026-11-10T18:00:00+07:00, guests abraham@avagenc.com: {"attendees": ["abraham@avagenc.com"], "html_link": "https://www.google.com/calendar/event?eid=…"}
- Human: email Ishmael the notes
- Rafal:
- Tool get_contacts: {"contacts": [{"name": "Abraham", "emails": ["abraham@avagenc.com"]}, {"name": "Ishmael", "emails": ["ishmael@avagenc.com", "ishmaelhasan@gmail.com"]}]}
Rafal is the Avagenc agent for a person's Google account, an AI agent that ships as a Go module any Avagenc product can import. It reads and sends mail, checks and adds calendar events, and finds and saves contacts by calling Google itself, and it treats the three as one connected surface. A wrong address sends mail to a stranger, so when a request names a person, Rafal finds the address in Contacts first and never guesses it from the name.
- Kind
- agent
- Field
- Agentic AI, AI engineering, prompt engineering, software engineering, API integration, OAuth and identity
- Stack
- Go, Google ADK, agentkit, gworkspace
- Your code using this library calls sess.Get(ctx, &session.GetRequest{AppName: "chat", UserID: "ardian", SessionID: "8f2c41d0"})
- Then this library read the last 10 messages of the Zep thread (thread 8f2c41d0)
- Then this library checked that the thread belongs to your user (owner ardian)
- Then this library put the local time and the speaker in front of every message ([2026-11-10 15:58 ardian] play Cigarettes)
- Then this library wrote the current local time into the instruction (Time since previous message: 2 minutes)
- The code results in your user's conversation, each message with its time and speaker (err nil)
- Your code using this library calls sess.Get(ctx, &session.GetRequest{AppName: "chat", UserID: "abraham", SessionID: "8f2c41d0"})
- Then this library read the Zep thread (thread 8f2c41d0)
- Then this library compared the owner Zep reports with the user asking (owner ardian)
- The code results in a named error, which the server answers with 403 (zepadk.ErrSessionOwnerMismatch)
An open source Go library, go.trueardian.com/agentkit, that plugs Go clients into AI agents built on Google's Agent Development Kit, ADK for short. An agent can only do what its tools let it do, and it only remembers what its session hands back. Without agentkit, every agent that plays music, switches a lamp, reads mail, or comes back to something later wraps each client call as a tool again, writes what the model reads about it, turns each error into something the model can act on, and connects its conversations to Zep by hand. With agentkit, each service is one import, and one Zep thread can hold one person and many agents, each knowing who said what and what time it is where the person is.
- Kind
- library
- Field
- Agentic AI infrastructure, AI engineering, multi-agent systems, conversation design, software engineering, API integration
- Stack
- Go, Google ADK, Zep, spotify, tuya, gworkspace, Postera
- Without Postera
- Human: I'm picking up Nay at 5, remind me
- Agent: sorry, I can't turn myself on at 5 to remind you, try setting an alarm on your phone
- With Postera
- Human: I'm picking up Nay at 5, remind me
- Agent:
- Tool wake_future_self with 16:45, "remind them to get ready to pick up Nay at 5": pstr_WO9PWWN09DEQKGUVE3781E9V7G
- Tool wake_future_self with 16:55, "check they are getting ready for Nay": pstr_CIK4A7DSLABAVZDYL0AC8FD3P4
- 16:45
- Agent: it's 4:45, time to get ready to pick up Nay at 5
- 16:55
- Agent: are you getting ready already? Nay is at 5
An open source Go library, go.trueardian.com/postera, that gives an AI agent prospective memory, the kind of memory that remembers to do something later. An agent only acts when someone talks to it, so when it promises to follow up tomorrow morning, nothing runs it tomorrow morning. Without Postera, every app that wants its agent to come back to things builds the same pieces again, a store for what the agent meant to do, a queue that calls the agent at that moment, a way to turn 9am into the right instant wherever the person is, and a cleanup for when one of the two fails halfway. With it, the agent writes a message to its future self, a posterum, and at that moment the message comes back and wakes it.
- Kind
- library
- Field
- Agentic AI infrastructure, AI engineering, software engineering, distributed systems, backend engineering, databases
- Stack
- Go, Postgres, Google Cloud Tasks
- Your code using this library calls client.Play(ctx, "ardian", spotify.PlayRequest{URI: "spotify:track:1kBMIYqe0ILRUJZ7K2PV0k"})
- Then this library read your user's refresh token from the store (spotify_tokens)
- Then this library traded it for a fresh access token (BQBp…m2Lw)
- Then this library asked Spotify to play the track on the active device (204 No Content)
- The code results in the track is playing (err nil)
- Your code using this library calls client.Play(ctx, "ardian", spotify.PlayRequest{URI: "spotify:track:1kBMIYqe0ILRUJZ7K2PV0k"})
- Then this library read your user's refresh token and traded it for a fresh access token (BQBp…m2Lw)
- Then this library asked Spotify to play, and Spotify answered 404 (Player command failed: No active device found)
- Then this library read the message to tell this 404 apart from a missing track
- The code results in a named error, ready for errors.Is (spotify.ErrNoActiveDevice)
A Go library, go.trueardian.com/spotify, that gives any Go app or AI agent Spotify search and playback for each of its users. Without it, every app that plays music for its users sets up the same things again, linking each user's Spotify account, storing and refreshing their credentials, and working around how Spotify reports failures and changes its API. With all of that in one library, an app imports it, chooses where credentials live, and stays focused on its own code, and a fix for one of Spotify's changes reaches every app at once.
- Kind
- library
- Field
- Software engineering, backend engineering, API integration, OAuth and identity, databases, agentic AI infrastructure
- Stack
- Go, zmb3/spotify, golang.org/x/oauth2, Postgres, Firestore
- Your code using this library calls calendar.AddEvent(ctx, "ardian", gworkspace.EventInput{Summary: "Swim with Abraham", …})
- Then this library read your user's one refresh token from the store (gworkspace_tokens)
- Then this library traded it for a fresh access token that covers Gmail, Calendar, and Contacts (…/gmail.modify …/gmail.send …/calendar …/contacts)
- Then this library built Google's event with Abraham as a guest and sent it (POST …/calendars/primary/events)
- Then this library turned Google's answer into a plain Go Event
- The code results in Swim with Abraham, 5 to 6 pm, Abraham invited (gworkspace.Event, err nil)
- Your code using this library calls client.Connect(ctx, "ardian", code)
- Then this library traded the code from Google's consent screen for a refresh token
- Then this library compared the scopes Google granted with the ones asked for (…/contacts missing)
- Then this library saved nothing
- The code results in a named error, ready for errors.Is (gworkspace.ErrMissingScopes)
A Go library, go.trueardian.com/gworkspace, that gives any Go app or AI agent its users' Gmail, Calendar, and Contacts through one permission each user gives once, and hands back plain Go types instead of Google's. Without it, every app that acts on a user's Google account sets up the same things again, three of Google's libraries, three lists of permissions, and the storing and refreshing of each user's credentials. With all of that in one library, an app imports it and stays focused on its own code, and when a user cuts it off, by unticking a permission, revoking it, or never linking, the app can tell which.
- Kind
- library
- Field
- Software engineering, backend engineering, API integration, OAuth and identity, databases, agentic AI infrastructure
- Stack
- Go, Google API Go client, golang.org/x/oauth2, Postgres, Firestore
- Your code using this library calls handler := user.HTTPWithID(session.HTTPWithID(timezone.HTTPWithZone(mux))) handler.ServeHTTP(w, r)
- Then this library read the user-id header into the request's context (u_123)
- Then this library read the session-id header into the context (s_456)
- Then this library read the time-zone header and checked it is a real IANA zone (Asia/Jakarta)
- Then this library ran your handler with all three in its context
- The code results in a handler that knows who is calling without touching a header (user.IDFromContext(ctx) "u_123", true)
- Your code using this library calls client := &http.Client{Transport: &api.Transport{Propagators: []api.Propagator{user.PropagateID, session.PropagateID, timezone.PropagateZone}}} resp, err := client.Do(req)
- Then this library read your user, their session, and their time zone from the request's context, where the middleware put them (u_123, s_456, Asia/Jakarta)
- Then this library cloned the request and wrote each one on the clone as a header, leaving your request as it was (user-id: u_123, session-id: s_456, time-zone: Asia/Jakarta)
- Then this library sent the clone to the next service through http.DefaultTransport (GET https://downstream.example.com/internal)
- Then this library read the three headers back into the next service's context through its own user, session, and timezone middleware (u_123, s_456, Asia/Jakarta)
- The code results in an answer from a handler that knows the same caller (resp.StatusCode 200, err nil)
An open source Go library, go.trueardian.com/api, that carries who is calling through a backend made of several Go services. A gateway in front of them signs the person in and passes on their user ID, their session, and their time zone as headers of each request. Without it, every service writes the same code again, reading each header at the door, refusing a request that lacks one, handing the values down to whichever handler needs them, and setting them again on every call to the next service, where one forgotten header makes that service refuse a call it should have taken. With it, a service wraps its routes once and its HTTP client once, and every handler and every next service knows the same caller.
- Kind
- library
- Field
- Software engineering, backend engineering, distributed systems, API design
- Stack
- Go, net/http
- Without Chronica
- Human: find us a quiet table for four in Kemang on Friday at 7pm
- Concierge:
- Tool search_places with "Kemang", 4, "quiet": Rumah Teduh, Kayu Manis
- Human: Rumah Teduh
- Concierge to Booking: book it for them
- Booking: sure, which restaurant, and for how many people?
- With Chronica
- Human: find us a quiet table for four in Kemang on Friday at 7pm
- Concierge:
- Tool search_places with "Kemang", 4, "quiet": Rumah Teduh, Kayu Manis
- Human: Rumah Teduh
- Concierge to Booking: book it for them
- Booking:
- Tool book_table with "Rumah Teduh", 4, "Friday 19:00", "Ardian": RT-4821
An open source Go library, go.trueardian.com/chronica, that gives AI agents episodic memory, the kind of memory that remembers what happened. An agent remembers a conversation only through the history it is handed before it answers, and when one person works with several agents, all of them need the same record. Without Chronica, every app that runs agents builds the same pieces again, a store for every message, thought, and tool call, a way to hand each agent the last part of it in the order it happened, a check that one person never reads the session of another, and a way to retry a write without recording a reply twice. With it, the person and every agent write what they do into one session, a chronicum, and each agent reads back what it needs in one call.
- Kind
- library
- Field
- Agentic AI infrastructure, AI engineering, software engineering, backend engineering, databases, distributed systems, application security
- Stack
- Go, Postgres
Estimates how often customers of a small self-service copy shop find it full and have to wait outside, with one copier and with two. A discrete-event simulation runs the shop for 64 hours, 64 times over for each setup.
- Kind
- simulation
- Field
- Simulation modeling, discrete-event simulation, queueing theory, steady-state analysis (Kendall's M/M/c, Erlang C, Little's law), operations research, dashboard development, web development
- Stack
- R, R Markdown, knitr
- System
- Poisson arrivals, exponential copy jobs, first come first served, limited room inside with overflow waiting outside, no one leaves, each run from an empty shop, rates assumed, not counted
- Parameters
- 24 customers an hour, 2-minute copy jobs on average, room for 4 inside, 64 runs of 64 hours
- Method
- Discrete-event simulation, checked against M/M/c theory
Findings
- 01
A second copier is worth adding, since customers waiting outside drop from 40.5% to 3.6%, and those who do stand there 1.6 min instead of 9.6 min
- 02
In a deadline rush of 28 customers an hour, theory puts 75.9% outside with one copier and 6.5% with two
Finds how many dozen donuts a bakery should bake each day when both the number of customers and the size of their orders are random. Each amount is judged by its average profit over 5 selling days, because a dozen too many is sold off at a loss at closing and a dozen too few is a sale turned away. A Monte Carlo simulation tries every multiple of 5 dozen from 5 to 100 with 100 trials each.
- Kind
- simulation
- Field
- Simulation modeling, Monte Carlo methods, probability modeling, operations research, inventory optimization, dashboard development, web development
- Stack
- R, Shiny, shinydashboard, plotly, DT
- System
- Baked once each morning, random customers each ordering a random number of dozens, leftovers sold off at closing and never carried over, every day alike, probabilities assumed, not from sales records
- Parameters
- 8 to 14 customers a day buying 1 to 4 dozen each, Rp80,000 price, Rp55,000 cost, Rp40,000 salvage a dozen, 100 trials of 5 days per batch size
- Method
- Monte Carlo simulation, checked against the exact expected profit of the newsvendor model
Findings
- 01
Baking 20 dozen a day earns the most, Rp2,135,200 over 5 days, with 1.8 dozen left over a day
- 02
14.4% of 2,000 reruns pick 25 dozen instead, which earns only Rp43,339 less over 5 days
- 03
Without rounding to a multiple of 5, baking 22 dozen a day would earn Rp19,629 more over 5 days
Estimates the chance that a commuter catches a KRL Commuter Line train at Manggarai station when neither the commuter nor the train keeps to a fixed time. A Monte Carlo simulation draws the train's departure from Depok, its travel time, and the commuter's arrival at the platform 20,000 times.
- Kind
- simulation
- Field
- Simulation modeling, Monte Carlo methods, probability modeling, transportation, dashboard development, web development
- Stack
- R, Shiny, shinydashboard, ggplot2, DT
- System
- One commuter and one train, independent, uniform trip time rounded to the minute, the train never waits, probabilities assumed, not from KRL records
- Parameters
- Depok departure 13:00 to 13:10, 28 to 32 min trip, platform arrival 13:28 to 13:34, on time by 13:30, 20,000 runs
- Method
- Monte Carlo simulation, checked against the exact answer
Findings
- 01
The commuter catches the train on 70.5% of simulated afternoons, against 70.0% worked out exactly
- 02
Reaching the platform by 13:30 means boarding 85.2% of the time, against 36.4% when later
- 03
The commuter is late on 30% of days, and those days make up 65% of the misses
Counts how many cars in a queue clear a single-lane intersection during a 15-second green light. A discrete-time simulation moves every car through reaction and acceleration one second at a time.
- Kind
- simulation
- Field
- Simulation modeling, discrete-time simulation, traffic flow modeling, kinematics, dashboard development, web development
- Stack
- R, Shiny, shinydashboard, dplyr, ggplot2, plotly
- System
- One lane of queued cars, every driver assumed alike, a car is through once its rear clears the intersection
- Parameters
- 16 cars, 5 m long, 2 m apart, 15 s green, 2 s reaction, 1 m/s² acceleration, 11 m/s limit, 12 m intersection, 1 s time step
- Method
- Discrete-time simulation, matches the kinematic formulas on 8,192 of 8,192 settings
Findings
- 01
A 15-second green clears 3 cars, or 4 if counted at the stop line
- 02
A 20-second green clears 5 cars and a 25-second one 7, about 2.6 s per extra car
- 03
Cutting reaction time from 2 to 1 second clears 5 cars, as many as cars accelerating at 8 m/s²
Compares three ways for two carhops at a drive-in restaurant, the faster Ali and the slower Badu, to decide who takes a car when both are free. A discrete-event simulation runs 20,000 evenings of 32 cars under each rule and compares the average wait per car.
- Kind
- simulation
- Field
- Simulation modeling, discrete-event simulation, queueing theory, Markov chains, operations research, dashboard development, web development
- Stack
- R, Shiny, shinydashboard, DT
- System
- Two carhops, Ali faster than Badu, cars served in arrival order, each evening from an empty lot, whole-minute times assumed, not timed at a real lot
- Parameters
- Car gaps of 1 to 4 min, Ali's orders 2 to 5 min, Badu's 3 to 6 min, 20,000 evenings of 32 cars
- Method
- Discrete-event simulation, checked against the exact answer
Findings
- 01
Sending Ali first cuts the wait to 40.0 s a car, against 41.2 s for a random pick and 42.3 s for Badu first
- 02
Ali first saves only 2.3 s a car over Badu first, small next to the 37.3 s the wait swings from one evening to the next
- 03
Ali first leaves Badu idle 22.7 min an evening against Ali's 10.9 min, while a random pick splits the idle time evenly
Reads 2,269 Qatar Airways reviews from 2013 to 2024 to find what passengers praise, what they complain about, and where the rating is heading. GPT-4o mini fills in the 376 missing ratings, and keywords tag every review by topic. A seasonal ARIMA forecasts the monthly average rating, picked by MAPE on two years it has never seen because a percentage error reads the same whatever the rating scale.
- Kind
- machine learning model
- Field
- Natural language processing, text mining, large language models, time series forecasting, data science
- Stack
- R, tm, Python, GPT-4o mini, statsmodels
- Dataset
- Qatar Airways reviews, 2013 to 2024
- Target
- Monthly average rating
- Algorithm
- Seasonal ARIMA
- Winner
- SARIMA(0,1,6)(0,1,1)12
- MAPE
- 13.6%
Findings
- 01
The next 12 months are forecast at 5.97 of 10 on average, down from 6.55 over the last 12
- 02
The average rating fell from 8.23 in 2021 to 6.66 in 2022 and has not recovered since
- 03
Service and time are the most praised topics, and also among the most complained about



A web app for HR teams who get hundreds of applications for one opening and cannot read them all. The recruiter uploads the resumes as PDFs and types the skills the role needs, and Resume Wizard ranks every resume by how many of those skills it names, then groups the resumes by the skills they share, so the reading starts with the people most likely to fit. It matches the exact words of each skill instead of guessing what a resume means, so a recruiter can always see which skills put a resume where it is.
- Kind
- app
- Field
- Natural language processing, text mining, information retrieval, machine learning, clustering, data science, data visualization, web development, recruitment
- Stack
- R, Shiny, shinydashboard, pdftools, tm, tokenizers, plotly, DT, wordcloud, shinyapps.io
- Language
- English
- Status
- Offline





A web app for teachers who grade homework by hand and have no time to compare every submission with every other. The teacher uploads the homework of a class as PDFs, and Homework Truthweaver ranks every pair by how much wording the two share and flags the pairs at or above a threshold the teacher sets, so the reading starts with the pairs most likely copied. A word counts for more the rarer it is in the class, so two essays on the same assigned topic do not look alike only because both use the words of that topic. The screens here show it on the sample essays that came with the app, which a chatbot wrote as rewrites of one another.
- Kind
- app
- Field
- Natural language processing, text mining, information retrieval, data science, data visualization, web development, education, academic integrity
- Stack
- R, Shiny, shinydashboard, pdftools, tm, proxy, tokenizers, plotly, DT, wordcloud, shinyapps.io
- Language
- English
- Status
- Offline
Estimates how long a New York green taxi ride will take from its distance, pickup and dropoff zones, hour, and weekday, trained on 69,715 cleaned trips from July 2021. Five models were compared by mean absolute error, how many minutes an estimate misses by on average, alongside MAPE and RMSE. One of them is a feed-forward neural network fed with an out-of-fold k-nearest-neighbour prediction, so the extra feature never comes from a model that has seen the trip.
- Kind
- machine learning model
- Field
- Machine learning, deep learning, transportation analytics, data science
- Stack
- R, Keras, TensorFlow, caret, randomForest, FNN
- Dataset
- NYC TLC green taxi trips, July 2021
- Target
- Trip duration in minutes
- Algorithms tried
- Linear Regression, Random Forest, Feed-Forward Neural Network, K-Nearest Neighbour, FNN + KNN Feature
- Winner
- Neural network with out-of-fold KNN
- MAE
- 3.09 minutes
Findings
- 01
Linear regression misses by 4.11 minutes a ride, against 3.09 for the neural network with out-of-fold KNN
- 02
The neural network with out-of-fold KNN also beats the other four on MAPE and RMSE
- 03
There are 16 times more pickups at 10:00 than at 3:00
Estimates the fare of a New York taxi ride from its distance, passenger count, hour, weekend, and year, trained on 149,102 cleaned trips from 2009 to 2015. Three models were compared by mean absolute error, how many dollars a predicted fare misses by on average, and by whether every dollar of the fare they predict can be explained.
- Kind
- machine learning model
- Field
- Machine learning, deep learning, regression, data science
- Stack
- R, Keras, TensorFlow, FNN
- Dataset
- NYC taxi fares, 2009 to 2015
- Algorithms tried
- Linear Regression, Feed-Forward Neural Network, K-Nearest Neighbour
- Winner
- Linear Regression
- MAE
- $1.47 a ride
Findings
- 01
Linear Regression misses by 7 cents more than the neural network but explains every dollar of the fare
- 02
Each mile adds $2.12 to the fare
- 03
The same 1.9-mile ride costs $7.69 at 06:00 and $9.38 at 12:00
- 04
The fare per mile rose from $3.71 in 2009 to $4.53 in 2015
Flags telecom customers who are about to cancel from their contract, tenure, charges, and services, on the IBM Telco dataset of 7,032 customers, 27% of whom churned. The model is judged by sensitivity, because a retention offer sent to a loyal customer costs far less than a churner nobody called, and tuned by AUC instead of accuracy. A random forest is tuned with repeated cross validation, upsampling inside every fold.
- Kind
- machine learning model
- Field
- Machine learning, customer analytics, data science
- Stack
- R, caret, randomForest, pROC
- Dataset
- IBM Telco Customer Churn
- Model
- Tuned Random Forest
- Sensitivity
- 76%, 213 of 280 unseen churners
- AUC
- 0.847
Findings
- 01
Tenure drives churn the most, then two-year contract and monthly charges
- 02
55% of flagged customers really churn, and the rest get an offer they did not need
Flags the near-Earth asteroids NASA would call potentially hazardous from their orbit, size, and close approach, on 4,687 close approaches of 3,692 asteroids, 16% of them hazardous. The model is judged by sensitivity, because a hazardous asteroid called harmless is the one mistake planetary defense cannot afford. The close approaches are split into training and test sets by asteroid, so none is graded on a pass it has already seen.
- Kind
- machine learning model
- Field
- Machine learning, space data, data science
- Stack
- R, caret, randomForest, e1071, pROC
- Dataset
- NASA near-Earth object close approaches
- Algorithms tried
- Naive Bayes, Logistic Regression, Random Forest
- Winner
- Random Forest
Findings
- 01
Random Forest catches 118 of 121 hazardous close approaches with 1 false alarm
- 02
Lowering the threshold catches all 121 for 1 false alarm
- 03
NASA's own rule, an orbit within 0.05 AU of Earth's and a magnitude of 22 or lower, catches 121 of 121 with no model at all
Flags companies that are about to go bankrupt from their financial ratios, on the Taiwan company bankruptcy dataset of 6,819 companies, only 3% of which went bankrupt. Calling every company healthy would already score 97% accuracy, so the model is judged by sensitivity instead, because a bankruptcy nobody saw coming costs a lender far more than a second look at a healthy company. The companies are split before any upsampling or PCA, so nothing from the test companies leaks into training.
- Kind
- machine learning model
- Field
- Machine learning, credit risk modeling, dimensionality reduction, data science
- Stack
- R, caret, FactoMineR, class, pROC
- Dataset
- Taiwan company bankruptcy
- Target
- Bankrupt, yes or no
- Algorithms tried
- Logistic Regression, KNN
- Winner
- KNN
- Sensitivity
- 91%, 40 of 44 bankruptcies caught
- AUC
- 0.917
Findings
- 01
The model also flags 262 healthy companies, about 7 for every bankruptcy caught
- 02
A credit review should start from the riskiest companies and go down the list as far as the budget allows
Flags fake news articles from their title and text, on the Kaggle Fake and Real News dataset of 39,105 unique articles, close to evenly fake and real. The score that matters is sensitivity, because a missed fake keeps spreading, while a false alarm only costs a fact-checker one more read. A naive Bayes classifier over 4,537 terms is trained after removing duplicates, the Reuters dateline, and scraping artifacts.
- Kind
- machine learning model
- Field
- Natural language processing, text mining, data mining, machine learning, data science
- Stack
- R, tm, e1071, caret, pROC
- Dataset
- Kaggle Fake and Real News
- Target
- Fake or real
- Algorithm
- Naive Bayes
- AUC
- 0.984
Findings
- 01
Naive Bayes catches 94% of fake articles, and the 212 it misses keep spreading
- 02
Only 169 of 4,239 real articles are flagged by mistake, each costing a fact-checker one more read
- 03
Getty Images photo credits are the biggest giveaway, 516× more common in fake news
- 04
The model is best used as a first filter for these sources, not as a judge of truth
Predicts whether a pick-up area of Scotty, a ride sharing and delivery service in Istanbul, will be short of drivers in a given hour, from its trip requests of October to December 2017. Both mistakes cost Scotty, since a missed shortage leaves riders without a car and a false alarm sends drivers where nobody needs them, so accuracy is the main metric, with recall and specificity kept in balance. Naive Bayes, a decision tree, and a random forest were nearly tied on validation, so all three were scored on a hidden week.
- Kind
- machine learning model
- Field
- Machine learning, mobility analytics, data science
- Stack
- R, dplyr, lubridate, padr, e1071, partykit, caret, randomForest, lime
- Dataset
- Scotty trip requests, Istanbul, Oct to Dec 2017
- Algorithms tried
- Naive Bayes, Decision Tree, Random Forest
- Winner
- Decision Tree
- Hidden accuracy
- 82%
- Hidden recall
- 89%
Findings
- 01
Area sxk9 is predicted short in 168 of 168 hours, so it needs more drivers all day
- 02
Area sxk3 is predicted short almost every hour outside 02:00 through 06:00, so it needs more drivers then
- 03
Area sxk8 is predicted short in only 1 of 168 hours, so it can stay as it is
- 04
The tree raises a false alarm in 26% of the hours that had enough drivers
- Orders
- 265
- Merchants
- 69
- Customers
- 74
- Sales
- Rp16,655,000
Orders by hour of the day
Orders by merchant category
Orders by delivery district
Turns 265 GoFood orders in Pontianak, from September 2018 to March 2019, into a dashboard of which kinds of food sell, which merchants lead, when people order, and where the food goes. It was originally built in R as an interactive Shiny dashboard, and is rebuilt here with the same category filter and top merchants slider.
- Kind
- dashboard
- Field
- Data analytics, business intelligence, data visualization, dashboard development, web development
- Stack
- R, Shiny, shinydashboard, ggplot2, plotly
- Dataset
- Gojek orders in Pontianak, Sep 2018 to Mar 2019
- Cut by
- Category, merchant, hour, age, district
Findings
- 01
Cafes take 43% of orders because there are more of them, not because each is busier
- 02
There is no rush hour, and every hour from 6:00 to 22:59 gets 9 to 21 orders
- 03
50% of orders are picked up in Pontianak Kota, yet deliveries spread almost evenly, 37 to 49 per district
- 04
87% of orders are delivered outside the merchant's district
- 05
Only 6 of the top 10 merchants by orders are also in the top 10 by sales
- Orders
- 5,009
- Sales
- $2,297,201
- Profit
- $286,397
- Customers
- 793
Sales by month, 2014 to 2017
Sales by category
Sales by region
Turns 5,009 orders from a US superstore, from 2014 to 2017, into a dashboard of orders, sales, and profit by month, segment, region, ship mode, category, and product. It was originally built in R as an interactive Shiny dashboard, and is rebuilt here with the same year and segment filters, and one switch between orders, sales, and profit in place of three tabs.
- Kind
- dashboard
- Field
- Data analytics, business intelligence, data visualization, dashboard development, web development
- Stack
- R, Shiny, shinydashboard, ggplot2, plotly
- Dataset
- Superstore orders in the US, Jan 2014 to Dec 2017
- Cut by
- Month, segment, region, category, product
Findings
- 01
Furniture brings in 32% of sales but only 6% of profit
- 02
Sales grow 51% over four years and peak every September, November, and December
- 03
Tables lose $17,725 and bookcases lose $3,473
- 04
Central sells more than the South but keeps less of it, at 24% off on average
Wrote my first R programs in RStudio and R Markdown, from data types and coercion to vectors, factors, matrices, lists, and data frames. Cleaned and subset a retail sales dataset, then summarized it with table, prop.table, xtabs, and aggregate to answer business questions.
Learned the statistics every later model stands on: central tendency, spread, covariance, and correlation, the normal distribution with its density and mass functions, confidence intervals, and hypothesis testing with p-values and t-tests, all on real retail data.
Built charts in R with base graphics and the grammar of graphics in ggplot2, from exploratory boxplots to multivariate plots, custom themes, and Leaflet maps. Practiced on YouTube trending videos and Kiva loans, then shipped a Superstore sales analysis as my learn-by-building project.
Turned static ggplot2 charts into interactive plotly charts and published them as flexdashboard and Shiny web dashboards. Built two of my own: a GoFood Pontianak dashboard that ranks merchant categories, top merchants, order hours, and customers by age and district, and a Superstore dashboard that tracks orders, sales, and profit by year, category, segment, and region.
Modeled continuous targets with least squares, from simple to multiple linear regression, and selected features with backward, forward, and both-direction step-wise regression. Validated every model against its assumptions with residual plots, homoscedasticity and normality checks, and VIF for multicollinearity, then used it to estimate Gojek ride durations.
Built classifiers with logistic regression, reading them through log of odds, and with k-nearest neighbors, tuning k and rescaling features. Modeled credit risk on 2017 loans, diagnosed breast cancer from cell measurements, wrote k-NN from scratch to segment wholesale customers, and judged models by sensitivity, specificity, and precision instead of accuracy alone.
Went deeper with Naive Bayes, decision trees, and random forests, including a spam filter built with text mining, ROC curves and AUC, pruning, and k-fold cross validation. Closed the academy with a capstone that predicts driver shortages for a ride sharing service by area, hour, and weekday, where my decision tree scored 82% accuracy and 89% recall on the hidden test set and was explained with LIME.
Reduced dimensions with PCA on NYC property sales, visualized loan defaults with FactoMineR, rebuilt faces as eigenfaces, and used PCA to flag anomalies. Clustered whiskies into recommendations with k-means, then combined PCA with k-means to cluster high-dimensional data.
Broke time series into trend, seasonality, and residuals, then forecasted them with simple moving averages, exponential smoothing, Holt-Winters, and seasonal ARIMA. Made series stationary with differencing and validated every model's residuals with ACF, PACF, and the Ljung-Box test.
Built neural networks from first principles, working through cost functions, backpropagation, and gradient descent, then moved to Keras with dense layers and the SGD, RMSprop, and Adam optimizers. Predicted the success of a bank telemarketing campaign and classified handwritten digits from MNIST.
Picked up Python for analytics with pandas, from data types and categorical conversion to indexing, conditional subsetting, and referencing versus copying DataFrames. Practiced on supermarket rice receipts and company sales records.
Explored household purchase receipts in pandas by parsing datetimes and categories, summarizing them with crosstabs, aggregation tables, and pivot tables, and treating missing values and duplicates before drawing any conclusion.
Reshaped data with stack, unstack, and melt, aggregated it with groupby and agg, and visualized it with pandas and Matplotlib. Compared the growth and volatility of Apple, Google, and Tesla stock, and kept every analysis reproducible with pinned requirements.
Queried a relational music store database from Python with SELECT, JOIN, GROUP BY, and WHERE, then moved the results into pandas for analysis. The capstone was a Flask API over an Austin bike sharing database that records stations and trips and serves insights like the busiest stations.
Ran the full scikit-learn workflow, from EDA, outlier handling, encoding, and standardization to train-test splitting. Predicted bank customer churn with a support vector classifier, priced diamonds with support vector regression, and tuned C, kernel, gamma, and epsilon to improve both.
Forecasted daily sales of 1C Company, one of the largest Russian software firms, across 2.9 million records with Prophet. Modeled trend, seasonality, and holiday effects, evaluated forecasts with a train-test split and expanding window cross validation, and tuned hyperparameters to improve them.