secret
Last active

  • Download Gist
robisonsantos.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
#!/usr/bin/ruby -w
 
# Robison WR Santos
# Brazil
# rwrsantos@gmail.com
#
# This method calculates the average time given a list with all time values
# you want the count.
# It assumes that the first value on the list is the lesser value of it.
# By this assumption, it treats this value as the base to do all the computation
# and find the most probable average time of the passed list.
 
# How many seconds do we have in one day?
A_DAY = 24 * 60 * 60
 
def average_time_of_day(times_str)
# transforms all str_time into float time representation and store them into
# an array
times = times_str.map {|t| Time.parse(t).to_f}
# get the first element as a basis
base_time = times.delete_at(0)
# get all deltas between the current t time and the base time
# as Time.parse assumes the time from today, if the current time is lesser than
# the base time, we assume that it comes from the next day.
deltas = times.map {|t| t >= base_time ? t - base_time : (t + A_DAY) - base_time}
# sum all the deltas
deltas_sum = deltas.inject(0) {|s,d| s + d}
# calculate the average delta
average_delta = deltas_sum / (times.size + 1)
# calculate the average time by the sum of the average_delta and the base_time
Time.at(base_time + average_delta).strftime("%I:%M%p")
end
 
# tests
require 'test/unit'
 
class TestAverageTimeOfDay < Test::Unit::TestCase
def test_five_values_on_the_same_range
times_str = ['11:50pm','11:52pm','11:54pm','11:56pm','11:58pm']
assert_equal '11:54PM', average_time_of_day(times_str)
end
def test_four_values_on_the_same_range
times_str = ['11:50pm','11:52pm','11:54pm','11:56pm']
assert_equal '11:53PM', average_time_of_day(times_str)
end
def test_time_passes_from_midnight
times_str = ['11:51pm','11:56pm','12:01am','12:06am','12:11am']
assert_equal '12:01AM', average_time_of_day(times_str)
end
def test_time_passes_from_noon
times_str = ['11:51am','11:56am','12:01pm','12:06pm','12:11pm']
assert_equal '12:01PM', average_time_of_day(times_str)
end
def test_three_value_on_the_same_range
times_str = ['6:41am','6:51am','7:01am']
assert_equal '06:51AM', average_time_of_day(times_str)
end
def test_only_one_value_in_the_morning
times_str = ['6:41am']
assert_equal '06:41AM', average_time_of_day(times_str)
end
def test_only_one_value_in_the_afternoon
times_str = ['6:41pm']
assert_equal '06:41PM', average_time_of_day(times_str)
end
def test_twelve_hours_different_from_morning
times_str = ['6:41am','6:41pm']
assert_equal '12:41PM', average_time_of_day(times_str)
end
def test_twelve_hours_different_from_afternoon
times_str = ['6:41pm','6:41am']
assert_equal '12:41AM', average_time_of_day(times_str)
end
def test_mixed_time_post_midnight_with_the_lesser_value_before_midnight
times_str = ['11:10pm','11:15pm','12:03am','11:30pm','11:48pm']
assert_equal '11:33PM', average_time_of_day(times_str)
end
def test_mixed_time_post_midnight_with_the_lesser_value_after_midnight
times_str = ['12:03am','11:10pm','11:15pm','11:30pm','11:48pm']
assert_equal '06:45PM', average_time_of_day(times_str)
end
def test_all_values_the_same
times_str = ['11:10pm','11:10pm','11:10pm','11:10pm','11:10pm']
assert_equal '11:10PM', average_time_of_day(times_str)
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.