The Internet I wish we had: Making Toast

“Why is the light in the refrigerator purple? It looks like I’m making a breakfast for zombies!”

I grab the makings for a mushroom cheddar omelet. We’re running low on butter.  I say “Ok refrigerator” and then wait.. its display shows it’s thinking about what I said and then beeps an error tone at me. It writes out “unrecognized command”. This time I hit the listen button and say, “We’re running low on butter.” It shoots back, “Salted or unsalted?”, “Salted” I say. It beeps happily having understood that I want butter added to my shopping todo list. I hit the settings button, and follow the menus to “light”, “color” and set it back to “natural full spectrum”. The food glows a healthily once again.

I start cooking while my family runs around getting ready for work and school. I put the kettle on the stove for tea, I leave the frying pan heating up, put the toast in the toaster. A usual weekday morning. As the eggs are starting to firm, up the toaster in a loud shrill voice beeps three times that it’s done. It waits a few moments and beeps again, three times. I’m still working the eggs but the toaster doesn’t care. It wants me to walk over to it and hit “cancel” even though it’s done and there’s nothing to cancel. I glance in its direction and it flashes its LED display back at me in annoyance. “DONE” it reads and then beeps three times again. Something needs to be done about that toaster.

I go to put the eggs back into the fridge and the lights are purple again. What the hell? Must be one of the kids’ idea of a joke. “Hey Sara, can you grab me my debugging cable when you have a chance?” I serve breakfast and it’s devoured before I even get a chance to sit down. Everyone starts to head out, leaving me with hugs and kisses and dirty dishes. Sara hands me my debugging cable with her goodbye kiss and runs off to catch the bus. I clean up from breakfast and then get to work. That toaster has it coming.

A debugging cable isn’t much more than a USB host cable. One end plugs into my cell phone and the other is an octopus of different usb ports, mini, micro, A and B. The toaster is a little older too, so it has a micro usb port. Newer ones would just have the USB C ports with the nifty cables that you can plug in to either end and upside down. Remember when no matter which way you plugged in your cable it was wrong? Those days are almost long gone. I pull up the CodeCat app on my phone. I’m sure the toaster has an official app but the community keeps better track of these things. The app detects it’s plugged into a “SmartTek Heatmaster 1520” with stock firmware. It downloads the code from the toaster and opens it up. Boy this thing is a mess. I find where it keeps beeping but I can’t figure out why it keeps beeping, something must be calling the beep function over and over.  I hit the “community firmware” tab on CodeCat I bet someone has already solved this. It’s not a popular toaster oven but there are at least 3 firmwares with “STOP THE BEEPING” in their names so I hit the most popular one and view a diff.

It shows me where the firmware was changed to stop the beeping, and it also looks like they turned the toasting levels down a bit. That’s great! It used to be “kinda toasty”, “burnt”, “burnt to a crisp”, “fire hazard”,  and two more levels I’ve never dared to toast with. I wish they had said they fixed that in the docs but this is wonderful news. I hit install and it downloads into the toaster. I then test it with a nice piece of fresh sourdough. The bread turns golden brown and then a nice low “beep” happens once. The display reads “Thank You”.

Now for the fridge! Something keeps changing the settings, and I bet it’s a script written by someone who wants to paint their room black and purple. The fridge has its own display and is capable of user scripts. This lets us write a script that runs either in response to events or all the time. It also lets us fork the scripts that the fridge came with. When we first got the fridge I played around with it a bit, and modified the light script to slowly increase the brightness when you open the door and then flash it a few times if the door is left open more than 30 seconds. In all honestly I thought it was a gimmick at the time. But when I figured out how to bypass the fridge’s quaint todo app and have it send todos to a shared shopping list on phones, I was sold 100 times over. There’s not much more I want from my fridge. And thank god fridge companies stopped trying to automatically detect what’s in there and place orders for us. Those were dark days. I mean someone even tried to get RFID chips put in individual eggs. Crazy, right?

There were no additional scripts but the modification time on my light script had been updated. I checked a diff and noticed almost every line had been modified, but only its whitespace? The fridge doesn’t support suppressing changes to spaces and tabs and only showing the actual code differences. So I plugged in my phone again (this time with USBC!) and pulled up CodeCat again. I found the lighting script again and had it show me only the code changes, no spaces this time. A new section had been hidden in the middle that would reset the color of the light every 7 minutes. Crafty. I copied it out and then reset the file to the previous version.

With the fridge fixed, I logged into my house’s command and control box. This is an old mini computer (about the size of my phone) that I had laying around and hooked up to the wifi. It primarily listens for all the switches and turns on the lights in whatever room you’re in. It can also listen for commands from your phone and it knows if we’re home or not and can turn on the porch light. Simple stuff. I add a new script for the switch in the kids’ bedroom, every 3rd time the light is turned on, and only if it hasn’t happened in the last 2 hours, flash the lights bright green for 30 seconds and then go back to purple or whatever. That will show them!

The kids haven’t really figured out about the house control as it’s not right in front of them like the fridge, and they’re still pretty young. I leave them with write access to the script so they can fix it if they figure it out. No point being completely mean. Time for work I suppose!

The Internet I wish we had: Texting

