Category Archives: Ruby

How to: Trello 3-Legged OAuth with Sinatra

The ruby-trello gem does a decent job of illustrating how to thread-safe (as much as one can w/ Ruby) authentication, but practically nil on thread-safe 3-Legged OAuth. It took me far longer than I care to admit to get it actually working, but now that I have I thought I’d post an example application.

I primarily deploy my simple webapps on Heroku, so you’ll definitely see some Heroku-isms (e.g. Procfile) in the code repository.

You can see the code in action here.

Solving Hanging with Friends (Pt. 1)

I like to play Hanging with Friends, and those that I play with are very competitive. I’ve been staying on top, but just barely. I’ve spent a lot of time informally deducing. I wondered if I could write a program to solve the games for me.

Where to start? It seemed like a big task…

There are two distinct activities to solving a hangman game:

  1. Finding a list of possible words
  2. Figuring out what letter to guess next

Each can be developed independently and then brought together for an effective solution.

There are many, many ways to do this, but I thought I’d just start hacking away in Ruby and then transition to something else at the pain points. Ater a couple hours of late-night coding, I found the Ruby-only solution to be good enough for personal use.

Part 2 deals with figuring out which letter to guess next
Part 3 focuses on how to find the list of possible words
Part 4 brings them together
Part 5 talks about next steps

Solving Hanging with Friends (Pt. 2)

Continued from Part 1, I’m off to write something to solve my Hanging with Friends games for me.

Because the two pieces of the puzzle (word list and next letter) are independent I can begin with either. I started with the letter frequency analysis because it seemed like a more tractable problem.

Ok, so it seemed easier but where should I start? Since I’m not totally clear on what it should do yet, I’ll start with the tests (aka how it should behave).

Given a list of viable words,

  • it should count how many words a letter appears in
  • it should only count a letter once per word
  • it should count each letter of the word

Here’s the full RSpec for those tests:


    describe "letter frequencies" do
      before(:each) do
        @words = ["lilly", "silly"]
      end

      it "should not return nil" do
        Frequency.letter_frequencies(@words).should_not be_nil
      end

      it "should return a hash" do
        Frequency.letter_frequencies(@words).is_a?(Hash).should be_true
      end

      it "should count the number of words with that letter" do
        freqs = Frequency.letter_frequencies(@words)
        freqs[:s].should == 1
        freqs[:y].should == 2
      end

      it "should not return a frequency larger than the number of words in the list" do
        freqs = Frequency.letter_frequencies(@words)
        freqs.values.count {|c| c> @words.length}.should == 0
      end
    end
    
    describe "letters per word" do
      before(:each) do
        word = "lilly"
        @letters = Frequency.letters_per_word(word)
      end
      it "should not return nil" do
        @letters.should_not be_nil
      end
      it "should return an array" do
        @letters.is_a?(Array).should be_true
      end
      it "should convert the letter to symbols" do
        @letters.count { |e| e.class == Symbol}.should == @letters.length
      end
      it "should only include repeated letters once" do
        @letters.count { |e| e == :l}.should == 1
      end
    end

Hmm, that’s a little more straightforward than I thought. Let’s make those tests green.

My first pass:


  class Frequency
    def self.letter_frequencies(words)
      freq = {}
      words.each do |word|
        letters_per_word(word).each do |letter|
          freq[letter] ||= 0
          freq[letter] += 1
        end
      end
      freq
    end
    
    def self.letters_per_word(word)
      chars = []
      word.each_char do |char| 
        char = char.to_sym
        chars << char unless chars.include? char 
      end
      chars
    end
  end

Ok, so more code to the tests than to the actual implementation. That seems about right...

Next we'll deal with how to make the word list contain only the words we actually want.

The most recent version of the code is available at GitHub: https://github.com/jeffweiss/hanging_solver.