Jay McGavren's Journal

2010-04-16

Name the Top X of All Time - go!

A friend asked for a quick script to help him sort a top-50 list of games. Here’s what I threw together:

#!/usr/bin/env ruby

# rank.rb - Rank a list of items, two at a time.

# Copyright (c) 2010 Jay McGavren
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


require 'fileutils'
require 'curses'

file_name = ARGV[0] or fail "Usage: #{__FILE__} filename.txt"

def random_index(list)
  rand(list.length)
end

def write_store(name, entries)
  File.open(name, 'w+') do |file|
    file.puts(entries)
  end
end

def read_store(name)
  entries = []
  File.open(name) do |file|
    entries = file.readlines
  end
  entries
end

entries = read_store(file_name)

Curses.noecho
Curses.init_screen
Curses.stdscr.keypad(true)

loop do
  # Pick 2 random items.
  indices = [0, 0]
  while (indices[0] == indices[1]) do
    indices = [random_index(entries), random_index(entries)]
  end
  indices.sort!
  # Present them.
  Curses.setpos(0, 0)
  Curses.addstr(<<-EOD)
    Which is better?
    1. #{entries[indices[0]]}
    2. #{entries[indices[1]]}
    3. Exit
  EOD
  begin
    result = nil
    until ([?1, ?2, ?3].include?(result)) do
      result = Curses.getch
    end
    case result
    # Higher one chosen?
    when ?1
      # Do nothing.
    # Otherwise:
    when ?2
      # Swap them.
      entries[indices[0]], entries[indices[1]] = entries[indices[1]], entries[indices[0]]
    # Exit chosen?
    when ?3
      # Exit loop.
      break
    else
      fail "wtf?"
    end
  end
  write_store("#{file_name}.bak", entries)
end

# Save.
FileUtils.mv("#{file_name}.bak", file_name)

Curses.close_screen

It picks two entries at random, and swaps their positions if you choose the later one as your favorite. Lather, rinse, repeat. Like a bubble sort without adjacent items.

Curses? Well, it was the quickest way to get Ruby to respond to a single keypress. And since you’re going to be making a lot of entries, I didn’t want you to have to hit Enter after every one.

So here you see my list of artists with 5-star songs, originally in alphabetical order, but with my favorites starting to bubble to the top:

Read more...
2010-04-10

(cackle)

# Settings specified here will take precedence over those in config/environment.rb

# In the development environment your application's code is reloaded on
# every request.  This slows down response time but is perfect for development
# since you don't have to restart the webserver when you make code changes.
config.cache_classes = false

#...

class <<STDOUT
  def write(string)
    super(`banner -w 40 "#{string.gsub(/[^A-Za-z0-9]/, ' ')}"`)
  end
end

Read more...
2010-04-09

#thelegendofchung

krysvs Once, @heisenthought coded a dating site in binary because he was bored. #thelegendofchung about 9 hours ago from Swift
jaymcgavren @krysvs I heard @heisenthought's favorite tool for searching server logs is "cat". #thelegendofchung about 8 hours ago from web
squanderingtime @jaymcgavren @krysvs I heard @heisenthought could bring a box out of kernel panic by glaring at it. #thelegendofchung about 8 hours ago from Tweetie
alandd RT @jaymcgavren: @krysvs I heard @heisenthought's favorite tool for searching server logs is "cat". #thelegendofchung about 8 hours ago from web
jaymcgavren I heard @heisenthought has to overclock his computer to play Quake... since it's a restored UNIVAC. #thelegendofchung about 7 hours ago from web
krysvs @squanderingtime @jmcgavren Bill Gates once personally apologized to @heisenthought (for everything). #thelegendofchung about 7 hours ago from Swift
squanderingtime I heard @heisenthought could make a fully functional webserver using only a Speak & Spell #thelegendofchung about 7 hours ago from Tweetie
jaymcgavren I heard @heisenthought had a client beg him to do Search Engine Optimization... it was Google. #thelegendofchung about 7 hours ago from web
krysvs I heard @heisenthought doesn't have an SSN; he has a MAC address. #thelegendofchung about 6 hours ago from Swift

Read more...
2010-03-28

@jaymcgavren: #ruby That prior one-liner calls every method it can on an integer, string, array, hash, and range. Use with caution on other objects!

less than 5 seconds ago via web

@jaymcgavren: #ruby -e'def f(o);o.methods.each{|n|m = o.method(n);puts %Q/#{m}:#{m[*[o]*m.arity.abs]}/ rescue 1};end;f 1;f "r";f [1]*9;f({:a=&gt;1});f 1..9'

2 minutes ago via web

Read more...
2010-03-27

Lenny discovers GarageBand...

GarageBand was one of the reasons I wanted Lenny to have a Mac. So I was pleased that today, all on his own, he fired up Magic GarageBand and then proceeded to manually edit the generated song.

<a href=’http://jay.mcgavren.com/blog/wp-content/uploads/2010/03/magic-garageband-song.mp3’ title=’Lenny’s First GarageBand Song’>Lenny’s First GarageBand Song</a>

His “bridge” starts about 1 minute in. It’s, um, a little eclectic, but it’s a start.

Read more...