Skip to content

Instantly share code, notes, and snippets.

@jmhodges
Created April 20, 2009 03:01
Show Gist options
  • Save jmhodges/98338 to your computer and use it in GitHub Desktop.
Save jmhodges/98338 to your computer and use it in GitHub Desktop.
# Requirements: Pass the unit tests at the bottom (in a non-trivial
# way) and be cleanly translatable to Java. That means no block and
# yield magic allowed nor setting values in the condition statements
# of loops.
require 'test/unit'
class UserBuffer
def initialize(arr)
@file = arr
@last_values = {}
end
def read_user
if @last_values.empty?
user_id,item_id,value = get_split_line
else
user_id, item_id, value = @last_values[:user_id], @last_values[:item_id], @last_values[:value]
end
output_user_id = user_id
ratings = {}
while true
if user_id == output_user_id && !(output_user_id.nil? && user_id.nil?)
ratings[item_id] = value
user_id, item_id, value = get_split_line
else
if !user_id.nil?
@last_values = {:user_id => user_id, :item_id => item_id, :value => value}
else
@last_values = {}
end
break
end
end
if output_user_id
{
:user_id => output_user_id,
:ratings => ratings
}
end
end
def get_split_line
foo = @file.shift
if foo
foo.split(" ")
else
[nil,nil,nil]
end
end
end
class TestCase < Test::Unit::TestCase
def test_reads_one_line_file
file = ["1 2 3"]
b = UserBuffer.new(file)
h = b.read_user
assert_equal '1', h[:user_id]
assert_equal({'2' => '3'}, h[:ratings])
end
def test_reads_two_lines_one_user
file = ['1 2 3', '1 3 4']
b = UserBuffer.new(file)
h = b.read_user
assert_equal '1', h[:user_id]
assert_equal '3', h[:ratings]['2']
assert_equal '4', h[:ratings]['3']
end
def test_two_lines_two_users
file = ['1 2 3', '2 3 4']
b = UserBuffer.new(file)
h = b.read_user
assert_equal '1', h[:user_id], "first user id"
assert_equal '3', h[:ratings]['2'], "rating value for first user is 3"
assert_equal 1, h[:ratings].size, "only one rating for first user"
h = b.read_user
assert_equal '2', h[:user_id], 'second user id'
assert_equal '4', h[:ratings]['3'], 'rating value for second user is 4'
assert_equal 1, h[:ratings].size, 'only one rating for second user'
end
def test_one_line_file_three_reads
file = ['1 2 3']
b = UserBuffer.new(file)
assert_not_nil b.read_user
assert_nil b.read_user
assert_nil b.read_user
end
def test_three_two_users_two_ratings_at_end
file = ['1 2 3', '2 3 4', '2 2 1']
b = UserBuffer.new(file)
b.read_user
h = b.read_user
assert_equal '2', h[:user_id], 'second user id'
assert_equal '4', h[:ratings]['3'], 'rating for 4'
assert_equal '1', h[:ratings]['2'], 'rating for 2'
assert_equal 2, h[:ratings].size, 'two ratings'
assert_nil b.read_user
end
def test_longer
file = ['1 2 3', '1 7 8', '1 9 3', '1 10 11', '2 4 3', '2 3 3', '3 9 2', '3 10 2', '3 4 2']
b = UserBuffer.new(file)
h = b.read_user
assert_equal 4, h[:ratings].size
assert_equal '1', h[:user_id]
h = b.read_user
assert_equal 2, h[:ratings].size
assert_equal '2', h[:user_id]
h = b.read_user
assert_equal 3, h[:ratings].size
assert_equal '3', h[:user_id]
h = b.read_user
assert_nil h
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment