Here’s the second refactoring from the Rubyize This workshop. See the first refactoring for an explanation of what’s going on and why this code is so darn ugly! Don’t forget to check out the third and final refactoring
This script loads the file full of random numbers from the first refactoring and makes a beautiful ascii-art histogram from it.
#!/usr/bin/env ruby
require 'pp'
BIG_NUMBER = 32768
# Get data from a file, turn it in to a float, and find the max
data = File . readlines ( 'random.txt' )
max = - BIG_NUMBER
for n in ( 0 ... data . length )
data [ n ] = data [ n ]. chomp . to_f
if data [ n ] > max
max = data [ n ]. to_i + 1 # max is ceil(max(data[n]))
end
end
# Create the empty histogram
histogram = []
for n in ( 0 .. max )
histogram . push ( 0 )
end
# Fill the histogram
for n in ( 0 ... data . length )
histogram [ data [ n ]. to_i ] += 1
end
# Print the histogram
pp histogram
puts
for n in ( 0 .. max )
puts "*" * histogram [ n ]
end
Here’s a very concise one-liner from the crowd:
0 . upto (( data = File . readlines ( 'random.txt' ) . collect { | e | e . chomp! . to_f }) . max . to_i ) { | i | puts i . to_s + " " + data . select { | a | a == i } . size . to_s }
Here’s Owen’s refactoring:
require 'pp'
histogram = []
File . readlines ( 'random.txt' ) . each do | value |
i = value . chomp . to_i
histogram [ i ] ||= 0
histogram [ i ] += 1
end
# Print the histogram
pp histogram
puts
histogram . each { | v | puts "*" * v }
Here’s Sam Livingstone Gray’s refactoring
#!/usr/bin/env ruby
require 'pp'
# Get data from a file, turn it in to a float, and find the max
module Enumerable
def value_counts
h = Hash . new ( 0 )
each { | e | h [ e ] += 1 }
h
end
end
lines = File . readlines ( 'random.txt' )
histogram = lines . map { | line | line . chomp . to_i } . value_counts
# Print the histogram
pp histogram
puts
histogram . keys . sort . each { | n | puts '*' * histogram [ n ] }
I really like this one. Sam created a simple extension to Enumerable that I can see using over and over again.
Here’s what I came up with, with some debugging help from the group
#!/usr/bin/env ruby
require 'pp'
data = File . readlines ( 'random.txt' ) . collect { | datum | datum . chomp . to_f }
max = data . max
histogram = data . inject ( [ 0 ] * ( max + 1 )) do | histogram , datum |
histogram [ datum . to_i ] += 1
histogram
end
pp histogram
histogram . each do | bucket |
puts "*" * bucket
end
view the Markdown source of this page