Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add UnitGroup docs; import UnitGroup in REPL #239

Merged
merged 3 commits into from
May 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,112 @@ scala> val sum = List(USD(100), USD(10)).sum
sum: squants.market.Money = 110.0 USD
```

## Unit groups

Squants provides an experimental API for grouping related `UnitOfMeasure` values together.
This are called `UnitGroup`s. Squants provides `UnitGroup` implementations for the SI, the US Customary system, and various other systems. End-users can create their own ad-hoc `UnitGroup`s for `UnitOfMeasure`s in a related dimension.

The `UnitGroup` trait defines two public fields: `units`, a `Set[UnitOfMeasure]`, and `sortedUnits`, which contains `units` sorted in ascending order.

### SI UnitGropus

Almost every `Dimension` in Squants has SI Units (with the exception of `Information`
and `Money`). To avoid boilerplate, Squants generates `UnitGroup`s for SI using implicits.

There are two `UnitGroup`s provided for SI: "strict" and "expanded." Strict only includes SI
UnitOfMeasure defined in the SI; "expanded" includes [non-SI units that are commonly used in](http://www.bipm.org/en/publications/si-brochure/table6.html)
SI, such as litre, hectare, hour, minute, etc). See the linked document for a detailed list.

To summon the strict SI `UnitGroup` for `Length`, you would use this code:

```scala
import squants.space.Length
// import squants.space.Length

import squants.unitgroups.ImplicitDimensions.space._
// import squants.unitgroups.ImplicitDimensions.space._

import squants.unitgroups.UnitGroup
// import squants.unitgroups.UnitGroup

import squants.unitgroups.si.strict.implicits._
// import squants.unitgroups.si.strict.implicits._

val siLengths: UnitGroup[Length] = implicitly[UnitGroup[Length]]
// siLengths: squants.unitgroups.UnitGroup[squants.space.Length] = squants.unitgroups.si.strict.package$implicits$$anon$1@1045e253
```

To print out units and their conversion factors to the primary SI unit, you could use this code:

```scala
import squants.{Quantity, UnitOfMeasure}
// import squants.{Quantity, UnitOfMeasure}

def mkConversionFactor[A <: Quantity[A]](uom: UnitOfMeasure[A]): Double = {
val one = uom(1)
one.to(one.dimension.siUnit)
}
// mkConversionFactor: [A <: squants.Quantity[A]](uom: squants.UnitOfMeasure[A])Double

def mkTuple[A <: Quantity[A]](uom: UnitOfMeasure[A]): (String, Double) = {
(uom.symbol, mkConversionFactor(uom))
}
// mkTuple: [A <: squants.Quantity[A]](uom: squants.UnitOfMeasure[A])(String, Double)

siLengths.sortedUnits.toList.map(mkTuple).foreach(println)
// (nm,1.0E-9)
// (µm,1.0E-6)
// (mm,0.001)
// (cm,0.01)
// (dm,0.1)
// (m,1.0)
// (dam,10.0)
// (hm,100.0)
// (km,1000.0)
```

Note that `UnitGroup`'s `sortedUnits` field is a `SortedSet`, so before mapping over it,
you will probably want to convert it to a List, otherwise the output may be resorted.

### Non-SI UnitGroups

Other `UnitGroup` definitions don't use implicits. For example, `squants.unitgroups.uscustomary.space.UsCustomaryLiquidVolumes` or `squants.unitgroups.misc.TroyMasses` can be imported and used directly.

### Creating an ad-hoc UnitGroup

To create an ad-hoc `UnitGroup` just implement the trait. For example, to make a US cooking measure `UnitGroup`:

```scala
import squants.{Quantity, Dimension}
// import squants.{Quantity, Dimension}

import squants.space._
// import squants.space._

import squants.unitgroups.UnitGroup
// import squants.unitgroups.UnitGroup

val usCookingUnitGroup = new UnitGroup[Volume] {
// units don't have to be specified in-order.
val units: Set[UnitOfMeasure[Volume]] = Set(UsPints, UsGallons, Teaspoons, Tablespoons, UsQuarts, FluidOunces)
}
// usCookingUnitGroup: squants.unitgroups.UnitGroup[squants.space.Volume]{val units: Set[squants.UnitOfMeasure[squants.space.Volume]]} = $anon$1@25f41c10

// squants automatically sorts units
usCookingUnitGroup.sortedUnits.foreach(println)
// squants.space.Teaspoons$@797a286f
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this output includes memory locations, this part of the README will change every time tut is run.

As a future enhancement we should provide a stable toString for UnitOfMeasure that outputs the unit's name.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or reduce the top README to a placeholder and put the documentation on github site, The README is getting fairly large

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I've been thinking we should split the README up into multiple smaller files. Probably just have the sbt instructions and a small quick example in the main README. I can tackle that in a later PR after this round gets merged.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to export this documentation to squants.com, That still shows version 0.6.2 😄

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I think updating squants.com should be the next priority after this release.

