Inspiration

It started, as all great schisms do, with an argument: is a hot dog a sandwich? Is a wrap? A taco? Cereal??

Rather than resolve this in a group chat (impossible, several friendships were already on the line), we decided to build an entire research wing dedicated to the cause. We learned that the word "sandwich" itself was basically invented so a British Earl wouldn't have to leave a card game to eat β€” and figured if humanity's bread-based ingenuity deserved an etymology lesson, a world map, and a pop quiz, who were we to refuse?

What it does

sandwich.wiki is a three-tab shrine to stuffed bread:

  • πŸ“– About & Etymology β€” the origin story of the word "sandwich" (gambling Earl included), plus an AI-powered fun-fact generator that will produce a suspiciously confident paragraph about literally any sandwich-adjacent topic you throw at it.
  • πŸ—ΊοΈ World Map β€” an interactive Folium map pinning 23 sandwiches to their countries/cities of origin, from the Cubano to the BΓ‘nh MΓ¬ to the Bunny Chow. Click a pin, get the lore.
  • 🎯 Trivia Bot β€” an OpenAI Agents SDK-powered quiz master that fires multiple-choice sandwich trivia at you, judges your answers, and roasts or rewards you accordingly.

How we built it

  • Python + Streamlit for the UI, because hackathon time is a flat circle and we refuse to write a single line of CSS under deadline pressure.
  • OpenAI Agents SDK powers the trivia master and fun-fact historian β€” two Agents with very strong, very specific opinions about bread.
  • Folium + streamlit-folium for the world map, because st.map() doesn't do popups and we needed popups.
  • python-dotenv to keep our API key out of git (mostly successfully).
  • 23 hand-curated sandwiches, painstakingly geotagged via "approximately where I think that is."

Challenges we ran into

  • The OpenAI Agents SDK is async-first; Streamlit's execution model is decidedly not. Runner.run_sync saved us from writing our own event loop at 2am.
  • Maintaining multi-turn conversation state for the trivia bot meant wrangling result.to_input_list() across Streamlit reruns β€” Streamlit re-executes the whole script on every interaction, which is a fun fact you only learn the hard way.
  • Drawing the line on "what counts as a sandwich" for the world map. We made executive decisions. Some people will be mad. We accept this.
  • Picking only 23 sandwiches when humanity has invented several thousand.

Accomplishments that we're proud of

  • A fully functional trivia bot that can write and grade its own pop quizzes β€” we built a bread-based academic institution in an afternoon.
  • A genuinely fun-to-explore world map that makes "geography homework" feel like snacking.
  • Zero CSS files. Not one. We are very proud of this.
  • We never once had to answer "is a hot dog a sandwich" ourselves β€” we just let the bot field that one.

What we learned

  • The word "sandwich" is younger than the sandwich. The concept predates the Earl by millennia; he just got the naming rights.
  • Runner.run_sync + to_input_list() is the cheat code for stateful agent chat in Streamlit.
  • Folium popups with inline HTML are a delightfully low-tech way to make a map feel alive.
  • Never put your API key in a place where the IDE will helpfully highlight it for a screenshare.

What's next for Which Sandwich

  • User-submitted sandwiches β€” crowdsource the map until every regional bread-stuffing tradition on Earth has a pin.
  • "Is It A Sandwich?" Court β€” an AI judge that rules on hot dogs, wraps, tacos, and open-faced controversies, with citations.
  • Multiplayer trivia β€” leaderboards, head-to-head sandwich knowledge duels, bragging rights.
  • Image recognition β€” upload a photo of your lunch, get told what it's called and where it's from (and whether it's really a sandwich).
  • Streaming agent responses β€” because watching the trivia bot type is half the fun.

Built With

Share this project:

Updates

Submission history