- Court Street Data
- Posts
- Engineering an Olympic Medal Tracker and Message Bot with Claude 3.5 Sonnet
Engineering an Olympic Medal Tracker and Message Bot with Claude 3.5 Sonnet
A few months ago, a viral video of Sam Altman made the rounds on LinkedIn. In an interview with Alexis Ohanian, he suggested that we will soon see one person, enabled by AI, build a billion dollar company. Was it a bit egotistic and self-aggrandizing, given that Altman founded and leads the largest AI company in the world? Perhaps. On the flip side, is he wrong?
Wanting more hands-on experience with LLM-powered development, I set out on a journey to find out. I had read a lot of great things about Anthropic’s Claude 3.5 Sonnet, and while I have no plans to build a billion dollar company solo in the immediate future, I had a small project in mind.
My conclusion? He might not be wrong after all.
The two ways to achieve product market fit.
The Problem
Like many of my peers, I spend way too much time thinking about fantasy football.1 Whether it’s a new sacko punishment, rule changes, or in this case, choosing a draft order, from August to December, there’s always something going on (to my partner’s constant dismay).
This year, we decided to determine the draft order by randomly assigning the 12 teams in our league a country in the Summer Olympics and rank order by medal count. For example, if my team were randomly assigned to the U.S., and the U.S. had the most total medals in the Games, I would be awarded the first overall pick in the draft.2
As a data person, I felt the need for daily updates on my projected draft pick for no reason other than instant gratification. Also, I wanted to share updates to the projected order with the league as a way to boost chatter in our group chat.
The problem, put simply: can I use Claude to write an app that ingests and shapes medal count data, posts a daily GroupMe3 message to inform league members of their projected draft pick, and do so with the following restraints?
Build fast: the feature is useless after the Olympics end, hence the need for an LLM to supercharge foundation code development and debugging.
Build at no cost: see above re: “I already spend too much time thinking about fantasy football”; it shouldn’t impact my wallet as well.
The Scope
I broke down the problem into four components:
Access: an underrated piece of every technical project! There’s no point in continuing if these applications don’t provide developer access.
Ingest Medal Count Data: post an API request or scrape the frontend of the official webpage. There’s some uncertainty here, so this requires a bit of scoping.
Shape the Data: filter countries, sort by medal counts, and map teams to countries. I knew going in that this would be the most straightforward component.
Post the Message: converting the values to string and posting the message via the GroupMe API.
The Solution
Access
First stop: check the GroupMe documentation. Does GroupMe allow you to send messages via API?
As it turns out, it was easy enough to Google “GroupMe API”, log into the GroupMe developer page, create an application, and be granted a personal access token.
Access: ✅
Post the Message
I was already deep in the GroupMe developer docs and wanted to double check access, so I tackled this component next. Historically, I’ve found LLMs great at laying the foundation for a technical project. In this case:
Claude provides the initial framework that can then be iterated on.
I saw this through in multiple ways, with follow-up prompts like:
> How do I find the group_id for my chat?
> Do I need provide the source_guid?
All in all, I created a sandbox message chat and was able to post a test message:
Original? Nope. Functional? Yep.
Post the Message: ✅
Ingest Medal Count Data
I was most uncertain about the medal ingestion piece for one reason only: the scope was unclear. Would there be a free, public API? Or would I have to scrape the frontend of the official medal count site?
After some web searching and only finding paid APIs, I decided to move forward with the web scraping route. Because I have less experience with web scraping, I relied on Claude to guide me in the right direction.
Claude recommended BeautifulSoup, which I had used before. However, I quickly learned that the official site used dynamic JavaScript, only loading results in the table upon scroll, and the resulting data did not include all countries’ medal counts. This led me to a series of prompts, starting with the following:
“Provide more options” works well.
In fact, I found the most value conversing through a series of troubleshooting prompts:
Claude asks to include debugging info that will be submitted in future prompts.
Accepting the cookie.
Introducing more advanced logic as needed.
I was pleasantly surprised, and even a bit taken aback by the levels of detail, complexity, and acutely human touch included in each answer. In short, it felt like I was Slack messaging a mid-level engineer. Further, because Claude holds context throughout the conversation, you can refer back to earlier Q&A in prompts. Unfortunately, I broke restraint two (build for free): in order for Claude to hold the context in the lengthy conversation, I upgraded to Pro for $20 😔.
Eventually, I (we?) built a web scraper with a headful browser, cookie acceptance, and delayed scrolling until all country HTML classes were collected.
Ingest Medal Count Data: ✅
Shape the Data
Easy peazy. Load the results into a data frame, exclude extraneous countries, map fantasy football team to country, sort by different medal counts, and reset the index.
Shape the Data: ✅
The final result…
I’m aiming for back-to-back championships in 2024 👑
Closing Thoughts
Claude 3.5 Sonnet was not perfect, but exceeded expectations. Even within the same issue group, it required several rounds of back-and-forth, which is often the case in traditional technical debugging. Still, I was impressed with the ease in which pasting outputs and output errors led to context building, additional solutions, and eventually, the desired result.
Claude performs exceedingly well with a high volume of context, but rate limits prevent this functionality. Users have the option to start multiple conversations, but context does not transfer across conversations. In order to fully maximize capabilities, users must purchase a pro plan. Overall, this is a strong PLG motion that clearly works.
A minimally technical business owner with grit, execution skills, and a great idea can build a low-code software business. After this experience, I have significantly more confidence in building larger technical products. However, product management and communication skills are all of the more important as feature building becomes increasingly commoditized.
And now, we wait… go Sweden! 🇸🇪
1 If you have no idea how fantasy football works, check out this Reddit thread.
2 The tiebreaker would be most Gold, most Silver medals, and then randomly chosen if all 3 medal categories are tied.
3 GroupMe is a messaging app from the 2010s that rode the original smart phone boom and, for this reason, still exists today.
Have an interesting data problem to solve, interested in the repo for the project above, or want to chat about fantasy football GOAT Christian McCaffrey? Reach out at [email protected].