Ruby Can Help you TXT

I’ve never been a “Txter.” I’d much rather call my friends or have them call me. Its a pain to have to search for this small letters, push keys 1-4 times, search for shift, etc. Its a pain ever time I have to text. Hopefully this will be completely avoided as I consider replacing my iPod Touch with an iPhone this coming week after the WWDC Keynote. Either way I decided to employee Ruby to help me out.

It all started with a simple function to convert phone numbers with letters to their numbered equivalent. For instance converting “555-HELP” to “555-4375″ like so:

# Extend the String Class
class String

  # Converts a phone number with letters to numbers
  # Ex. AAA-FFFF => 222-3333
  def convert_to_phone_number
    letters = 'abcdefghijklmnopqrstuvwxyz'
    numbers = '22233344455566677778889999'
    self.downcase.tr(letters, numbers)
  end

end

puts "555-HELP".convert_to_phone_number # => 555-4357

I decided to take it a step further. Why don’t I have Ruby tell me what I should push to text a string? So with a few modifications, and some studying of my cellphone I came up with the following function, also extending the String class (not shown):


  # Converts the given string to the sequence of
  # numbers that you would need to push to create
  # that string. Shift = *, Space = #
  # Input: "Hello hi"
  # Output: "*44 33 555 555 666 # 44 444"
  def how_to_text
    letters    = 'abcdefghijklmnopqrstuvwxyz '
    numbers    = '22233344455566677778889999#'
    multiplier = '123123123123123123412312341'
    str = ''
    self.each_byte do |char|
      char = char.chr
      if char =~ /[A-Z]/
        str += '*'
        char.downcase!
      end
      str += if letters.include? char
        index = letters.index(char)
        numbers[index].chr * multiplier[index].chr.to_i
      else
        char
      end + " "
    end
    str.chop
  end

  # Converts the given numeric sequence back to
  # a text string.
  # Input: "*44 33 555 555 666 # 44 444"
  # Output: "Hello hi"
  def decode_text
    letters = 'abcdefghijklmnopqrstuvwxyz '
    numbers = '22233344455566677778889999#'
    str = ''
    self.split.each do |part|
      shift = part[0].eql?(?*) ? true : false
      part = part[1,part.length] if shift
      pos = numbers.index(part) + (part.length-1)
      str += if shift
        letters[pos].chr.upcase
      else
        letters[pos].chr
      end
    end
    str
  end

Texting is no longer a burden. I even have a decode function to convert back from the cryptic pattern to its original string. Right now the function is limited to typing lowercase letters, uppercase letters, and spaces. I might spend the time to abstract this even more so you can pass in your phone’s texting “model”, a String/Hash/Object providing such information, and it would use that to generate the keystrokes required to text. For now I’m pleased with what I have.

>> "until next time".how_to_text
# => "88 66 8 444 555 # 66 33 99 8 # 8 444 6 33"

I use tab-autocompletion in my IRB and I load this library from my ~/.irbrc, but if you are really interested you could alias how_to_text to how_to_txt to make it a little more fun. That makes it a little harder on tab-autocompletion though.

Feel free to download and improve it. I’ll keep it out of my GitHub for now and just store it in my free directory:
Download
Test Case

Add a Comment

search