Skip to content

Instantly share code, notes, and snippets.

@schwehr
Last active March 17, 2023 20:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schwehr/3dba211da336b9a6cbdffc75db9f2ab6 to your computer and use it in GitHub Desktop.
Save schwehr/3dba211da336b9a6cbdffc75db9f2ab6 to your computer and use it in GitHub Desktop.
Experiments with crafting unit strings in jsonnet
// SPDX-License-Identifier: Apache-2.0
// Copyright 2023 Google Inc. All Rights Reserved.
// Created by Dan Pencoske
local unit_obj = {
label: error 'provide a label',
pow(exp): '%s^%d' % [self.label, exp],
per(denom): '%s / %s' % [
self.label,
if std.isString(denom) then denom
else denom.label
],
times(units): std.join(' ', [self.label] + [
if std.isString(u) then u else u.label
for u in (
if std.isArray(units) then units
else [units]
)
]),
};
local unit(label) = unit_obj {
label: label
};
local meter = unit('m');
local second = unit('s');
local kilogram = unit('kg');
local ampere = unit('A');
{
meter: meter.label,
second: second.label,
kilogram: kilogram.label,
ampere: ampere.label,
velocity: meter.per(second),
acceleration: meter.per(second.pow(2)),
newton: unit(
kilogram.times(meter)
).per(second.pow(2)),
volt: unit(
kilogram.times(meter.pow(2))
).per(unit(second.pow(3)).times(ampere)),
}
// Yields:
//
// {
// "acceleration": "m / s^2",
// "ampere": "A",
// "kilogram": "kg",
// "meter": "m",
// "newton": "kg m / s^2",
// "second": "s",
// "velocity": "m / s",
// "volt": "kg m^2 / s^3 A"
// }
{
"base": {
"kelvin": "K",
"kilogram": "kg",
"meter": "m",
"second": "s"
},
"derived_calculated": {
"acceleration": "m / s^2",
"energy_density": "J / m^3",
"specific_entropy": "J / K kg",
"torque": "N m",
"velocity": "m / s"
},
"derived_named": {
"joule": "J",
"newton": "N"
}
}
// SPDX-License-Identifier: Apache-2.0
// Copyright 2023 Google Inc. All Rights Reserved.
// Created by Dan Pencoske
// See also: https://github.com/google/earthengine-catalog/blob/main/catalog/units.libsonnet
// You can try this on https://jsonnet.org in the editable examples
{
pow(unit, exp):: '%s^%d' % [unit, exp],
squared(unit):: $.pow(unit, 2),
cubed(unit):: $.pow(unit, 3),
per(num, denom):: '%s / %s' % [num, denom],
times(units):: std.join(' ', units),
base: {
second: 's',
meter: 'm',
kilogram: 'kg',
kelvin: 'K',
},
derived_named: {
newton: 'N',
joule: 'J',
},
derived_calculated: {
velocity: $.per(
$.base.meter, $.base.second
),
acceleration: $.per(
$.base.meter, $.squared($.base.second)
),
torque: $.times([
$.derived_named.newton, $.base.meter
]),
energy_density: $.per(
$.derived_named.joule,
$.cubed($.base.meter)
),
specific_entropy: $.per(
$.derived_named.joule,
$.times([
$.base.kelvin, $.base.kilogram
])
),
},
}
// SPDX-License-Identifier: Apache-2.0
// Copyright 2023 Google Inc. All Rights Reserved.
// Created by Dan Pencoske
local pow(unit, exp) = '%s^%d' % [unit, exp];
local squared(unit) = pow(unit, 2);
local cubed(unit) = pow(unit, 3);
local composed(units, per=[]) = {
# units: Union[str, list[str]]
# per: Optional[Union[str, list[str]]
local num = (
if std.isString(units) then units
else std.join(' ', units)
),
local denom = (
if std.isString(per) then per
else std.join(' ', per)
),
label: (
if denom == '' then num
else '%s / %s' % [num, denom]
),
}.label;
{
base: {
second: 's',
meter: 'm',
kilogram: 'kg',
kelvin: 'K',
},
derived_named: {
newton: 'N',
joule: 'J',
},
derived_calculated: {
velocity: composed(
$.base.meter, per=$.base.second
),
acceleration: composed(
$.base.meter, per=squared($.base.second)
),
torque: composed(
[$.derived_named.newton, $.base.meter]
),
energy_density: composed(
$.derived_named.joule,
per=cubed($.base.meter)
),
specific_entropy: composed(
$.derived_named.joule,
per=[$.base.kelvin, $.base.kilogram]
),
newton: composed(
[$.base.kilogram, $.base.meter],
per=squared($.base.second)
),
},
}
// {
// "base": {
// "kelvin": "K",
// "kilogram": "kg",
// "meter": "m",
// "second": "s"
// },
// "derived_calculated": {
// "acceleration": "m / s^2",
// "energy_density": "J / m^3",
// "newton": "kg m / s^2",
// "specific_entropy": "J / K kg",
// "torque": "N m",
// "velocity": "m / s"
// },
// "derived_named": {
// "joule": "J",
// "newton": "N"
// }
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment