Nine One-Liners for Ruby

Bryan McKelvey

(about 1 year ago)

I just thought this was an interesting post on Scala showcasing the ease that some exists in many newer (and some older) languages for dealing with complex operations on ordered data.

Multiply each item in a list by 2

(1..10).map { |n| n * 2 }

Magic.

Sum a list of numbers

(1..1000).inject(&:+)
(1..1000).inject { |r, n| r += n }
(1..1000).inject(0) { |r, n| r += n }

This takes advantage of Symbol#to_proc, which converts a symbol into a procedure. The above three lines — I prefer the first — are semantically equivalent.

Verify if exists in a string

word_list = ["scala", "akka", "play framework", "sbt", "typesafe"]
tweet = "This is an example tweet talking about scala and sbt."
word_list.any? { |w| tweet.include?(w) }  # nice
!(tweet.split & word_list).empty?         # cute, but too cute by half

The latter certainly isn’t that efficient, but it’s nice to know.

Read in a file

file_text  = File.read("data.txt")
file_lines = File.read("data.txt").lines

The String#lines method applies to strings, not files, although there are other methods to work through lines of files. Either way, working with strings is one of the easier things in Ruby. Many other languages simplify this greatly, too, but I can speak of the pain of doing these things with stuff like VBA and AppleScript.

Happy Birthday to You!

4.times { |n| puts "Happy Birthday #{n == 2 ? "dear NAME" : "to you"}" }

Not too difficult, although it does showcase the legibility of Ruby’s string interpolation.

Filter list of numbers

passed, failed = [49, 58, 76, 82, 88, 90].partition { |n| n > 60 }

This will split a list of grades into passing and failing camps. Without such functionality, you’d likely go about this by initializing a passing and failing array, then iterating over the grades and pushing them to the passing and failing arrays based on the outcome of an if statement. That’s not horrible, but it’s a common enough operation where a bit of terseness is nice.

Fetch and parse an XML web service

require "nokogiri"
require "open-uri"
results = Nokogiri::XML(open("http://search.twitter.com/search.atom?&q=ruby"))

Okay, so this one’s not so straightforward as Ruby has two requirements. But Nokogiri is a very nice thing. OpenURI monkey patches the open method to also open URIs.

Find minimum (or maximum) in a list

[14, 35, -7, 46, 98].min
[14, 35, -7, 46, 98].max

The nice thing here is that any object that can implements Enumerable and can compare its elements with each other benefits from min and max.

Sieve of Eratosthenes

(a = (2..127).to_a).each { |n| a.reject! { |m| m > n && m % n == 0 } }

That’s hideous. It’s not what Ruby’s for, and it’s not as “exciting” as following through the recursion of Lisp-y languages. But it works.

The other one listed involved parallel processing. You got me there.


OECD Sovereign Debt Ratings

Bryan McKelvey

(almost 2 years ago)

The countries below are ordered more or less by their average rating:

Rating Agencies % of GDP
Country S&P Moody’s Fitch Debt
Austria AAA AAA 70.4
Canada AAA AAA 84.0
Denmark AAA AAA 43.6
Finland AAA AAA 48.4
France AAA AAA 83.5
Germany AAA AAA 78.8
Luxembourg AAA AAA 16.2
Netherlands AAA AAA 64.6
Norway AAA AAA 47.7
Sweden AAA AAA 39.8
Switzerland AAA AAA 38.2
United Kingdom AAA AAA 76.5
United States AA+ Aaa AAA 58.9
Australia AAA AA+ 22.4
Belgium AA+ AA+ 98.6
New Zealand AA+ AA+ 25.5
Spain AA A2 AA+ 63.4
Slovenia AA AA 41.0
Japan AA- Aa3 AA 225.8
Italy A+ Aa2 AA- 118.1
Chile A+ A+ 6.2
Slovakia A+ A+ 41.0
Czech Republic A A+ 38.5
Estonia A A+ 6.6
South Korea A A+ 23.7
Israel A A 77.3
Poland A- A- 55.0
Ireland BBB+ Ba1 BBB+ 94.2
Mexico BBB BBB 41.5
Hungary BBB- BBB- 76.1
Portugal BBB- Ba2 BBB- 83.2
Iceland BBB- BB+ 123.8
Turkey BB BB+ 48.1
Greece CC Ca CCC 144.0

For reference, these are the ratings by issuer:

S&P Moody’s Fitch
Prime AAA Aaa AAA
High-grade AA+ Aa1 AA+
AA Aa2 AA
AA- Aa3 AA-
Upper mid-grade A+ A1 A+
A A2 A
A- A3 A-
Lower mid-grade BBB+ Baa1 BBB+
BBB Baa2 BBB
BBB- Baa3 BBB-
Junk BB+ Ba1 BB+
BB Ba2 BB
BB- Ba3 BB-
B+ B1 B+
B B2 B
B- B3 B-
CCC Caa CCC+
Ca3 CCC
Ca CC

Recent Earthquakes in Japan

Bryan McKelvey

(about 2 years ago)

Since Japan has been experiencing increased earthquake activity since the Tōhoku earthquake and tsunami on March 11th, I put together the chart below for each daily earthquake (blue dots) and the weekly average (red line) based on data from the JMA. The chart shows daily earthquakes registering at 1.0 or higher on the moment magnitude scale.

Weekly average is the total magnitude for the week, with the date plotted as the midpoint. I simply add all the seismic moments (M_0 in the formula below) for the week, divide by 7 and convert that to MMS. The scale is logarithmic, such that one quake registering a 9.0 releases 1000 times as much energy one measuring 7.0 does, which likewise releases 1000 times as much energy as one registering 5.0 does. It’s not a perfect measure, but it does provide some perspective on directionality.

M_w = 2 / 3 * log(M_0) - 10.7

Unfortunately, the chart I made is missing data for early April, but it’s otherwise pretty complete.

You can download the spreadsheet here.

Sources (in Japanese)