Skip to content

A simple value object for basic temperature conversion operations.

License

Notifications You must be signed in to change notification settings

marian13/basic_temperature

Repository files navigation

Basic Temperature

Gem Version GitHub Actions CI Maintainability Ruby Style Guide Coverage Status Inline docs Patreon License: MIT

basic_temperature is a Ruby library which provides a simple value object to work with temperatures and allows to perform basic operations like conversion from Celsius to Kelvin, from Kelvin to Fahrenheit etc.

Features

  • Provides a Temperature class which encapsulates all information about a certain temperature, such as its amount of degrees and its scale.

  • Provides APIs for exchanging temperatures from one scale to another (currently Celsius, Fahrenheit, Kelvin and Rankine).

  • Allows comparing temperatures between each other.

  • Queries like boil_water?, freeze_water?.

  • Tested against Ruby 2.3, 2.4, 2.5, 2.6, 2.7, 3.0 and 3.1. See .github/workflows/ci.yml.

Dependencies

  • None.

Documentation

Installation

Gemfile:

gem 'basic_temperature', '~> 1.0.0'

And then run:

$ bundle install

And that's it.

You can access all the features of basic_temperature by creating instances of BasicTemperature::Temperature.

But there is a shorter form.

If Temperature constant was not used before in your app, you can add this line to your Gemfile:

gem 'basic_temperature', '~> 1.0.0', require: ['basic_temperature/alias']

This way BasicTemperature::Temperature class will be accesible simply by Temperature.

The following guide assumes you have chosen the shorter form.

If not, just replace all Temperature to BasicTemperature::Temperature.

Usage

Creating Temperatures

A new temperature can be created in multiple ways:

  • Using keyword arguments:
Temperature.new(degrees: 0, scale: :celsius)
  • Using positional arguments:
Temperature.new(0, :celsius)
  • Even more concise way using Temperature.[] (an alias of Temperature.new):
Temperature[0, :celsius]

Creating Temperatures from already existing temperature objects

Sometimes it is useful to create a new temperature from an already existing one.

For such cases, there are set_degrees and set_scale.

Since temperatures are value objects, both methods return new instances.

Examples:

temperature = Temperature[0, :celsius]
# => 0 °C

new_temperature = temperature.set_degrees(15)
# => 15 °C

temperature = Temperature[0, :celsius]
# => 0 °C

new_temperature = temperature.set_scale(:kelvin)
# => 0 K

Conversions

Temperatures can be converted to different scales.

Currently, the following scales are supported: Celsius, Fahrenheit, Kelvin and Rankine.

Temperature[20, :celsius].to_celsius
# => 20 °C

Temperature[20, :celsius].to_fahrenheit
# => 68 °F

Temperature[20, :celsius].to_kelvin
# => 293.15 K

Temperature[20, :celsius].to_rankine
# => 527.67 °R

If it is necessary to convert scale dynamically, to_scale method is available.

Temperature[20, :celsius].to_scale(scale)

All conversion formulas are taken from RapidTables.

Conversion precision: 2 accurate digits after the decimal dot.

Comparison

Temperature implements idiomatic <=> spaceship operator and mixes in Comparable module.

As a result, all methods from Comparable are available, e.g:

Temperature[20, :celsius] < Temperature[25, :celsius]
# => true

Temperature[20, :celsius] <= Temperature[25, :celsius]
# => true

Temperature[20, :celsius] == Temperature[25, :celsius]
# => false

Temperature[20, :celsius] > Temperature[25, :celsius]
# => false

Temperature[20, :celsius] >= Temperature[25, :celsius]
# => false

Temperature[20, :celsius].between?(Temperature[15, :celsius], Temperature[25, :celsius])
# => true

# Starting from Ruby 2.4.6
Temperature[20, :celsius].clamp(Temperature[20, :celsius], Temperature[25, :celsius])
# => 20 °C

Please note, if the second temperature has a different scale, the first temperature is automatically converted to that scale before comparison.

Temperature[20, :celsius] == Temperature[293.15, :kelvin]
# => true

IMPORTANT !!!

degrees are rounded to the nearest value with a precision of 2 decimal digits before comparison.

This means the following temperatures are considered as equal:

Temperature[20.020, :celsius] == Temperature[20.024, :celsius]
# => true

Temperature[20.025, :celsius] == Temperature[20.029, :celsius]
# => true

while these ones are treated as NOT equal:

Temperature[20.024, :celsius] == Temperature[20.029, :celsius]
# => false

Queries

Temperature[0, :celsius].boil_water?
# => false

Temperature[0, :celsius].freeze_water?
# => true

Versioning

Basic Temperature follows the Semantic Versioning standard.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/marian13/basic_temperature.

Development

Local Machine

  • Check specs:

    bundle exec rspec
  • Check linter:

    bundle exec rubocop
  • Update docs:

    bundle exec sdoc lib -T rails -o docs --github
  • Find missed docs:

    bundle exec inch
  • Check for vulnerable gem versions, insecure gem sources, etc...

    bundle exec bundle-audit check --update

Docker

  • Build container:

    docker build . -f docker/3.1/Dockerfile -t basic_temperature:3.1
  • Run specs inside the container:

    docker run --rm -it basic_temperature:3.1 bundle exec rspec
  • Interactive Bash shell:

    docker run --rm -it basic_temperature:3.1 bash
  • Run container with volume (share gem folder between host and container):

    docker run --rm -it -v $(pwd):/gem basic_temperature:3.1 bash
  • Ruby REPL with already required gem files:

    docker run --rm -it basic_temperature:3.1 bin/console
  • 3.1 can be replaced by 2.3, 2.4, 2.5, 2.6, 2.7, and 3.0.

License

The gem is available as open-source under the terms of the MIT License.

Copyright (c) 2022 Marian Kostyk.