Archive for the ‘Uncategorized’ Category

The Five Golden Rules of Bumper Sticker Influence

May 21, 2013

This is a departure from my site’s usual topic of Ruby and Ruby Accessories, but I’m nothing if not a renaissance man.

At one time or another, we all attempt to influence others via the humble bumper sticker. A younger, more idealistic version of myself even sported “Don’t Mess With Texas” once upon a time. I’m not sure exactly what I was trying to convey, except that I was from Texas and it was important that every Nebraska driver knew that.

This graphic indicates that the driver is from Texas and, while there is no explicit rule about messing with the driver, their home state is clearly off limits.

This graphic indicates that the driver is from Texas and, while there is no explicit rule about messing with the driver, their home state is clearly off limits.

Since the sweet, siren song of bumper sticker activism (ie, something for nothing) will lure us all at some point, it’s important to at least understand the mechanics of bumper sticker influence, and how much influence each individual bumper sticker carries. This science can be boiled down to Five Golden Rules.

Let’s say you have something important to say, and I’m a fellow driver destined to drive behind you at some point. You’ve decided that the best way to change my entire world view is through a bumper sticker. It’s perfect – you drive in front of hundreds of cars every day, and you can champion a noble cause while listening to Kesha on the radio with the windows rolled up tightly. Of course, you don’t like Kesha, but there’s a train-wreck attraction there that others simply won’t understand.* Anyhow, on to the rules:

  1. As a fellow human with a pulse, you begin with a base level of Credibility.
  2. This Credibility Score is automatically cut in half by the mere act of displaying bumper stickers.
  3. The Influence Quotient for each bumper sticker is a share of the remaining Credibility Score, proportional to the surface area of the given bumper sticker. In other words, if you have a small sticker and a large one, the larger sticker gets the lion’s share of the Influence.
  4. If you spell out any message using “coexist” style religious symbols, the value of any adjacent sticker is flipped to negative.
  5. Finally, since you and I don’t know each other, you started this process with a Credibility of zero. Use this as the basis of your calculations.

Assuming a grid pattern in rush hour traffic, there might be as many as eight cars surrounding yours at any given time. Of those eight, 5 are doing the same thing you are. Tick tock, don’t stop.

Kansas City, Google Fiber, and the Great Divide

November 28, 2012

On the left is the Missouri side of Kansas City, with a Time Warner Cable truck in the driveway. On the right is the Kansas side, with a Google Fiber truck installing service in a building being used to house a number of new startups.

For those of you not familiar with Kansas City, it’s an interesting metro area where two distinct municipalities – the Kansas side or “KCK”, and the Missouri side, known as “KCMO”.  The city is literally divided by a street called “State Line Road”, and that’s where I took the above picture.

In practice, the two sort of blend together to make one big city.  For the most part, residents move from one to the other in the course of their day without really even noticing.  There are even state universities with local campuses that offer in-state tuition to residents of the metro area on both sides of the line.

What’s in a Line?

One of the biggest differences I’ve noticed since moving here five years ago is how cable/broadband services operate.  Time Warner Cable spans the entire metro, but the Kansas side has the benefit of a couple smaller players in the cable market.  Even though I currently have Time Warner, I benefit greatly from these competitors.  How? TWC is drastically different on each side of the line – both in price, and service.

When I first moved to town from Omaha, I had to start a job immediately. I didn’t have time to house hunt for my family first, so I rented a temporary place of my own on the Missouri side, close to my employer.  Setting up cable was a nightmare.  It took three scheduled appointments, with the infamous four-hour windows, before they actually showed up and installed the service.  That was just for internet, which is a simple as it gets.  No set-top boxes or routing cable to multiple rooms.  And it was relatively expensive.

It took 3 months to find a place on the Kansas side for my wife and kids to move down as well.  When the big day came, I called TWC on a friday to inform them I’d need service switched over on monday.  They promptly gave me an appointment to make sure I wouldn’t go a day without service in the new house.  And I didn’t.  To top it off, I called them an hour before the appointment to ask them to throw a TV package on as well, and they were more than accommodating.  I don’t remember the specifics, but even with adding TV service, the monthly rate went up very little if at all.

And Then There Was Fiber

It would be fun to say the Missouri side finally got its fair share with Fiber moving to town, but Google chose to focus on the Kansas side for now.  And thus, the picture.  I was walking back from lunch today, down State Line Road itself, when I saw a Time Warner truck sitting in a driveway on the Missouri side, and a Google Fiber truck sitting in the driveway of “Homes for Hackers” on the Kansas side.

