GithubHelp home page GithubHelp logo

scimath's Introduction

scimath: Scientific and Mathematical calculations

http://scimath.readthedocs.org/en/latest/

The SciMath project includes packages to support scientific and mathematical calculations, beyond the capabilities offered by SciPy.

  • scimath.interpolate
  • scimath.mathematics
  • scimath.units
  • scimath.physical_quantities

Prerequisites

Development Environment Setup

To set up an EDM environment for this project:

$ edm install -e name_of_your_scimath_env click
$ edm shell -e name_of_your_scimath_env
$ python etstool.py install
$ python etstool.py test

scimath's People

Contributors

aaronayres35 avatar cfarrow avatar conorfleming avatar corranwebster avatar homosapien-lcy avatar jcorson avatar jonathanrocher avatar lnxpy avatar mdickinson avatar pgrimaud avatar prabhuramachandran avatar rahulporuri avatar rkern avatar scopatz avatar senganal avatar snegovikufa avatar stefanoborini avatar tassoneroberto avatar timdiller avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scimath's Issues

Raise TypeError for order comparisons of a `UnitScalar` with a float

Currently an order comparison (e.g., <) between a UnitScalar and a float returns a result based on the value for the UnitScalar. That comparison doesn't really quite make sense except in the case where the UnitScalar is actually unitless, and we end up with odd-looking situations like the following, where < doesn't give a partial order:

>>> x = UnitScalar(2.0, units="ft")
>>> y = UnitScalar(1.0, units="m")
>>> z = 1.5
>>> x < y
UnitScalar(True, units='None')
>>> y < z
UnitScalar(True, units='None')
>>> z < x
UnitScalar(True, units='None')

I'd suggest that the last two comparisons above should raise TypeError.

For comparison, we do get an exception (though not TypeError) when comparing incomparable UnitScalar objects:

Python 3.6.0 |Enthought, Inc. (x86_64)| (default, Mar  3 2017, 03:26:01) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from scimath.units.api import UnitScalar
>>> x = UnitScalar(3.2, units="kg")
>>> y = UnitScalar(2.3, units="m")
>>> x < y
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/mdickinson/.edm/envs/test36/lib/python3.6/site-packages/scimath/units/unit_array.py", line 415, in __lt__
    other, u = self.__convert_other(other)
  File "/Users/mdickinson/.edm/envs/test36/lib/python3.6/site-packages/scimath/units/unit_array.py", line 247, in __convert_other
    other = convert(numpy.array(other), ou, su)
  File "/Users/mdickinson/.edm/envs/test36/lib/python3.6/site-packages/scimath/units/convert.py", line 102, in convert
    raise ex
  File "/Users/mdickinson/.edm/envs/test36/lib/python3.6/site-packages/scimath/units/convert.py", line 97, in convert
    factor = float(from_unit / to_unit)
  File "/Users/mdickinson/.edm/envs/test36/lib/python3.6/site-packages/scimath/units/unit.py", line 149, in __float__
    raise InvalidConversion(self)
scimath.units.unit.InvalidConversion: dimensional quantities ('m*kg**-1') cannot be converted to scalars

Units not __future__.division proof

The following snippet of code returns the wrong result with __future__.division import (Python 2.7):

#from __future__ import division
from scimath.units.api import UnitScalar
x = UnitScalar(1.2, units="kg/m**3")
print repr(x/100.)

Testing the type of a unit

I believe this package is missing functions to test the type of a unit and be able to tell, looking at the derivation, if something is a length or if something is a mass, ...

enthought-dev mailing list does not allow new subscribers

Sorry for filing a bug, don't know how else to get ahold of you guys.

Response in browser after filling out the form to subscribe to enthought-dev and clicking "Subscribe":

Bug in Mailman version 2.1.9

We're sorry, we hit a bug!

Please inform the webmaster for this site of this problem. Printing of traceback and other system information has been explicitly inhibited, but the webmaster can find this information in the Mailman error logs.

+= operator buggy

In [1]: from scimath.units.api import UnitScalar
In [2]: x = UnitScalar(1, units="cm")
In [3]: x += UnitScalar(1, units="cm")
In [4]: print repr(x)
UnitScalar(2, units='None')

