Skip to content

Commit

Permalink
Merge 3f251b8 into 88180b3
Browse files Browse the repository at this point in the history
  • Loading branch information
marian13 committed Mar 23, 2020
2 parents 88180b3 + 3f251b8 commit 5256068
Show file tree
Hide file tree
Showing 6 changed files with 626 additions and 68 deletions.
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Metrics/AbcSize:
Metrics/MethodLength:
Max: 15

Style/AsciiComments:
Enabled: No

Style/Lambda:
EnforcedStyle: literal

Expand Down
14 changes: 14 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,23 @@ GEM
tins (~> 1.6)
diff-lcs (1.3)
docile (1.3.2)
ffi (1.12.2)
jaro_winkler (1.5.4)
json (2.3.0)
listen (3.2.1)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
parallel (1.19.1)
parser (2.7.0.3)
ast (~> 2.4.0)
rainbow (3.0.0)
rake (12.3.3)
rb-fsevent (0.10.3)
rb-inotify (0.10.1)
ffi (~> 1.0)
rdoc (6.2.1)
rerun (0.13.0)
listen (~> 3.0)
reverse_coverage (0.1.1)
rspec (~> 3.8)
rexml (3.2.4)
Expand All @@ -48,6 +58,8 @@ GEM
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 1.7)
ruby-progressbar (1.10.1)
sdoc (1.1.0)
rdoc (>= 5.0)
simplecov (0.16.1)
docile (~> 1.1)
json (>= 1.8, < 3)
Expand All @@ -69,9 +81,11 @@ DEPENDENCIES
byebug (~> 10.0)
coveralls
rake (~> 12.0)
rerun
reverse_coverage
rspec (~> 3.0)
rubocop (~> 0.80.0)
sdoc
simplecov

BUNDLED WITH
Expand Down
199 changes: 175 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,21 @@

![alt text](https://raw.githubusercontent.com/marian13/basic_temperature/master/logo.png)

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.
`basic_temperature` is a Ruby library which provides a simple [value object](https://martinfowler.com/bliki/ValueObject.html) to work with temperatures and
allows to perform basic operations like conversion from Celsius to Kelvin, from Kelvin to Fahrenheit etc.


### Features
- Provides a `BasicTemperature` 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, Kelvin and Fahrenheit).
- Provides a `BasicTemperature` 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.
- Supports basic math operations like addition and subtraction.
- Tested against Ruby 2.3, 2.4, 2.5, 2.6 & 2.7. See [.travis-ci.yml](https://github.com/marian13/basic_temperature/blob/9b13cb9909b57c51bb5dc05a8989d07a314e67d6/.travis.yml) for the exact versions.
- Tested against Ruby 2.3, 2.4, 2.5, 2.6 & 2.7. See
[.travis-ci.yml](https://github.com/marian13/basic_temperature/blob/9b13cb9909b57c51bb5dc05a8989d07a314e67d6/.travis.yml)
for the exact versions.

## Installation

Expand Down Expand Up @@ -42,49 +48,194 @@ Or install it yourself as:

## Usage

### Creating Temperatures

A new temperature can be created in multiple ways:

- Using keyword arguments:

```ruby
require 'basic_temperature'
Temperature.new(degrees: 0, scale: :celsius)
```

temperature = BasicTemperature.new(degrees: 20, scale: :celsius)
# Scale can be one of celsius, kelvin or fahrenheit.
- Using positional arguments:

temperature.to_celsius
# => 20 Celsius
```ruby
Temperature.new(0, :celsius)
```

temperature.to_kelvin
# => 293 Kelvin
- Even more concise way using `Temperature.[]` (an alias of `Temperature.new`):

temperature.to_fahrenheit
# => 68 Fahrenheit
```ruby
Temperature[0, :celsius]
```

You can try to utilize `BasicTemperature#to_scale` if you need to convert temperatures dynamically, for example:
### Creating Temperatures from already existing temperature objects

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

For such cases, there are `set_degrees` and `set_scale`.

Since temperatures are [value objects](https://martinfowler.com/bliki/ValueObject.html), both methods returns
new instances.

Examples:

```ruby
temperature.to_scale(scale)
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
```

Temperatures can be compared between each other.
### Conversions

Temperatures can be converted to diffirent scales.

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

```ruby
temperature = BasicTemperature.new(degress: 0, scale: :celsius)
Temperature[20, :celsius].to_celsius
# => 20 °C

other = BasicTemperature.new(degress: 0, scale: :celsius)
Temperature[20, :celsius].to_fahrenheit
# => 68 °F

temperature == other
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.

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

All conversion formulas are taken from
[RapidTables](https://www.rapidtables.com/convert/temperature/index.html).

Conversion precision: 2 accurate digits after the decimal dot.

### Comparison

Temperature implements idiomatic [<=> spaceship operator](https://ruby-doc.org/core/Comparable.html) and mixes in [Comparable](https://ruby-doc.org/core/Comparable.html) module.

As a result, all methods from [Comparable](https://ruby-doc.org/core/Comparable.html) are available, e.g:

```ruby
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
```

When temperatures have different scales - conversion to common scale is handled under the hood.
Please note, if the second temperature has a different scale, the first temperature is automatically
converted to that scale before comparison.

```ruby
temperature = BasicTemperature.new(degress: 0, scale: :celsius)
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.

other = BasicTemperature.new(degress: 273.15, scale: :kelvin)
This means the following temperatures are considered as equal:

temperature == other
```ruby
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:

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

### Math

#### Addition/Subtraction.

```ruby
Temperature[20, :celsius] + Temperature[10, :celsius]
# => 30 °C

Temperature[20, :celsius] - Temperature[10, :celsius]
# => 10 °C
```

If second temperature has a different scale, first temperature is automatically converted to that scale
before `degrees` addition/subtraction.

```ruby
Temperature[283.15, :kelvin] + Temperature[10, :celsius]
# => 10 °C
```

Returned temperature will have the same scale as the second temperature.

It is possible to add/subtract numerics.

```ruby
Temperature[20, :celsius] + 10
# => 30 °C

Temperature[20, :celsius] - 10
# => 10 °C
```

In such cases, returned temperature will have the same scale as the first temperature.

Also [Ruby coersion mechanism](https://ruby-doc.org/core/Numeric.html#method-i-coerce) is supported.

```ruby
10 + Temperature[20, :celsius]
# => 30 °C

10 - Temperature[20, :celsius]
# => -10 °C
```

#### Negation

```ruby
-Temperature[20, :celsius]
# => -20 °C
```

## Versioning
Basic Temperature follows the [Semantic Versioning](https://semver.org/) standard.

Expand Down
2 changes: 2 additions & 0 deletions basic_temperature.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'byebug', '~> 10.0'
spec.add_development_dependency 'coveralls'
spec.add_development_dependency 'rake', '~> 12.0'
spec.add_development_dependency 'rerun'
spec.add_development_dependency 'reverse_coverage'
spec.add_development_dependency 'rspec', '~> 3.0'
spec.add_development_dependency 'rubocop', '~> 0.80.0'
spec.add_development_dependency 'sdoc'
spec.add_development_dependency 'simplecov'
end
Loading

0 comments on commit 5256068

Please sign in to comment.