It’s amazing to see how one company (Time Warner) can treat people on opposite sides of a street so differently, purely because of the presence/absence of competition.  Believe it or not, it’s what makes me a hardcore capitalist.  Competition raises the bar, and it can come from anywhere seemingly overnight.  Whether you’re an entrepreneur, a nine-to-fiver, or somewhere in between, the lesson here is “do your best”.  Don’t make it so easy for somebody to swoop in and put you out of business because you were resting on your laurels.

Why Aren’t You Building Angry Ruby Robots?

October 25, 2012

If you’re reading this article, you’re wasting valuable time that could be spent building robots, in ruby, that battle each other to the death.  I can hear you already: “Does such a thing actually exist??”  Well no, not really.  But there are two consolation prizes:

  • it will exist in the very near future, and
  • until it does, I’ve created a simplified version to whet your appetite.

Rubots!

“Rubots” is the word you use when you’re referring to Ruby Robots but don’t want to waste precious rubot-coding time pronouncing the full phrase.  My goal is simple: to create Ruby-based games where you can code your own player classes to battle against the sample players provided, other players you’ve created, or for the most fun: players created by your Rubyist friends!

The popularity of Rails has brought many people to the Ruby camp.  Sadly, many of these people don’t learn how to code Ruby outside of the Rails environment.  I got my start through Rails, and there were times I wasn’t sure where one ends and the other begins.  I want to get programmers comfortable coding pure Ruby, and there’s no better way than the promise of digital violence.

Prisoner’s Dilemma

My first iteration of this concept is a Rubot implementation of the classic game theory exercise, Prisoner’s Dilemma.  The gist is that you’re one of two prisoners who have been placed in separate rooms and questioned by the authorities for a crime.  You have to decide whether to cooperate with your partner in crime by not saying anything, or betray them by cutting a deal.  There are different rewards/consequences based on how each of the two players decides to act.

You can download it here:

https://github.com/bellmyer/prisoners_dilemma

The README is pretty comprehensive, so I won’t rehash all of it here.  The basic idea is that you create player classes that decide whether to cooperate with, or betray, their opponents.  The game is played in multiple turns, so you can base your decision on how you and your opponent have behaved in previous turns, or any other criteria you want to consider.  Maybe your prisoner gets grumpy around nap time, and from 2-4pm it only betrays its opponent :)

This is meant to be played tournament style, and so I’ve included a basic round-robin script that loads all player classes in the project directory and pits them against each other in a battle royale.  This is a great activity for Ruby groups, especially among beginners.  Player classes inherit from a prefabbed parent class, and simple strategies can be implemented with even a basic understanding of the language.

Enjoy, and please provide feedback.  This will be the first of (hopefully) many games offered in this same style.  Rubots unite!

The Sifteo Platform, From a Developer’s Perspective

September 28, 2011

Sifteo Cubes are a novel idea first publicized in a TED talk in 2009.  In January 2011, Sifteo invited a limited number of people to join the early release program by pre-purchasing their starter kits.  The $100 kits sold out quickly, and customers received them about three months later.  I was one of those customers.

I don’t have, or spend, a lot of time on games.  But I was intrigued by their soon-to-be-available SDK.  As a developer, I was interested in seeing if this platform “had legs” by trying it out. I also wanted to get in on the ground floor as a third-party developer.

The SDK (Software Development Kit)

Fast forward to September. I’m personally tired of waiting for the Sifteo SDK, and my cubes have collected dust for the last six months:

The current location of my Sifteo cubes, for the last several months

This is the box of stuff I don't quite have a place for, in my office. I walked past it today, remembered that I had them, and decided to see if they ever got around to releasing that SDK.

I’ve been waiting since I ordered my early release cubes the first week of the year. I was led to believe the SDK was just around the corner. My interest was primarily in development, so they got my $100+ under false pretenses. I’m not saying they lied or did this on purpose, but the end result is the same to me.

Part of me wonders if they didn’t want to complete with third party developers on the core apps they had in the works. This is based on their failure to answer even simple questions until recently – such as, what language/platform will be used? I couldn’t think of a simpler and more readily available answer to give. Developers resorted to studying screen shots of code to take their best guess. Java and Python were the front-runners of the guessing game, but both were wrong: C# is the winner.

