[Python-ideas] Break multiple loop levels

haael haael at interia.pl
Sun May 12 09:20:24 EDT 2019



The concrete example I was working on when I started to miss double 
break. This is an implementation of polynomial long division in Galois 
field. Almost unmodified.

With outer break, I would't need to use the `running` variable. In fact, 
for mathematical clarity, I would like to put a test in the outer loop, 
like: `while dividend`. It would make clear what this algorithm is 
actually doing.

Sure, it could be refactored, but it would lose the relative simplicity. 
For such operations it is sometimes important to remain close to the raw 
mathematical notation.




def __divmod__(self, other):
     dividend = self.canonical()

     try:
         divisor = other.canonical()
     except AttributeError:
         return NotImplemented
     	
     if not dividend:
         return Field.zero(self.size), Field.zero(self.size)

     try:
         d = next(iter(divisor)) # leading term of the divisor
     except TypeError:
         d = self.const(divisor)

     do = self.__monomial_order(d)

     result = Field.zero(self.size)
     running = True
     while running: # outer loop, retry the changing `dividend`
         for x in dividend: # yield all monomials from this polynomial
	    if self.__monomial_order(x) < do:
                 # encountered monomial of too small order, finish
                 running = False
                 break # exit outer loop
                 try:
                     c = self.__monomial_division(x, d) # may fail
                     assert c # sanity check
                     result += c
                     dividend -= c * divisor
                     dividend = dividend.canonical()
                     # if `dividend` nonzero, try again
                     # if `dividend` is zero, finish
                     running = bool(dividend)
                     break
                 except ArithmeticError:
                     # monomial division failed, try next one
                     continue # inner loop
         else:
             # `dividend` exhausted, finish
             running = False
             pass

     if not hasattr(result, 'operator'):
         result = self.const(result)

     return result.canonical(), dividend.canonical()



More information about the Python-ideas mailing list