# [Tutor] how to make classes play well together

Kent Johnson kent37 at tds.net
Fri Apr 10 19:47:04 CEST 2009

```On Fri, Apr 10, 2009 at 12:34 PM, C or L Smith <smiles at worksmail.net> wrote:
> Unum is a module that allows one to handle units with numbers, e.g. 3*M -> 3 [m], a measurement of 3 meters.
>
> I have a module that I wrote some time ago that handles uncertainties with numbers as they are involved with calculations. Let's call it the pnum module (for physical numbers) e.g. pnum(3,.1) specifies a value of 3 +/- 0.1.
>
> I worked with someone at that time of writing it who said..."it would be nice to get this working with Unum." Well...it's that time, perhaps, but I could use some help in knowing what's the best way to go.
>
> (Q1) My basic question is how to have these two work together. If they are to be two separate entities, my routines need to check whether they are dealing with a unum or not before doing certain operations. e.g. my routines define "x" and "u" attributes for the numbers, but if the pnum gets wrapped up with a unum then asking for x and u no longer works. I have to extract the pnum part from the pnum/unum composite before asking for x and u.

I think I would try wrapping unums with pnums rather than the other
way around, so you could have pnum(3, .1) or pnum(3*M, .1*M) and you
probably want to allow pnum(3*M, .1) where the units are implied on
the uncertainty.

> But...does that mean I have to be unum aware in the pnum module? i.e. I have to import unum (actually Unum from unum) so I can figure out what I am dealing with in the routines that I have defined,

Yes

> e.g.
>
>  def __mul__(self, other):
>  if isinstance(other,Unum):
>   return other*self
>  else:
>   return pnum(self.x*other.x,math.hypot(other.u*self.x,other.x*self.u),1)

I don't think you would need the test for Unum, assuming math.hypot()
works with unums.

>  def cos(x):
>  if isinstance(x,pnum):
>   return x.cos()
>  elif isinstance(x,Unum):
>   arg = x.asNumber(1)
>   if isinstance(arg,pnum):#it's a pnum unum
>    return pnum(arg[0],arg[1],1).cos()
>   else:#it's a pure unum
>    return math.cos(arg)
>  return math.cos(x)

Here you might need some special code but not quite like this.

> (Q2) If someone doesn't have unum installed, they should still be able to run pnum...but now it has tests for unums sprinkled all throughout it. Do I now have to put the tests for unums inside a try/except sort of structure to allow pnum to run if unum isn't present?

You can probably do something like this, to import the actual Unum
class if it is present, otherwise define a dummy class:
try:
from unum import Unum
except:
class Unum(object): pass

Then any tests for isinstance(x, Unum) will fail so the code inside
the if block doesn't have to work without unum.

Kent
```