Sifteo has traditionally been very tight-lipped about their SDK release schedule, claiming several times that they didn’t have a date in mind, wanted the SDK to be solid, and so it would take however long it would take. Of course, this was well *after* developers like myself had paid to be part of the early release program. Again, even if they had the best of intentions, my end result is the same as if they’d deliberately mis-led me.

Signing up for their SDK-specific mailing list, I only received a couple e-mails over the months. They were general marketing blasts targeted to consumers. It turns out, I was really just signing up for their general mailing list. Ironically, I’ve since learned that their blog has been posting SDK-related info, that I *didn’t* receive via e-mail. I didn’t know they’d publicized a September SDK release until today (09/28/2011). Of course, it’s starting to look like it was just as well, since it doesn’t appear that they’ll actually *have* a September release.

The latest word from Sifteo staff is that the SDK should be ready within a week, pushing the release to early October:

Sifteo SDK release pushed back to October, according to staff

Sifteo staff's latest estimate of the SDK release date

The explanation given is that they have a small development team, and SDK development/documentation took a back seat to consumer-facing issues. That’s a reasonable response, mostly, but it would have been more useful and appreciated months ago.

The Product

The cubes themselves are novel and fun, but limited. Far from the “tiny blocks with brains“, as Time Magazine called them, they are simply small color screens with motion sensors and bluetooth connectivity. They don’t run apps, your computer does. The distinction is lost on many people, which is why I think reviewers have overlooked it thus far. Your computer must be nearby and running the Siftrunner application. You can’t switch games on the cubes themselves – you must go back to your computer to do this, as well. The cubes are merely new peripherals, like a mouse and small screen rolled into one. My kids can’t play them on long car rides, unless I bring my laptop to actually run the applications the whole time.

Bluetooth means you can’t stray too far from your computer. And despite the fact that the apps are actually running on your computer, which presumably has internet access, there’s no support for using your internet connection. This would open a whole new dimension of game play. Because of their simplicity, any game played on the cubes could easily be played against online players. The bandwidth requirements would be very small.

Product Comparison

Let’s put on our Consumer Reports hat for a moment, and contrast Sifteo with similar handheld platform: Cube World. My oldest son was into these for a couple years.  Similar in size, they have a low-resolution black-and-white display which allows you to interact with funny stick people.

Like Sifteo cubes, Cube World cubes can detect motion. Roll your cube over and over, and the tiny person trapped inside rolls around as if bound by gravity.  Keep it up, and he actually vomits digital blocks.  Put multiple cubes together, and the stick people can interact.  They have different games and toys, and seeing the interaction (sometimes playful, sometimes antagonistic) is fun.

Value

Cube World lacks a color display, multiple games, wireless connectivity, or the complexity of Sifteo. But they’re also not tethered to a computer, and the price ($25 a pair when they were in production) allowed you to buy a dozen cubes for the price of the Sifteo starter kit ($150 for three cubes and a charger).

With limited input options (movement, and placing cubes in proximity to one another), Sifteo cubes are limited as a gaming platform.  For another $20, you can walk into your local Sears and buy a brand new Nintendo 3DS.  I haven’t played a Sifteo game yet that keeps my interest for more than half an hour.  Speaking as a parent with a lot of road trip experience, you get a lot more peace and quiet for your dollar with the DS.

Summary

Suffice to say, I’ve been disappointed in Sifteo so far. They’ve done a great job of marketing. They got my $100 commitment before they ever had a physical product to sell, and they’ve gotten a lot of publicity from the media.

MIT degrees and TED exposure can only *start* a business. At some point, you have to deliver the goods. I can’t speak to consumer satisfaction. That will bear itself out soon, since I believe cubes have started shipping to the general public. From a developer’s perspective however, Sifteo’s debut falls short.

KC on Rails Hits 20,000 Page Views Today!

January 14, 2011

A little over a year ago, I ported my blog to WordPress and something magical happened – somebody else started counting the hits, and putting them in chart form that was really motivating. It hasn’t officially happened yet, but my traffic is pretty consistent. As I write this, I’m just a couple dozen hits away, and I’ll make that by this afternoon. I’d like to thank everyone who made this possible.

To my nonhuman peeps:

Thank you Google, without whom my site, and everyone else’s, and indeed the entire internet economy, would crash and burn into little ashes. Years later, people would stumble onto those ashes, and the conversation would go something like this:

