Avatar of davearonson

davearonson's solution

to Gigasecond in the Ruby Track

Published at Jul 13 2018 · 5 comments
Instructions
Test suite
Solution

Note:

This solution was written on an old version of Exercism. The tests below might not correspond to the solution code, and the exercise may have changed since this code was written.

Calculate the moment when someone has lived for 10^9 seconds.

A gigasecond is 10^9 (1,000,000,000) seconds.


For installation and learning resources, refer to the exercism help page.

For running the tests provided, you will need the Minitest gem. Open a terminal window and run the following command to install minitest:

gem install minitest

If you would like color output, you can require 'minitest/pride' in the test file, or note the alternative instruction, below, for running the test file.

Run the tests from the exercise directory using the following command:

ruby gigasecond_test.rb

To include color from the command line:

ruby -r minitest/pride gigasecond_test.rb

Source

Chapter 9 in Chris Pine's online Learn to Program tutorial. http://pine.fm/LearnToProgram/?Chapter=09

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

gigasecond_test.rb

require 'minitest/autorun'
require_relative 'gigasecond'

# Common test data version: 1.0.0 61e7d70
class GigasecondTest < Minitest::Test
  def test_date_only_specification_of_time
    # skip
    assert_equal Time.utc(2043, 1, 1, 1, 46, 40), Gigasecond.from(Time.utc(2011, 4, 25, 0, 0, 0))
  end

  def test_second_test_for_date_only_specification_of_time
    skip
    assert_equal Time.utc(2009, 2, 19, 1, 46, 40), Gigasecond.from(Time.utc(1977, 6, 13, 0, 0, 0))
  end

  def test_third_test_for_date_only_specification_of_time
    skip
    assert_equal Time.utc(1991, 3, 27, 1, 46, 40), Gigasecond.from(Time.utc(1959, 7, 19, 0, 0, 0))
  end

  def test_full_time_specified
    skip
    assert_equal Time.utc(2046, 10, 2, 23, 46, 40), Gigasecond.from(Time.utc(2015, 1, 24, 22, 0, 0))
  end

  def test_full_time_with_day_roll_over
    skip
    assert_equal Time.utc(2046, 10, 3, 1, 46, 39), Gigasecond.from(Time.utc(2015, 1, 24, 23, 59, 59))
  end

  # Problems in exercism evolve over time, as we find better ways to ask
  # questions.
  # The version number refers to the version of the problem you solved,
  # not your solution.
  #
  # Define a constant named VERSION inside of the top level BookKeeping
  # module, which may be placed near the end of your file.
  #
  # In your file, it will look like this:
  #
  # module BookKeeping
  #   VERSION = 1 # Where the version number matches the one in the test.
  # end
  #
  # If you are curious, read more about constants on RubyDoc:
  # http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html

  def test_bookkeeping
    skip
    assert_equal 6, BookKeeping::VERSION
  end
end
class Gigasecond

  VERSION = 1

  def self.from(start_time)
    start_time + SECONDS_IN_GIGASECOND
  end

  private

  SECONDS_IN_GIGASECOND = 1e9

end

Community comments

Find this solution interesting? Ask the author a question to learn more.
Avatar of acamino

@davearonson This version is looking good.

IMHO SECONDS_IN_GIGASECOND is redundant, you can have a look at giga definition, GIGASECOND is good enough.

Use SECONDS_IN_GIGASECOND is equivalent to have something like METERS_IN_KILOMETER, what do you think?

Avatar of davearonson

I see what you mean, with the ${UNIT}S_IN_${MULTIPLIER}${UNIT}. Two hard things and all that. :-) GIGASECOND would be fine too, but SECONDS_IN_& also makes it clear that the variable is expected to be in seconds, vs., say, milliseconds or days. Having times in milliseconds, when practically everything else wants seconds, has bitten me before. coughJavaScriptcough. On the other claw, one could go even shorter, with just GIGA -- if it were in Rails I might be tempted to do that, for "start_time + GIGA.seconds"....

Avatar of acamino

@davearonson, I like the explanation about why did you include the explicit transformation unit, I'm not totally sold, but I guess at this point this is more like a preference of style.

If I think for something like a kilometre the natural transformation is meters, I'm not thinking in another unit but the base one. The same idea is applicable to gigasecond.

if it were in Rails I might be tempted to do that, for "start_time + GIGA.seconds"

I disagree with what you said, GIGA.second implies to write some class GIGA and expose a public method seconds just to hold the concept of a gigasecond, that should be a huge indirection. An indirection adds more complexity to any solution, and those should be avoided.

Avatar of davearonson

By GIGA.seconds I only meant to declare GIGA as a constant, and then use the stuff that Rails (in this case, ActiveSupport) adds to Numeric, as seen at http://api.rubyonrails.org/classes/Numeric.html (and in particular http://api.rubyonrails.org/classes/Numeric.html#method-i-seconds). It's possible someone might think it's a class name, since it starts with a capital and has a dot after it which might indicate a class method, but since it's in all-caps, I'd think it would be clear that it's a (normal) constant.

On the other claw, I am starting to think that just calling the thing GIGASECOND in the first place would indeed be the best compromise. A reader would clearly see from the names that we're adding a time and an amount of time. They probably don't need to know that one is "seconds since epoch" and the other is an integer, as opposed to a Time or DateTime plus a TimeInterval or some such thing.

Avatar of acamino

Thanks for clarifying the idea behind GIGA.seconds I really appreciate it.

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?