scimath has a dependency on traitsui

from scimath.units.api import UnitScalar
from traitsui.api import EnumEditor

After installing traitsui the import works. Please add this dependency to setup.py

Odd behavior with units parsing

Units are being run through "eval" at some point, resulting in this:

In [70]: UnitScalar(1, units='min')
Out[70]: UnitScalar(1, units='<built-in function min>')

In [71]: UnitScalar(1, units='__import__("os").system("ls -l /")')
total 45
drwxrwxr-x+ 73 root  admin  2482 Jun 26 17:24 Applications
drwxr-xr-x+ 64 root  wheel  2176 Aug 31  2016 Library
drwxr-xr-x@  2 root  wheel    68 Nov  9  2015 Network
drwxr-xr-x@  4 root  wheel   136 May 17 13:55 System
drwxr-xr-x   6 root  admin   204 Nov  9  2015 Users
drwxrwxrwt@  3 root  admin   102 Jul  3 13:04 Volumes
drwxr-xr-x@ 39 root  wheel  1326 May 17 13:55 bin
drwxrwxr-t@  2 root  admin    68 Nov  9  2015 cores
dr-xr-xr-x   3 root  wheel  4210 Jul  3 10:08 dev
lrwxr-xr-x@  1 root  wheel    11 Nov  9  2015 etc -> private/etc
dr-xr-xr-x   2 root  wheel     1 Jul  3 10:08 home
-rw-r--r--@  1 root  wheel   313 Aug 22  2015 installer.failurerequests
dr-xr-xr-x   2 root  wheel     1 Jul  3 10:08 net
drwxrwxr-x@  6 root  wheel   204 Sep 14  2016 opt
drwxr-xr-x@  6 root  wheel   204 Aug 31  2016 private
drwxr-xr-x@ 59 root  wheel  2006 May 17 13:55 sbin
lrwxr-xr-x@  1 root  wheel    11 Nov  9  2015 tmp -> private/tmp
drwxr-xr-x@ 13 root  wheel   442 Nov 12  2015 usr
lrwxr-xr-x@  1 root  wheel    11 Nov  9  2015 var -> private/var
Out[71]: UnitScalar(1, units='0')

Basically, right now unit labels should not be accepted from an untrusted source.

incompatibility when multiplying a unit by a numpy.float64

This code:
import numpy as np
import scimath
from scimath.units.time import second

print 'version = ',scimath.version

t = 3.0 * second
k = 1.0 / second

print 4 * t
print t * np.exp(-k*t)

gives this error:
version = 4.1.0
12.0_s
Traceback (most recent call last):
File "C:\users\jkitchin\Dropbox.spyder2.temp.py", line 19, in
print t * np.exp(-k_t)
File "C:\Python27\lib\site-packages\scimath\units\unit.py", line 78, in mul
value = self.value * other.value
AttributeError: 'numpy.float64' object has no attribute 'value'

the problem seems to be the return value from the np.exp is missing the value attribute.

this works fine:
print t * float(np.exp(-k*t))

Division/multiplication between two dimensionless UnitScalars converts units type to int

When dividing between two dimensionless UnitScalars, units is converted to an int. Is this the expected behavior?

Example:

>>> foo = UnitScalar(1000, units='mole')
>>> bar = UnitScalar(10, units='mole')
>>> baz =  foo / bar
>>> print baz.units
1
>>> print type(baz.units)
<class 'scimath.units.unit.unit'>

>>> foo_2 = UnitScalar(1000, units='none')
>>> bar_2 = UnitScalar(10, units='none')
>>> baz_2 = foo_2 / bar_2
>>> print baz_2.units
1
>>> print type(baz_2.units)
<type 'int'>

Inconsistent presence of labels on units

Some of the units we provide have a label, others don't:

from scimath.units.power import kilowatt, watt

>>> repr(kilowatt.label)
'None'

>>> watt.label
'watt'

This is causing issues if one wants to rely on these labels for serialization of unitted quantities.

Bug/feature request: convert/convert_unitted