“What’s with all the ashes?”

“Oh, that used to be the internet.”

“Huh, I don’t see what the big fuss was about. Let’s use our hyperconnective implanted brain-chips to play a game of virtual scrabble.”

“Okay.”

I’d also like to thank the many spambots, who never stopped believing they could crack my approve-only comment policy by tossing generic praise my way, while pimping their latest herbal viagra supplement. Actually, the fact that you thought highly enough of my site to assume it would be teaming with your aging, oversexed baby boomer demographic is just the flattery I needed to get through those Mondays.

Ooh, that reminds me – I’d like to thank the comic strip character Cathy for retiring this year. No longer writing all those angry letters forced me to vent into another creative outlet, and KC on Rails bore the brunt of it.

To the strangers:

Thanks to the haughty experts who delighted in pointing out syntax or logical mistakes. We need more people like you, so I promptly forwarded your contact info to the herbal viagra companies I mentioned above.

To the friends:

Thanks to my heros like Dr. Nic, Technical Pickles, Ryan Bates, and the entire Thoughtbot crew (including former bot Tamir Saleh whose code I dug through on many late nights). Not just for the guidance, but thanks in advance for not publicly shaming/mocking my excitement over my number of lifetime views that you probably get daily.

I actually met most of you in person at RailsConf last year, and you were awesome. Dr. Nic, you were very friendly and social for a programming expert. I’ve only ever heard of 6 actual people from Australia that weren’t fictional characters on Lost, so maybe you were just lonely. Josh and Thoughtbot, you guys were very cool about me unknowingly crashing what was apparently a Boston rubyists exclusive lunch :)

And finally, thanks to the loads of real people who came to my blog for answers, and hopefully found them. And a very special thank you to Vladimir, who has translated some of my posts into Russian. If you know the language, check out his blog at Developing Ruby and Rails.

In Summary

With the decline of quality late night television, expect me to continue to ramp up my online contributions, and don’t be afraid to ask for something you’d like me to explain (keep it to the ruby, rails, or ninja genres), or just say “hi” if you stop by. I appreciate it.

Memoize Techniques in Ruby and Rails

December 13, 2010

The headline isn’t a typo. If you haven’t heard of “memoizing”, it’s the act of caching the result of a method so that when you call the method in the future, it doesn’t have to do all the processing again. I’ll show you a few different ways to do this, along with the pros and cons of each.

Setup

Let’s setup a sample rails app to play with. I’m using Rails 3, and we’ll generate a simple model to work with:

memoize$ rails g model user first_name:string last_name:string
      invoke  active_record
      create    db/migrate/20101204003605_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/unit/user_test.rb
      create      test/fixtures/users.yml
memoize$ rake db:migrate
(in /Users/bellmyer/Desktop/bellmyer/blog/memoize)
==  CreateUsers: migrating ====================================================
-- create_table(:users)
   -> 0.0013s
==  CreateUsers: migrated (0.0014s) ===========================================

The Standard Idiom

You’ve probably seen the simplest form of memoization, whether you called it that or not. Our user model has a first_name and last_name. Let’s say we want to create a full_name method to combine the two:

class User < ActiveRecord::Base
  def full_name
    "#{first_name} #{last_name}"
  end
end

Let’s verify that it works as we expect:

memoize$ rails c
Loading development environment (Rails 3.0.1)
ruby-1.9.2-p0 > user = User.new :first_name => 'Bob', :last_name => 'Smith'
 => #<User id: nil, first_name: "Bob", last_name: "Smith", created_at: nil, updated_at: nil> 
ruby-1.9.2-p0 > user.full_name
 => "Bob Smith" 

Great! Now let’s try the simplest form of memoization:

class User < ActiveRecord::Base
  def full_name
    @full_name ||= "#{first_name} #{last_name}"
  end
end

The first time this method is called, @full_name doesn’t exist yet, so the code to the right of ||= is executed. The next time this method is called, the result of the method has already been stored in @full_name, so the method doesn’t need to recalculate it.

A Better Way

This quick-and-dirty method works well for a lot of stuff, but it doesn’t work in all cases. Let’s add another memoized method, and see if you can find the logical flaw:

  def has_full_name?
    @has_full_name ||= (!first_name.blank? && !last_name.blank?)
  end

