Perspectives

Fatnum

What's Your FatNum?

Numbers are a big deal. Whether you're talking about business, family, fun, personal goals, a lot can be simply boiled down to one big, fat number...

  • How many people registered for my app?
  • How many batches are left in my database import?
  • How many days left until my birthday?
  • How many pounds have I lost on my diet?
  • And so on...

So what's the big, fat number that you need to keep track of? Whatever it is, FatNum.com can help.

What is FatNum.com?

FatNum.com lets you signup and start tracking your FatNums right now! Right away you are given a simple Web interface for creating your FatNums and keeping them up to date. Each FatNum is assigned a five-character code, so you can share your FatNum with others discreetly without having to log in.

For all you programmers who want their Ruby apps to share data with FatNum.com, I've built this RubyGem for easily accessing and updating your FatNums. From the documentation:

require 'rubygems'
require 'fat_num'

f = FatNum.new('your@email.com', 'password')

# get your statistic
response = f.get('e37gh')
response.digit #=> 120
response.description #=> 'batches left'

# update your statistic
f.update('e37gh', 119)

# sure enough, our update was successful
f.get('e37gh').digit #=> 119

There's also some love for all you Mac users out there -- download the FatNum Dashboard Widget and easily track your FatNums from the comfort of your OSX Dashboard!

Any More Examples?

Here are a couple FatNums that FatNum.com is using for itself:

FatNum.com is super simple, almost to a ridiculous degree, but I hope you can find some imaginitive uses for it!



Spring

Get FlexibleCSV from GitHub

A Challenge in Flexibility

As part of a contact management system we are building for a client, I encountered a unique challenge with allowing users to upload and import their contacts from CSV files. Usually this would not be a problem, except that in this case there was no standardization to what the header names would be or what order the columns were in. Because the FasterCSV gem relies on using the header names as access keys, this process was suddenly quite complicated.

One solution would be to create a user interface that would display our database fields, their CSV columns and allow them to pair them up. For example, my database column is 'email' but their CSV column is 'Email Address', so they could mark those as equivalent. What would I do, however, for the users who have a "Full Name" column when I use 'first_name' and 'last_name' database columns? Suddenly the user interface could get very complicated and confusing.

Introducing FlexibleCSV

Instead, I developed FlexibleCSV, a gem that allows you to parse through a CSV file without knowing exactly what the headers are named. By providing a list of possible header names, you can access all the CSV columns with a uniform interface.

require 'flexible_csv'

# Arbitrary CSV data
csv_data1 = %Q{Full Name, Email Address\nJohn Doe, john@doe.com}
csv_data2 = %Q{Email, Name\njohn@doe.com, John Doe}

parser = FlexibleCsv.new do |csv|
  csv.column :full_name, "Name", "Full Name", "Client Name"
  csv.column :email, "Email", "Email Address"
end

parser.parse(csv_data1).each do |row|
  puts row.full_name #=> 'John Doe'
  puts row.email     #=> 'john@doe.com'
end

parser.parse(csv_data2).each do |row|
  puts row.full_name #=> 'John Doe'
  puts row.email     #=> 'john@doe.com'
end

Both data sets can now be accessed using the uniform #full_name and #email accessors.

Handling Complexity with Adapters

Going back to my original example, how would we handle CSV files that separated first and last names when my database uses the full name? Or vis versa? Though I considered adding this kind of functionality to the FlexibleCSV gem, ultimately I thought it best to keep that kind of logic in a separate adapter class. For example:

require 'flexible_csv'

# Arbitrary CSV data
csv_data1 = %Q{Full Name\nJohn Doe}
csv_data2 = %Q{First Name, Last Name\nJohn,Doe}

parser = FlexibleCsv.new do |csv|
  csv.column :full_name, "Name", "Full Name", "Client Name"
  csv.column :first_name, "First Name", "First"
  csv.column :last_name, "Last Name", "Last", "Surname"
end

class CsvAdapter
  def initialize(row)
    @row = row
  end

  def full_name
    row.full_name || "#{row.first_name} #{row.last_name}"
  end

  def last_name
    row.last_name || row.full_name.split(' ').last
  end

  def first_name
    row.first_name || row.full_name.split(' ').first
  end

  def method_missing(method_name, *args)
    row.send(method_name, *args)
  end
end

parser.parse(csv_data1).each do |row|
  ad_row = CsvAdapter.new(row)
  puts ad_row.full_name  #=> 'John Doe'
  puts ad_row.first_name #=> 'John'
  puts ad_row.last_name  #=> 'Doe'
end

parser.parse(csv_data2).each do |row|
  ad_row = CsvAdapter.new(row)
  puts ad_row.full_name  #=> 'John Doe'
  puts ad_row.first_name #=> 'John'
  puts ad_row.last_name  #=> 'Doe'
end

Using the adapter class, we can once again access each row of data from any CSV file with a uniform interface.

Go Get It!

To use the FlexibleCSV gem, you can follow or fork the project on GitHub or just install the gem:

sudo gem install chrisjpowers-flexible_csv



Birthday

One Year Down...

Today, Killswitch is celebrating the 1-year birthday of our blog Perspectives! Since its introduction, Perspectives has been our outlet for giving back to the communities we rely on. It has been a lot of fun sharing our thoughts and ideas with you, so be assured that we will continue delivering hot, fresh content on a weekly basis.

Over the last twelve months I have been asked a few times:

Why go to so much trouble to blog? Aren't you just giving away your trade secrets?

It's true that Perspectives is no money maker — obviously no one is paying to read these articles, and we certainly wouldn't want them to! So why do we continue to ask our entire staff at Killswitch to spend valuable man-hours writing?

And Many More

As I mentioned before, a big part of it is the importance of giving back to the communities that support our business. From a development standpoint, we solely use Open Source coding languages, libraries and programs, which means that these tools have been provided free of charge. In stark contrast to Microsoft tools like .NET which are supported internally and leased to developers, Open Source code is maintained by a community of volunteers who are concerned enough about the success of the industry to pitch in and help.

Every time I run into a bug while developing a Web app, my first inclination is to Google my issue and see if someone has already written a blog article with a fitting solution — and often times that works! Maintaining Perspectives with helpful tutorials and free downloadable code is our way of saying 'thank you' to the community and giving something back.

Keep It Coming

Perspectives is a place where we can show you a more candid, honest look at the people who make The Killswitch Collective what it is. This is our opportunity to express our passion for intuitive design, clever development and fruitful business relationships. We want to show our readers how we think, how we work through problems and how we strive to make the Web a better place.

With one year under our belts, we're just starting to get warmed up. Keep checking back each week for more articles about development, design and anything else we're thinking about. If you are new to Perspectives, here are a few tips to help get you started:

  • Subscribe to Perspectives by adding this URL to your RSS reader: http://feeds.feedburner.com/killswitchcollective/perspectives. Not using an RSS reader yet? Try Google Reader!
  • Start following @KSCollective on Twitter for up-to-the-minute updates about what we are working on and thinking about.
  • Use the Category links in the sidebar to narrow down articles to topics that interest you (design, development, etc).
  • Click on an author's picture at the bottom of their articles to read their other entries.
  • Drop us a note, we'd love to answer any questions!




RSS Feed


CATEGORIES


ARCHIVES


BOOKMARKED


Add to Technorati Favorites