[I feel like I have had this conversation before, but can't find trace of it anymore. Hope it is not a duplicate]

I keep forgetting that the convert function only works for float, not UnitScalars. As a result, and because UnitScalar is a subclass of np.ndarray, the following happens:

In [3]: from scimath.units.api import convert, UnitScalar

In [4]: x = UnitScalar(1., units="cm")

In [5]: from scimath.units.length import meter

In [6]: convert(x, from_unit=x.units, to_unit=meter)
Out[6]: UnitScalar(0.01, units='0.01*m')

which feels very buggy. I believe that we should:

  1. either raise an exception when a UnitScalar is passed, and create a new convert_unitted function that accepts UnitScalars/UnitArrays
  2. or support the UnitScalars correctly.

I think I like option 2 better, but it makes things not backward compatible, so is probably a no go.

Opinions? @timdiller @rkern ?

QuantityTrait and QuantityTraitHandler lack tests. Deprecate?

There are currently no tests for either QuantityTrait or QuantityTraitHandler. We should consider whether these classes should be maintained or not, and either add tests or deprecate as appropriate.

FWIW, I see uses of QuantityTrait in blockcanvas, but I'm not seeing any other uses.

Integer division being used when dividing two dimensionless quantities.

There are some surprising results when doing divisions with dimensionless quantities.

>>> from scimath.units.SI import *
>>> dimensionless / dimensionless
1
>>> type(dimensionless / dimensionless)
<type 'int'>
>>> dimensionless / (2*dimensionless)
0

I'd expect float and 0.5, here.

I also find it surprising that a multiplication or division with a unitless result returns a scalar (int or float) rather than another scimath.units.unit.unit instance, but that's another issue.

Bug with unitted functions

Not sure exactly the jargon to express this in, but there is a strange usage issue with united functions.

Take the "add()" function described here: http://scimath.readthedocs.org/en/latest/units/unit_funcs.html

I get the following behavior:

testsm.add(UnitScalar(2,units="m"),UnitScalar(3, units="m"))
Out[69]: UnitScalar(4.999999999999999, units='1.0*m+0.0')

testsm.add(2,3)
Out[70]: 1.524

testsm.add(2_m,3_m)
Out[71]: 1.524*m+0.0

Out 69 and 70 are expected. Out[71] is not. It got the type right, but not the value. It looks like it is ignoring the provided units and assuming feet, as if the parameters were regular python types instead of special unit-carrying types.

Is there a mailing list for this project?

error using scimath errors in scipy.optimize.fsolve

I thought this should work, but it did not.

import numpy as np
from scimath.units.volume import liter
from scimath.units.substance import mol
from scimath.units.time import second
from scipy.optimize import fsolve

mol, liter, second = 1,1,1

CA0 = 1.0 * mol / liter
CA = 0.01 * mol / liter
k = 1.0 / second

t0 = 2.3 * second

exponential = np.exp

def func(t):
z = CA - CA0 * exponential(-k*t)
return z

print fsolve(func, t0)

Leads to this error:
Traceback (most recent call last):
File "C:\Users\jkitchin\Desktop\untitled0.py", line 27, in
print fsolve(func, t0)
File "C:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 115, in fsolve
_check_func('fsolve', 'func', func, x0, args, n, (n,))
File "C:\Python27\lib\site-packages\scipy\optimize\minpack.py", line 13, in check_func
res = atleast_1d(thefunc(
((x0[:numinputs],) + args)))
File "C:\Users\jkitchin\Desktop\untitled0.py", line 24, in func
z = CA - CA0 * exponential(-k_t)
AttributeError: exp

document has_units

Documentation for has_units is missing (a blank section has been stubbed out for it).

Contents of this section should:

  • describe how the function should appear to clients
  • describe how the decorator alters the function arguments
  • describe how the return value is altered before it is passed to the caller
  • provide an example function which makes explicit all of the above by showing an equivalent function with all the wrapper code included.
  • give example of how (or if?) one can return a tuple of unitted values from a unitted function

Missing imports

(scimath)bash-3.2$ flake8 scimath | grep F821
scimath/physical_quantities/dimensions.py:139:23: F821 undefined name 'TraitsError'
scimath/physical_quantities/dimensions.py:140:15: F821 undefined name 'TraitsError'
scimath/physical_quantities/units.py:107:19: F821 undefined name 'QuantityTypeError'
scimath/physical_quantities/units.py:125:19: F821 undefined name 'QuantityTypeError'
scimath/physical_quantities/units.py:137:19: F821 undefined name 'QuantityTypeError'
scimath/physical_quantities/units.py:154:20: F821 undefined name 'Quantity'
scimath/physical_quantities/units.py:160:20: F821 undefined name 'Quantity'
scimath/physical_quantities/units.py:166:20: F821 undefined name 'Quantity'
scimath/physical_quantities/units.py:203:43: F821 undefined name 'dict_add'
scimath/physical_quantities/units.py:211:44: F821 undefined name 'dict_sub'
scimath/physical_quantities/units.py:219:43: F821 undefined name 'dict_mul'
scimath/physical_quantities/units.py:244:16: F821 undefined name 'format_expansion'
scimath/physical_quantities/units.py:246:51: F821 undefined name 'unicode_power'
scimath/physical_quantities/units.py:250:16: F821 undefined name 'format_expansion'
scimath/physical_quantities/units.py:255:15: F821 undefined name 'dimensionless'
scimath/units/quantity.py:137:32: F821 undefined name 'em'
scimath/units/unit_db.py:126:48: F821 undefined name 'column_names'
scimath/units/unit_db.py:172:59: F821 undefined name 'converters'
scimath/units/unit_db.py:221:35: F821 undefined name 'system_names'
scimath/units/unit_manager.py:225:34: F821 undefined name 'us'
scimath/units/unit_manager.py:482:33: F821 undefined name 'numpy'

Offset is ignored when dividing by UnitScalar

This seems like an odd behavior. Does it make sense to autoconvert to the base units?

>>> u = UnitScalar(10.0, units='degC')
>>> u
UnitScalar(10.0, units='1.0*K+273.15')
>>> 1/u
UnitScalar(0.1, units='1.0*K**-1')

Remove loading WX automatically when using scimath.units.api

Certain scimath objects define a TraitsUI editor which depends on wx. Unfortunately the imports are not hidden in the method that uses it and as a consequence, when someone imports anything from scimath.units.api, that imports wx and launches a GUI event loop. It slows things down.

wrong unit conversion

Hello,

I just installed scimath with pip, and I'm testing the conversion between units, as I think it's a really helpful feature.
But I think there is an issue :

import scimath.units as sci
In [27]: sci.convert(6.28,sci.angle.radians,sci.angle.deg)
Out[27]: 3598.17495342157

It should return 359.8 : I think there is a factor 10 mistake in the implementation of one of the unit. I tested the other way around 'converting deg to radians) and it is also wrong by a 10 factor.

"Deprecated NumPy API" warning during extension build.

compiling C++ sources
C compiler: g++ -fno-strict-aliasing -fno-common -dynamic -arch x86_64 -DNDEBUG -g -O3 -I/tmp/_py/libraries/usr/local/include -arch x86_64

compile options: '-Iscimath/interpolate -I/Users/tdiller/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/numpy/core/include -I/Applications/Canopy.app/appdata/canopy-1.3.0.1715.macosx-x86_64/Canopy.app/Contents/include/python2.7 -c'
g++: scimath/interpolate/_interpolate.cpp
In file included from scimath/interpolate/_interpolate.cpp:5:
In file included from /Users/tdiller/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h:4:
In file included from /Users/tdiller/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:17:
In file included from /Users/tdiller/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1760:
/Users/tdiller/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:15:2: warning: "Using deprecated NumPy API, disable it by "          "#defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-W#warnings]
#warning "Using deprecated NumPy API, disable it by " \
 ^
1 warning generated.

Provides trait types that support unit groups

It would be convenient if we could define TraitTypes that validate units based on the a quantity

e.g.

from scimath.units.length import Length, feet, meters
from scimath.units.mass import kg

class MyClass(HasTraits):

     unit = Length(feet)

my_class = MyClass()

# This is valid
my_class.unit = meters

# This is invalid
my_class.unit = kg

The trait might be as simple as an Enum with all the available unit objects.

Error on install - requires Microsoft Visual C++ 14.0 or greater

Is scimath actually dependent on Microsoft Visual C++? That seems to be where the install (pip install scimath) is getting hung up on when it attempts to build the wheel:

error: Microsoft Visual C++ 14.0 or greater is required. Get it with "Microsoft C++ Build Tools": https://visualstudio.microsoft.com/visual-cpp-build-tools/
  ----------------------------------------
  ERROR: Failed building wheel for scimath

error with scimath and odeint

import numpy as np
from scipy.integrate import odeint

from scimath.units.volume import liter
from scimath.units.substance import mol
from scimath.units.time import second

CA0 = 1.0 \* mol / liter
k = 1.0 / second

def myode(Ca, t):
    dCdt = -k \* Ca
    return dCdt

print(myode(CA0, 0_second))
print(odeint(myode, CA0, np.linspace(0.0, 9.0)_second))

gives this error:

-1000.0_m__-3_s**-1_mol
Traceback (most recent call last):
  File "C:\Users\jkitchin\Desktop\untitled2.py", line 24, in <module>
    print odeint(myode, CA0, np.linspace(0.0, 9.0)_second)
  File "C:\Python27\lib\site-packages\scipy\integrate\odepack.py", line 143, in odeint
    ixpr, mxstep, mxhnil, mxordn, mxords)
  File "C:\Python27\lib\site-packages\scimath\units\unit.py", line 144, in **float**
    raise InvalidConversion(self)