I hung up my phone and started typing. “Jason just called me, ideas for dinner before the movie?” and sent it to Sara. My phone know’s a lot about Sara and where she might be. It encrypted the message for her eyes only, indicated that the message will probably be delivered in midtown with a 70% confidence rating. After all it was 4pm on a Thursday, where else would she be?

My office runs a messages hub. It takes messages from nearby devices and puts them on the internet where they’re sent to hubs closer to their delivery locations. Midtown is full of hubs and even if it wasn’t there’s enough people in manhattan that it would only take a few extra seconds to go phone to phone.

My office’s hub took at look at the message and queried it’s routing database. It didn’t have a better idea of where Sara might be so it remembered mine and chose it’s favorite hub in midtown the one at Egyptian restaurant down the block. This hub has the best relationship with mine out of all the nearby hubs. It’s rarely overloaded, has a decent enough connection and it’s pretty close to Sara’s phone most of the time. It also knows my hub is in a similar situation when sending me messages.

The Egyptian restaurant’s hub broadcasts the message, it’s too far away from Sara’s phone for it to hear but a business man is walking near by. His phone picks up the message and sends it to everyone on the block. A woman at the far end had recently taken the elevator past Sara’s floor of the office and their phone had seen hers. Her phone relays it to the doorman of her building who’s still in range. The doorman always kept his phone plugged in and is in a perfect spot to relay messages. He doesn’t really know too much about the messaging app, other than it gives him some spending money at the end of the month and people are happier when he keeps it on.

Sara had tried to get reception to put in a hub, or at least keep the messaging app in “hub mode” on their phones. They’re plugged in, someone is almost always there and they’d help relay all the messages to the floor of the office. It would be great for everyone! Except one of the receptionists claimed it slowed down his phone. (Probably gave his online games some lag.) And the other one jacked up the price for each relay 100 times the market rate and everyone routed around him. He never made any money and turned it off. Their loss, they can keep paying for their service plans.

The doorman’s phone sends the message bouncing up the phones in the elevator cars until it hits someone walking across the office on the floor above who’s also in range of Sara.  Her phone receives the message with a “Beep Boop” The whole affair took 7 seconds and negligible battery life.

“I just left work. Swinging by comics, then I’ll head towards the theater. I had pizza for lunch, what did he say?”

 

Ducktyping. Quack.

I was working on one of our projects when I happened to run across some code that set off my rubber ducky detector. It’s a page that displays the days production quantities or displays an estimate if it’s too early in the day to tell. Both cases have very similar views and they share a common interface. Our controllers were too fat and our views knew too much.

Here’s the culprit.

class ProductionRunsController < ApplicationController
  def print_recipes
    @date = date_query
    @production_run = production_run_for_date(@date)
    @projection_run = ProductionRunProjection.new(@date) unless @production_run
  end
end
# view
<h1>Print Recipes <%= @date.strftime("%A %b. %e, %Y") %></h1>
<% if @production_run %>
  <%= render 'production_run', object: @production_run %>
<% else %>
  <%= render 'projection_run', object: @projection_run %>
<% end %>

We have this one view that renders either a projection_run or a production_run depending on if a user has a production run on that date or not. The code works but I have a few problems with it.

  • We have 3 instance variables in 1 controller action. One of which will always be nil! We literally have a variable holding nil. This totally breaks Sandi Metz rule of having 1 instance variable per action. Hard

  • More importantly, what happens later on down the road if the client we’re building this for wants past_runs to be formatted differently? Continuing this pattern, it would probably look something like this.

class ProductionRunsController < ApplicationController
  def print_recipes
    @date = date_query
    @past_run = past_run_for_date(@date)
    @production_run = production_run_for_date(@date)
    @projection = ProductionRunProjection.new(@date) unless @production_run
  end
end
# view
<h1>Print Recipes <%= @date.strftime("%A %b. %e, %Y") %></h1>
  <%= render 'past_run', object: @past_run if @past_run %>
  <%= render 'production_run', object: @production_run if @production_run %>
  <%= render 'projection_run', object: @projection_run if @projection %>

As the conditions that the client gives get greater and greater, this view will get more ifs and more variables in the action. As a best practice, it is good to have the least amount of logic in the views as possible and this has a lot.

A more elegant solution involves two patterns: the facade pattern and duck typing.

The facade pattern



The facade pattern is pretty much what it sounds like. We’re hiding logic in some sort of object and asking that object to do work for us rather than the controller. Doing this allows us to stick to one variable and please the ever lovely Sandi Metz. A quick refactoring might looking something like this:

class ProductionRunsController < ApplicationController
  def print_recipes
    @facade = ProductionRunFacade.new(@date)
  end
end

class ProductionRunFacade
  attr_reader :date

  def initialize(date)
    @date = date
  end

  def production_run
    @_production_run ||= production_run_for_date(date)
  end

  def projection
    @_projection_run ||= projection_run_for_date(date)
  end

  private

  def production_run_for_date
    #some logic
  end

  def projection_run_for_date
    #some logic
  end
end
# view
<h1>Print Recipes <%= @facade.date.strftime("%A %b. %e, %Y") %></h1>
#stuff omitted
<% if @facade.production_run %>
  <%= render @facade.production_run %>
