Chapter 1. Using Prototypes to Explore Project Ideas
Imagine that you work for an agency that helps clients navigate the early stages of product design and project planning.
No matter what problem space you are working in, the first step is always to get ideas out of a client’s head and into the world as quickly as you possibly can. Conversations and wireframes can be useful for finding a starting point, but exploratory programming soon follows because words and pictures alone can only take you so far.
By getting working software into the mix early in the process, product design becomes an interactive collaboration. Fast feedback loops allow stumbling blocks to be quickly identified and dealt with before they can burn up too much time and energy in the later (and more expensive) stages of development.
There are many moving parts in even the most simple software systems, so it pays to set them in motion early on to discover how they interact with one another. In some ways every project is different, but in this sense every project is the same.
This week, you will work with your pairing partner Samara to develop a functional prototype of a music video recommendations system. The initial feature set does not need to be perfectly polished; it just needs to be useful enough to collect feedback from people who may find the product interesting.
In this chapter…
You will learn how exploratory programming techniques can be used to build and ship a meaningful proof of concept for a product idea within hours after development begins.
Start by understanding the needs behind the project
This music recommendations project is brand new, so you don’t know at all what to expect yet. You get together with the client (Ross) for a quick chat to kick things off:
You: Hi Ross! Thanks for meeting with me. My pairing partner (Samara) is listening in as well. We’re ready to get started if you are.
Ross: Yep, I’m ready. What’s the first step?
You: Well, first of all, I’d like to hear about what got you interested in music video recommendations. Knowing where an idea came from helps us figure out what to focus on in our prototypes.
Ross: OK, sure. We’ve been running a blog where we post curated lists of music videos for a few years now. We have collaborators who specialize in building lists for many kinds of music, and people usually find our posts through organic search.
Over the years, we’ve shared over 4,000 videos on our site. That’s a massive library of music, but the only way to navigate it right now is one blog post at a time.
We started to think through ideas on how to make our collection easier to explore. After considering some options, we decided that building some sort of recommendations system might be the way to go.
The initial version can be simple, but we’d like to get something in front of a few dozen of our most active community members and blog contributors as soon as we can.
You: Sounds like a great project! Let’s dig in.
With the basic theme sorted out, you talk for a few more minutes with Ross about how to get a rough proof of concept put together. One question that often comes up in projects like this is whether the new work will be a standalone project or will need to integrate into some existing system.
In this case, Ross isn’t entirely sure what he wants. But when you suggest that it might make sense to bring the question up later in order to focus all of the team’s energy on figuring out whether the idea will even work, he agrees.
You talk through ways to make the prototype a bit more approachable to the readers of the music video blog and come up with a simple solution: use the blog itself to find the videos that’ll serve as samples in the prototype. This way, the content within the new recommendations system will be familiar to both Ross and the readers of his blog, and there will be a clear connection between the new application and the original website even if they’re technically operating in two totally separate codebases.
Use wireframes to set expectations about functionality
With a few of the big picture ideas sorted out, you shift your focus back to figuring out how to get started on the first iteration of the project. Wireframe diagrams are usually helpful at this stage, because they allow you to communicate the basic structure of what you’re about to build, while creating a shared understanding of the work to be done—without getting bogged down in implementation details.
Rather than getting into a long discussion about different ways of implementing a recommendations system, you suggest starting with what might be “The Simplest Thing That Could Possibly Work.”1
You: For our first attempt at a basic user interface, we might start with a page where the video player is displayed front and center. Underneath the player, there will be a few thumbnail images of recommended videos, which will be selected based on whatever is currently playing. Does that sound alright?
Ross: Sure, seems reasonable. I’ll know better when I see it, though.
You: While we’ve been chatting, Samara has been working on a wireframe sketch that might serve as a good starting point. One second, I’ll upload it…
You: What do you think? We’re trying to keep things as simple as possible to start with.
Ross: That looks fine. It’s similar to how I’ve seen video players work elsewhere on the Web, and that will probably make it easy for our users to understand it.
You: Great! Before we take our conversation any further, Samara and I would like to put together something similar to this sketch as an actual web page. We’re just going to use placeholder images for everything, so this won’t take us long, but it will help us test a few basic assumptions that will inform the rest of our work.
Ross: Sure, if you think that will help, go for it.
You are ready to dig in, but Samara appears to be lost in thought. When you ask her what’s wrong, she explains that an idea for a better interface popped into her mind at the exact moment you asked Ross for feedback on her sketch.
Instead of the original workflow, Samara suggests building a player that would show a single video at a time with “thumbs up” and “thumbs down” buttons to allow viewers to indicate their preferences, and a single big “next video” button that would cause a new recommended video to begin playing immediately. This would be roughly similar to flipping through TV channels, but in a smart system that can guess what you might want to watch next.
This is a great idea, but it wouldn’t be quite as easy to implement. After a brief discussion about the tradeoffs, Samara accepts the idea of trying out the more simple approach first, since it provides a faster path toward putting the project into the hands of the real people that might put it to good use.
Set up a live test system as soon as you start coding
The point of rapid prototyping is to reduce distance between everyone involved in a project: both between developer and client, and between client and customer.
To serve both of these purposes, having a running system that everyone can interact with is essential; it promotes trying things out rather than simply talking about them, and makes it easier to share progress as you go. With this in mind, you begin the usual chores involved in getting a web application up and running on the Internet.
Because you are using a decent application hosting platform, this mostly means setting up a generic “Hello World” page using your favorite web framework, and then pushing the code to a Git repository that detects the toolchain you are using. From there, the platform takes care of installing all the necessary dependencies and starting up a web server automatically.
Although it’s running one of those weird URLs that looks like baby-robot-pants-suit.somehostingprovider.com, the application is live on the Internet within minutes.
At this stage, you have no clue what the production environment will end up looking like for the finished project and you don’t really care. You’re building exploratory features that serve the purpose of getting useful feedback from the client’s target audience, and your code will be thrown away before the finished product ships anyway.
You cut every possible corner when it comes to infrastructure—you don’t even set up a database system right away, because it’s not yet clear whether one will be needed or not. Massive underinvestment is the name of the game here, and you manage to pull it off skillfully.
“Should we bother doing any sort of custom styling for this?” Samara asks.
You pause for a moment and think about it. But then you remember the YAGNI principle,2 and the answer becomes clear.
“Nope. If the goal of this prototype was to make some sort of slick demo software for a marketing screencast, we’d want to focus on the looks from the get-go. But in this case, I think that Ross just wants to get this in front of a few of his friends to see what they think of it functionality-wise. On top of that, since this is a simple video playing application, the interface is going to be pretty minimal no matter what.”
Samara seems convinced by your answer, even though you’ve once again chosen the expedient path over the elegant one. But you’ve worked together for long enough where this is just something you’re both used to by now; there have been plenty of times where Samara has kept you from overthinking things, too.
You spend a few minutes wiring up the CSS framework you usually use while Samara pieces together some placeholder images. Once that work is done, you write some simple HTML to align the images in a grid layout with some hardcoded captions.
You spend just a little too long trying to figure out exactly where song titles should be placed and what size they should be. But then you remember two important points: none of those details matter right now, and it’s time to get some lunch!
You deploy the code as-is, and a minute later the page is live on the Web:
It really doesn’t look like anything special, and you start to worry that the client will not understand why you might want to show him something this minimal.
To check your assumptions, you ask Samara what she thinks. She points out that not even the most simple things survive first contact with the customer, and that it would be better to ask for feedback too early than it would be to wait too long.
Feeling reassured, you remind yourself that the real goal of this first iteration is to set up a running system that will allow you to rapidly deploy new changes and kickstart the discovery process. From here on out, the client can directly interact with the software, and that will help you move a lot faster.
You send out a quick message to Ross letting him know that you have something ready for him to review, and you take a short break while waiting for a response.
Discuss all defects, but be pragmatic about repairs
When you return to your desk, you find feedback from Ross waiting for you:
Hello developer friends!
I just got the chance to try this out. On my laptop, the page looks pretty much like what you showed me in Samara’s sketch, so no complaints there.
I also tried to load the page on my phone, but things look awkward there. All of the videos take up the full width of the screen, and the recommendations are displayed in one long column rather than being shown side by side.
We definitely don’t need to make this thing look beautiful any time soon, but it seems like we should at least try to make sure all the recommendations are visible on a single screen, rather than having to scroll past a bunch of full-size videos.
Is that something you think you can do something about?
As Samara predicted, something did manage to slip through the cracks, even in this extraordinarily simple first iteration. It’s impossible to entirely guard yourself from making mistakes, but how you respond to them is critical.
You know that you can’t leave the mobile UI question unanswered, but you don’t want to dwell on it either. A reasonable response would be to draw up a fresh wireframe to communicate what the site should look like when rendered correctly.
Samara begins looking at a few popular video-based sites on her phone and finds that several of them use a common layout. She then sketches up something similar, but stripped down to the bare essentials.
You send the wireframe along to Ross, and then spend a few moments talking over next steps with him:
Ross: Thanks for the drawing! It looks like a decent starting point.
You: That’s great to hear. Now we have a decision to make: do we work on fixing the mobile layout issue right away, or do we put it off until later?
Samara and I think that it may be worth implementing some useful recommendations functionality first, and then revisit UI questions down the line.
That said, if you feel that a mobile-friendly design is essential even during the early stages of gathering feedback, we can take care of this before we move on.
Ross: Is this kind of issue harder to fix later than it would be to deal with up front?
You: I don’t think so. Most of the work on the recommendations system will be under the hood, and so the desktop UI shouldn’t need to change much. And if for some reason we do need to make major UI changes, we’d need to go back to the drawing board for the mobile sketches anyway.
Ross: OK, let’s wait a bit then. If any of our early testers complain about not being able to easily use this on their phones I may change my mind, but we can wait until we start collecting some feedback to worry about that.
Whenever you find a flaw in your software, it is tempting to drop what you’re doing to work on repairs right away. But in the exploratory stages of a project, it’s important to balance the cost of each defect you encounter with the cost of the time it might take to fix it.
In this particular case, time not spent on dealing with minor style tweaks on mobile is time that could be spent exploring the music video data sets and trying to come up with some recommendations rules. But by putting together a rough plan for how to fix the issue and communicating your ideas to the client, you eliminated some risks up front without having to invest a huge amount of effort.
Check your assumptions early and often
Early conversations with Ross have hinted that he is just trying to build something fun for his music community, a much easier problem to solve than “trying to create the most sophisticated predictive music playing service in the entire world!” or anything else along those lines.
However, it always pays to check assumptions on things like this as early in the process as possible. The initial wireframe sketches focused on what the UI for the application might look like, but now it is time to discuss how it should work:
You: Now I’ll ask a more technical question…
What kind of rules should we use to implement recommendations?
Ross: Oh… hmm… I was hoping you might have some insights into that. Up until a few weeks ago, it didn’t even occur to us that this project might be worth working on, so it isn’t something we’ve done a ton of research on yet.
You: Well, there are a bunch of options here, ranging from basic category matching to very sophisticated approaches involving machine learning. It really depends, and although we could probably help you get a jump start no matter what, it isn’t an area we specialize in.
Ross: I’m not sure if it’s helpful, but our blog posts are all curated lists (e.g. “Ten great Miles Davis tunes you’ve probably never listened to,” “A collection of live hip-hop performances from 1980s New York,” “Family favorites for the Christmas season”).
Our goal with this recommendations tool would be to help cut across these lists so that the listener can find other things they might like. So, for example, they might be listening to a 1980s hip-hop recording that was live in New York, and then we’d find other songs by that same artist, or we’d find other 1980s hip-hop songs, etc.
You: OK, this gives us something to think on, thanks. I think Samara and I might let these ideas percolate for a little while, and then we’ll have more to show you sometime tomorrow. Does that sound good?
Ross: Absolutely! Thanks for the work so far; this was fun.
This conversation confirms that a simple recommendations system might be good enough and that Ross is flexible about its implementation details. You may have lucked out in this case, but if he had a more complicated idea in mind, it would have been better to find out sooner rather than later. So it never hurts to ask!
Limit the scope of your work as much as possible
Everything up until this point was just about finding an entry point into the project, but now it is time to roll up your sleeves and get some real work done. There are still plenty of unknowns to work out, and just studying Samara’s original sketches for a few minutes generates many questions about implementation details:
These questions crop up in a non-linear fashion, but before you can do any useful work, you’ll need to prioritize them somehow.
Of the five important issues you and Samara have identified, two appear to be low-hanging fruits: how to generate embed codes for videos, and how to construct URLs for thumbnail images.
You pull up the music blog that Ross manages and check to see what video hosting service they’re using. You also click through a few posts and check their source code to see how things are structured.
“Most posts use only embedded videos from FancyVideoService. The embed codes follow a standard format; the only thing that differs from video to video is its unique identifier.”
“How about thumbnails? What do those look like?”
You hesitate for a moment, and then your clicking on various blog links intensifies, until you are convinced that you aren’t getting anywhere.
“It doesn’t look like they actually use thumbnails on their site. Everything I’ve seen so far is just embedded videos. So I guess we’ll need to look that up.”
You search the Web for a few minutes, but don’t find any official documentation from FancyVideoService about how to grab thumbnails for their videos. You do, however, find a blog post that describes the URL format they use internally, and it’s easy to generate these links using the same unique identifier that is used in video embed codes.
You manually create a few thumbnail URLs based on the videos from Ross’s blog. They seem to work fine, although it is questionable whether this is actually a supported use case. For now, you hope for the best, but you’ll need to get in touch with FancyVideoService to confirm that this approach is legitimate before the project wraps up.
With these chores out of the way, you can go back to the more subjective questions that came up when you were reviewing the mockup: what data to collect about each music video, how to go about storing that data, and how to use the data to generate useful recommendations behavior.
You and Samara start to talk through options, but then realize you’re getting too far out into the weeds. So you go back to the classic question: “What is the simplest thing that could possibly work?”
After a few moments of quiet rumination, Samara gets a burst of inspiration.
“What if we started with artist matching? Based on whatever video is playing, randomly pick a few more songs by that same artist.”
“Good idea. I think we’ll need something more complicated before Ross sends this out for feedback, but I’m just really itching to get something on the screen that we can interact with right now.”
Artist matching is an easy starting point, because all that is needed are video identifiers from FancyVideoService, song names, and artist names. If you grab a couple dozen songs from Ross’s blog, that would be a decent sample data set to work with.
“What should we do about data storage? Should I go ahead and provision a—”
Samara abruptly cuts you off in the interest of keeping things simple.
“No need for that yet. Let’s hardcode a sample data set as a bunch of arrays, and walk over those to generate the recommendations.”
“You know that won’t last us that long, right?”
“Doesn’t matter. It doesn’t have to!”
Samara is on a roll, so you ask her to do the coding while you piece together a handful of song names, artists, and video identifiers.
Fifteen minutes later, the two of you have something that looks halfway decent3 running live in production:
Just to show signs of progress and to hint at things to come, you drop one last note to Ross before wrapping up for the day:
You: Hey Ross, if you check out the website you’ll see that we now have something up and running that kind of looks like a music recommendation system. It’s very limited at the moment (only does artist matching), but thought it’d be fun to show you what we’ve been able to put together so far.
Ross: Whoa! Nice work. It definitely feels good to be able to interact with this rather than just looking at placeholder images, and it seems to be working mostly how I imagined it would in my mind.
I assume you’ll be adding some more interesting recommendation behavior tomorrow? It doesn’t need to be fancy, but it’d be nice to go beyond just artist matching.
You: Absolutely. We’re still giving that some thought, but we will be in touch tomorrow with more to show you.
Ross: Great. Thanks again for working on this. I’m super pleased to see an early version of this idea take shape in the span of a single workday.
The basic walking skeleton4 that you and Samara have put together will increasingly become more interesting to work with in future iterations.
While most of the first day of work consisted of getting the various moving parts into position, it has put you in a good place to begin exploring the real problem you are trying to solve. Had you attempted to jump straight into thinking about how to solve the full problem, it would have been harder to find a starting point, meaning much more stumbling along the way.
With not much time left on the clock for the day, you decide to spend the afternoon taking care of minor chores, reading blog posts, and using your phone to chase imaginary animals in exchange for imaginary Internet points.
Remember that prototypes are not production systems
After half an hour of quiet procrastination, Samara breaks the silence with some exciting news:
“Oh hey, customer support at FancyVideoService got back to us.”
“They did? I didn’t even know that you had emailed them. When did you do that?”
“While you were talking to Ross. I figured it’d be better to hear back about this sooner rather than later, but I’m surprised we got such a quick response.”
You look over her shoulder to see what they had to say:
Hotlinking to the thumbnails for the videos we host is technically not against our policies, because we do want to be able to support a wide range of different use cases around sharing the videos we host.
That said, it’s not officially supported either, and there is no guarantee that the URL scheme will not change. We also reserve the right to deny access to anyone who seems to be abusing the service, at our sole discretion.
A better solution would be to register for our developer network and then use the data APIs we provide. By looking up thumbnail URLs this way, your code will continue to work even if we make changes to the URL structure in future updates.
Another benefit of registering for the developer network is that if there is ever a situation in which your code unintentionally violates our service terms, we’ll be able to identify you and send you proper notice about how to resolve the issues.
Hope that helps, and have a “Fancy” day!
You’re relieved to find out that this feature is supported, even if the exact approach you took isn’t what FancyVideoService prefers.
In the interest of saving time, you decide to stick with the unofficially supported way of generating thumbnail links for now, but you make a note about the issue so that whoever ends up building the production version of this software will know about it.
Happy with your progress, you call it quits for the day.
Design features that make collecting feedback easy
The next morning, you arrive at the office to see the whiteboards filled with a ton of notes that weren’t there the night before. Curious about what Samara has been up to, you start to look them over.
“Oh wow! Ross will love this. What time did you get in this morning?”
“About an hour ago. I had this idea while eating breakfast, and decided to come in and start playing around with it.”
Samara looks like she didn’t get enough sleep, but you’re so happy with her idea that you feel no need to mention that.
“So, should we get started on this then? I think it looks promising, and your notes are really, really good.”
“Already done. Check the website.”
You sit down and spend a couple minutes playing around with the new features. They are all working well, especially for a first major deliverable.
“How did you build this so quickly? I assume you cut some corners as we always do, but I doubt I’d be able to get that much done in an hour.”
“Oh, you really do not want to see the code for this. You see all those recommendation scores? They’re all being stored in a single browser cookie.”
Figuring out the right balance of when to play fast and loose and when to tighten things up takes practice, but you trust Samara’s judgment. You ping Ross to collect his feedback on the new functionality:
You: Hi Ross. I’m happy to say that we have something ready to show you whenever you’re able to check it out. Just visit the website whenever you get a chance, and then I can walk you through what is going on there.
Ross: I’ll take a look soon, thanks. I wasn’t expecting to hear from you until at least lunchtime, so this is a pleasant surprise.
You: Here’s a screenshot5 that shows what things look like after viewing a bunch of videos. But definitely try it out yourself to get the full effect. :-)
Ross: Just spent a few minutes playing with the new feature. This is awesome!
One thing I noticed is the “interests” sidebar, which we never really talked about yesterday. Can you explain to me what that’s meant to be used for?
You: Sure. It’s worth mentioning up front that this sidebar isn’t meant to be a permanent part of the application’s interface.
Because the recommendation behavior is a little harder to explain than it is to see in action, we made this sidebar so that you can see how your tag scores are added up as you select videos in the application. Each tag is clickable, and whenever you click on a tag you will be sent to a randomly selected video in that category. You can use this to influence the scores and change the recommendation behavior.
Ross: Can you give me an example of how to try this out?
You: Sure. Click “Thelonious Monk” a bunch of times, and see what happens.
Ross: Aha! As I did that, the recommendations for antifolk music started to become less frequent, and jazz recommendations become more frequent. Eventually, the system was offering me nothing but videos from Monk, which I guess is what was supposed to happen.
You: Yep. Do you feel like you understand this now?
Ross: I think I understand it well enough to want to play with it some more, and we may even be far enough along where I can send this to a few other people today and collect their feedback as well.
I am really glad you made that sidebar, though, because I would have had trouble understanding how the recommendations system worked based on your description alone. So thanks for that.
You: It was Samara’s idea, and it’s something we really should do more of. It helps you see a little bit of what’s going on under the hood, and it gives you a chance to explore the rules we’ve implemented.
* * *
Ross: One more question before I send this out for feedback: where is the sample data coming from?
You: Right now, we’re using a very small set of hand-picked videos based off of things we saw on your blog, but this is another area where we put in some effort to allow you to customize it yourself.
The system is currently set up to read its data from a CSV file, which you can edit in any spreadsheet software. Here, take a look at a few of the records that we currently have in the system:
You: The first column is the unique identifier for the video, which appears at the end of each FancyVideoService URL. The second column is the artist name, and the third column is the name of the song. Every column after that is treated as an arbitrary tag. Right now we have only two tags (genre and release year), but you can add as many of these as you want.
Ross: Wait…am I understanding this correctly? If you sent me this spreadsheet and I edited it to include any videos I wanted, you’d be able to directly import that and the videos would start showing up in the system with the tags I set?
You: Yes, that’s the basic idea. We may need to be a little careful at first just because these things do need to be correctly formatted, but this is something we can help you with where needed.
What we had in mind here is that maybe you’d want to create a list of a couple hundred songs from your blog, and then that would give you a more realistic test of the existing recommendations behavior.
Once you’ve done that, we can definitely talk about ways to automate pulling your entire collection of 4,000 songs from your blog, but we figured that could probably wait until later.
Ross: This is great. I’m going to do exactly as you suggested, and put together a small list of songs based on the blog posts. After that, I’m going to make sure that at least a handful of people get to try this out today, and by the late afternoon I should be able to share their feedback with you. From there, we can figure out what to focus on next.
I can’t thank you enough for putting this together. Really nice work.
You: This has been fun, and you’ve made our job very easy, so thank you, too.
Despite the feeling of mutual appreciation, it won’t necessarily be smooth sailing from here. As the old saying goes, “the devil is in the details,” and the next several iterations will get more detailed, probably stirring up at least one major unanticipated issue before you complete the prototyping phase.
But that isn’t a sign of a flawed process; it’s exactly what you should expect as a side effect of accelerated feedback loops. Prototypes can help you figure out how to build useful things faster, but they also help you fail faster. If you can spot a dead-end path before you’ve already spent a ton of time walking down it, it means you can spend more energy on figuring out where the right path is.
For the moment, though, both you and Samara are content to celebrate your early progress. A little bit of goodwill and trust built up in the early stages of a project can help build the kind of momentum that gets you through the inevitable rough patches that crop up in any creative work.
Hey, you finished the first chapter! Awesome work.
Please enjoy this unrelated puzzle6 as a token of my appreciation for your efforts.
Start at the beginning and end with a bang! Jump around if you must, but don’t get lost in the noise. If you look carefully, you’ll surely hash out what the hidden message is.
1 This idea from Ward Cunningham serves as a reminder to focus on the goal that is driving your work, rather than getting lost in thoughts about imagined future costs and benefits.
2 You aren’t gonna need it (YAGNI)—A design principle that says functionality should not be added until it’s truly necessary to do so.
3 Image sources: Piano; Regina #1; Regina #2; Regina #3
4 A walking skeleton is a small end-to-end implementation of a feature that gives you a starting point for thinking through and evolving the rest of the system it will eventually become a part of.
5 Image sources: Ella Fitzgerald; Beck; Thelonious Monk; Regina Spektor
6 You won’t need to write code to solve this problem, but an ASCII table will come in handy. Once you know the rules that govern this little Turing tarpit, a solution can be found in a few seconds with pen and paper.
Get Programming Beyond Practices now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.