We are all resistant to change

Came across this quote from John Kenneth Galbraith in a presentation by L. Carson of the University of Sydney about Strategic Questioning (pdf):

Faced with the choice between changing one’s mind and proving that there is no need to do so, almost everyone gets busy on the proof.

Universal prefaces

From Sandi Metz’s “The Shape at the Bottom of All Things”:

I totally understand that this is a small example and that these techniques can feel like overkill for a problem of this size. Perhaps they are; I wouldn’t resist if you insisted it were so. However, there are bigger problems for which these techniques are the perfect solution and I rely on your ability to see the larger abstraction. You can’t choose whether to use these techniques unless you know them and it’s much easier practice on a small example like this.

From the Chapter 1 of Robert Martin’s Clean Code:

Consider this book a description of the Object Mentor [the group of authors of this book] School of Clean Code. The techniques and teachings within are the way that we practice our art. We are willing to claim that if you follow these teachings, you will enjoy the benefits that we have enjoyed, and you will learn to write code that is clean and proessional. But don’t make the mistake of thinking that we are somehow “right” in any absolute sense. There are other schools and other masters that have just as much claim to professionalism as we. It would behoove you to learn from them as well.

Indeed, many of the recommendations in this book are controversial. You will probably not agree with all of them. You might violently disagree with some of them. That’s fine. We can’t claim final authority. On the other hand, the recommendations in this book are things that we have thought long and hard about. We have learned them through decades of experience and repeated trial and error. So Whether you agree or disagree, it would be a shame if you did not see, and respect, our point of view.

Rigorous complaint

“The Heriarchy of not-for-profit rigor” from White Courtesy Telephone;

The hierarchy of rigor

At a certain level of experience in some fields, one realizes that “the problem” is not that people are incompetent or bad at their jobs, but rather that they are spectacularly excellent at what they are doing but they happen to be doing the wrong thing. Which is what makes the above chart so enjoyable for me, having reached the level of nonprofit experience in which I can juxtapose the superb competence of those inside the sector with those voices outside the sector braying of its incompetence, while recognizing just how closely aligned both of them are.

testing

http://www.reddit.com/r/rails/comments/1mligj/how_to_organize_rspec/ccakk4u

I think you have 2 separate questions:

  1. How to write good, clear tests.
  2. How to make writing tests something that improves your development process and outcome.

As for the first thing, I think that’s googleable and I’d start with somethign like  Railscasts or  Everyday Rails. Also The Perfect Rspec (it nearly made me weep when I first read it):  … and after that, read the somewhat disagreeing  http://betterspecs.org

As for the second thing, I would recommend you:

  • Install  Guard to constantly run your tests as you develop…which makes a TDD process effortless and becomes a great harness for inspecting objects without cracking open rails console, just  put *.inspect  in your test and guard will dump the object to the console just by saving the file. Install  Spring to run them even faster.
  • Have your tests run with a continous integration service like Travis (free for open source) or CircleCI. For bonus points, have them continuously deploy your app to staging/production too if the tests pass. They also integrate with Github and will show whether tests on pull requests are passing before you merge. This makes the outcome of your tests more visible and not something you forget to do in development.
  • Sign up for a test coverage service like  Coveralls  (you can run simplecov locally, but these services can integrate really nicely with travis/circle and github). This will help you find holes in your code coverage and makes writing tests more like like a game and less like a big time sink.

Now exhale

From  Why’s (Poignant) Guide to Ruby:

Let’s start with some deep breathing. Give me a good deep breath and count to four with me.

Here we go. 1. 2. 3. 4. Now exhale. You can feel your eyes. Good, that’s exactly it.

Now let’s take a deep breath and, in your mind, draw a hippopotamus as fast as you can. Quick quick. His legs, his folds, his marshmallow teeth. Okay, done. Now exhale.

Take another deep breath and hold it tight. As you hold it tightly in your chest, imagine the tightness is shrinking you down into a bug. You’ve held your breath so hard that you’re an insect. And all the other bugs saw you shrink and they loved the stunt. They’re clapping and rubbing their feelers together madly. But you had an apple in your hand when you were big and it just caught up with you, crushed the whole crowd. You’re dead, too. Now exhale.

Give me a solid deep breath and imagine you live in a town where everything is made of telephone cords. The houses are all telephone cords, the shingles, the rafters. The doorways are a thick mass of telephone cords which you simply thrust yourself through. When you go to bed, the bedspread is telephone cords. And the mattress and box springs are telephone cords, too. Like I said, everything is made out of telephone cords. The telephone itself is made of telephone cords. But the telephone cord going to the telephone is made out of bread and a couple sticks. Now exhale.

Breathe in. 1. 2. 3. 4. Breathe out.

Breath in. 1. 2. Another short breath in. 3. 4. Imagine both of your hands snapping off at the wrists and flying into your computer screen and programming it from the inside. Exhale.

Big, big deep breath. Deep down inside you there is a submarine. It has a tongue. Exhale.

Breathe through your nostrils. Deep breath. Filter the air through your nostrils. Breathing through the nostrils gives you quality air. Your nostrils flare, you are taking breaths of nature’s air, the way God intended. Imagine a floppy disk drive clogged up with orphans. And while it chokes on orphans, you have good, wholesome God’s breath in your lungs. But that pleasurable, life-giving air will become a powerful toxin if held too long. Hurry, exhale God and nature’s air!

Now, you will wake up, smoothing out the creases of this page in your web browser. You will have full recollection of your whole life and not forgetting any one of the many adventures you have had in your life. You will feel rich and renewed and expert. You will have no remembrance of this short exercise, you will instead remember teaching a rabbit to use scissors from a great distance.

And as you will wake up with your eyes directed to the top of this exercise, you will begin again. But this time, try to imagine that even your shadow is a telephone cord.

Meet Ravel!

ravel-screens

I’ve spent the last 6 months working at OkCupid Labs building an iOS native mobile app I’m very proud of: Ravel!—”Share Photos. Meet People.” We’ve described it as a dating app for Instagrammers: your public profile is the photos that you pull in from Instagram, Facebook or your camera roll and you can introduce yourself and start chatting with other people based on the photos they share.

We built Ravel! using RubyMotion, a toolchain for writing native iOS apps in (nearly)Ruby. In building it, I learned a lot more both about Ruby and Objective-C along with the intricacies of developing for a mobile device. The mobile app is powered by a Rails-based API server, which is also the backend for the website (for sharing your photo and profile via the web). One of the strengths of RubyMotion is its wonderful automation tools; and the drawbacks is that it’s memory management still has requires some work and workarounds. Perhaps you’ve seen this quote: “It’s not just you. I’m experiencing these memory-related types of crashes (like SIGSEGV and SIGBUS) with about 10-20% of users in production.” That was me on the RubyMotion mailing list.

I also learned a lot of about instrumentation and building a consumer-facing app. Even though a lot of our focus was on in-app engagement, we also invested a lot of time in growth and retention. From optimizing the download  and App Store texts, to adding events and triggers in-app and on the server, to adding sharing and open graph integration through Facebook and on the web.

As I cycle off of Ravel!, time will tell how it survives as a product, but I’m very proud of how we brought it to market.

State of the Shirt, 2012

dayoftheshirt-2012
 

2012 was a big year for Day of the Shirt: it moved from being one of a constellation of hobby projects to becoming the main focus of my spare development time and a largely self-sustaining business.

As a project

As a technology project, Day of the Shirt went through a lot of changes in 2012. Including:

  • It started off the year featuring just 10 t-shirt vendors. By the end of the year, that number had grown to 21 vendors, including some that featured multiple shirt sales.

  • The technology stack morphed a lot. Originally built in PHP, I first rewrote the backend in Node.JS (though I was still using PHP for HTML templating). Then, as the year closed out, I began the task of rewriting it for Ruby on Rails.

  • In moving Day of the Shirt from PHP to Node (and towards Rails), I improved the instrumentation and error logging a lot. This meant I’m much more quickly able to respond to changes in t-shirt vendors websites and ensure that designs on Day of the Shirt are up-to-date.

  • Added a daily RSS Feed

  • Started pushing daily updates to Facebook (in addition to Twitter) with about 1,500 likes on the Facebook Page by year’s end.

As a business

2012 marked the first time that Day of the Shirt ever earned any money. Like:

  • After 1.5 years of having Google Adsense advertisements on Day of the Shirt, I finally received my first payout in February.

  • In addition to showing advertisements, I also started adding affiliate links to shirts. The majority of t-shirt vendors I list don’t have affiliate programs, but I went ahead and signed up as an affiliate for those that do.

  • Because I was actually earning some revenue for the first time, in November I completed the process of registering Day of the Shirt as a Sole Proprietorship in the City of San Francisco.

  • The income has allowed me to pay a designer to help with the visual and interaction design and a developer to help migrate the t-shirt collection scripts to Ruby: having already migrated a lot of automated scripts from PHP to Javascript, I was happy to lighten my load and focus on building out the website itself.

As a passion

I’ve always juggled several web projects (like Brompt and Panlexicon… and all of this), but 2012 really cemented my commitment and interest in Day of the Shirt:

  • Traffic went up, way up. Over the course of the year Day of the Shirt went from having 200 daily visitors in January to more than 8,000 by December.

  • People started writing about Day of the Shirt on Reddit and online forums. And tweeting about it. And in November Day of the Shirt was featured on Lifehacker.

  • People started emailing me (and we don’t feature our email address very prominently): thanking me for the website and suggesting new daily t-shirt vendors to add to the website.