<% else %>
  <%= render @facade.projection %>
<% end %>

It’s getting there but it could use a bit more love. Let’s move the date logic from the view to the facade.

class ProductionRunFacade
  attr_reader :date

  #code omitted

  def formatted_time
    date.strftime("%A %b. %e, %Y")
  end
end
# view
<h1>Print Recipes <%= @date.formatted_time %></h1>

Here’s a small win! and it’s all about those small wins. We can take this a step farther but first let’s talk about Duck Typing.

Duck Typing


Sandi can explain duck typing better than I can. In her words,

Duck types are public interfaces that are not tied to any specific class. These across-class interfaces add enormous flexibility to your application by replacing costly dependencies on class with more forgiving dependencies on messages.

Duck types objects are chameleons that are defined more by their behavior than by their class. This is how the technique get its name; if an object quacks like a duck and walks like a duck, then its class is immaterial, it’s a duck.

An example that you may all be familiar with is the [] operator.

array = [0,1,2,3,4]
string = "hello world"
array[0] #returns 0
string[0] #returns h
array[1..-1] #returns [1,2,3,4]
string[1..-1] #returns "ello world"

We can call the [] operator an both an array and a string, [] is the quack and both objects are ducks.

Now let’s apply this to our code.

class ProductionRunFacade
  attr_reader :date

  def initialize(date)
    @date = date
  end

  def run
    @_run ||= production_run || projection_run
  end

  def formatted_time
    date.strftime("%A %b. %e, %Y")
  end

  private

  def production_run
    #some logic
  end

  def projection_run
    #some logic
  end
end
# view
<h1>Print Recipes <%= @facade.formatted_time %></h1>
<%= render @facade.run %>
<% end %>

There are a couple things that happened here. First, @production_run and @projection_run became one variable called @run. Secondly, we no longer have any measly ifs in our view anymore, we only call render on @facade.run. What is this magic? Here we are using the power of duck typing and trusting that ProductionRun and ProjectionRun have implemented to_partial_path which render calls. Because of this trust we no longer care what the object is but care about the messages it sends.

With this new architecture, adding new potential runs is made extremely easy. Actually, let’s implement past_runs as well! It’s only a few additional lines of code.

class ProductionRunFacade
  attr_reader :date

  def initialize(date)
    @date = date
  end

  def run
    @_run ||= production_run || projection_run || past_run
  end

  def formatted_time
    date.strftime("%A %b. %e, %Y")
  end

  private

  def past_run
    #some logic
  end

  def production_run
    #some logic
  end

  def projection_run
    #some logic
  end
end

Done. We don’t have to add any more ifs in our view and we don’t have to add any additional instance variables in our controller. Easy as quack.

Arranging Complex Factories (for fun and profit)

FactoryGirl the oddly named testing tool for database models is something we use a lot at Wizard Development. If you’re unfamiliar with how it works, I strongly suggest you check it out. Unlike fixtures which loads a bunch of data into your database, factories will create the objects you need with the data preloaded. The difference allows you to only get what you need, allows skipping using the database all together (for much faster and more isolated tests) and a few other great things.

Individual models are fairly straightforward to test. I’ll be using examples with rspec and ActiveRecord.

# Model
class User < ActiveRecord::Base
  scope :admins, -> { where(admins: true) }
  def admin!
    update!(admin: true)
  end
end
# Factory
FactoryGirl.define do
  factory :user do
    sequence(:name) { |n| "#{Faker::Name.name} #{n}" }
    sequence(:email) { |n| "#{n}#{Faker::Internet.email}" }
    admin false

    trait :as_admin do
      admin true
    end
  end
end
# Test
require 'rails_helper'

describe User do
  let(:user) { build_stubbed(:user) }
  let(:admin) { build_stubbed(:user, :as_admin) }

  describe '#admin!' do
    it 'makes a user an admin' do
      user.admin!
      expect(user.admin?).to eq(true)
    end
    it 'keeps admins in power' do
      admin.admin!
      expect(admin.admin?).to eq(true)
    end
  end

  describe '.admins' do
    it 'returns only the admins' do
      admin = create(:admin)
      create(:user)
      expect(User.admins).to contain_exactly(admin)
    end
  end
end

For the model’s instance functions we used FactoryGirl.build_stubbed a method that creates a model that pretends it’s saved to the database. All validations, and database methods will pretend to work as expected and we’ll be sure to never actually talk to the database, which is significantly faster.

For the scope we have to talk to the database so we create both models and ensure the result only has the admin object. Since only those two objects are needed, that’s all we make.

As your app grows you’ll start needing to test service objects that work with several models at once, and your models themselves will get more complected requiring each other to be in specific states to be valid. It’s going to get difficult to have a single factory properly setup the environment for testing. (If you find it impossible to use factories you need to have a long hard look at your design because it wont ever get easier on it’s own.)

A common situation is when you want “Multitenancy” where your app needs to support users having their own objects. This is very straightforward to support with factories, at first.

class User < ActiveRecord::Base
  has_one :photo
end

class Photo < ActiveRecord::Base
  validates :user, presence: true
end