scimath.units.unit.InvalidConversion: dimensional quantities ('m**-3*mol') cannot be converted to scalars

np.dot is not supported by scimath

I came from he pint package, disappointed with its numpy support to scimath in hopes that the UnitArray could present some interesting possibilities. Unfortunately this is not the case. I would like to run a unit-aware dot product using 2 unit arrays, but this won't work:

a = UnitArray(np.linspace(0, 5, 6), units="cm")
b = UnitArray(np.linspace(0, 9, 6), units="sec")
c = np.dot(a,b)

type(c) shows that this is a numpy.float64 object and not a UnitArray of length 0 or a UnitScalar as I would expect. This makes it difficult for me to see the use of UnitArrays since they currently only appear to support element wise multiplication in numpy...

Is there a concise way of doing a unit-aware dot product with scimath? If so how? If not how to implement it?

Deprecation Warnings in interpolate

when building scimath, the following deprecation warnings are raised:

scimath/interpolate/_interpolate.cpp:13:30: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                             ^
scimath/interpolate/_interpolate.cpp:13:34: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                                 ^
scimath/interpolate/_interpolate.cpp:13:38: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                                     ^
scimath/interpolate/_interpolate.cpp:13:46: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                                             ^
scimath/interpolate/_interpolate.cpp:63:30: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                             ^
scimath/interpolate/_interpolate.cpp:63:34: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                                 ^
scimath/interpolate/_interpolate.cpp:63:38: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                                     ^
scimath/interpolate/_interpolate.cpp:63:46: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                                             ^
scimath/interpolate/_interpolate.cpp:113:30: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                             ^
scimath/interpolate/_interpolate.cpp:113:34: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                                 ^
scimath/interpolate/_interpolate.cpp:113:38: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                                     ^
scimath/interpolate/_interpolate.cpp:113:46: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                                             ^
scimath/interpolate/_interpolate.cpp:164:30: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                             ^
scimath/interpolate/_interpolate.cpp:164:34: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                                 ^
scimath/interpolate/_interpolate.cpp:164:38: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                                     ^
scimath/interpolate/_interpolate.cpp:164:46: warning: conversion from string literal to 'char *' is deprecated [-Wdeprecated-writable-strings]
    static char *kwlist[] = {"x","y","new_x","new_y", NULL};
                                             ^

