Making Laundry Less Terrible with Machine Learning

Since my son was born, I’ve been doing a lot of laundry. An infant’s laundry needs are small (well the clothes are) but frequent so to be efficient you might as well do the whole family’s the laundry. When you do enough laundry, you’ll notice those little tags. Each garment has a set of shapes – triangles, circles, squares, and other shapes – that intend to describe how to care for it.

Laundry care tags - Wash at 60 degrees Celsius, Do not bleach

Well last year, I got obsessed and started to learn how to interpret each one. It’s not complicated but it is not obvious either. So I set out to make it easier on myself and others. It’s easy enough to create a pocket guide for laundry tags. But, I thought it would be neat to be able to take a picture of the care tag and present which tag it matched. This seemed like an opportunity to play around with machine learning and computer vision tools as well.

Each time I did laundry I would take photos of the tags. I would then organize them based on which type of care tag it was (Wash at 30 degrees Celsius vs Non-Chlorine Bleach). Using Firebase’s Automl Vision Edge, I could then create a machine learning model.
Vision edge generates a TFlite model to use to classify an image. To use the model, I then created an Android app and an iOS app to consume results from the camera.

Here’s what the Kotlin code looks like to process an image

 override fun onImageSaved(file: File) {
     val uri = file.toUri()
     if (uri != null) {
         // loads the machine learning model
         val localModel = FirebaseAutoMLLocalModel.Builder()
 val options = FirebaseVisionOnDeviceAutoMLImageLabelerOptions.Builder(localModel)
        .setConfidenceThreshold(0.5f)  // Sets the appropriate confidence threshold
    // loads the labeler
    val labeler = FirebaseVision.getInstance().getOnDeviceAutoMLImageLabeler(options)

    val image: FirebaseVisionImage
    try {
        // loads the image as a firebase vision image
        image = FirebaseVisionImage.fromFilePath(applicationContext, uri)
            .addOnSuccessListener { labels ->
                for (label in labels) {
                    val text = label.text
                    val confidence = label.confidence
                    Log.d("RECOGNITION", text + " " + confidence)
                // do a thing with the confidence and label
            .addOnFailureListener { e ->

    } catch (e: IOException) {

The code in Swift is very similar
   let localModel = AutoMLLocalModel(manifestPath: manifestPath)
         let options = VisionOnDeviceAutoMLImageLabelerOptions(localModel: localModel)
         options.confidenceThreshold = 0.05  
         let labeler = options)
    var config = YPImagePickerConfiguration()
    config.showsCrop = .rectangle(ratio: 1.0)
    config.showsPhotoFilters = false
    let picker = YPImagePicker(configuration: config)

    picker.didFinishPicking { [unowned picker] items, _ in
        if let photo = items.singlePhoto {
            self.image = photo.image
            let image = VisionImage(image: photo.image)

            labeler.process(image) { labels, error in
                for label in labels {
                    self.result = GuideResult(label:label.text, confidence: label.confidence ?? 0)
        picker.dismiss(animated: true, completion: nil)
        self.dismiss(animated: true, completion: nil)

This project also leveraged SwiftUI so I ended up building an Apple Watch and iPad version as well

I’m really proud with how it came out. I released both apps under the LaundrySnap name in the respective app stores back in May but I just launched it on Product Hunt Today!

Product Hunt Link
Apple App Store
Google Play Store

Screenshot of iOS app

The Westworld Software Team is bad at XP and DevOps

While watching Season 1 of Westworld, I spent the entire time annoying my wife. I would bug her about the anti-patterns I saw the software teams at Westworld using.  Of course, the anti-patterns were for dramatic effect. It wouldn’t be interesting if everything went right. But, since it’s rife with bad practices it can be a good way to point out when teams are doing things wrong.

What follows will be a load of spoilers. We will learn from the Westworld team’s mistakes and prevent them in our own teams.

Again there will be many spoilers, so if you haven’t finished Season 1 and don’t want it to spoiled: stop reading.

Without further ado.

Continue reading “The Westworld Software Team is bad at XP and DevOps”

Molasses! A feature toggle library for Elixir

Early this year when I read about Erlang in Seven Languages In Seven Weeks, I mentioned that Elixir was a language I intended to explore this year. At Maxwell Health, we also started to investigate Elixir for new projects because we wanted a functional language in our arsenal and we liked it’s concurrency story. So I thought it would be in my best interest to dive into Elixir. I read through Programming Elixir and Programming Phoenix and recently started work on several Elixir projects.

Feature toggling is a way to release code to production without executing it by default. There are several ways to leverage feature toggles: releasing a feature production that may not be ready for customers or may be broken, releasing a feature to a subset of users or simply A/B testing. I wanted to create a library that captured all of these features for Elixir. Having contributed to other feature toggle libraries, I had a basic sense of the features I wanted. I wanted to be able to activate and deactivate features, have features that could be shown to a percentage of users and have features that could be only available to groups of users. In languages like PHP, this can mean several classes that are managing these pieces of functionality. However, in Elixir I could leverage pattern matching which shrank my code down.


    def is_active(client, key, id)  do
        case get_feature(client, key) do
            {:error, _} -> false
            %{active: false} -> false
            %{active: true,percentage: 100, users: []} -> true
            %{active: true,percentage: 100, users: users} -> Enum.member?(users, id)
            %{active: true,percentage: percentage} when is_integer(id) ->
                value = Integer.to_string(id) |> :erlang.crc32 |> rem(100) |> abs
                value <= percentage 
            %{active: true,percentage: percentage} when is_bitstring(id) ->
                value = id |> :erlang.crc32 |> rem(100) |> abs
                value <= percentage

The code above handles all of those features in just a few lines and it handles several kinds of Ids (strings and integers). Isn’t that cool? Other than pattern matching, other languages features I’ve enjoyed are the piping of functions into one another. It has been a great way to visualize how data is being manipulated in the pipeline. I can’t wait to explore more of Elixir in the new year.

You can check out the whole repo on Github.


More Books in 2016!

I’m back with another set of books I read this year. I’ll be finishing a few more by the end of the year.

  • Walkable city: How Downtown Can Save America, One Step at a Time –  When I travel, I love to use the public transit of a city and walk as much as I can. This book captures why the cities that are easy to travel in will continue to be and how you can transform your difficult to travel city to be walkable. 
  • The hard thing about hard things – Ben Horowitz talking about his companies experiences from the dark times to the less dark times. 
  • The Devil In the White City – It takes a bit to get moving, but once we’re moving this book switches beautifully from the World’s fair to one of the worst serial killers in the US. 
  • Programming Phoenix and Programming Elixir – I’ll be writing more about how much I’ve been enjoying learning Elixir, but these are great books to get started with it. 
  • Holy Sh*t: A Brief History Of Swearing- I swear a lot. I felt good to know that my behavior is as old as the written word. I enjoyed how what we concern to be a swear has changed over time – from religious swearing to obscenity.
  • Ha! The Science of Why We Laugh and Why – Any book that references the Aristocrats is a good book.
  • TED Talks: The Official TED Guide to Public Speaking – TED is full of helpful hints to engage the people you’re speaking to.  If you want to step up your speaking game this is a good place to start. 
  • Payoff: The Hidden Logic That Shapes Our Motivation – A short read about motivation by Dan Ariely. He brings forward more studies to prove the things that get people to do the things they do. 
  • White Trash: The 400-Year Untold History of Class In America – Before our forefathers got to shore they already had identified white trash in England. For the last 400 years, our politicians and most influential Americans have criticized and manipulated poor whites. Hearing the uncensored cruel words that our presidents and founding father’s said about the poor of all races was disturbing and enlightening.
  • Weapons of Math Destruction – Algorithms aren’t clever yet, they lack nuance and context. Could you imagine if they determined your ability to go to college, how long you’ll be sentenced in jail and making important financial trades without context or based on too few inputs? Well don’t imagine it, it happens every day. 
  • Blue Ocean Strategy – Sara read this in college and suggested it to me. While I hate the word “value-innovate,” it creates a gameplan on how to create a business that creates its own market. 
  • On Writing Well – I will write shorter sentences. I will be a strong voice. I will write what I care about and make people care about it. 
  • Between The World and Me – This is a beautiful book. This is an important book. This is a book you should read.  





As of data released yesterday, the state of Massachusetts loses 5 people a day to opioid overdose. The whole nation is facing an epidemic, young people are dying at an alarming rate and more people becoming addicted to opioids every day. Naloxone is a drug that reverses the effects of an opioid overdose and saves lives.  Civilians can be trained to administer the drug and be there to reverse the fatal effects of an overdose. However, in order to administer the drug they must be in the right place at the right time. To help connect responders with those in need the FDA held a month-long hackathon.

To help connect responders with those in need the FDA held a month-long hackathon. The goal of which was to provide a mobile application to get Naloxone to those who need it within the 5 minutes after the person in need begins overdosing. In many parts of the country, the number of overdoses that happen in one evening far outpaces the number of EMTs and police officers who are on duty to respond.

Cory, Carrie and I were inspired to participate after several years of watching our towns getting gutted by heroin addiction. We’ve lost friends and neighbors who had so much more to experience, so when the FDA opportunity came about we knew that our skill sets could help make a difference.

simulator-screen-shot-nov-8-2016-12-51-46-pmThe application is called Antidote. It is designed to connect those who need Naloxone to their area with those who have it. It has two roles: the responder, and the requester. The responder is a user who is trained to administer Naloxone and the requester is someone who needs it. We wanted the workflow to be minimal and familiar. The guiding principal was if you have used Uber you would know how this would work. The application asks for minimal information, just a phone number and your location, to respect the privacy of those involved.


From a technology perspective, we knew we wanted to support both iOS and Android. While we never used React Native before, it made sense to adopt it as it is designed for those who have used React on the web and it integrates well with Redux. There are an endless number of plugins for React Native, so the implementation of location, maps, notifications, styling and persistence was relatively straightforward. We didn’t want to bother with authentication or authorization and wanted to be able to verify accounts with SMS.  Auth0 provides this SMS/passwordless functionality out of the box and made itself an even easier choice in its implementation.

You can experience a demo of our application at Youtube and read all of the code on Github: here and here. We’re really proud of the work we’ve done and hope to expand on it in the future.


TV Pilots are a treasure trove of data

A few months ago, I did a little weekend project of looking at TV comedy pilot scripts. For those unfamiliar with the concept, when a television show is being developed a network will order a pilot episode as a test to see if it will pick it up for a full season. As a result, the idea may be reworked and elements changed to “make it work” for that network.

Part 1: Fetching and Normalizing the data

To start, I scraped about 450 television pilots from Here was my first challenge, some of these were just text files (awesome) but others were PDFs. In order to extract the text, I turned to Tesseract. Below is the script I used to extract the text:

for f in $(find . -name '*.pdf'); do
  PAGES=`pdfinfo $f | grep Pages: | awk '{print $2}' | tail -n 1`
  if [ ! -f textfiles/$parsedfilename.txt ]
    #some text was parsable just using pdftotext
    pdftotext -layout $f - > textfiles/$parsedfilename.txt
    echo "File $parsedfilename does not exists"
    for i in `seq 1 $PAGES`; do
      # converts the file to an image
      convert -density 500 -depth 8 $f\[$(($i - 1 ))\] images/page$i.png
      # tesseract parses the image for text and puts it into a file
      tesseract images/page$i.png stdout >> parsed/$parsedfilename.txt

This got most of the scripts in a format that could be queried. Here’s a sample of the very funny 30 Rock pilot – note the different character names –

The studio's homebase set. Workman are polishing a big
sign that reads, "Friday Night Bits with Jenna DeCarlo.
"Pull back through the picture window to where KENNETH a
bright and chirpy (Clay Aiken type) NBC page is giving a
tour. He stands next to-a life-size standee of impish
comedian Jenna DeCarlo. '

Part 2: Apache Spark analysis

Now that the data was machine readable, the best first course of action was to query the text files for data that I thought might be interesting.  Apache Spark is a great tool for loading up datasets like this so I went into the Spark shell and ran some different experiments. Here is some of the code I used to get to these numbers:

//loads both folders of the 450 comedy scripts into the RDD
var parsedFiles = sc.textFile("./tvscript/parsed,./tvscript/textfiles")
//outputs the count of the phrase "20s"
parsedFiles.filter(line => line.contains("20s")).count()

Exterior vs interior scenes

Screenplays are unique because of the way they are formatted, they announce whether a scene is interior or exterior at the beginning of the scene with either INT. or EXT. so I started there.


Screen Shot 2016-10-09 at 1.46.01 PM

My take: It is significantly cheaper to shoot indoors than outdoors, this might be a self-selection by writers to make sure their show gets picked up.


Age of characters

When announcing a character in a screenplay you usually give a short description which includes their age usually by decade, for example from The Grinder script “STEWART SANDERSON (30’s) drives with his family”.

Screen Shot 2016-10-09 at 1.48.06 PM


My Take: No surprises here, television is geared towards 24-54 and they want to show a good distribution of those people on TV.

Part 3: Sentiment Analysis

That was a fun experiment, but it was time to go further. In looking at the data, I realized I could do a sentiment analysis of block of text in an episode and see if there were any patterns that appeared. I created a new scala project focused on using Stanford’s natural language processing library and based on work done here. Each block of text was taken and analyzed then put into a MongoDB store with a structure that looks like this

  "sentiment" : 1,
  "textFile" : "Black-ish 1x01 - Pilot",
  "line" : " DIANE\n She’s weird, so feel free to say no.",
  "weight" : 263

Here the “sentiment” is a scale from 1-5 with 1 being most negative, “line” is the actual block of text and “weight” is what order it occurs in the episode, so this was the 263rd thing said in the episode. With the data in place, I built a small node server that could display a chart for the scripts I parsed. Here are some screenshots of the results


Screen Shot 2016-06-05 at 11.08.25 AM Screen Shot 2016-06-05 at 11.07.40 AM

Pretty neat right? Well the completely interactive version is located at where you can look at the 100+ scripts I did sentiment analysis for.

Some More Books I Read in 2016

When I started the year I had a goal that I would write a blurb about each book I finished this year however I’ve fallen way behind in the writing piece. As a form of catch-up (read as cheating), I’m going to quickly recap the books I’ve read since The Power Of Habit.

  • Born To Run – A great read while I trained for my first half marathon. I always enjoy reading about forgotten knowledge and for running long distances we’ve certainly forgotten more than we know Today.
  • Domain Driven Design Distilled – If you are building software applications, domain driven design is an approach to wrangling complex business logic by structuring your applications as your users will think and speak of them. This book and others will help you work through the brainstorming process for that as well some design patterns like CQRS and Event sourcing to aid in communicating changes in your domain driven services.
  • Food a love story – Jim Gaffigan writing about food, it is great.
  • Infrastructure as code – You’ll be inspired to rewrite your entire infrastructure so it’s not a set of hand-rolled fragile pets but an automated, repeatable, scalable infrastructure made of ready to kill at any moment servers.
  • Disrupted: My Misadventure in the Start-Up Bubble- A man in his 50s joins Hubspot and hilarity ensues. Of course about half through the book things take a dark turn. A great read for anyone who has worked at a start up and thinks sometimes that you are all going nuts.
  • Packing for Mars – An adventure of all of the weird stuff about going to space (how do they determine who has “the right stuff”?), floating in space (has anyone ever had sex in there?) and how we’ll ever colonize space (It’s probably like locking people in a space capsule on earth for months at a time… let’s see how that goes)
  • American Icon: Alan Mulally and the Fight to Save Ford –Alan Mulally took a company that by all rights should have been dead and rebuilt it by getting people to work with each other, focusing the product line, and solving problems of quality above all else.
  • The Psychopath Test – There is a test that professionals use to determine if someone is a psychopath. Jon Ronson explores whether he can learn to identify psychopaths by learning the test and finds out a lot about crazy people along the way.
  • The Etymologicon – My favorite feature of google is asking <WORD> etymology. This was basically 7 hours of that but a constant flow of words, it was so much fun.
  • Grunt – Military science rarely gets covered in the news, this was a fun way to learn about it. I saw Mary Roach speak about this book when it came out, she said she focused on the human stories and innovations that are largely ignored,
  • Omnivore’s Dilemma – It’s tough being humans. We  are making complicated trade-offs – organic, local, slow, fast, …whatever the trend, none of them are silver bullets and this book covers a lot of these trade-offs.
  • Sienfeldia- I’m a big Seinfeld fan and to hear all about how the ideas and stories came to light is fascinating. Can you imagine where we would all be without the big salad, yadda yadda yadda and the contest? Probably the darkest timeline.
  • Shoe dog- I didn’t know the story of Nike. To hear about the giant risks they took to create one of the largest shoe companies and one of the most recognizable brands of all time is a ton of fun. Reading this book after Born To Run was great as well because you can see how early Nike design decisions influenced the shoe industry that may lead to a backlash that turns into the barefoot running movement.
  • Spook – I’m clearly a fan of Roach’s writing – while this wasn’t my favorite of her works it’s still a good time to explore what happens after we die. Roach doesn’t pull punches as she explores reincarnation, people who communicate with the dead and even stories about past popes.
  • American nations a history of the eleven rival regional cultures of North America – This was probably the one book I read this summer where I couldn’t stop talking about it. “And see the nations have never got along it was just these 3 events where we pretended to” or “Can you believe that people from the Appalachian states have made up the most of our military since the revolution but only account for a small piece of our population?”  is how I annoyed Sara every time I put down the book. When I finished the book I was amazed because the first article I read was about the prison sentences being widely different county to county. You can read the full article here, but the map of where the harshest prison sentences aren’t red states and blue states but almost an exact map of the “Borderland” states.
  • The Phoenix project – A fictional book about DevOps, what will they think of next. But you know what despite the deus ex machina up the wazoo – oh how convenient that the factory down the street has the exact same problem as our infrastructure team! – it was fun to see XP principles and DevOps applied and how it can transform an organization.
  • Notorious RBG – Ruth Bader Ginsburg’s journey to the Supreme Court and her impact on the court is inspiring. While the author tends to float into meme-heavy pieces about how cool RBG is, it was still a great story about a woman who has been steadfast in her fight to make our nation into a more perfect union.
  • The Ego Is the Enemy – Ryan Holiday goes deep throughout history and does a fantastic job finding examples where ego ruined a successful person. As much as we love Kanye, in looking at the data he is the exception not the rule.
  • Harry Potter and The Cursed Child – We’re going to see the plan in London next fall and after reading through the play, I can’t wait to see it on stage.


The Power of Habit: Why We Do What We Do in Life and Business By Charles Duhigg

At my old job, we used to have cans of Coca-Cola available in our fridge. I remember every day I would start to drag around 3 PM, and then the lovely sound of someone else opening a can would cause me to get up, drift to the fridge, open my own and drink it as fast as possible. By 3:30 I was ready to tackle that important piece of work I had to do.

This was a habit. It was set off by a cue, followed by a routine and punctuated with a reward. According to The Power of Habit, these are three elements of the habit loop. The book gives you the lowdown of how habits are built, ignored, exploited and how to break them. The author weaves together stories of Alcoholics Annoynomous, the Tampa Bay Buccaneers, early toothpaste salesmen and the launch of Febreeze to create a compelling tale. He reminds us that we can use habits for both good and bad and how they can be used to build better businesses and lives, a great read for those looking to create a “sticky” brand.

The Power of Habit: Why We Do What We Do in Life and Business

This Is Your Brain on Sports: The Science of Underdogs, the Value of Rivalry, and What We Can Learn from the T-Shirt Cannon by L. Jon Wertheim and Sam Sommers

I like sports but I think I love the human side of sports more. I read Deadspin, when I had cable I watched Outside The Lines and 30 for 30 and I listen weekly to Only A Game on NPR. Sometimes it feels like professional sports are its own universe where outlandish behavior is acceptable and normal human beings go from boring to insane. This Is Your Brain On Sports proves using studies and journal articles that our outlandish behavior in sports is happening but it’s also very much happening outside of sports.

One of my favorite pieces was about how the public views quarterbacks as universally good looking. The authors dug into this and ran their own study. They found that their subjects, who were not football fans when shown many players’ faces found quarterbacks to be less attractive on average than running backs and defensive linemen. I actually experienced this first hand on our flight to Paris, where Sara and I sat next to a Patriot’s linebacker who Sara would later tell me was “much better looking then either Manning brother.”

What was most interesting about the study was that subjects found quarterbacks to have more leadership qualities purely based on photos. It aligned with a similar study that was done with faces of employees and CEOs and had similar results with CEOs having more presumed “leadership” qualities. These studies got me thinking about getting asked for directions. Discussing with my brother and father, we’ve found we get asked for directions far more than people we know. On my current trip to Paris and Brussels, I’ve been asked for directions in 3 different languages in two different languages, with many other people standing close enough who could be up to the task. So why do they ask me? Maybe I have a face that says I’m approachable? Good with directions? Willing to help? Who knows! But, if you like reading about sports and how it reflects our daily lives check out this book.

This Is Your Brain on Sports: The Science of Underdogs, the Value of Rivalry, and What We Can Learn from the T-Shirt Cannon

Seven Languages in Seven Weeks By Bruce Tate

Full disclosure: I didn’t fully embrace this book, I didn’t do the exercises at the end of each chapter. For most of the languages, I don’t even have them installed on my computer. Ok, It feels good to admit that. With that disclosed, I will say Seven Languages In Seven Weeks was a treat. Of the 7 languages in this book, Ruby, Io, Prolog, Scala, Clojure, Erlang, and Haskell, I had only used 2 of them in the past, Ruby and Scala. My background is mostly in object-oriented, procedural and prototypical languages, however, this book shifts its focus towards languages that are more functional, and are built with pattern matching and concurrency in mind. Concepts that are not focuses of the languages I’ve worked with in the past other than Scala.
Seeing the evolution of languages was insightful to me, how closely tied to Lisp Closure is or how Scala and Erlang’s pattern matching are inspired by Prolog. While first investigating Scala, I could see the implementation of pattern matching but it wasn’t clear how powerful it could be until I saw how Erlang and Prolog leverage it in this book.  While I’ve appreciated limiting state in the systems I build, it was made much more clear how functional programming can be leveraged to supercharge concurrency. Working with languages like Java and Go, concurrency can be a proceed with caution situation because the developers writing the code are worried about race conditions and side effects. When we can significantly limit race conditions and mutable state then concurrency is less scary.
The interviews with the authors of each language spoke volumes about what the tradeoffs and intentions of each language were. Ruby is a language where the trade-offs are most obvious, a great syntax which leads to productivity traded for speed.  Having revisited Ruby recently for other projects both personal and for work, you can see the productivity increase right away but, it might take some time to feel that trade off in speed. The challenge, of course, is knowing when to migrate.
What I discovered at the end of reading this book was the language I wanted to explore next. Oddly enough, it wasn’t in this book and even more strange after doing some more reading it was partially inspired BY this book and that language is Elixir. Elixir combines some of the syntactical sugar we love about Ruby, the metaprogramming of Clojure and the concurrency and power of Erlang.

Seven Languages in Seven Weeks: A Pragmatic Guide to Learning Programming Languages (Pragmatic Programmers)