FactoryGirl.define do
  factory :user do
    sequence(:name) { |n| "#{Faker::Name.name} #{n}" }
    trait :with_photo do
      photo
    end
  end

  factory :photo do
    title "My cat Kris"
  end
end

# to build a stubbed user with a stubbed photo
FactoryGirl.build_stubbed(:user, :with_photo)

Now you’ll probably want to support a user with many photos. FactoryGirl suggessts using the after and before callbacks for creating the associations. Lets try it

class User < ActiveRecord::Base
  has_many :photos
end

class Photo < ActiveRecord::Base
end

FactoryGirl.define do
  factory :user do
    sequence(:name) { |n| "#{Faker::Name.name} #{n}" }
    trait :with_photos do
      transient do
        photo_count 2
      end

      after(:create) do |user, evaluator|
        create_list(:photo, evaluator.photo_count, user: user)
      end
    end
  end

  factory :photo do
    title "My cat Kris"
  end
end

# to create a user with 2 photos
FactoryGirl.create(:user, :with_photos)

# When we build_stubbed or build or any of the other methods, we no longer have any photos!
FactoryGirl.build(:user, :with_photo) # no photos!
FactoryGirl.build_stubbed(:user, :with_photos) # no photos!

Since this approach only works with specific methods, you’ll either need to write callbacks for each method or do some magic. I’ll rewrite the factory with some magic.

FactoryGirl.define do
  factory :user do
    sequence(:name) { |n| "#{Faker::Name.name} #{n}" }
    trait :with_photos do
      transient do
        photo_count 2
      end

      photos do |t|
        photo_count.times.map {
          t.association(:photo, user: t.instance_variable_get(:@instance))
       }
     end
    end
  end

  factory :photo do
    title "My cat Kris"
  end
end

# Now however we want our test data we'll get what we expect!
FactoryGirl.create(:user, :with_photos)
FactoryGirl.build(:user, :with_photo)
FactoryGirl.build_stubbed(:user, :with_photos)

The t that’s passed into the block on photos, I think this is called an evaluator internal to FactoryGirl, but I’m not positive. Names are hard. We’re able to use the t.association to mimic however we called the parent factory. When we are building a factory it uses build() when we’re creating it uses create(). Yay!

I know t.instance_variable_get(:@instance) looks very strange but there doesn’t seem to be another way to get a reference to the parent object to give to the child object. Not all children need their parents, but when they do you need to provide them.

We should also note that we’re using a transient attribute to allow us to customize how many photos get created.

# if we want a ton of photos
FactoryGirl.create(:user, :with_photos, photo_count: 400)

Lets go for an even more complex example.

class User < ActiveRecord::Base
  has_many :photos
  has_one :album
end

class Album < ActiveRecord::Base
  has_many :photos
  validates :user, presence: true
end

class Photo < ActiveRecord::Base
  validates :user, presence: true
end

Photos still belong to users but can now also belong to an album that belongs to a user. Lets also ensure there’s always a user for these objects.

A factory setup could be

FactoryGirl.define do
  factory :user do
    sequence(:name) { |n| "#{Faker::Name.name} #{n}" }
    trait :with_album do
      album
    end
  end

  factory :photo do
    title "My cat Kris"
    user
  end

  factory :album do
    user
    title "Kitties"
    transient { photo_count 2 }
    photos do |t|
      photo_count.times.map { t.association(:photo) }
    end
  end
end

Lets try this out

user = FactoryGirl.create(:user, :with_album)
user.album.photos.count # 2
user.photos.count # 0 !?!?!?!
User.count # 4 !!!!!

We have a user with an album of other users photos! That’s not what we wanted.

The photo factory was creating it’s own users for it’s photos since we didn’t specify who should own them. Additionally the album factory created a user and then got assigned to the one we created. Lets try again.

