Velocity Reviews > Re: division

# Re: division

Sean Ross
Guest
Posts: n/a

 06-24-2003
>
> That works great for simple 2 number ones
>
> txt = pattern.sub(replaceint, "4/3")
> eval(txt)
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> File "<string>", line 0, in ?
> File "<stdin>", line 6, in __div__
> __main__.ExactDivisionError: exact division only
>
>
> bit if the user types something more complex like
> >>> txt = pattern.sub(replaceint, "((4 * 5) -2) / 5 ")
> >>> eval(txt)

> 3
>
> it doesnt raise an exception even though im dividing
> 18 / 5 which doesnt go evenly .
>

Adding the following method to the myint class solves this issue:

def __rdiv__(self, other):
return self.__div__(other)

import re

class ExactDivisionError(Exception):
pass

class myint(int):
def __div__(self, other):
"does exact division only"
quotient, remainder = divmod(self, other)
if remainder:
raise ExactDivisionError, "exact division only"
return quotient

def __rdiv__(self, other):
return self.__div__(other)

def replaceint(match):
"substitues 'myint(integer)' for each matched integer"
return 'myint(%s)'% match.string[match.start():match.end()]

# some testing...
pattern = re.compile(r'\d+') # matches integers
txt = '((4 * 5) -2) / 5'
txt = pattern.sub(replaceint, txt)
print txt # 'myint(2) + myint(22)/myint(5)'

try:
result = eval(txt) # this will raise an exception for 'txt'
print result
except ExactDivisionError:
print "ExactDivisionError"

#OUTPUT
# ((myint(4) * myint(5)) -myint(2)) / myint(5)
# ExactDivisionError

Sean Ross
Guest
Posts: n/a

 06-24-2003

"Steven Taschuk" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> You need the values produced by + etc. to be myints as well;
> merely inheriting the arithmetic methods from int is inadequate,
> since these methods return ints. So you need to extend __add__,
>

Sure.
It was never my intention to produce a complete solution for the OP's
problem - it wasn't that interesting to me. I offered a quick hack to show a
way they could go about solving their particular problem *in the way that
they had set out to do so* (should they choose to continue in that manner).
I did not suggest that my solution was complete, optimal, or correct (in
fact, I indicated the opposite). This was just a possible avenue to explore.
If they chose to explore this route, then yes, they'd have to do as you
suggest, and hopefully, they would come to realize that, and perhaps learn a
few things along the way. Regardless, you're correct to point out the
shortcomings to this approach. So, thanks...heh

> Expressions are pretty easy to parse and evaluate, btw; it seems
> to me simpler to write your own parser/evaluator, rather than
> using eval.

Yes. I suggested the OP use SPARK, which has some example code for parsing
and evaluating expressions that use only addition and multiplication. It
should be fairly uncomplicated to extend that code to handle subtraction and
division, and to do so in a manner that complied with their requirements re:
division in particular. However, if they weren't interested in doing so,
they could still try to do what they want using the method I suggested (with
have to address if they chose to use the 'myint' approach; namely, that
they'd have to be able to ensure that the expressions typed in by their
users only ever included ints, and not floats. Beyond that, they'd also need
to ensure that the only other characters were (,),+,-,*,/, and that all of t
he expressions were well-formed. Which is *why* it would be simpler to make
a parser/evaluater - since they're pretty much going to have to parse and
evaluate the strings anyway to ensure that those strings are suited to their
purpose (and to handle them appropriately when they are not). Just feeding
in possibly arbitrary strings to eval and crossing your fingers that
everything will work out the way you've planned is a recipe for
disappointment.