SyntaxError: unqualified exec is not allowed in function 'units_wrap' it is a nested function (has_units.py, line 304)

I get a SyntaxError testing scimath for OSX and Windows with Python 2. The syntax error is:

SyntaxError: unqualified exec is not allowed in function 'units_wrap' it is a nested function (has_units.py, line 304)

Here is the full traceback:

======================================================================
ERROR: Failure: SyntaxError (unqualified exec is not allowed in function 'units_wrap' it is a nested function (has_units.py, line 304))
----------------------------------------------------------------------

Traceback (most recent call last):
  File ".../lib/python2.7/site-packages/nose/loader.py", line 420, in loadTestsFromName
    addr.filename, addr.module)
  File ".../lib/python2.7/site-packages/nose/importer.py", line 47, in importFromPath
    return self.importFromDir(dir_path, fqname)
  File ".../lib/python2.7/site-packages/nose/importer.py", line 94, in importFromDir
    mod = load_module(part_fqname, fh, filename, desc)
  File ".../lib/python2.7/site-packages/scimath/units/tests/has_units_test_case.py", line 17, in <module>
    import scimath.units.has_units as has_units_
SyntaxError: unqualified exec is not allowed in function 'units_wrap' it is a nested function (has_units.py, line 304)

"getting started" documentation is misleading

