Ruby tweets!
A while back I stumbled across a page of JAPHs, or Just Another Perl Hacker scripts. This was an ongoing competition Perl users had years ago to print the phrase “Just Another Perl Hacker” in the most convoluted way possible, utilizing little-known tricks of the language. They usually stuffed these mini-scripts into their Usenet signatures. I had always admired JAPHs, and decided to try my hand at a Ruby version. But I needed a forum, and I hadn’t been on Usenet in years.
So what’s the modern version? Why, Twitter, of course! The 140-character limit would provide an extra level of challenge, enough so that I didn’t feel a need restrict myself to printing “Just Another Ruby Hacker”.
I started simple, printing a wave to STDOUT.
ruby -e "i=0;loop{puts ' '*(29*(Math.sin(i)/2+1))+'|'*(29*(Math.cos(i)/2+1)); i+=0.1}"#ruby
Copy-paste that to a terminal, and hit Enter. (If you copy from Twitter, there’s no need to worry about line breaks or the Favorite star; the browser strips them.) You get something like this:
|||||||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||
|||||||||||||||||||||||||
|||||||||||||||||||||
||||||||||||||||||
|||||||||||||||
||||||||||||||
||||||||||||||
|||||||||||||||
||||||||||||||||||
|||||||||||||||||||||
|||||||||||||||||||||||||
||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||||
|||||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||||||||
|||||||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||||||||
|||||||||||||||||||||||||||||||||||||
||||||||||||||||||||||||||||||||||
|||||||||||||||||||||||||||||
|||||||||||||||||||||||||
|||||||||||||||||||||
...
Here’s a more-readable version:
#Have to initialize i before incrementing.
i=0;
#loop{} is a few characters less than 1000.times{}.
#People know where Ctrl-C is on their keyboards. :)
#Brackets cost less characters than do/end.
loop {
#sin() and cos() range -1 to 1.
#We change result to range 0 to 1.
left_width = Math.sin(i) / 2 + 1
wave_width = Math.cos(i) / 2 + 1
#Indentation of wave's left side.
print ' ' * (29*left_width)
#Wave's width, which decides placement of right side.
print '|' * (29*wave_width)
print "n"
#Increasing input for sin()/cos() makes wave undulate.
i += 0.1
}That’s still among my favorites. But anybody can use puts(). The next was more ambitious…
Read more...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_screenIt 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...(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
#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 SwiftRead more...
@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
Read more...@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=>1});f 1..9'2 minutes ago via web