This method checks to see if the user has both a first and last name. At first, it looks like it will work as well as our first method. But what if the result is false? @has_full_name will be set to false, which means the right side of the equation will be run from scratch each time.

Instead of checking if @has_full_name equates to true or false, we need to check if @has_full_name has been defined, like so:

  def has_full_name?
    return @has_full_name if defined?(@has_full_name)
    @has_full_name = (!first_name.blank? && !last_name.blank?)
  end

Now we’re returning @has_full_name if it exists, and evaluating it otherwise. No more true/false gotchas. This method is more reliable, but it’s not as short and sweet, I’ll admit.

Memoization with Method Arguments

What if we have a method with arguments? We usually want the same input to produce the same output. If we enter the same arguments to a method over and over, we’d expect the same return value. So why not take our memoization a step further, and add caching for methods with arguments?

  def formal_name(salutation='Mr.', suffix=nil)
    @formal_name ||= {}
    return @formal_name[[salutation, suffix]] if @formal_name.has_key?([salutation, suffix])

    @formal_name[[salutation, suffix]] = "#{salutation} #{full_name} #{suffix}"
  end

This is a bit more complicated. Since this methd can be called with different arguments, we initialize a hash to store our cached results. We use Hash’s has_key? method to check if we already have a value for the given arguments. Let’s try it out:

memoize$ rails c
user Loading development environment (Rails 3.0.1)
ruby-1.9.2-p0 > user = User.new :first_name => 'Bob', :last_name => 'Smith'
 => #<User id: nil, first_name: "Bob", last_name: "Smith", created_at: nil, updated_at: nil> 
ruby-1.9.2-p0 > user.formal_name('Mr.', 'Jr.')
 => "Mr. Bob Smith Jr." 
ruby-1.9.2-p0 > user.first_name = 'John'
 => "John" 
ruby-1.9.2-p0 > user.formal_name('Mr.', 'Jr.')
 => "Mr. Bob Smith Jr." 

You know the memoization is working, because I changed the first name, and formal_name still gave us the same answer.

Using Rails’ Memoize Module

Our “better way” is bulletproof, and we’ve even added the ability to handle method arguments. But it’s a lot of work to do this for every method, and it gunks up the readability of the method. We have to wade through the caching code to figure out what the method really does.

If you’re using Rails, 2.2 or later, you can take advantage if its Memoize module to clean this up.
Let’s add a method that uses it:

class User < ActiveRecord::Base
  extend ActiveSupport::Memoizable

  # other methods...
  
  def initials(middle_initial)
    first_name[0] + middle_initial + last_name[0]
  end
  memoize :initials
end

It’s that easy! The memoize method takes care of things for you, but you have to extend your class with the module for it to work. And unlike the other memoization strategies discussed, this uses ActiveSupport, so it’s Rails-specific.

The good news is that if you’re using Rails for your project, you can use Memoizable anywhere. Let’s add a non-activerecord class in our lib folder:

# lib/my_number.rb
class MyNumber
  extend ActiveSupport::Memoizable
  
  attr_accessor :x
  
  def initialize(x)
    @x = x
  end
  
  def plus(y)
    @x + y
  end
  memoize :plus
end

And here’s the proof that it works:

memoize$ rails c
require 'myLoading development environment (Rails 3.0.1)
ruby-1.9.2-p0 > require 'my_number'
 => ["MyNumber"] 
ruby-1.9.2-p0 > num = MyNumber.new(5)
 => #<MyNumber:0x00000104434bf8 @x=5> 
ruby-1.9.2-p0 > num.plus 2
 => 7 
ruby-1.9.2-p0 > num.x = 0
 => 0 
ruby-1.9.2-p0 > num.plus 2
 => 7 

This is a much better solution if you’re using Rails, and I highly recommend it. The less code you type by hand, the less chance of adding a bug somewhere.

Things You Should Know

First, as mentioned above, the Memoizable module is only available in ActiveSupport, part of Rails. But the previous examples are pure Ruby, and can be used in any Ruby project.

You don’t want to use memoization everywhere. Here are some situations where it’s not appropriate:

  • The method is simple, and memoizing it won’t save you much (there is some overhead involved).
  • The method’s output needs to change over the life of its object
  • The method is unlikely to be called again with the same parameters.
  • There are so many combinations of parameters that will be called, it will eat up too much memory to store all the results.

Follow

Get every new post delivered to your Inbox.