The Getting Started documentation presents the creation of new units as if new quantities were being created. Even the text in the exception raised in the example speaks of quantities.

Specifically, the following examples need to be changed to be less misleading:

       from scimath.units.length import foot, inch, meter
       3 * foot
       0.9144000000000001*m
       foot / inch
       12.0
       foot / meter
       0.3048

However, adding incompatible units raises an IncompatibleUnits exception:

       from scimath.units.electromagnetism import volt
       from scimath.units.mass import kilogram
       1 * volt + 2 * kilogram
       Traceback (most recent call last):
       File "", line 1, in
       File "scimath/units/unit.py", line 62, in add
       raise IncompatibleUnits("add", self, other)
       scimath.units.unit.IncompatibleUnits: Cannot add quanitites with units of 'm**2*kg*s**-3*A**-1' and 'kg'

Remove "scimath.units.unit_converter.convert_quantity_old"

def convert_quantity_old(q, unit_system):
# I think importing within the function is needed to avoid circularity
from scimath.units.quantity import Quantity
try:
units = unit_system.units(q.family_name)
except KeyError:
logger.exception(
"Could not convert quantity: %s to system: %s" %
(q, unit_system))
return q.clone()
if q.units == units:
q = q.clone()
else:
data = units_convert(q.data, q.units, units)
q = Quantity(
data,
units=units,
name=q.name or q.family_name,
family_name=q.family_name)
return q

Failing test in has_units

======================================================================
ERROR: Failure: AttributeError ('vectorize' object has no attribute 'thefunc')
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/tdiller/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/nose/loader.py", line 413, in loadTestsFromName
    addr.filename, addr.module)
  File "/Users/tdiller/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/nose/importer.py", line 47, in importFromPath
    return self.importFromDir(dir_path, fqname)
  File "/Users/tdiller/Library/Enthought/Canopy_64bit/User/lib/python2.7/site-packages/nose/importer.py", line 94, in importFromDir
    mod = load_module(part_fqname, fh, filename, desc)
  File "/Users/tdiller/enthought/scimath/scimath/units/tests/has_units_test_case.py", line 386, in <module>
    vec_bar_with_units = has_units(numpy.vectorize(bar))
  File "/Users/tdiller/enthought/scimath/scimath/units/has_units.py", line 199, in has_units
    return _has_units(summary, doc, inputs_dict, outputs_list)(func)
  File "/Users/tdiller/enthought/scimath/scimath/units/has_units.py", line 225, in units_wrap
    thefunc = _func_.thefunc
AttributeError: 'vectorize' object has no attribute 'thefunc'

Should units be hashable?

At the moment, units are hashable on Python 2 but not on Python 3.

On Python 2 -

>>> from scimath.units.length import feet, meters
>>> d = {feet: 'a value', meters: 'another value'}
>>> d
{0.3048*m: 'a value', 1.0*m: 'another value'}

On Python 3, creating the dictionary leads to -

>>> d = {feet: 'a value', meters: 'another value'}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'unit'

This is because on Python 3, the definition of the __eq__ on the unit class prevents the inheritance of __hash__ from object.

Declare build dependencies in pyproject.toml

scimath requires numpy in order to build, which means that a plain pip install scimath in an otherwise bare environment (+ pip, setuptools) will fail with something like this:

