[Python-Dev] prePEP: Money data type

Batista, Facundo FBatista at uniFON.com.ar
Fri Oct 17 16:49:44 EDT 2003

Here I send it.

Suggestions and all kinds of recomendations are more than welcomed.

If it all goes ok, it'll be a PEP when I finish writing the code.

Thank you.

.	Facundo


Title: Money data type
Version: $Revision: 0.1 $
Last-Modified: $Date: 2003/10/17 17:34:00 $
Author: Facundo Batista <fbatista at unifon.com.ar>
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 17-Oct-2003
Python-Version: 2.3.3


The idea is to make a Money data type, basically for financial uses, where
decimals are needed but floating point is too inexact.  The Money data type
should support the Python standard functions and operations.


The detail of the requeriments are in the `Requirements`_ section.  Here
include all the decisions made and why, and all the subjects still in
discussion.  The requirements will be numbered, to simplify discussion on
each point.

As an XP exercise, I'll write the test cases before de class itself, so
comply exactly the requeriments of those tests.  Please see them for an
specification (and if you propose a different behaviour, please propose the
corresponding test case if possible, thanks).

Why Not To Use Tim Peters' FixedPoint?

As we'll see in Requeriments, thera are items that FixedPoint doesn´t comply
(because doesn't do something or does it different).  It could be extended
modified to comply the Requeriments, but some needs are own to currency, and
some features of FixedPoint are too much for Money, so taking them out will
make this class simplier.

Anyway, sometime maybe one could be made subclass of the other, or just make
one from both.  The code of the Money class is based in large part on the
code of Tim Peters' FixedPoint: thank you for your (very) valuable ideas.

Items In Discussion

6. About repr(). Should ``myMoney == eval(repr(myMoney))``?


1. The sintaxis should be ``Money(value, [precision])``.

2. The value could of the type:

       - another money (if you don't include *precision*, it get
       - int or long (default *precision*: 0)::
           Money(45): 45
           Money(45, 2): 45.00
           Money(5000000000,3): 5000000000.000
       - float (*precision* must be included)::
           Money(50.33, 3): 50.330
       - string (*precision* get extracted from the string)::
           Money('25.32'): 25.32
           Money('25.32', 4): 25.3200
       - something that could be coerced by long() or float()

3. Not to support strings with engineer notation (you don't need this when
   using money).

4. Precision must be a non negative integer, and after created the object
   you could not change it.

5. Attributes ``decimalSeparator``, ``currencySymbol`` and
   ``thousandSeparator`` could be overloaded, just to easy change them
   subclassing. This same *decimalSeparator* is that used by the constructor
   when receives a string. Defaults are::
       decimalSeparator = '.'
       currencySimbol = '$'
       thousandSeparator = ''

6. Calling repr() should not return str(self), because if the subclass
   indicates that ``decimalSeparator=''``, this could carry to a confusion.
   So, repr() should show a tuple of three values: IntPart, FracPart,

7. To comply the test case of Mark McEahern::

       cost = Money('5.99')
       percentDiscount = 10
       months = 3
       subTotal = cost * months
       discount = subTotal * (percentDiscount * 1.0) / 100
       total = subTotal - discount
       assertEqual(total, Money('16.17'))
8. To support the basic aritmetic (``+, -, *, /, //, **, %, divmod``) and
   comparisons (``==, !=, <, >, <=, >=, cmp``) in the following cases:
       - Money op Money
       - Money op otherType
       - otherType op Money
       - Money op= otherType
   OtherType could be int, float or long. Automaticlly will be converted to
   Money, inheritating the precision from the other component of the
   operation (and, in the case of the float, maybe losing precision
   the operation).
   When both are Moneys, the result has the larger precision from both.
9. To support unary operators (``-, +, abs``).

10. To support the built-in methods:

        - min, max
        - float, int, long (int and long are rounded by Money)
        - str, repr
        - hash
        - copy, deepcopy
        - bool (0 is false, otherwise true)

11. To have methods that return its components. The value of Money will be
    ``(int part) + (frac part) / (10 ** precision)``.
        - ``getPrecision()``: the precision
        - ``getFracPart()``: the fractional part (as long)
        - ``getIntPart()``: the int part (as long)

12. The rounding to be financial. This means that to round a number in a
    position, if the digit at the right of that position is bigger than 5,
    the digit at the left of that position is incremented by one, if it's
    smaller than 5 isn't::
        1.123 --> 1.12
        1.128 --> 1.13
    But when the digit at the right of that position is ==5. There, if the
    digit at the left of that position is odd, it gets incremented,
        1.125 --> 1.12
        1.135 --> 1.14

Reference Implementation

To be included later:

	- code
	- test code
	- documentation


This document has been placed in the public domain.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . .

La información contenida en este mensaje y cualquier archivo anexo al mismo,
son para uso exclusivo del destinatario y pueden contener información
confidencial o propietaria, cuya divulgación es sancionada por la ley. 

Si Ud. No es uno de los destinatarios consignados o la persona responsable
de hacer llegar este mensaje a los destinatarios consignados, no está
autorizado a divulgar, copiar, distribuir o retener información (o parte de
ella) contenida en este mensaje. Por favor notifíquenos respondiendo al
remitente, borre el mensaje original y borre las copias (impresas o grabadas
en cualquier medio magnético) que pueda haber realizado del mismo. 

Todas las opiniones contenidas en este mail son propias del autor del
mensaje y no necesariamente coinciden con las de Telefónica Comunicaciones
Personales S.A. o alguna empresa asociada. 

Los mensajes electrónicos pueden ser alterados, motivo por el cual
Telefónica Comunicaciones Personales S.A. no aceptará ninguna obligación
cualquiera sea el resultante de este mensaje. 

Muchas Gracias.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.python.org/pipermail/python-dev/attachments/20031017/b78dd115/attachment-0001.html

More information about the Python-Dev mailing list