the further adventures of

Mike Pirnat

a leaf on the wind

Text Me Maybe: Smarter Real-World Integrations with Python

Gosh, it's been a year since I last posted! Let me try to make it up to you...

I took some existing talks on the road last year (to CodeMash, PyCon, and OSCON!) but I've once again put together something new for PyOhio.

So my family likes to know when I'm on the way home from work, but I'm lousy at remembering to text or call before I leave. Some basic "out of the box" geofencing solutions are available, but none of them are smart enough to understand situations like going to lunch where sending a "coming home" message wouldn't be appropriate. Luckily, we can assemble our own solution pretty quickly and cheaply with Python at the core, and we don't even have to run our own servers to do it!

In this talk I showed how I created a cloud-hosted, location-triggered SMS notification service with some decision-making smarts by combining IFTTT (If This Then That), AWS Lambda, Twilio, and just the right amount of Python.

The talk seemed to go really well, and I have been flattered and humbled by the volume of positive feedback I got about it. I hope it will inspire you to go have some fun making your smart things a little smarter.

Here are the slides:

Unfortunately there's no video due to a variety of AV issues, so you'll either need to use your imagination or convince the PyCon program committee to accept it for 2017. ;-)

And who knows, maybe I'll start posting more often (hahahaahhahaahahahahahahaha *wipes away tears* whoooo wow, who am I kidding?).

Read and Post Comments

Using Python to Get Out the Vote

After taking a year off from PyOhio due to a scheduling snafu (off-by-one errors apparently aren't just for software), I was delighted to be back this year, and with a fresh talk to boot.

This spring, I helped my wife with the data munging aspect of a school levy get-out-the-vote campaign. We mashed up school directory data with Ohio voter registration records to produce targeted contact lists for phone calls, mailings, and door-to-door visits, reducing redundant contacts and eliminating wasted contacts.

The technology involved is pretty straightforward, involving a little bit of Python and some pretty basic SQLAlchemy and Alembic (in fact, it was my first serious dive into both SQLAlchemy and Alembic).

The talk seemed to go pretty well, and I had some great conversations about it afterwards. Hopefully it will be inspiring or at least of some value to folks looking to do some useful things with Python.

Here are the slides:

And you can watch the video too.

Read and Post Comments

A 365 Project for Code?


While Twittering in jest over the frequency of Requests' releases, Jeff Forcier inspired me to wonder if you could do the software equivalent of the photography 365 projects that seem to be all the rage this year. I started probing around at the edges of the idea, and it seemed like it could actually be an interesting challenge.

The closest thing I could find (which Jeff pointed me to) is Calendar About Nothing, which tracks your public GitHub commits and gives you a lovely red X for each day you push up something that's available to the public. That's really cool, but it's also pretty easy to just be a weasel and rack up an epic streak by twiddling one's dotfiles back and forth every day. You could script it.

So what would a "code 365" look like? Extrapolating from photography, I would say that it's basically:

  1. Write something unique every day -- as humble or as wild and involved as you like, but something new every day. You wouldn't just publish small tweaks to a photo to get extra days of a photography 365, so once your daily code is released, it's done. And while you might be inspired to emulate great photographers or programmers who came before you--and that's okay--it's not okay to just grab somebody else's FOSS and claim it as your own. The challenge is for you to produce something new. (I'm willing to make an exception for "Hello World" entries, especially if they're on day 1, because it's the sort of thing I would do.)

  2. Any language you want -- just as a photographic 365 invites you to try different tools, techniques, and subjects, if you're brave enough to do a code 365, why not experiment with different languages, programming paradigms, and platforms? We often talk a good, smug game about the value of polyglot programmers, but why not prove it to yourself?

  3. Release it -- push it up to GitHub or whatever your preferred platform is; get it out there where we can see it and admire your foolhardy audacity.

I guess the next question is... Who would be crazy enough to do one of these? People like Corey Haines or Gary Bernhardt come to mind. I bet Kenneth Reitz could do it, but then we'd miss out on updates to the ten million other things of his that are increasingly hard to do without.

