{"id":25651587,"url":"https://github.com/wise-home/quantity","last_synced_at":"2025-04-15T23:01:30.633Z","repository":{"id":39601641,"uuid":"234272545","full_name":"wise-home/quantity","owner":"wise-home","description":"An Elixir data structure that encapsulates a decimal value with a unit","archived":false,"fork":false,"pushed_at":"2025-04-11T10:40:52.000Z","size":231,"stargazers_count":14,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-11T10:43:01.127Z","etag":null,"topics":["elixir","erlang"],"latest_commit_sha":null,"homepage":"https://hex.pm/packages/quantity","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wise-home.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-16T08:34:19.000Z","updated_at":"2025-04-11T10:31:20.000Z","dependencies_parsed_at":"2024-03-18T09:47:05.779Z","dependency_job_id":"7febdb53-e15c-4cad-ab01-2a96cfa7359d","html_url":"https://github.com/wise-home/quantity","commit_stats":{"total_commits":203,"total_committers":9,"mean_commits":"22.555555555555557","dds":0.5024630541871922,"last_synced_commit":"6bf7e13d5946b5bf4e741e335fde1f5fdc61b49c"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wise-home%2Fquantity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wise-home%2Fquantity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wise-home%2Fquantity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wise-home%2Fquantity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wise-home","download_url":"https://codeload.github.com/wise-home/quantity/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248383809,"owners_count":21094611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","erlang"],"created_at":"2025-02-23T17:17:47.996Z","updated_at":"2025-04-15T23:01:30.594Z","avatar_url":"https://github.com/wise-home.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Quantity\n\n![](https://github.com/wise-home/quantity/workflows/CI/badge.svg)\n\nA `Quantity` is an Elixir data structure that encapsulates values with units. This data structure can be used to carry values and units through calculations using the calculation functions in the Quantity library.\n\n```elixir\n~Q[200.345 kWh] |\u003e Quantity.add(~Q[249.23 kWh])\n# {:ok, ~Q[449.575 kWh]}\n\n[\n  ~Q[13.49 second],\n  ~Q[12.39 second],\n  ~Q[4.49 second]\n]\n|\u003e Quantity.sum()\n# {:ok, ~Q[30.37 second]}\n\ncost = ~Q[0.40 $/banana]\namount = ~Q[2000 banana]\nQuantity.mult(cost, amount)\n# ~Q[800.00 $]\n```\n\n## Usage\n\n#### Creating Quantities\n\nA `Quantity` can be created in several ways, one is `Quantity.parse/1` or `Quantity.parse!/1`, which parses a Quantity from a string:\n\n```elixir\nQuantity.parse(\"200.345 EUR\")\n# {:ok, ~Q[200.345 EUR]}\n\nQuantity.parse!(\"200.345 EUR\")\n# ~Q[200.345 EUR]\n\nQuantity.parse!(\"20.67 EUR/beer\")\n# ~Q[20.67 EUR/beer] or the same as\n# Quantity.new(~d[20.67], {:div, \"EUR\", \"beer\"})\n\nQuantity.parse!(\"15.0 m*m\")\n# ~Q[15.0 m*m] or the same as\n# Quantity.new(~d[15.0], {:mult, \"m\", \"m\"})\n```\n\nNote: When complex units are used, the parse function allows for :div and :mult of the form `a*b*c/d*e*f`, which\nmathematically is interpretted as (a*b*c)/(d*e*f).\n\n```elixir\n~Q[1 a*b*c/d*e*f].unit\n# {:div, {:mult, \"a\", {:mult, \"b\", \"c\"}}, {:mult, \"d\", {:mult, \"e\", \"f\"}}}\n```\n\nQuantity supports unit-less quantities, which acts as decimals. Technically they have the unit `1`\n~Q[42].unit\n# 1\n\nThe `Quantity` module also has `new/2` which creates a `Quantity` from a `Decimal.t()` and a `String.t()`:\n\n```elixir\nQuantity.new(Decimal.new(\"300.445\"), \"km\")\n# ~Q[300.445 km]\n```\n\nAnd lastly a `Quantity` can be created from a value, an exponent and a unit:\n\n```elixir\nQuantity.new(6578, -2, \"second\")\n# ~Q[65.78 second]\n```\n\n#### Addition and subtraction\n\nBasic math can be done using the `add/2` and `sub/2` functions along with their `add!/2` and `sub!/2` siblings:\n\n```elixir\nQuantity.add(~Q[500 mL coffee], ~Q[250 mL coffee])\n# {:ok, ~Q[750 mL coffee]}\n\nQuantity.add!(~Q[500 mL coffee], ~Q[250 mL coffee])\n# ~Q[750 mL coffee]\n\nQuantity.sub(~Q[250 gram], ~Q[125 gram])\n# {:ok, ~Q[125 gram]}\n\nQuantity.sub!(~Q[250 gram], ~Q[125 gram])\n# ~Q[125 gram]\n```\n\n#### Summation\n\nTo sum non-empty lists with identical units, `sum/1` and `sum!/1` can be used:\n\n```elixir\nlap_times = [\n  ~Q[4.24 second],\n  ~Q[4.59 second],\n  ~Q[5.22 second],\n  ~Q[3.99 second]\n]\n\nlap_times |\u003e Quantity.sum()\n# {:ok, ~Q[18.04 second]}\n\nlap_times |\u003e Quantity.sum!()\n# ~Q[18.04 second]\n\n[] |\u003e Quantity.sum()\n# :error\n```\n\nWhen a list is empty, `Quantity` doesn't know what precision and unit the result should have. If a `Quantity` with value 0 is desired when summing an empty list, one can use `sum/3` and `sum!/3`:\n\n```elixir\nsales_2018 = []\n\nsales_2019 = [\n  ~Q[1234.39 EUR],\n  ~Q[228.50 EUR]\n]\n\nsales_2018 |\u003e Quantity.sum(-2, \"EUR\")\n# {:ok, ~Q[0.00 EUR]}\n\nsales_2019 |\u003e Quantity.sum(-2, \"EUR\")\n# {:ok, ~Q[1462.89 EUR]}\n```\n\n#### Multiplication and division\n\nQuantity has support for arbitrary complex units with :div and :mult\n\n```elixir\ncost = ~Q[20.00 $]\namount = ~Q[50 banana]\ncost_per_banana = Quantity.div(cost, amount)\n# ~Q[0.40 $/banana]\n\nQuantity.div(~Q[50 bananas], ~Q[5 bananas])\n# ~Q[10]\n\nnew_amount = ~Q[2000 banana]\nQuantity.mult(cost_per_banana, new_amount)\n# ~Q[800.00 $]\n\nQuantity.mult(~Q[5 m], ~Q[4.3 m])\n# ~Q[21.5 m*m]\n\nQuantity.mult(~Q[5 m], ~d[20.01])\n# ~Q[100.05 m]\n\nQuantity.mult(~Q[10 m/s*s], ~Q[5 s])\n# ~Q[50 m/s]\n```\n\n#### The ~Q and ~d sigils\n\n`Quantity` has a special `sigil_Q/2` sigil, as seen above. Quantities can be created using the `~Q` sigil, and they are printed as `~Q` when inspected.\n\n```elixir\nimport Quantity.Sigils, only: [sigil_Q: 2]\n\n~Q[500 bananas]\n# ~Q[500 bananas]\n\n# Supports :mult and :div units\n~Q[0.54 $/banana]\n~Q[13.2 m*m]\n\n```\n\nAdditionally a `sigil_d/2` sigil is also present to easily create decimals:\n\n```elixir\nimport Quantity.Sigils, only: [sigil_d: 2]\n\n~d[123.456]\n#Decimal\u003c123.456\u003e\n```\n\n#### Data structure\n\nUnderneath, a `Quantity` is simply a map consisting of `value` and `unit`, where `value` is a `Decimal.t()` and `unit` a `String.t()`:\n\n```elixir\n~Q[99 problems] |\u003e IO.inspect(structs: false)\n%{\n  __struct__: Quantity,\n  unit: \"problems\",\n  value: %{__struct__: Decimal, coef: 99, exp: 0, sign: 1}\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwise-home%2Fquantity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwise-home%2Fquantity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwise-home%2Fquantity/lists"}