Giter Club home page Giter Club logo

raku-physics-measure's Introduction

License: Artistic-2.0 raku-physics-measure -> DH

raku-Physics-Measure

Provides Measure objects that have value, units and error and can be used in many common physics calculations. Uses Physics::Unit and Physics::Error.

Instructions

zef --verbose install Physics::Measure

and, conversely, zef uninstall Physics::Measure

Synopsis

use lib '../lib';
use Physics::Measure :ALL;

# Basic mechanics example (SI units)...

# Define a distance and a time
my \d = 42m;                say ~d;     #42 m      (Length)
my \t = 10s;                say ~t;     #10 s      (Time)

# Calculate speed and acceleration
my \u = d / t;              say ~u;     #4.2 m/s   (Speed)
my \a = u / t;              say ~a;     #0.42 m/s^2 (Acceleration)

# Define mass and calculate force
my \m = 25kg;               say ~m;     #25 kg     (Mass)
my \f = m * a;              say ~f;     #10.5 N    (Force)

# Calculate final speed and distance travelled
my \v = u + a*t;            say ~v;     #8.4 m/s   (Speed)
my \s = u*t + (1/2) * a * t*t;  say ~s; #63 m      (Length)

# Calculate potential energy 
my \pe = f * s;             say ~pe;    #661.5 J   (Energy)

# Calculate kinetic energy
my \ke1 = (1/2) * m * u*u;
my \ke2 = (1/2) * m * v*v;

# Calculate the delta in kinetic energy
my \Δke = ke2 - ke1;

# Compare potential vs. delta kinetic energy
(pe cmp Δke).say;                      #Same

This example shows some key features of Physics::Measure...

  • support for SI prefixes, base and derived units (cm, kg, ml and so on)
  • imported as raku postfix operators for convenience and clarity
  • custom math operators (+-*/) for easy inclusion in calculations
  • inference of type class (Length, Time, Mass, etc.) from units
  • derivation of type class of results (Speed, Acceleration, etc.)

Use Cases