FactoryGirl.define do
  factory :user do
    sequence(:name) { |n| "#{Faker::Name.name} #{n}" }
    trait :with_album do
      album { t.association(:album, :with_photos, user: t.instance_variable_get(:@instance))
    end
  end

  factory :photo do
    title "My cat Kris"
    user
  end

  factory :album do
    user
    title "Kitties"
    trait :with_photos do
      transient { photo_count 2 }
      photos do |t|
        photo_count.times.map { t.association(:photo, user: user) }
     end
    end
  end
end

The user now gives itself to the album, the album now gives it’s user to the photos and we always get what we expect. We can create any factory and get a user who owns the photos that were generated and never get more users than we expect.

I think this is too complicated. I’m convinced there are easier ways to do the advanced examples in this blog post. When I find them I’ll happily update this post and a bunch of my factory code. In the meantime I’ll live with slightly complicated factories and enjoy easier testing.

Let me leave you with a with a small spec we include with most projects. It ensures that every factory and trait is valid and can be stubbed. And helps you keep all factories usable with expected results. FactoryGirl.lint has some unexpected creation of models and doesn’t cleanup after itself. If you’re using Foreign Key Constraints you’ll get an added bonus of errors when you accidently create models related to stubbed models.

require 'rails_helper'

FactoryGirl.factories.map(&:name).each do |factory_name|
  describe "#{factory_name} factory" do
    it 'builds valid' do
      model = FactoryGirl.build(factory_name)
      expect(model).to be_valid if model.respond_to?(:valid?)
    end

    it 'builds stubbed' do
      model = FactoryGirl.build_stubbed(factory_name)
      expect(model).to be_valid if model.respond_to?(:valid?)
    end
  end
end

Noob to Wizard: The Journey

cover

It’s been around six months since I quit my job as a PSI Analyst. For those of you unfamiliar with the terminology, it’s pretty much a glorified title for an Excel technician. I lasted a mere 3 months before the banal, repetitive tasks took their toll on me, slowly killing my sanity with every vlookup I did. There were more than a few reasons why I quit, but most of all, the corporate life wasn’t for me. I couldn’t imagine kissing ass for the rest of my life to get that 3% promotion every year. I couldn’t imagine doing something I didn’t enjoy for the rest of my life. I couldn’t imagine not being challenged… ever. So I quit.

I quit before I had anything lined up, but I knew I wanted to code. Luckily I had extremely supportive friends who had every intention of helping me reach my goal (shoutout to @alexiomota and @Yanyeeli ). They helped me research coding schools and vet the ones that would fit my needs. They answered any question to the best of their ability and helped me figure out what I wanted to do. Who knows what I would be doing if it weren’t for them!

A few weeks and interviews later, I got into the school of my choice, Metis. Unfortunately, after Kaplan acquired Dev Boot Camp, they have decided to streamline Metis as a Data Science school and removed Metis’s Ruby on Rails and UX-Front End Development courses. Regardless, my time at Metis was everything I wanted and more (shoutout to @tabfugnic, @dgalarza, harry (please excuse his lack of twitter), and @thoughtbot ).

Although it’s not a literal bootcamp, there was nothing easy about attending a coding “boot camp.” There were around 5 hours of lecture and 3 hours of practice problems almost every day. On top of that, in order to network, we attended meetups to mingle with other developers and expand our networks. If we weren’t able to follow along with the day’s material, there was studying to be done after class. Worst of all, I lost 3 hours commuting back and forth from school. “Easy” was never a word that came up when describing those 3 months. But if I were to go back in time and had the chance to do it over again, I would do it in a heartbeat. Not because I’m some sort of sick masochist or because I have $12,000 to just throw around. Not because the material is impossible to learn independently but because the experience taught me what I was capable of and, more importantly, because of the amazing people I met.

Having thoughtbotters as my instructors was invaluable. Not only are they passionate developers, but they are regarded by many to be some of the best in their trade. This was like having Sir Lancelot teaching me to fence or having Michael Jordan teaching me to shoot. They were able to answer questions based on previous experiences, teach us best practices, and show us how to write clean code. The best thing of all, though, was that they stayed connected and truly developed a relationship with us students.

Six months after I quit my job and started down this path, I’ve landed my first development job as a developer at Wizard Development and it’s everything I wanted. I have amazing co-workers, I’m challenged every day, I have a voice in my team, and I get 20% time to write this post. I get freedom to do things the way I see fit and get to learn on the job. I’m pretty much living the dream.

Out of everything I’ve learned thus far, the most important thing I’ve learned was just how much I rely on others and to embrace it. Looking back, I would never have gotten to this point without the help of friends I’ve had and the friends I’ve made along the way. Being a developer is great because I’m challenged every day and the things that I can learn are limitless. Best of all, the coding community is unrivaled. I’ve received so much help from others and I want to learn enough so that I can do the same and bring people through the same journey that I did. So if you have any questions about anything feel free to reach out to, eli@wizarddevelopment.com

The Winnower API

We recently added an API to The Winnower to support our new WordPress Plugin. It was a great experience in both product and software design. WordPress support is the first of a few great features we’re adding to The Winnower to aid our users in publishing.

cover

It was suprising to me, but these days a lot of academic publishing, if not in journals, is done on blogs. The Winnower provided publishing services to papers which were uploaded via Word or Latex, but people would have to copy their blog published papers from whatever they currently use into Word if they wanted publish them. That wasn’t great.

WordPress.org is one of the largest blogging software platforms. It’s crazy customizable and very easy to use. It was a very good first candidate to support. We figured a WordPress plugin would allow people to keep publishing as they do now, and allow them to get DOI’s and go through the open review processes through The Winnower.

The plugin needed to integrate with the site via some sort of API, and we wanted to adopt the JSON Api spec wich describes a restful JSON interface. Internally, the Winnower’s APIs were a bit of a mess. The site had evolved a lot since the initial structure was created and the technical debt that had accrued caused the APIs to loose some of their elegance. Because of that, they didn’t map cleanly to JSON API, or any other restful API.

We started by “green fielding” the API design to match the needs of the plugin and it’s users. Then we built the API alongside the existing interfaces. We built a bridge between the new and the old by creating some service objects that wrangled the internals into a reasonable shape and interface. Finally, we built out the controllers to handle the particulars of the JSON API requests.

This taught us a lot about what we really needed to publish a paper, and how we could restructure the internals across the site. Thankfully, we already had great integration test coverage for our publishing papers. We’re now able to start moving towards a much better designed app without the risk of breaking everything.

The coolest part of this sprint was that we got a lot of insight into our existing user experience (UX). Much of it existed to accommodate the original design as opposed to the features the users needed. We’re going to have a much easier time improving the experience after the internal restructuring and we’re going to find ourselves with a much better product in the end.

-Francis

PS If you’re interested in programming for The Winnower’s API please let us know! In the meantime we’ll keep building new uses for it. =)

Cleaning up your views with Simple Delegators

cover

While working on my pet project for matching tennis partners I decided to make a match history page. It displays a player’s recent matches and some information pertaining to them: who played when, who won, and how much that win affected their score on the site. I also wanted each match history log to be separated by color-coded boxes.

This was the end result:
Match-History-Image

The first solution I came up with used a bunch of if statements and some messy view logic:

# (most of the view omitted)

<% @matches.each do |match| %>
  <div class=<% match.winner == current_user ? "winning_class" : "losing_class" %>>
    <div><%= match.challenger %> vs <%= match.defender %></div>
    <div><%= match.match_at %></div>
    <% if match.winner == current_user %>
      <div>+ <%= match.elo_difference></div>
    <% else %>
      <div>- <%= match.elo_difference></div>
    <% end %>
    <%= link_to "Match Details", match %>
  </div>
<% end %>

But we’re doing Ruby, and this is some ugly Ruby. There’s a lot of logic in the views… and a ternary? Am I insane?

Enter Simple Delegators:

A concrete implementation of Delegator, this class provides the means to delegate all supported method calls to the object passed into the constructor and even to change the object being delegated to at a later time with #__setobj__.

Using this, we can make decorators to clean up our views.

Let’s start with the controller:

def index
  @matches = Match.all.map do |match|
    if match.winner == current_user
      WinningMatch.new(match)
    else
      LosingMatch.new(match)
    end
  end
end

Then we can make these decorated matches:

class WinningMatch < SimpleDelegator
  attr_reader :match

  def initialize(match)
    @match = match
    super(@match)
  end

  def match_outcome_class
    "match-stats-winner"
  end

  def elo_delta
    "+ #{match.elo_delta}"
  end

  def win_or_lose
    "won"
  end
end

We would do exactly the same for LosingMatch.

We end up with an array of matches in our #index action. Each match could either be a LosingMatch or a WinningMatch. Through the magic of duck typing, we can call the same method on either WinningMatch or LosingMatch and they’ll know what to return.

So, in the end, we can create a partial like this:

<li class="<%= match.match_outcome_class %>">
  <div class="match-stats">
    <p class="username"><%= match.challenger_username %> vs. <%= match.defender_username %></p>
    <p><%= match.match_at.strftime("%F") %></p>
    <p><%= match.win_or_lose %></p>
    <p><%= match.elo_delta %> </p>
    <p class="match-link"><%= link_to "Match Details", match %></p>
  </div>
</li>

This is pretty cool! We were able to take out the various if statements and employ SimpleDelegators and duck typing to create a clean partial with absolutely no branching. I’d call that an enormous win.

Teaching with Girl Develop It

cover
Recently, I’ve had the opportunity to teach the Intro to HTML and CSS course with Girl Develop It, a non profit organization that welcomes all, but focuses on teaching women software and web development skills. They not only teach programming, but also teach programming related topics, such as contributing to open source software, and support other organizations that provide women with opportunities in education and development.

The Intro to HTML and CSS course was created for those very new to programming, and started with the structure of HTML code. Some of the students had taken a course in high school or college where they learned the basics of HTML and CSS, but most had no experience with either language. So we started with the definitions of an element and a tag, and and went from there to creating basic structure, and then on to CSS for styling and positioning.

In the fall, I was a TA for a Girl Develop It Intro to JS and jQuery class, which got my feet wet with teaching coding. For those of you who don’t know me, I was a registered nurse working mostly in emergency rooms until just over a year ago – a position that is heavy in teaching about medical issues, medication regimens, and lifestyle changes (in some hospitals I would also sign off on learning objectives for med students and residents, and teach new nurses the things that aren’t covered in school). I was a tutor in bio and chem courses in college, and also taught kayaking and other outdoor skills.

Having 30 students in front of me, however, was a new and formative experience. There were different learning styles and paces to juggle, questions that I answered by showing students how to google for answers to programming questions (How does that clearfix approach we’re using work, exactly?) – an invaluable skill, but unnerving when you’re in the front of the room. We spent time trouble shooting our code together as a class (why isn’t our text wrapping around this div like we expected?). And the most important challenge- how do we keep everyone on the same step, without losing the attention of some, while leaving others behind?

In general, I like using live examples to teach, so that’s how I approached these classes. I learned quickly though, that its easy to get lost, as both instructor and student, when you’re going back and forth between the slides and code. After the first class, I kept all of the examples ready and available in a file that I tried not to change at all during class (the times I did change both the template and the example files, things got a little messy). I also started to not shy away from talking through problems we ran into with the class as a whole instead of fixing them ASAP and moving on. Coding is about problem solving, and learning how to think through unexpected or accidental behavior and to use developer’s tools are just as helpful as learning any other programming skill.