// squants.space.Tablespoons$@497f04bc
// squants.space.FluidOunces$@d657483
// squants.space.UsPints$@4db94d06
// squants.space.UsQuarts$@4ea9b1e8
// squants.space.UsGallons$@66d4bb6d
```

The `UnitGroup` values provided with Squants are only samples and aren't intended to be exhaustive.
We encourage users to make their own `UnitGroup` defintitions and submit them as PRs if they're generally
applicable.


## Type Hierarchy
The type hierarchy includes the following core types: Quantity, Dimension, and UnitOfMeasure

Expand Down Expand Up @@ -1200,6 +1306,7 @@ trait LoadRoute extends HttpService {
* Shadaj Laddad ([shadaj](https://github.com/shadaj))
* Ian McIntosh ([cranst0n](https://github.com/cranst0n))
* Doug Hurst ([robotsnowfall](https://github.com/robotsnowfall))
* Philip Axelrod ([Paxelord](https://github.com/paxelord))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see you add @paxelord here, so no need to update PR #238

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha. Yes. I just added a comment to #238 about this. No problem.


## Code of Conduct

Expand Down
1 change: 1 addition & 0 deletions project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ object Console {
squants.space._,
squants.thermal._,
squants.time._,
squants.unitgroups.UnitGroup,
squants.DimensionlessConversions._,
squants.electro.CapacitanceConversions._,
squants.electro.ConductivityConversions._,
Expand Down
75 changes: 74 additions & 1 deletion shared/src/main/tut/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,79 @@ implicit val moneyNum = new MoneyNumeric()
val sum = List(USD(100), USD(10)).sum
```

## Unit groups
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a refresher, this generates the top README.md right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this will build the main README.


Squants provides an experimental API for grouping related `UnitOfMeasure` values together.
This are called `UnitGroup`s. Squants provides `UnitGroup` implementations for the SI, the US Customary system, and various other systems. End-users can create their own ad-hoc `UnitGroup`s for `UnitOfMeasure`s in a related dimension.

The `UnitGroup` trait defines two public fields: `units`, a `Set[UnitOfMeasure]`, and `sortedUnits`, which contains `units` sorted in ascending order.

### SI UnitGropus

Almost every `Dimension` in Squants has SI Units (with the exception of `Information`
and `Money`). To avoid boilerplate, Squants generates `UnitGroup`s for SI using implicits.

There are two `UnitGroup`s provided for SI: "strict" and "expanded." Strict only includes SI
UnitOfMeasure defined in the SI; "expanded" includes [non-SI units that are commonly used in](http://www.bipm.org/en/publications/si-brochure/table6.html)
SI, such as litre, hectare, hour, minute, etc). See the linked document for a detailed list.

To summon the strict SI `UnitGroup` for `Length`, you would use this code:

```tut:reset:book
import squants.space.Length
import squants.unitgroups.ImplicitDimensions.space._
import squants.unitgroups.UnitGroup
import squants.unitgroups.si.strict.implicits._
val siLengths: UnitGroup[Length] = implicitly[UnitGroup[Length]]
```

To print out units and their conversion factors to the primary SI unit, you could use this code:

```tut:book
import squants.{Quantity, UnitOfMeasure}

def mkConversionFactor[A <: Quantity[A]](uom: UnitOfMeasure[A]): Double = {
val one = uom(1)
one.to(one.dimension.siUnit)
}

def mkTuple[A <: Quantity[A]](uom: UnitOfMeasure[A]): (String, Double) = {
(uom.symbol, mkConversionFactor(uom))
}

siLengths.sortedUnits.toList.map(mkTuple).foreach(println)
```

Note that `UnitGroup`'s `sortedUnits` field is a `SortedSet`, so before mapping over it,
you will probably want to convert it to a List, otherwise the output may be resorted.

### Non-SI UnitGroups

Other `UnitGroup` definitions don't use implicits. For example, `squants.unitgroups.uscustomary.space.UsCustomaryLiquidVolumes` or `squants.unitgroups.misc.TroyMasses` can be imported and used directly.

### Creating an ad-hoc UnitGroup

To create an ad-hoc `UnitGroup` just implement the trait. For example, to make a US cooking measure `UnitGroup`:

```tut:book
import squants.{Quantity, Dimension}
import squants.space._
import squants.unitgroups.UnitGroup

val usCookingUnitGroup = new UnitGroup[Volume] {
// units don't have to be specified in-order.
val units: Set[UnitOfMeasure[Volume]] = Set(UsPints, UsGallons, Teaspoons, Tablespoons, UsQuarts, FluidOunces)
}

// squants automatically sorts units
usCookingUnitGroup.sortedUnits.foreach(println)
```

The `UnitGroup` values provided with Squants are only samples and aren't intended to be exhaustive.
We encourage users to make their own `UnitGroup` defintitions and submit them as PRs if they're generally
applicable.


## Type Hierarchy
The type hierarchy includes the following core types: Quantity, Dimension, and UnitOfMeasure

Expand Down Expand Up @@ -935,7 +1008,7 @@ trait LoadRoute extends HttpService {
* Shadaj Laddad ([shadaj](https://github.com/shadaj))
* Ian McIntosh ([cranst0n](https://github.com/cranst0n))
* Doug Hurst ([robotsnowfall](https://github.com/robotsnowfall))
* Philip Axelrod ([Paxelord]|(https://github.com/paxelord))
* Philip Axelrod ([Paxelord](https://github.com/paxelord))

## Code of Conduct

Expand Down