(scimath)bash-3.2$ pip install scimath
Collecting scimath
  Downloading https://files.pythonhosted.org/packages/fc/cf/cae77166021b4624a503656e0ba0423fc948c6615c997ec931b2c2e951e2/scimath-4.2.0.tar.gz (89kB)
    100% |████████████████████████████████| 92kB 5.1MB/s 
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/private/var/folders/07/jbbjv8b53bs5y9xyjdyn1zgw0000gn/T/pip-install-h1q74gmd/scimath/setup.py", line 8, in <module>
        import numpy.distutils.core
    ModuleNotFoundError: No module named 'numpy'
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /private/var/folders/07/jbbjv8b53bs5y9xyjdyn1zgw0000gn/T/pip-install-h1q74gmd/scimath/

Modern pip allows for a pyproject.toml file to specify build dependencies. See https://github.com/enthought/ibm2ieee/blob/master/pyproject.toml for an example. Assuming that the NumPy build dependency is needed here, we could add a pyproject.toml file here.

Appveyor CI

While CI was setup in #71 , we currently only have travis running on pull requests and not appveyor. Appveyor builds aren't being triggered by pull requests, which needs to be sorted out.

Automatic construction of unit label via `*` and `/` operations

Given two units with defined labels, infer a new label when two units are multiplied or divided. Especially useful for user-defined units

from scimath.units.time import hour
from scimath.units.length import cm
hour.label = 'hr'
cm.label = 'cm'
cm_per_hour = cm / hour
print cm_per_hour.label # Currently '', but would be ideally 'cm/hr'
print cm_per_hour # '2.77777777778e-06*m*s**-1'

The behavior here isn't completely well defined, such as when we come to say units dealing with the same object of measure (e.g. m / cm shouldn't be 'm/cm'), but at the same time some user facing applications would rather not see 2.777777777777778e-06*m*s**-1

Address deprecation warnings raised in the testsuite

When we run the testsuite using unittest instead of nose (#123), there are a number of deprecation warnings raised. The main types of warnings are

C:\Users\rporuri\.edm\envs\scimath-test-3.6\lib\site-packages\scimath-4.3.0.dev385-py3.6-win-amd64.egg\scimath\interpolate\tests\test_basic.py:13: DeprecationWarning: Please use assertTrue instead.
  self.assert_(allclose(x, y))
C:\Users\rporuri\.edm\envs\scimath-test-3.6\lib\site-packages\scimath-4.3.0.dev385-py3.6-win-amd64.egg\scimath\units\tests\test_function_signature.py:185: DeprecationWarning: Please use assertEqual instead.
  "def args_and_kwds(x, z=1, y=2):")
C:\Users\rporuri\.edm\envs\scimath-test-3.6\lib\site-packages\scimath-4.3.0.dev385-py3.6-win-amd64.egg\scimath\units\tests\test_has_units.py:343: DeprecationWarning: Please use assertEqual instead.
  self.assertEquals(foo_with_units.__module__, foo.__module__)
 C:\Users\rporuri\.edm\envs\scimath-test-3.6\lib\site-packages\scimath-4.3.0.dev385-py3.6-win-amd64.egg\scimath\units\tests\test_meta_quantity.py:22: DeprecationWarning: Please use assertEqual instead.
  self.failUnlessEqual(mq.name, 'vp')
C:\Users\rporuri\.edm\envs\scimath-test-3.6\lib\site-packages\scimath-4.3.0.dev385-py3.6-win-amd64.egg\scimath\units\tests\test_meta_quantity.py:49: DeprecationWarning: Please use assertRaises instead.
  self.failUnlessRaises(TraitError, setattr, mq, 'units', 'hours')
C:\Users\rporuri\.edm\envs\scimath-test-3.6\lib\site-packages\scimath-4.3.0.dev385-py3.6-win-amd64.egg\scimath\units\tests\test_traits.py:180: DeprecationWarning: Please use assertFalse instead.
  self.failIf(obj is None)
C:\Users\rporuri\.edm\envs\scimath-test-3.6\lib\site-packages\scimath-4.3.0.dev385-py3.6-win-amd64.egg\scimath\units\tests\test_traits.py:181: DeprecationWarning: Please use assertEqual instead.
  self.failUnlessEqual(obj.family_name, 'distance')
C:\Users\rporuri\.edm\envs\scimath-test-3.6\lib\site-packages\scimath-4.3.0.dev385-py3.6-win-amd64.egg\scimath\units\tests\test_traits.py:188: DeprecationWarning: Please use assertRaises instead.
  'unknown to unit_manager')