Next time I teach a course I’ll keep a few other things in mind as well. Taking as much time as needed to review material at the beginning of class, and providing a template for students to start with saves a lot of time and energy rather than answering questions about previous material only as they come up (I’ll always encourage students to ask questions as well, of course!). Also, I realized that I’m a small component to big picture kind of person, so that’s how I should teach in the future. Some students will be big picture to component learners, but teaching in the style that I’m most comfortable with will help keep the flow of classes more smooth and organized. I talked individually with some of the TA’s for feedback and advice, but I wish that I had asked for more feedback from all of the TA’s and the students as well.

At Wizard Development, we’re working on creating our own course material, and it’s been invaluable to have this experience teaching a large group instead of the smaller groups that I had been accustomed to. I plan on continuing to teach with Girl Develop It and continue developing my teaching style.

-Amy

Steam Heat

My home has radiators that are 70ish years old. I’m going to guess the air vents are 10-30 years old. It’s supposed to let the air out while the pipe fills with steam. Then and this is the important part, it stops letting anything out of the pipe and keeps the steam in the pipe. Some of our valves weren’t letting the air out, and some was letting everything out.

Also;

  1. It’s cold in my room
  2. Our boiler runs out of water too often
  3. Our windows take a constant bath from condensation

So lets fix some things.

This slideshow requires JavaScript.

The vents in the peanut butter jar were old, came with the house. They didn’t quite close when the steam hit them so they whistled a ton. So if you have a PB jar full of vents I recommend installing them at night so nobody is awake to hear them. The next day Sara drove me in the snow to spend a lot of money on valves from a store. I replaced the vents in my bedroom which were clogged. The air couldn’t escape so it couldn’t fill with steam. The one in the bathroom would never close, so while our bathroom was very warm, it also very damp. Notice the rust around the vent in the photo? That’s crazy. The last two had similar problems.

It’s so quiet! I love it! I hope my bedroom is warmer, I’ll find out. I can’t confirm it but I bet the house will heat a little faster, and my hunch is that the air will be much less humid.

I wish I could somehow measure the heat in the house vs outside, the time it takes to warm the house, the humidity, etc etc. Oh wait! I know how!

nest

I’ll use my Nest! Unfortunately they don’t seem to make it easy to use the data. Looks like I may have to get clever.

Money Transferring

I was expressing frustration with moving money around the other day and was asked to share what I knew. This is an incomplete list of ways to move money, and their consequences. Moving money (and in turn getting paid or paying others) is one of the most important yet strangely high-friction things a business has to do. On top of that, most of it is frustrating from a technical standpoint.

I’m not going to cover moving money on behalf of other people, which is worthy of it’s own blog post. I also think it’s one of the more interesting areas for exploration (as far as money is concerned). I’m also going to gloss over specifics around the Automated Clearing House (ACH) and other payment networks. Just know that it’s actually a lot more complicated, with a ton more rules and a few more players then I talk about.

cover

The cover photo is of NYC’s MTA Money Train by “Orange Suede Sofa”.

Cash

Cash is the easiest to understand. It’s what we grow up with. It’s a physical object that holds value and it’s instantly convertible either to products or your bank account. The retail currency exchanges take a large cut, but if you’re in a single country it can’t be beat. Because of it’s physical nature there isn’t an accounting system in existence that doesn’t require you to manually track what you spend it on or where it goes.

  • Cost: Low – Usually none unless you have to change currencies
  • Time to clear: Instant
  • Hassle: High – You have to go get it and then physically give it to someone.
  • Risk: High – No fraud protection
  • Traceability: Very little
  • Accounting Cost: High – No way to know who received it or why without keeping your own records

Check

I don’t like checks but they are very common and are almost as cheap as cash. The checks themselves are not actually worth money. I don’t like them because they are unpredictable. If I give you cash, I no longer have it. If I give you a check, I need to ensure I have the money in my account until you deposit the check and it clears. It requires me to keep a separate log of accounting to ensure I don’t accidentally double spend. The Automated Clearing House (ACH) processes is crazy too.

Here’s the general processes:
1. I physically have to write how much money I want you to have on a piece of paper. (Or print it, but that isn’t easier.)
2. I have to physically get it to you. (mail, in person, etc)
3. You have to bring it to a branch of your bank and deposit it. (“Mobile deposit” is great but banks usually only risk around $2000 max on a single mobile deposit.)
4. Your bank scans the check and sends it in a nightly batch processes to the ACH.
5. The ACH does some level of fraud protection that I am unclear of the specifics.
6. The my bank receives a notice of my check and verifies the funds and authorizes the withdrawal.
7. The ACH lets your bank know that it was approved.
8. Our banks reconcile the funds. (Do their own bank to bank transfers.)
9. Sometime in the past few steps your bank updated your account with some or all of the balance.

The worst part for me is that you have around 6 months to deposit the check. Some banks will allow you to try to deposit checks of any age.

  • Cost: Low – Unless there’s a returned check, then fees are levied to both parties around $20-$60
  • Time to clear: Long – 2-4 days to clear plus 0-160 days to deposit
  • Hassle: High – Lots of physical interactions, lots of waiting and often you have to use the US postal system
  • Risk: Medium – Checks aren’t worth money but they can be faked. You can also deposit a “bad check” which can incur you fees.
  • Traceability: High – Every check comes from an account and goes to an account. Accounts usually have names and it shows up as an item in your bank statement.
  • Accounting Cost: Low – It’s easy to see to whom a check was written and the memo field usually says why (eg invoice number). It also usually reconcilable from the bank statements. That is of course they deposited the check.