The Physics::Measure and Physics::Unit modules were designed with the following use cases in mind:

  • convenient use for practical science - lab calculations and interactive presentation of data sets
  • a framework for educators and students to interactively explore basic physics via a modern OO language
  • an everyday unit conversion and calculation tool (not much point if it can't convert miles to km and so on)

Some other use cases - use for physical chemistry calculations (eg. environmental) and for historic data ingestion - have also been seen on the horizon and the author would be happy to work with you to help adapt to meet a wider set of needs.

Design Model

To address the Use Cases, the following consistent functional parts have been created:

  • a raku Class and Object model to represent Units and Measurements
  • methods for Measure math operations, output, comparison, conversion, normalisation and rebasing
  • a Unit Grammar to parse unit expressions and cope with textual variants such as ‘miles per hour’ or ‘mph’, or ‘m/s’, ‘ms^-1’, ‘m.s-1’
  • an extensible library of about 800 built in unit types covering SI base, derived, US and imperial
  • a set of "API" options to meet a variety of consumption needs

Together Physics::Measure and Physics::Unit follow this high level class design model:

class Unit {
   has Str $.defn;
   #... 
}
class Measure {
   has Real $.value;
   has Unit $.units;
   has Error $.error;
   #...
}
class Length is Measure {}
class Time   is Measure {}
class Speed  is Measure {}
#and so on

Type classes represent physical measurement such as (Length), (Time), (Speed), etc. They are child classes of the (Measure) parent class.

You can do math operations on (Measure) objects - (Length) can add/subtract to (Length), (Time) can add/subtract to (Time), and so on. A mismatch like adding a (Length) to a (Time) gives a raku Type error cannot convert in to different type Length. You can, however, divide e.g. (Length) by (Time) and then get a (Speed) type back. (Length) ** 2 => (Area). (Length) ** 3 => (Volume). And so on. There are 36 pre-defined types provided. Methods are provided to create custom units and types.

Therefore, in the normal course, please make your objects as instances of the Child type classes.

Three Consumer Options

Option 1: Postfix Operator Syntax (SI Units)

As seen above, if you just want SI prefixes, base and derived units (cm, kg, ml and so on), the :ALL export label provides them as raku postfix:<> custom operators. This option is intended for scientist / coders who want fast and concise access to a modern Unit library. Here is another example, basic wave mechanics, bringing in the Physics::Constants module:

use Physics::Constants;  #<== must use before Physics::Measure 
use Physics::Measure :ALL;

$Physics::Measure::round-to = 0.01;

my= 2.5nm; 
my= c / λ;  
my \Ep =* ν;  

say "Wavelength of photon (λ) is " ~λ;              #2.5 nm
say "Frequency of photon (ν) is " ~ν.norm;          #119.92 petahertz 
say "Energy of photon (Ep) is " ~Ep.norm;           #79.46 attojoule

The following SI units are provided in all Prefix-Unit combinations:

SI Base Unit (7) SI Derived Unit (20) SI Prefix (20)
'm', 'metre', 'Hz', 'hertz', 'da', 'deka',
'g', 'gram', 'N', 'newton', 'h', 'hecto',
's', 'second', 'Pa', 'pascal', 'k', 'kilo',
'A', 'amp', 'J', 'joule', 'M', 'mega',
'K', 'kelvin', 'W', 'watt', 'G', 'giga',
'mol', 'mol', 'C', 'coulomb', 'T', 'tera',
'cd', 'candela', 'V', 'volt', 'P', 'peta',
'F', 'farad', 'E', 'exa',
'Ω', 'ohm', 'Z', 'zetta',
'S', 'siemens', 'Y', 'yotta',
'Wb', 'weber', 'd', 'deci',
'T', 'tesla', 'c', 'centi',
'H', 'henry', 'm', 'milli',
'lm', 'lumen', 'μ', 'micro',
'lx', 'lux', 'n', 'nano',
'Bq', 'becquerel', 'p', 'pico',
'Gy', 'gray', 'f', 'femto',
'Sv', 'sievert', 'a', 'atto',
'kat', 'katal', 'z', 'zepto',
'l', 'litre', 'y', 'yocto',

#litre included due to common use of ml, dl, etc.

Option 2: Object Constructor Syntax

In addition to the SI units listed above, Physics::Measure (and Physics::Unit) offers a comprehensive library of non-metric units. US units and Imperial units include feet, miles, knots, hours, chains, tons and over 200 more. The non-metric units are not exposed as postfix operators.

my Length $d = Length.new(value => 42, units => 'miles');   say ~$d;         #42 mile
my Time   $t = Time.new(  value =>  7, units => 'hours');   say ~$t;         #7 hr
my $s = $d / $t;                                  say ~$s.in('mph');         #6 mph

A flexible unit expression parser is included to cope with textual variants such as ‘miles per hour’ or ‘mph’; or ‘m/s’, ‘ms^-1’, ‘m.s-1’ (the SI derived unit representation) or ‘m⋅s⁻¹’ (the SI recommended string representation, with superscript powers). The unit expression parser decodes a valid unit string into its roots, extracting unit dimensions and inferring the appropriate type.

#Colloquial terms or unicode superscripts can be used for powers in unit declarations 
    #square, sq, squared, cubic, cubed
    #x¹ x² x³ x⁴ and x⁻¹ x⁻² x⁻³ x⁻⁴

Of course, the standard raku object constructor syntax may be used for SI units too:

my Length $l = Length.new(value => 42, units => 'μm'); say ~$l; #42 micrometre

This syntax option is the most structured and raku native. For example, it helps educators to use units and basic physics exercises as a way to introduce students to formal raku Object Orientation principles.

Option 3: Libra Shorthand Syntax

In many cases, coders will want the flexibility of the unit expression parser and the wider range of non-metric units but they also want a concise notation. In this case, the unicode libra emoji ♎️ is provided as raku prefix for object construction. The subject can be enclosed in single quotes ♎️'', double quotes ♎️"" of (from v1.0.10) angle brackets ♎️<>. Separate the number from the units with a space.

#The libra ♎️ is shorthand to construct objects...
    my $a = ♎️<4.3 m>;                  say "$a";		#4.3 m
    my $b = ♎️<5e1 m>;                  say "$b";		#50 m
    my $c = $a;                          say "$c";		#4.3 m
    my Length $l = ♎️ 42;                say "$l";		#42 m (default to base unit of Length)
#...there is an ASCII variant of <♎️> namely <libra> 

Use the emoji editor provided on your system (or just cut and paste)

#About 230 built in units are included, for example...
    my $v2 = ♎️<7 yards^3>;          #7 yard^3         (Volume)
    my $v3 = $v2.in( 'm3' );        #5.352 m^3        (Volume) 
    my $dsdt = $s / $t;             #0.000106438 m/s^2 (Acceleration)
    my $sm = ♎️<70 mph>;             #70 mph           (Speed)
    my $fo = ♎️<27 kg m / s2>;       #27 N             (Force)
    my $en = ♎️<26 kg m^2 / s^2>;    #26 J             (Energy)
    my $po = ♎️<25 kg m^2 / s^3>;    #25 W             (Power)

Special Measure Types

Angles

#Angles use degrees/minutes/seconds or decimal radians
    my $θ1 = ♎️<45°30′30″>;      #45°30′30″ (using <> to deconfuse quotation marks)
    my $θ2 = ♎️<2.141 radians>;  #'2.141 radian'
#NB. The unit name 'rad' is reserved for the unit of radioactive Dose

# Trigonometric functions sin, cos and tan (and arc-x) handle Angles
    my $sine = sin( $θ1 );      #0.7133523847299412
    my $arcsin = asin( $sine, units => '°' ); #45°30′30″
#NB. Provide the units => '°' tag to tell asin you want degrees back

Time

#The Measure of Time has a raku Duration - i.e. the difference between two DateTime Instants:
    my $i1 = DateTime.now;
    my $i2 = DateTime.new( '2020-08-10T14:15:27.26Z' );
    my $i3 = DateTime.new( '2020-08-10T14:15:37.26Z' );
    my Duration $dur = $i3-$i2;

#Here's how to us the libra assignment operator ♎️ for Time...
    my Time $t1 = ♎️<5e1 s>';     	#50 s
    my Time $t2 = ♎️ $dur;        	#10 s
    my $t3 = $t1 + $t2;         	#60 s
    my Time $t4 = ♎️<2 hours>;   	#2 hr
    $dur = $t4.Duration;         #7200

Unit Conversion

#Unit Conversion uses the .in() method - specify the new units as a String
    my Length $df = ♎️<12.0 feet>;         #12 ft
    my $dm = $df.in( 'm' );               #3.658 m
       $dm = $df.in: <m>;                 #alternate form
    my Temperature $deg-c = ♎️<39 °C>;
    my $deg-k = $deg-c.in( 'K' );         #312.15 K
    my $deg-cr = $deg-k.in( '°C' );       #39 °C

#Use arithmetic to get high order or inverse Unit types such as Area, Volume, Frequency, etc.
    my Area	      $x = $a * $a;           #18.49 m^2
    my Speed      $s = $a / $t2;          #0.43 m/s
    my Frequency  $f = 1  / $t2;          #0.1 Hz

#Use powers & roots with Int or Rat (<1/2>, <1/3> or <1/4>)
    my Volume     $v = $a ** 3;           #79.507 m^3
    my Length	   $d = $v ** <1/3>;       #0.43 m

The ① symbol is used to denote Dimensionless units.

Rounding & Normalisation

#Set rounding precision (or reset with Nil) - does not reduce internal precision
    $Physics::Measure::round-to = 0.01;
#Normalize SI Units to the best SI prefix (from example above)
    say "Frequency of photon (ν) is " ~ν.norm;    #119.92 petahertz
#Reset to SI base type with the .rebase() method
    my $v4 = $v2.rebase;                  #5.35 m^3

Thousand Separator | Euro Decimal

#Set behaviour if number part contains a comma ','
#use '' to allow as thousands sep / '.' to convert european style decimals
    $Physics::Measure::number-comma = ''; 
    my Speed $s2 = ♎️'24,000 miles per hour'; #24000mph

Comparison Methods

#Measures can be compared with $a cmp $b
    my $af = $a.in: 'feet';             #4.3 m => 14.108 feet
    say $af cmp $a;                     #Same
#Measures can be tested for equality with Numeric ==,!=
    say $af == $a;                      #True
    say $af != $a;                      #False
#Use string equality eq,ne to distinguish different units with same type  
    say $af eq $a;                      #False
    say $af ne $a;                      #True

Output Methods

To see what you have got, then go:

my $po = 25W;   
say ~$po; say "$po"; say $po.Str;       #25 W  (defaults to derived unit)
say +$po; say $po.value; say $po.Real;  #25 
say $po.^name;                          #(Power)
say $po.canonical;                      #25 m2.s-3.kg   (SI base units)
say $po.pretty;                         #25 m²⋅s⁻³⋅kg   (SI recommended style)
                                              ^...^......unicode Dot Operator U+22C5

Dealing with Ambiguous Types

In a small number of case, the same units are used by different unit Types. Type hints steer type inference:

our %type-hints = %(
    Area        => <Area FuelConsumption>,
    Energy      => <Energy Torque>,
    Momentum    => <Momentum Impulse>,
    Frequency   => <Frequency Radioactivity>,
);

To adjust this, you can delete the built in key and replace it with your own:

my %th := %Physics::Unit::type-hints;

#default type-hints
my $en1 = ♎️'60 J';     #'$en1 ~~ Energy';
my $tq1 = ♎️'5 Nm';     #'$tq1 ~~ Torque';

#altered type-hints
%th<Energy>:delete;
%th<Torque> = <Energy Torque>;

my $fo3 = ♎️'7.2 N';
my $le2 = ♎️'2.2 m';
my $tq2 = $fo3 * $le2;  #'$tq2 ~~ Torque';

Custom Measures

To make a custom Measure, you can use this incantation:

GetMeaUnit('nmile').NewType('Reach');

class Reach is Measure {
    has $.units where *.name eq <nm nmile nmiles>.any;

    #| override .in to perform identity 1' (Latitude) == 1 nmile
    method in( Str $s where * eq <Latitude> ) { 
        my $nv = $.value / 60; 
        Latitude.new( value => $nv, compass => <N> )
    }   
}

Summary

The family of Physics::Measure, Physics::Unit and Physics::Constants raku modules is a consistent and extensible toolkit intended for science and education. It provides a comprehensive library of both metric (SI) and non-metric units, it is built on a Type Object foundation, it has a unit expression Grammar and implements math, conversion and comparison methods.

Any feedback is welcome to librasteve / via the github Issues above.

Copyright (c) Henley Cloud Consulting Ltd. 2021-2023

raku-physics-measure's People

Contributors

librasteve avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

simrit1 melezhik

raku-physics-measure's Issues

Test trig

need to worry about trig functions - AB = BCcos(theta) take unit from BC

Snagging for 1.0.0 bump

documentation (see recent issues)
normalisation
avoid zef compiling AffixUnit.rakumod --- e.g. new module Physics::UnitAffix
(then split Physics::Unit and Physics::Measure - to stop someone else camping on Physics::Unit)
then call it v1.0.0??

Postfixes instead of libra operators

The idea of the libra operator is interesting, but I think particularly for this type of a module where the information is fairly simple (that is, /+ +/), using postfixes might work better on top of being more easily typed (or at least as an addition). See https://codereview.stackexchange.com/questions/159150/mass-and-length-calculator-using-perl-6-custom-operator/227804#227804 for an example.

If you're ammenable to it, I'd be happy to work it up and submit a pull request.

Generalize Length synonyms

406 #Synonyms for Length...
407 #FIXME need eg. my Distance $d = 42cm
408 class Distance is Length is export {}
409 class Breadth is Length is export {}
410 class Width is Length is export {}
411 class Height is Length is export {}
412 class Depth is Length is export {}

right now
$distance ~~ Length #ok
$length ~~ Distance #fail

"in" identified as "imaginary", not "inches"

#!/usr/bin/raku

use     Physics::Unit;
use     Physics::Measure;
use     Physics::UnitPostfix;

my $a;

# Works
$a = Length.new('7.27 in');
say $a;

# Fails
$a = Length.new('7.27in');
say $a;

Here's the output:

Physics::Measure::Length.new(value => 7.27, units => Unit.new( factor => 0.0254, offset => 0, defn => 'ft/12', type => '',
          dims => [1,0,0,0,0,0,0,0], dmix => ("ft"=>1).MixHash, 
          names => ['in','inch','inchs']  );
)
Cannot convert 0+7.27i to Real: imaginary part not zero
  in sub extract at [redacted] (Physics::Measure) line 32
  in method new at [redacted] (Physics::Measure) line 53
  in block <unit> at ./intest line 14

Using the same version as last time (0.0.3)

HTH!

Automate (or predefine) 'TimesSquare' types...

Consider this... only works ootb with t * t and not t ** 2

1 #!/usr/bin/env raku
2 use lib '../lib';
3 use Physics::Measure :ALL;
4
5 GetMeaUnit('s^2').NewType('TimesSquare');
6 class TimesSquare is Measure {}
7 GetMeaUnit('m^2/s^2').NewType('SpeedSquare');
8 class SpeedSquare is Measure {}
9
10 my \d = 42m; say ~d; #42 m
11 my \t = 10s; say ~t; #10 s
12
13 my \u = d / t; say ~u; #4.2 m/s
14 my \a = u / t; say ~a; #0.42 m/s^2
15
16 my \m = 25kg; say ~m; #25 kg
17 my \f = m * a; say ~f; #10.5 N
18
19 my \v = u + at; say ~v; #8.4 m/s
20 ##my \s = u
t + (1/2) * a * tt; say ~s; #63 m
21 my \s = u
t + (1/2) * a * t**2; say ~s; #63 m
22
23 my \pe = f * s; say ~pe; #661.5 J
24
25 my \ke1 = (1/2) * m * uu;
26 my \ke2 = (1/2) * m * v
v;
27
28 my \Δke = ke2 - ke1;
29 (pe cmp Δke).say; #Same

.norm broken on m^3

my \area = ♎️ '60 sq km';
my \n2g = ♎️ '0.5 ①';
my \φ = 0.2;
my \sat = 0.7;

say my \volume = area * d * n2g * φ * sat;
dd volume;
my \vol = volume.norm();

H:M:S

raku -pne '$_ = .Int.polymod(60,60).reverse.join(":")'

Add class method to add disambiguation

This gives type => Length, Reach

Custom Measures
To make a custom Measure, you can use this incantation:

GetMeaUnit('nmile').NewType('Reach');

class Reach is Measure {
    has $.units where *.name eq <nm nmile nmiles>.any;

    #| override .in to perform identity 1' (Latitude) == 1 nmile
    method in( Str $s where * eq <Latitude> ) { 
        my $nv = $.value / 60; 
        Latitude.new( value => $nv, compass => <N> )
    }   
}

make round-to a class attr

there is a general dislike of our scope things that can be set from consumers of class
nevertheless the behaviour of rounding is something that should be changed as a setting

Support Agri Emissions (and other Chemical Brothers)

https://uk-air.defra.gov.uk/assets/documents/reports/empire/naei/annreport/annrep99/app1_212.html

eg. kg N / year
eg. kg CH4/head/year

also ...

N2O(AWMS) = 44/28 . å NT . Nex(T) . AWMS(T) . EF(AWMS)
where
N2O(AWMS) = N2O emissions from animal waste managment systems
(kg N2O/yr)
NT = Number of animals of type T
Nex(T) = N excretion of animals of type T (kg N/animal/yr)
AWMS(T) = Fraction of Nex that is managed in one of the different
waste management systems of type T
EF(AWMS) = N2O emission factor for an AWMS (kg N2O-N/kg of Nex in AWMS)

Make Short cut factor a Rat literal

change factor and offset to Rat for short cut round trip (ie for knots = nmiles/hrs)
currently this relies on round-to to give one results

fix .raku

fro @kjpye
The default output with say (i.e. using the non-existent gist method) is also problematic. Perhaps a new gist method which does the same as a (possibly upgraded) Str method would be more suitable.

add proto method new(|) {*}

#rakulang tip of the day: if you're using a multi method new, you probably want to define a proto method new(|) {*} along with it. Otherwise the default new method will be one of the candidates which can lead to some confusing errors.

Does not install on Mac, with raku version 2022.3

$ zef --verbose install Physics::Measure
===> Searching for: Physics::Measure
===> Found: Physics::Measure:ver<1.0.5>:authzef:p6steve:api<1> [via Zef::Repository::Ecosystems]
===> Searching for missing dependencies: Physics::Unit, Physics::Error
===> Found dependencies: Physics::Error:ver<0.1.1>:authzef:p6steve:api<1>, Physics::Unit:ver<1.1.9>:authzef:p6steve:api<1> [via Zef::Repository::Ecosystems]
===> Searching for missing dependencies: SVG, SVG::Plot
===> Found dependencies: SVG::Plot, SVG [via Zef::Repository::Ecosystems]
===> Searching for missing dependencies: XML::Writer
===> Found dependencies: XML::Writer [via Zef::Repository::Ecosystems]
===> Fetching [OK]: Physics::Measure:ver<1.0.5>:authzef:p6steve:api<1> to /Users/stevedondley/.zef/tmp/1654343335.25217.1668.456363682831/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz
===> Fetching [OK]: Physics::Unit:ver<1.1.9>:authzef:p6steve:api<1> to /Users/stevedondley/.zef/tmp/1654343335.25217.757.8403821563973/b4a3a245c4ed42d15089f263514b2a61db91ffc4.tar.gz
===> Fetching [OK]: Physics::Error:ver<0.1.1>:authzef:p6steve:api<1> to /Users/stevedondley/.zef/tmp/1654343335.25217.6759.642564553906/f83a8dfe57695e4855f7d79ef94b07714d139108.tar.gz
===> Fetching [OK]: SVG to /Users/stevedondley/.zef/tmp/1654343335.25217.7283.084125426776/svg.git
===> Fetching [OK]: SVG::Plot to /Users/stevedondley/.zef/tmp/1654343335.25217.8532.353125146228/svg-plot.git
===> Fetching [OK]: XML::Writer to /Users/stevedondley/.zef/tmp/1654343335.25217.4940.226940977098/xml-writer.git
===> Extraction [OK]: Physics::Measure to /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz
===> Extraction [OK]: Physics::Error to /Users/stevedondley/.zef/tmp/f83a8dfe57695e4855f7d79ef94b07714d139108.tar.gz
===> Extraction [OK]: Physics::Unit to /Users/stevedondley/.zef/tmp/b4a3a245c4ed42d15089f263514b2a61db91ffc4.tar.gz
===> Extraction [OK]: SVG::Plot to /Users/stevedondley/.zef/tmp/svg-plot.git
===> Extraction [OK]: SVG to /Users/stevedondley/.zef/tmp/svg.git
===> Extraction [OK]: XML::Writer to /Users/stevedondley/.zef/tmp/xml-writer.git
===> Testing: XML::Writer
[XML::Writer] t/escaping.t ... ok
[XML::Writer] t/structure.t .. ok
[XML::Writer] All tests successful.
[XML::Writer] Files=2, Tests=11, 1 wallclock secs ( 0.01 usr 0.01 sys + 0.86 cusr 0.09 csys = 0.97 CPU)
[XML::Writer] Result: PASS
===> Testing [OK] for XML::Writer
===> Testing: SVG
[SVG] t/basics.t .. ok
[SVG] All tests successful.
[SVG] Files=1, Tests=3, 0 wallclock secs ( 0.01 usr 0.00 sys + 0.44 cusr 0.04 csys = 0.49 CPU)
[SVG] Result: PASS
===> Testing [OK] for SVG
===> Testing: SVG::Plot
[SVG::Plot] t/series.t .. ok
[SVG::Plot] t/ticks.t ... ok
[SVG::Plot] All tests successful.
[SVG::Plot] Files=2, Tests=10, 1 wallclock secs ( 0.01 usr 0.01 sys + 0.79 cusr 0.09 csys = 0.90 CPU)
[SVG::Plot] Result: PASS
===> Testing [OK] for SVG::Plot
===> Testing: Physics::Unit:ver<1.1.9>:authzef:p6steve:api<1>
[Physics::Unit] t/01-tst.t ....... ok
[Physics::Unit] t/02-dim.t ....... ok
[Physics::Unit] t/99-testMETA.t .. ok
[Physics::Unit] All tests successful.
[Physics::Unit] Files=3, Tests=34, 14 wallclock secs ( 0.01 usr 0.01 sys + 15.51 cusr 0.42 csys = 15.95 CPU)
[Physics::Unit] Result: PASS
===> Testing [OK] for Physics::Unit:ver<1.1.9>:authzef:p6steve:api<1>
===> Testing: Physics::Error:ver<0.1.1>:authzef:p6steve:api<1>
[Physics::Error] t/00-sanity.t .... ok
[Physics::Error] t/99-testMETA.t .. ok
[Physics::Error] All tests successful.
[Physics::Error] Files=2, Tests=7, 1 wallclock secs ( 0.01 usr 0.01 sys + 0.69 cusr 0.08 csys = 0.79 CPU)
[Physics::Error] Result: PASS
===> Testing [OK] for Physics::Error:ver<0.1.1>:authzef:p6steve:api<1>
===> Testing: Physics::Measure:ver<1.0.5>:authzef:p6steve:api<1>
[Physics::Measure] Type check failed in assignment to $!error; expected Physics::Error::Error but got Bool (Bool::False)
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 54
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 66
[Physics::Measure] in block at t/01-new.t line 23
[Physics::Measure] # You planned 21 tests, but ran 5
[Physics::Measure] t/01-new.t .......
[Physics::Measure] Dubious, test returned 255 (wstat 65280, 0xff00)
[Physics::Measure] Failed 16/21 subtests
[Physics::Measure] Type check failed in assignment to $!error; expected Physics::Error::Error but got Bool (Bool::False)
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 54
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 66
[Physics::Measure] in sub prefix:<♎️> at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 562
[Physics::Measure] in block at t/02-asn.t line 17
[Physics::Measure] # You planned 11 tests, but ran 3
[Physics::Measure] t/02-asn.t .......
[Physics::Measure] Dubious, test returned 255 (wstat 65280, 0xff00)
[Physics::Measure] Failed 8/11 subtests
[Physics::Measure] Type check failed in assignment to $!error; expected Physics::Error::Error but got Bool (Bool::False)
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 54
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 66
[Physics::Measure] in sub prefix:<♎️> at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 562
[Physics::Measure] in block at t/03-add.t line 14
[Physics::Measure] t/03-add.t .......
[Physics::Measure] Dubious, test returned 255 (wstat 65280, 0xff00)
[Physics::Measure] Failed 26/26 subtests
[Physics::Measure] Type check failed in assignment to $!error; expected Physics::Error::Error but got Bool (Bool::False)
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 54
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 66
[Physics::Measure] in sub prefix:<♎️> at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 562
[Physics::Measure] in block at t/04-uni.t line 31
[Physics::Measure] # You planned 37 tests, but ran 7
[Physics::Measure] t/04-uni.t .......
[Physics::Measure] Dubious, test returned 255 (wstat 65280, 0xff00)
[Physics::Measure] Failed 30/37 subtests
[Physics::Measure] Type check failed in assignment to $!error; expected Physics::Error::Error but got Bool (Bool::False)
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 54
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 66
[Physics::Measure] in sub prefix:<♎️> at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 562
[Physics::Measure] in block at t/05-cvt.t line 13
[Physics::Measure] t/05-cvt.t .......
[Physics::Measure] Dubious, test returned 255 (wstat 65280, 0xff00)
[Physics::Measure] Failed 52/52 subtests
[Physics::Measure] Type check failed in assignment to $!error; expected Physics::Error::Error but got Bool (Bool::False)
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 54
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 66
[Physics::Measure] in sub prefix:<♎️> at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 562
[Physics::Measure] in block at t/06-com.t line 12
[Physics::Measure] t/06-com.t .......
[Physics::Measure] Dubious, test returned 255 (wstat 65280, 0xff00)
[Physics::Measure] Failed 37/37 subtests
[Physics::Measure] Type check failed in assignment to $!error; expected Physics::Error::Error but got Bool (Bool::False)
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 54
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 66
[Physics::Measure] in sub prefix:<♎️> at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 562
[Physics::Measure] in block at t/07-ugg.t line 10
[Physics::Measure] t/07-ugg.t .......
[Physics::Measure] Dubious, test returned 255 (wstat 65280, 0xff00)
[Physics::Measure] Failed 39/39 subtests
[Physics::Measure] Type check failed in assignment to $!error; expected Physics::Error::Error but got Bool (Bool::False)
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 54
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 66
[Physics::Measure] in sub prefix:<♎️> at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 562
[Physics::Measure] in block at t/08-syn.t line 13
[Physics::Measure] t/08-syn.t .......
[Physics::Measure] Dubious, test returned 255 (wstat 65280, 0xff00)
[Physics::Measure] Failed 12/12 subtests
[Physics::Measure] Type check failed in assignment to $!error; expected Physics::Error::Error but got Bool (Bool::False)
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 54
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 66
[Physics::Measure] in sub prefix:<♎️> at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 562
[Physics::Measure] in block at t/09-cmp.t line 10
[Physics::Measure] t/09-cmp.t .......
[Physics::Measure] Dubious, test returned 255 (wstat 65280, 0xff00)
[Physics::Measure] Failed 14/14 subtests
[Physics::Measure] Type check failed in assignment to $!error; expected Physics::Error::Error but got Bool (Bool::False)
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 54
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 66
[Physics::Measure] in sub prefix:<♎️> at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 562
[Physics::Measure] in block at t/10-sap.t line 10
[Physics::Measure] t/10-sap.t .......
[Physics::Measure] Dubious, test returned 255 (wstat 65280, 0xff00)
[Physics::Measure] Failed 19/19 subtests
[Physics::Measure] t/11-pwr.t ....... ok
[Physics::Measure] Type check failed in assignment to $!error; expected Physics::Error::Error but got Bool (Bool::False)
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 54
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 66
[Physics::Measure] in sub prefix:<♎️> at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 562
[Physics::Measure] in block at t/12-uax.t line 47
[Physics::Measure] # You planned 22 tests, but ran 17
[Physics::Measure] t/12-uax.t .......
[Physics::Measure] Dubious, test returned 255 (wstat 65280, 0xff00)
[Physics::Measure] Failed 5/22 subtests
[Physics::Measure] Type check failed in assignment to $!error; expected Physics::Error::Error but got Bool (Bool::False)
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 54
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 66
[Physics::Measure] in sub prefix:<♎️> at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 562
[Physics::Measure] in block at t/13-nrm.t line 26
[Physics::Measure] # You planned 6 tests, but ran 3
[Physics::Measure] t/13-nrm.t .......
[Physics::Measure] Dubious, test returned 255 (wstat 65280, 0xff00)
[Physics::Measure] Failed 3/6 subtests
[Physics::Measure] Type check failed in assignment to $!error; expected Physics::Error::Error but got Bool (Bool::False)
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 54
[Physics::Measure] in method new at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 66
[Physics::Measure] in sub prefix:<♎️> at /Users/stevedondley/.zef/tmp/4419122c24a1a93fe1d5f391a12beccf93c406b6.tar.gz/dist/lib/Physics/Measure.rakumod (Physics::Measure) line 562
[Physics::Measure] in block at t/14-err.t line 53
[Physics::Measure] # You planned 16 tests, but ran 2
[Physics::Measure] t/14-err.t .......
[Physics::Measure] Dubious, test returned 255 (wstat 65280, 0xff00)
[Physics::Measure] Failed 14/16 subtests
[Physics::Measure] t/99-testMETA.t .. ok
[Physics::Measure] Test Summary Report
[Physics::Measure] -------------------
[Physics::Measure] t/01-new.t (Wstat: 65280 Tests: 5 Failed: 0)
[Physics::Measure] Non-zero exit status: 255
[Physics::Measure] Parse errors: Bad plan. You planned 21 tests but ran 5.
[Physics::Measure] t/02-asn.t (Wstat: 65280 Tests: 3 Failed: 0)
[Physics::Measure] Non-zero exit status: 255
[Physics::Measure] Parse errors: Bad plan. You planned 11 tests but ran 3.
[Physics::Measure] t/03-add.t (Wstat: 65280 Tests: 0 Failed: 0)
[Physics::Measure] Non-zero exit status: 255
[Physics::Measure] Parse errors: Bad plan. You planned 26 tests but ran 0.
[Physics::Measure] t/04-uni.t (Wstat: 65280 Tests: 7 Failed: 0)
[Physics::Measure] Non-zero exit status: 255
[Physics::Measure] Parse errors: Bad plan. You planned 37 tests but ran 7.
[Physics::Measure] t/05-cvt.t (Wstat: 65280 Tests: 0 Failed: 0)
[Physics::Measure] Non-zero exit status: 255
[Physics::Measure] Parse errors: Bad plan. You planned 52 tests but ran 0.
[Physics::Measure] t/06-com.t (Wstat: 65280 Tests: 0 Failed: 0)
[Physics::Measure] Non-zero exit status: 255
[Physics::Measure] Parse errors: Bad plan. You planned 37 tests but ran 0.
[Physics::Measure] t/07-ugg.t (Wstat: 65280 Tests: 0 Failed: 0)
[Physics::Measure] Non-zero exit status: 255
[Physics::Measure] Parse errors: Bad plan. You planned 39 tests but ran 0.
[Physics::Measure] t/08-syn.t (Wstat: 65280 Tests: 0 Failed: 0)
[Physics::Measure] Non-zero exit status: 255
[Physics::Measure] Parse errors: Bad plan. You planned 12 tests but ran 0.
[Physics::Measure] t/09-cmp.t (Wstat: 65280 Tests: 0 Failed: 0)
[Physics::Measure] Non-zero exit status: 255
[Physics::Measure] Parse errors: Bad plan. You planned 14 tests but ran 0.
[Physics::Measure] t/10-sap.t (Wstat: 65280 Tests: 0 Failed: 0)
[Physics::Measure] Non-zero exit status: 255
[Physics::Measure] Parse errors: Bad plan. You planned 19 tests but ran 0.
[Physics::Measure] t/12-uax.t (Wstat: 65280 Tests: 17 Failed: 0)
[Physics::Measure] Non-zero exit status: 255
[Physics::Measure] Parse errors: Bad plan. You planned 22 tests but ran 17.
[Physics::Measure] t/13-nrm.t (Wstat: 65280 Tests: 3 Failed: 0)
[Physics::Measure] Non-zero exit status: 255
[Physics::Measure] Parse errors: Bad plan. You planned 6 tests but ran 3.
[Physics::Measure] t/14-err.t (Wstat: 65280 Tests: 2 Failed: 0)
[Physics::Measure] Non-zero exit status: 255
[Physics::Measure] Parse errors: Bad plan. You planned 16 tests but ran 2.
[Physics::Measure] Files=15, Tests=43, 36 wallclock secs ( 0.04 usr 0.03 sys + 42.20 cusr 1.74 csys = 44.01 CPU)
[Physics::Measure] Result: FAIL
===> Testing [FAIL]: Physics::Measure:ver<1.0.5>:authzef:p6steve:api<1>
Aborting due to test failure: Physics::Measure:ver<1.0.5>:authzef:p6steve:api<1> (use --force-test to override)

Errors

add ± for symmetric % errors

Error in Unit conversion Velocity = Length / Time

When running the code below, the velocity is not calcualted from time and length.

Error: "cannot convert in to different type Length"
in method in at /opt/rakudo-star-2020.01/install/share/perl6/site/sources/E184BD56357B91198F066C3A2CD14FEB4D0BDB42 (Physics::Measure) line 199
in method rebase at /opt/rakudo-star-2020.01/install/share/perl6/site/sources/E184BD56357B91198F066C3A2CD14FEB4D0BDB42 (Physics::Measure) line 206
in method divide at /opt/rakudo-star-2020.01/install/share/perl6/site/sources/E184BD56357B91198F066C3A2CD14FEB4D0BDB42 (Physics::Measure) line 153
in sub infix:</> at /opt/rakudo-star-2020.01/install/share/perl6/site/sources/E184BD56357B91198F066C3A2CD14FEB4D0BDB42 (Physics::Measure) line 477
in block at test.pl6 line 6

Environment: "Rakudo version 2020.01 built on MoarVM version 2020.01.1 implementing Perl 6.d."

<---------------------->
use Physics::Measure;
use Physics::UnitPostfix;

my $s = Measure.new(value => 5.1, units => 'm'); say ~$s;
my $t = Measure.new(value => 2.3, units => 's'); say ~$t;

my $v = $s / $t; say ~$v;
<---------------------->

Load time

selectable load of units subsets :all, :SI, :metric, :imperial, :US

Fix cm unit

The following fails with an error:

#!/usr/bin/raku

use     Physics::Unit;
use     Physics::Measure;

my $a = Length.new(value => 21.006, units => 'cm');

say $a;

Metres work fine, cm don't.

Version 0.0.3

Thanks for your work on this!

Better errors for undefined

The error coming from the following would be more useful if it were to complain about the undefined value in some way; what I really want is a documented way to test if it's undefined like this. For the record, calling defined($!height) inside foo() also fails.

#!/usr/bin/raku

use     Physics::Unit;
use     Physics::Measure;

class   Test {
        has Length $.length;
        has Length $.width;

        method  foo {
                say $!length <=> $!width;
        }
}

my $a = Test.new();

$a.foo();

HTH,

Label UnitPostfix for use statement

Apply labels for 8 base unit types: ":m, :s, :kg, :l ..."
Apply labels for prefix: ":c, :d, :μ..." maybe bucket to ":tiny, :macro, :vast"

Right now with 81 combinations on (all prefixes / just :m, :kg, :s, :l) and 566 off compile time (ie. no precomp is 66sec), uncomment all and compile time is ~30 mins

Long term fix is macros (or faster raku)

ToDos

#snagging

need power ** operator

catch sqrt as ** 1/2

need mechanism to convey Measure "Role" to e.g. Polygons classes

need to think about drawing elements to a scale

need to worry about trig functions - AB = BCcos(theta) take unit from BC

need to get it working with 2018.10 and then? 6.d

fix .gist

from @kjpye
The default output with say (i.e. using the non-existent gist method) is also problematic. Perhaps a new gist method which does the same as a (possibly upgraded) Str method would be more suitable.

Hardening of .norm test

FIXME test corner cases

  • name both PHz and petahertz (maybe subst?)
  • check crossing 1
  • check guardrails
  • add autonorm (check use of bless)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.