469,924 Members | 1,429 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,924 developers. It's quick & easy.

Re: type-checking support in Python?

En Mon, 06 Oct 2008 11:19:58 -0300, Joe Strout <jo*@strout.netescribió:
Finally, one thing I've considered is adopting some identifier prefixes
indicating type. Maybe "iFoo" for integer, "fFoo" for floating-point
numbers, "d" for dictionary, "l" for list, "t" for tuple, "o" for
object, and "v" for variable types that may be more than one of the
above. I gather (from just a couple days of browsing) that such a
naming convention isn't common in the Python community, but is there
anyone else here who does it? I'd rather adopt an existing standard
(even if it's not widely used) than make one up.
Apart from the wise words that others have said, I'd add that I see no
point in identifier prefixes when they merely indicate "type" (in the
Python sense or even a broader sense) - called "system Hungarian notation"
by some.
In contrast, the prefix used in "apps Hungarian notation" declares the
"kind" or "intent" of the variable, and it may be useful in some cases.
This appears to be the original intent of Charles Simonyi when he wrote
his paper [1]; the differences between both approaches are discussed here
[2].
As an example, in the oil industry here in my country there is a mix of
measurement units in common usage. Depth is measured in meters, but pump
stroke in inches; loads in lbs but pressures in kg/cm². So it's important
to keep track of which unit some variable represents - its type would be
always float, and that carries no information; but its unit *is* important
informacion, so I sometimes use a postfix to indicate that.
Variable names should be *meaningful* - before automatically sticking an
"f" or "i" or "m_" prefix to something, think what you gain from it. If
you always represent a street address using a string in your application,
"szAddress" (or "sAddress") don't give you any more information than
"address" alone, so the prefix is useless.

[1] http://msdn.microsoft.com/en-us/library/Aa260976.aspx
[2] http://blogs.msdn.com/ericlippert/ar.../12/52989.aspx

--
Gabriel Genellina

Oct 7 '08 #1
13 1391
In message <ma**************************************@python.o rg>, Gabriel
Genellina wrote:
As an example, in the oil industry here in my country there is a mix of
measurement units in common usage. Depth is measured in meters, but pump
stroke in inches; loads in lbs but pressures in kg/cm².
Isn't the right way to handle that to attach dimensions to each number?
Oct 7 '08 #2
On 7 Ott, 08:36, Lawrence D'Oliveiro <l...@geek-
central.gen.new_zealandwrote:
In message <mailman.2089.1223358567.3487.python-l...@python.org>, Gabriel

Genellina wrote:
As an example, in the oil industry here in my country there is a mix of
measurement units in common usage. Depth is measured in meters, but pump
stroke in inches; loads in lbs but pressures in kg/cm².

Isn't the right way to handle that to attach dimensions to each number?
Can you afford to avoid floats and ints? Attaching suffixes is the
best one can do with the builtin types.
In C++ one can check dimensions at compile time (http://www.boost.org/
doc/libs/1_36_0/doc/html/boost_units.html) with a modest increase of
cumbersomeness, but Python would need very heavyweight classes
containing a value and its dimension and a replacement of all needed
functions and operations.

Regards,
Lorenzo Gatti
Oct 7 '08 #3
En Tue, 07 Oct 2008 03:36:12 -0300, Lawrence D'Oliveiro
<ld*@geek-central.gen.new_zealandescribió:
In message <ma**************************************@python.o rg>, Gabriel
Genellina wrote:
>As an example, in the oil industry here in my country there is a mix of
measurement units in common usage. Depth is measured in meters, but pump
stroke in inches; loads in lbs but pressures in kg/cm².

Isn't the right way to handle that to attach dimensions to each number?
Maybe, but I prefer the values to be plain float objects. In my case it's
not that units are dynamic themselves: "this" file format has depth in
feet, "that" one uses meters, but that's known from start. I think I'd
attach units to values if they were dynamic and I had to reproduce the
original format exactly, but hasn't happened yet (fortunately).

--
Gabriel Genellina

Oct 7 '08 #4
Bas
On Oct 7, 8:36 am, Lawrence D'Oliveiro <l...@geek-
central.gen.new_zealandwrote:
In message <mailman.2089.1223358567.3487.python-l...@python.org>, Gabriel

Genellina wrote:
As an example, in the oil industry here in my country there is a mix of
measurement units in common usage. Depth is measured in meters, but pump
stroke in inches; loads in lbs but pressures in kg/cm².

Isn't the right way to handle that to attach dimensions to each number?
What they taught me as a physics undergrad is to always convert random
units given as input to SI units as soon as possible, do all your
calculations internally in SI units and (only if really needed)
convert back to arbitrary units on output. Now, 15 years later, I am
still trying to stick to this rule whenever possisble. This convention
allows you to 'forget' about units and save your pre/post-fixes for
the exceptional case:
inch = 0.0254
lenght_inch = some_user_input_in_inch()
length = length_inch * inch

I have heard about some python package which overloads numbers and
calculations to include units (quick google found unum, not sure if
that is the only one). I guess that unless you are dealing with life-
critical equipment or are using extreme programming, this is overkill
(but I guess python is not really the right language for that anyway,
imagine a garbage collection just when you want to launch your
shuttle).

Bas
Oct 7 '08 #5
On Oct 7, 5:24*am, Bas <wegw...@gmail.comwrote:
On Oct 7, 8:36 am, Lawrence D'Oliveiro <l...@geek-

central.gen.new_zealandwrote:
In message <mailman.2089.1223358567.3487.python-l...@python.org>, Gabriel
Genellina wrote:
As an example, in the oil industry here in my country there is a mix of
measurement units in common usage. Depth is measured in meters, but pump
stroke in inches; loads in lbs but pressures in kg/cm².
Isn't the right way to handle that to attach dimensions to each number?

What they taught me as a physics undergrad is to always convert random
units given as input to SI units as soon as possible, do all your
calculations internally in SI units and (only if really needed)
convert back to arbitrary units on output.
(snip)

If you think it's a potential source of error, a lightweight version
wouldn't be hard to implement. This one is absolute minimal, using
strings for the units. Multiplication is harder, since you want 'foot
pounds' == 'pound feet'.
>>class UnitScalar:
.... def __init__( self, val, type ):
.... self.val, self.type= val, type
.... def __add__( self, other ):
.... assert self.type== other.type, 'Must be same type'
.... return self.__class__( self.val+ other.val,
self.type )
.... def __repr__( self ):
.... return '<UnitScalar %f %s>'% ( self.val, self.type )
....
>>a, b= UnitScalar( 2, 'feet' ), UnitScalar( 3, 'feet' )
a+ b
<UnitScalar 5.000000 feet>
>>a, b= UnitScalar( 2, 'feet' ), UnitScalar( 3, 'inches' )
a+ b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __add__
AssertionError: Must be same type
Oct 7 '08 #6
hi,

On Oct 7, 3:24*am, Bas <wegw...@gmail.comwrote:
I have heard about some python package which overloads numbers and
calculations to include units (quick google found unum, not sure if
that is the only one). I guess that unless you are dealing with life-
critical equipment or are using extreme programming, this is overkill
(but I guess python is not really the right language for that anyway,
imagine a garbage collection just when you want to launch your
shuttle).
FWIW, the python papers volume 3 issue 1 is mentionning another
package, 'scalar':
http://archive.pythonpapers.org/TheP...ume3Issue1.pdf
http://russp.us/scalar.htm

cheers,
sebastien.
Oct 7 '08 #7
I also wrote a units package which I'm using for a project of my own
(a spiking neural network simulator package called 'Brian'), released
separately as a package called Piquant which you can get at
sourceforge:

http://sourceforge.net/projects/piquant

I'm also looking for people to help improve it (get in touch!). The
way the package works is to have a Quantity class derived from float,
with extra operations. One thing that is different from the other
packages out there (and the reason I went to the effort of writing my
own package rather than using unum or scalar) is that we also have a
QuantityArray or qarray class that derives from numpy.ndarray. There
are at the moment two supported types of qarray, with homogeneous
units (one unit for the whole array), and heterogeneous units
(different unit for each item in the array). At the moment the
heterogeneous units implementation is horrible and very slow, but I
have a plan for a nicer version at some point (based on numpy's
broadcasting rules, so allowing you to have one unit for each row or
each column in a matrix for example).

Actually I think it would be a really good idea for someone at some
point to make a standardised system for units and add it to numpy/
scipy. I'd love to do it myself, but at the moment I have grant
applications, papers to finish, etc... :-(

Dan

Sebastien Binet wrote:
hi,

On Oct 7, 3:24�am, Bas <wegw...@gmail.comwrote:
I have heard about some python package which overloads numbers and
calculations to include units (quick google found unum, not sure if
that is the only one). I guess that unless you are dealing with life-
critical equipment or are using extreme programming, this is overkill
(but I guess python is not really the right language for that anyway,
imagine a garbage collection just when you want to launch your
shuttle).

FWIW, the python papers volume 3 issue 1 is mentionning another
package, 'scalar':
http://archive.pythonpapers.org/TheP...ume3Issue1.pdf
http://russp.us/scalar.htm

cheers,
sebastien.
Oct 7 '08 #8
dg**************@thesamovar.net wrote:
I also wrote a units package which I'm using for a project of my own
(a spiking neural network simulator package called 'Brian'), released
separately as a package called Piquant which you can get at
sourceforge:

http://sourceforge.net/projects/piquant

I'm also looking for people to help improve it (get in touch!). The
way the package works is to have a Quantity class derived from float,
with extra operations. One thing that is different from the other
packages out there (and the reason I went to the effort of writing my
own package rather than using unum or scalar) is that we also have a
QuantityArray or qarray class that derives from numpy.ndarray. There
are at the moment two supported types of qarray, with homogeneous
units (one unit for the whole array), and heterogeneous units
(different unit for each item in the array).
I have a unit system module (unity) in progress as well (it's working
but it's as yet unreleased), but which takes a different approach which
I think has more promise. Instead of having multiple united types
derived from different fundamental types, it has its own type Quantity
which takes two arguments: the amount and the units (which are further
data structures). That way, the amount and the units are kept
separately and the unit system doesn't know anything specific about the
amount and only deals with the unit system. Operations between
quantities enforce the type system (either combining the units for
operations like multiplication, or requiring that they be compatible for
operations like addition or comparison), and simply perform the
appropriate operations on the amount without enforcing any type. This
allows you to have united operations on integers, floating point
numbers, decimals, vectors, matrices, quaternions -- whatever values you
may want to support units.

Mine is more of a dimensional analysis tool (as well as a general unit
converter) since it allows you to define a basis of units, then define
units within that basis and manipulate them -- thus it remembers the
definitions of all the units it has encountered. You can define whole
new unit systems (e.g., c.g.s. vs. SI) and have them all relate to each
other, or even define brand new unit systems (e.g., man-day-widgets for
questions like, "If it takes one man three days to make two widgets, how
many widgets can five men make in two weeks?").

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
San Jose, CA, USA && 37 18 N 121 57 W && AIM, Y!M erikmaxfrancis
Those who forget the past are condemned to repeat it.
-- George Santayana
Oct 7 '08 #9
On Oct 7, 3:52*pm, Erik Max Francis <m...@alcyone.comwrote:
dg.google.gro...@thesamovar.net wrote:
(e.g., man-day-widgets for
questions like, "If it takes one man three days to make two widgets, how
many widgets can five men make in two weeks?").
Wouldn't that be 'widgets per man-day'?
Oct 7 '08 #10
On Tue, 07 Oct 2008 19:36:12 +1300, Lawrence D'Oliveiro wrote:
In message <ma**************************************@python.o rg>,
Gabriel Genellina wrote:
>As an example, in the oil industry here in my country there is a mix of
measurement units in common usage. Depth is measured in meters, but
pump stroke in inches; loads in lbs but pressures in kg/cm².

Isn't the right way to handle that to attach dimensions to each number?
This thread may be dead by now, but just for the record "dimensions" are
not "units". 1 inch and 1 kilometre have the same dimension (Length) but
obviously they can't be added to make 2 inches (or 2 kilometres).

On the other hand, dimensions are very handy for sanity results; if
somebody suggested to me that adding 15 inch second per gram to 195 cm
month per tonne gave 6.7 gallons per millgram hour, I don't even need to
do the conversion to see that this *must* be wrong because the dimensions
don't match: the original arguments have dimensions Length*Time/Mass but
the supposed argument has dimensions L**3/(M*T).

Dimensions are useful to check if quantities are compatible, but you
still need to convert them to a common unit.
--
Steven
Oct 11 '08 #11
On Oct 7, 9:52*pm, Erik Max Francis <m...@alcyone.comwrote:
I have a unit system module (unity) in progress as well (it's working
but it's as yet unreleased), but which takes a different approach which
I think has more promise. *Instead of having multiple united types
derived from different fundamental types, it has its own type Quantity
which takes two arguments: the amount and the units (which are further
data structures). *That way, the amount and the units are kept
separately and the unit system doesn't know anything specific about the
amount and only deals with the unit system. *Operations between
quantities enforce the type system (either combining the units for
operations like multiplication, or requiring that they be compatible for
operations like addition or comparison), and simply perform the
appropriate operations on the amount without enforcing any type. *This
allows you to have united operations on integers, floating point
numbers, decimals, vectors, matrices, quaternions -- whatever values you
may want to support units.

Mine is more of a dimensional analysis tool (as well as a general unit
converter) since it allows you to define a basis of units, then define
units within that basis and manipulate them -- thus it remembers the
definitions of all the units it has encountered. *You can define whole
new unit systems (e.g., c.g.s. vs. SI) and have them all relate to each
other, or even define brand new unit systems (e.g., man-day-widgets for
questions like, "If it takes one man three days to make two widgets, how
many widgets can five men make in two weeks?").

--
Erik Max Francis && m...@alcyone.com &&http://www.alcyone.com/max/
* San Jose, CA, USA && 37 18 N 121 57 W && AIM, Y!M erikmaxfrancis
* *Those who forget the past are condemned to repeat it.
* * -- George Santayana
It's funny how many people have had the need for this! I have written
a module that seems to be very similar. It contains:

* A BasicDimension class whose objects are basis vectors in the
dimensions vector space.
* A Dimension class which is simply a vector in the dimension vector
space, which optionally can be named.

E.g.

distance = new_basic_dim('distance', 'metre')
mass = new_basic_dim('mass', 'gram')
time = new_basic_dim('time', 'second')

speed = new_dim('speed', distance/time)
accel = new_dim('accel', speed/time)

area = new_dim('area', distance**2)
volume = new_dim('volume', distance**3)

density = new_dim('density', mass/volume)

force = new_dim('force', mass*accel)

Then:
>>volume/area
distance
>>speed*time
distance
* A Units class whose objects can registered with a dimension

* DObject class whose objects are just objects with a dimension. You
can do arithmetic with DObjects provided that you can do arithmetic
with their underlying objects.
>>s = Units(time, 1)
ms = Units(time, 0.001)
s.symbol = 's'
print DObject(2, s) + DObject(19, ms)
2.019 s
>>m = Units(distance, 1)
print DObject(3.0, m) / DObject(2.0, s)
1.5 [units distance*time**-1 1]
>>Units(distance/time, 1).symbol = 'm/s'
print DObject(3.0, m) / DObject(2.0, s)
1.5 m/s
>>print DObject(23.0, s).convert_to(ms)
23000 ms

* You can also have separate 'Dimensions systems', e.g. you can have
speed, force, time as basic dimensions instead of distance, mass, time
(IOW you have a different basis for the dimensions vector space).
Then you can convert DObjects between systems. Although this feature
is not working to my satisfaction.

I have designed this as part of a program to mark automatically online
maths/science worksheets, so speed is not really a consideration in my
implementation.

I have always thought of this as just a tool for my program, but I
suppose it can be seen as a sort of dynamic type checking system!

--
Arnaud

Oct 11 '08 #12
In message <01**********************@news.astraweb.com>, Steven D'Aprano
wrote:
... just for the record "dimensions" are not "units".
Yeah, OK. "unit" = "dimensions" x "multiplier".

Where "multiplier" can be arbitarily set to 1 for SI units.
Oct 13 '08 #13
In message
<1d**********************************@q9g2000hsb.g ooglegroups.com>, Bas
wrote:
What they taught me as a physics undergrad is to always convert random
units given as input to SI units as soon as possible, do all your
calculations internally in SI units and (only if really needed)
convert back to arbitrary units on output.
If only NASA's Mars Climate Orbiter engineers had followed that rule. :)
Oct 13 '08 #14

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Richard Lee | last post: by
11 posts views Thread by Johan | last post: by
5 posts views Thread by Fabio Fracassi | last post: by
5 posts views Thread by Axter | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.