2012 was a really important year for Day of the Shirt and has set a lot of the foundation for improvements and new features I’m adding in 2013.

Selling

From “How Draft Grew Paying Customers by 200%” by Nathan Kontny on Intercom’s Blog:

One other thing you might notice in this reminder window is it’s an Intercom conversation, so it’s a two way dialogue. This way I was able to include a question “If there’s a reason you won’t subscribe, I’d love to hear your feedback. You can reply to this message below.“

I got this idea from Noah Kagan, the founder of AppSumo and blogger at OkDork. One of three things is going to happen:

  1. Your potential customer will realize they don’t actually have an objection to buying today.

  2. You’ll hear real objections which you can test and solve immediately and potentially win a new customer.

  3. You’ll learn what features paying customers value so you know where to focus development.

That whereof we cannot speak we must consign to silence

Roger Scruton:

Thomas Aquinas, who devoted some two million words to spelling out, in the Summa Theologica, the nature of the world, God’s purpose in creating it and our fate in traversing it, ended his short life (short by our standards, at least) in a state of ecstasy, declaring that all that he had written was of no significance beside the beatific vision that he had been granted, and in the face of which words fail. His was perhaps the most striking example of a philosopher who comes to believe that the real meaning of the world is ineffable. Having got to this point, Aquinas obeyed the injunction of Wittgenstein, whose Tractatus Logico-Philosophicus concludes with the proposition: “that whereof we cannot speak we must consign to silence.”

But Aquinas was exceptional. The history of philosophy abounds in thinkers who, having concluded that the truth is ineffable, have gone on to write page upon page about it. One of the worst offenders is Kierkegaard, who argues in a hundred ways that the ultimate is inexpressible, that truth is “subjectivity,” that the meaning of life can be given by no formula, no proposition, no abstraction, but only by the concrete experience of surrender whose content can never be given in words.

[…]

The temptation to take refuge in the ineffable is not confined to philosophers. Every inquiry into first principles, original causes and fundamental laws, will at some stage come up against an unanswerable question: what makes those first principles true or those fundamental laws valid? What explains those original causes or initial conditions? And the answer is that there is no answer — or no answer that can be expressed in terms of the science for which those laws, principles and causes are bedrock. And yet we want an answer. So how should we proceed?

There is nothing wrong with referring at this point to the ineffable. The mistake is to describe it.

Automatic analysis

Karl Fogel on The Open Source Report Card:

So, approximately every year or so, someone launches Yet Another Fully Automated Statistical Tool Dashboard Thing that tries to show the skills & activity of a given open source contributor, or the “health” of a given open source project.

The next thing that happens then follows as surely as night follows day, or as unrequited nostalgia follows the latest James Bond release:

People try the tool, and say “Hmm, well, it’s wildly inaccurate about *me* (or about the projects I have expertise in), but maybe it’s useful to someone else.”

And maybe it is. But what’s really going on, I think, is that the developers of these tools are trying to solve too much of the problem.

Investigating the activity of a particular developer, or the health of an open source project, inevitably involves human judgement calls informed by experience and by out-of-band knowledge. These judgements can be tremendously improved by good tool support – one could imagine certain dashboard-like tools that would make such investigations orders of magnitude more convenient and accurate than they currently are.

But because that kind of tool deliberately doesn’t go the last few inches, it’s a lot harder to demo it. There’s no one-size-fits-all final screen displaying conclusions, because in reality that final screen can only be generated through a process of interaction with the human investigator, who tunes various queries leading up to the final screen, based on knowledge and on specific questions and concerns.

And because it’s harder to demo, people are less likely to write it, because, hey, it’s not going to be as easy to post about it on Slashdot or Hacker News :-). Well, also because it’s a lot more work: interactive tools are simply more complex, in absolute terms, than single-algorithm full-service dashboards that load a known data query and treat it the same way every time.

So what I’m saying is: Any tool that tries to do this, but where you just have to enter a person’s name or a project’s name and click “Go”, is going to be useless. If you didn’t shape the query in partnership with the tool, then whatever question the tool is answering is probably not the question you were interested in.

Added: June 10, 2016 - From The Daily WTF’s “The Oracle Effect”:

Work against the Oracle Effect by building software systems that do not provide conclusions, but arguments. Resist throwing some KPIs on a dashboard without working with your users to understand how this feeds into their decision-making. Keep in mind how your software is going to be used, and make sure its value, its reasoning is transparent, even if your code is proprietary. And make sure the software products you use can also answer the important question about every step of their process: Why?


Newer posts Older posts