I'd be tempted to do it--what's good for the goose is good for the gander, right?--but I'm definitely not willing to consider in 2012. I think one 365 project is more than enough!

What do you think? Is this silly? Or could this Be A Thing?

Read and Post Comments


On Friday I ran across this modest proposal to make the output of Python's unittest2 more closely resemble the emotional state of the tester when there are a lot of failing unit tests. Once my coworkers were done asking if I was all right, or if they should be worried about the cackling and giggles coming from my cube, I resolved to make this dream a reality.

My workplace has settled on the nose testing framework. Like other frameworks, nose offers a plugin architecture to allow all kinds of additional customization and tweaks, and since I had never written one before, it seemed like this might be a good opportunity to give it a try. I found the plugin development docs to be a little too terse and not terribly n00b-friendly, but over the course of a couple of hours I was able to cobble something together. (I mostly ended up cheating off of Kumar McMillan's nose-nicedots, which got me over the hurdle of realizing I needed my own flavor of TestResult to make sure I got the usual stack trace output while still emitting the F's and U's correctly.)

It basically goes like this:

$ nosetests --with-f7u12

FAIL: test_f7u12.TestGeneratesLotsOfFailures.test_generates_failures(7,)
Traceback (most recent call last):
line 197, in runTest
line 15, in _make_a_test
    assert False


< lots more test failure output; use your imagination... >

Ran 50 tests in 0.021s

FAILED (errors=30)

After some wrangling with PyPI (which could also be a lot friendlier to a packaging n00b--big thanks to Michael Foord for helping set me straight), it should be easy_install-able, or you can grab the source from Github (patches welcome!). And if you prefer pytest over nose, it looks like they've got a plugin too.

It's a tremendously silly thing, but it brought me some joy; I hope it can brighten your day too, or at least bring some comfort and commiseration to your test failure rage.

Read and Post Comments

When GPX Files Lie

After our May photowalk, I found that my GPS tagger had missed a bunch of data points (probably due to all the buildings and trees), so I got a copy of Dave Snyder's GPX track to use as an additional reference. At first I was excited to see a really solid track, rich with data, but was disappointed to see that it still wasn't helping--none of my photos were lining up with where I knew they should be.

Then I looked at the times on the GPX track. That started four hours before we'd started the walk.

It turns out that RunKeeper on Dave's Android phone emits timestamps that claim to be UTC, but populates them with unconverted local times. In other words--it lies.

I wrote a very quick and very, very dirty Python script to fix up all the timestamps, and that did all right for the immediate job, but it seemed like it might be useful for someone else out there, so I took some time this morning to tidy it up and make it usable as a general utility.

Using it is pretty simple; this will adjust a GPX file by +4 hours and dump it to stdout: 4 bad_timestamps.gpx

Or perhaps we need to fix a bunch of files and want to overwrite them instead of doing the stdout donce: -o 4 bad_timestamps.gpx really_bad.gpx super_bad.gpx

It can do negative offsets as well (in case our data points are east of UTC): -o -- -1 east_but_still_bad.gpx

The code is up on github and I welcome pull requests for improvements or things that I'm lazy about (I am profoundly bored by packaging, so it's not PyPI-able yet).

Share and enjoy.

Read and Post Comments

The Tourniquet Pattern

I was delighted today when, on a walk down to Starbucks, Aaron Oliver coined "the Tourniquet Pattern" to explain something I'd done a while back. I would have thought that someone far more clever had come up with this ages ago, but Google seems to suggest otherwise.

Some may argue that it's basically just the Adapter or Facade with a more exciting name, but neither of these names conveys the same degree of distate and judgment that Tourniquet does. This is the battlefield medicine of Adapters--we're going to have to lose that leg eventually, but in the mean time let's accomplish the mission and live to tell the tale.