C:\Users\rporuri\.edm\envs\scimath-test-3.6\lib\site-packages\scimath-4.3.0.dev385-py3.6-win-amd64.egg\scimath\units\tests\test_traits.py:194: DeprecationWarning: Please use assertTrue instead.
  self.failUnless(obj.family_name is None)
C:\Users\rporuri\.edm\envs\scimath-test-3.6\lib\site-packages\scimath-4.3.0.dev385-py3.6-win-amd64.egg\scimath\units\tests\test_traits.py:136: DeprecationWarning: Please use assertNotEqual instead.
  self.failIfEqual(units.derivation, dimensionless.derivation)
C:\Users\rporuri\.edm\envs\scimath-test-3.6\lib\site-packages\scimath-4.3.0.dev385-py3.6-win-amd64.egg\scimath\units\tests\test_unit_array.py:350: DeprecationWarning: Please use assertTrue instead.
  self.assert_(result.units is None)
C:\Users\rporuri\.edm\envs\scimath-test-3.6\lib\site-packages\scimath-4.3.0.dev385-py3.6-win-amd64.egg\scimath\units\tests\test_unit_manipulation.py:361: DeprecationWarning: Please use assertEqual instead.
  self.assertEquals(len(outs), 2)
C:\Users\rporuri\.edm\envs\scimath-test-3.6\lib\site-packages\scimath-4.3.0.dev385-py3.6-win-amd64.egg\scimath\units\tests\test_units.py:295: DeprecationWarning: Please use assertTrue instead.
  self.assert_(unit_manager.are_compatible_families('none', 'pvelocity'))

Support rounding of UnitScalars in Python 3

In Python 3, I am seeing the following when attempting to round a UnitScalar.

In [1]: from scimath.units.api import UnitScalar

In [2]: u = UnitScalar(10.1234, units="gram")

In [3]: u
Out[3]: UnitScalar(10.1234, units='0.001*kg')

In [4]: round(u)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-dfdf7062be34> in <module>()
----> 1 round(u)

TypeError: type UnitScalar doesn't define __round__ method

Is this expected?

This is with scimath 4.2.0.

UnitArray.__pow__ fails for units=None

Example

>>> from scimath.units.api import UnitScalar
>>> UnitScalar(1, units=None)**2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/7.1/lib/python2.7/site-packages/scimath/units/unit_array.py", line 374, in __pow__
    result.units = units
UnboundLocalError: local variable 'units' referenced before assignment

Looking at the source, the error is obvious: result.units = units should be indented one level to lie within the if block above.

Release 4.2.0

Release a new version of scimath, which now supports Python 3.

Accidental (?) implicit dependency on TraitsUI

The package doesn't advertise TraitsUI as a dependency, but attempting to run e.g. from scimath.units.api import UnitScalar crashes with an ImportError if it's not installed. It's highly desirable that it be usable with Traits only, as we will be deploying code on headless systems.

The culprit appears to be this line (although there may be others):

from traitsui.api import EnumEditor

This is an issue for our consulting project, so I could spend some time on it if folks can point me in the right direction. See also #8.

UnitArray __rmul__ and __rdiv__ drop units when isinstance(other, numpy.generic)

I have discovered that scimath.units is dropping the units from the result when the left hand operand to * or / is a numpy scalar. Simple test cases:

>>> import numpy
>>> from scimath.units.api import UnitArray
>>> from scimath.units import SI
>>> a = UnitArray(1., units=SI.meter)
>>> b = numpy.array(1.)
>>> a*b # This will work
UnitArray(1.0, units='1.0*m')
>>> b*a # This also works
UnitArray(1.0, units='1.0*m')
>>> c = numpy.sqrt(1.)
>>> type(c)
<type 'numpy.float64'>
>>> a*c # this, i.e. __mul__ works
UnitArray(1.0, units='1.0*m')
>>> c*a # __rmul__ fails!
UnitArray(1.0, units='None')
>>> c / a # __rdiv__ shows the same bug
UnitArray(1.0, units='None')

It is not immediately clear to me how to fix this.

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.