Wire Transfer

This is pretty easy and can usually be done from an online interface with your bank. In the US it uses the ACH like checks but electronically sends the account information. Internationally it uses IBAN and SWIFT, which are neat. This will usually cost between $10-$40 to both send and receive.

  • Cost: Medium $10-$40 for all parties involved
  • Time to clear: 2-4 days
  • Hassle: Medium – You need address, name, account info, routing info and for the person you’re paying to know what an ACH transfer is.
  • Risk: Medium – The money is usually immediately withdrawn. The medium rating comes from having near zero recourse if you send the money to the wrong place.
  • Traceability: Medium – I’d say high except if you have the information wrong you can’t easily find out who you sent the money to.
  • Account Cost: Low – Same as checks

Direct Deposit

This uses the same infrastructure as checks and is usually free to the sender and receiver. Same hassle as a wire transfer with a little extra because you need a service to assist. I’m hazy on the details.

Online Bill Pay

Your bank will helpfully send a check. They may or may not debit your account and send a bank check. They may or may not fine you for overdraft fees. They may or may not send a check regardless of balance (and then fine you for a bounced check). They may or may not fall back to electronic means with larger companies that have accounts with them. For most small businesses, you’ll get a check in the mail if someone pays you via this method.

I am unaware of the regulation of this feature.

Credit Cards

In the past you’d have to open a merchant account and negotiate fees. These days the merchant account is virtual and you’ll get an ACH transfer for free with your cash minus $0.30 and %3 in a few days. Stripe, Braintree and a few others are great in this space.

  • Cost: Medium – $0.30 and 1.5-5% This can add up for large payments when compared to checks or wire transfers, but if you have volume and are a low risk you can negotiate the fee down.
  • Time to clear: Medium – You’ll get the money in your merchant account instantly, but can’t get access to it for 2-7 days depending on how nice your relationship is with your processor / merchant account and how much risk they think you are. If you’re using a modern payment gateway it’s usually 4 days and you don’t have to have a merchant account.
  • Hassle: Low – Easy to initiate, money usually shows up without issue. Some larger charges will fail for unspecified reasons, but a phone call to the bank will usually clear it up.
  • Risk: Low – There is fraud protection on both sides of the transaction. You get to verify credit card details if you wish before authorizing the charge. If your card is stolen you usually get the charges refunded. If you are receiving money a chargeback can cost you $10-$75 but they are usually rare depending on your business.
  • Traceability: High – Everyone has their name on both sides of the charge.
  • Accounting Cost: Low – It’s like another bank account. You know where your money went and where it came from.

Paypal, Venmo, Square Cash, etc

They use a combination of Credit cards, ACH transfers and debit card refunds to move money around.

  • Cost: Low – They range from free to credit card style fees
  • Time to clear: Medium – Unless you stay within their network you usually need to wait 2-7 days to get your money. You often need to “transfer” it into your bank account via the ACH.
  • Hassle: Medium – If you already have an account on the payment network it might be low, but chances are you or your client won’t.
  • Traceability: Varies
  • Risk: High – There’s a good chance you’ll get your money, there’s a big chance you won’t know the rules of the network or be able to access your money right away. Fraud protection is often amped up very high on these networks and they’ll lock down accounts involved in any transaction of scale, to give them time to check you out.
  • Accounting Cost: Medium – It’s not unlike a credit card processors account but each system has their own reporting and accounting systems. You may or may not have accountability

Bitcoin

This is a funny one. Currently there are many exchanges where you can buy and sell bitcoins. Some legitimate, some shady, some with large fees and some with very low fees. Coinbase for example lets you take payment with bitcoin and instantly transfers it to cash like a credit card processor would. It’s fees are only 1% but may not give your customers the best exchange rate. Bitcoin to bitcoin transactions can be made with a transaction fee well under $0.05. Obtaining bitcoins isn’t easy and their value is volatile.

  • Cost: Low – There are no or very low ($0.05 cents to 1%) fees depending on if you’re keeping bitcoin as a currency or using it as a fund transfer mechanism.
  • Time to clear: Medium – Bitcoins will transfer in a matter of minutes – usually less than an hour to be safe. Getting your money from an exchange will either use the ACH or checks and that may take days to weeks.
  • Hassle: High – Coinbase makes it easy but very few people will have bitcoins or a coinbase account. Buying bitcoins without fees is very hard. Storing bitcoins online isn’t recommended and it’s easy to lose them as they can be erased or stolen.
  • Risk: High – Lots of bitcoin based companies have been hacked. It’s not safe to keep large amounts of bitcoins online. There is no fraud protections. Some exchanges will even monitor what your coins were used for and shut down your account if they think you’re part of illicit activities.
  • Traceability: High – There are no names on accounts but every transaction is public.
  • Accounting Cost: High – Try explaining bitcoins to your accountant. The statements from exchanges won’t look much different from a credit card processor however.