I fell instantly in love with this name (at least as much as I'm already in love with the Diaper Pattern) and I intend to share it far and wide. Enjoy.

Read and Post Comments

How Does Your Software Garden Grow?

Farewell to Daffodils
Farewell to Daffodils
Originally uploaded by mikepirnat

Every time I spend a few hours working in my garden, I find myself inescapably drawn to the parallels between gardening and software development. Whether you're digging in the dirt or head-down in code, there are many lessons from one that are equally valid and valuable in the other. Here are the ones that I keep coming back to:

  1. Vision: Whether you're planning a garden or starting a new program (or maybe just implementing a new feature), you need to have a vision for what the finished product looks like, and always keep it in mind as you build toward it. Without some discipline to guide you, your code garden will be a disharmonious mish-mash with no direction, and your efforts will be wasted.

  2. Vigilant Weeding: Your garden and your codebase are going to be under constant assault from weeds of all kinds. It might be thistles and dandelions, or it might be subtle bugs and poor designs, but only your continuing vigilance keeps them from getting out of control and spoiling what you're trying to achieve.

  3. No Mercy: Is something not working out the way it should? Has a bush grown into an oversized monster? A class gained so many features that it's unmaintainable? Something just not flourishing? Don't keep it just because it's already there--refactor. Rip it out. Replace it with a better alternative. You won't really miss it, and the eventual result will be better off without it.

  4. Openness to Change: The original vision might not be attainable; that's okay. Rethink the vision and you'll probably come up with something that will be even better than what you thought you wanted in the first place.

  5. Keep an Eye on Your Neighbors: Pests like grubs and dandelions don't respect property lines, and neither do bugs, bad designs, or performance problems in systems that your code may have to talk to. Be on your guard for nasty things that might leak across and foul your work. Wall them off and isolate them before they move in permanently.

  6. Use Good Tools: One day, I got fed up trying to dig a hole with the same old shovel that had been in the garage forever--an old hand-me-down even when it came to us. I broke down and bought a new shovel; the blade was sharp, the handle more comfortable. It felt good to use, it took a lot less effort to get the job done, and I didn't hurt after using it. So too in software, using modern tools like a DVCS can be a lot more effective than older, worn-out counterparts.

  7. Know How to Use Your Tools: Whether you're in the garden or hacking on code, you need practice and knowledge to use your tools effectively. You'll save time and be far less likely to injure yourself (or those around you).

  8. If It's Worth Doing, It's Worth Doing Right: You wouldn't drop a bunch of money on new plants only to have them die without fertilizer or water. So write tests. Practice good methodologies. Don't skimp on documentation or streamlining your deployment. Don't half-ass it, or you'll pay for it eventually--and probably a lot sooner than you expect.

  9. It's Alive: Your garden and your code are organic, living things. They need your love and devotion, your sweat and toil, if they are to grow successfully. Sometimes that love is tough, but it's necessary.

  10. Take Pride in What You Do: At the end of the day, it's nice to relax and enjoy the beauty and you've created, to appreciate the small oasis of order that you've carved out of the entropy and chaos of the world. You want to be able to enjoy the fruits of your labors. You don't want your yard or your code to be an eyesore that all the neighbors complain about.

  11. Enjoy What You're Doing: If you're not enjoying it, you're doing something wrong. Figure out what's keeping you from being happy about your work and do something to change it.

  12. Talk to People: Just as you wouldn't want to plant a sun-loving flower in the shade of your apple tree, you also wouldn't want to use a dictionary when you really need a set. Many problems have already been solved, and there's a tremendous wealth of knowledge and experience out there; whether it's the guy at your local garden shop or the folks in your local user group, you'll be amazed at what you can pick up from even a little bit of human interaction.

If you're writing code but not gardening, try it out and see if you don't have some similar revelations. If you are a coder who gardens, what parallels have you drawn? How has gardening influenced your programming work?

Read and Post Comments

Words of Wisdom

I like to post things above my screens at work, partly to decorate, but primarily to keep them near the surface of my thoughts as I work, to subtlely reinforce things that I'd like to keep in the periphery of my consciousness. Right now I've got two posters that I whipped up--one is a slightly abridged version of The Zen of Python and the other is a recent remark from one of my coworkers. I thought a few of you might appreciate them, so here are PDFs for your enjoyment:

Read and Post Comments