bslatkin / effectivepython

Effective Python: Second Edition — Source Code and Errata for the Book
https://effectivepython.com
2.2k stars 710 forks source link

Item 25: missing indent and - infinity for negative numerator #84

Closed pierreyanni closed 1 month ago

pierreyanni commented 4 years ago

As it is in the book (online edition), this function doesn't work:

def safe_division(number, divisor,
                  ignore_overflow,
                  ignore_zero_division):
    try:
         return number / divisor
    except OverflowError:
         if ignore_overflow:
              return 0
    else:
         raise
    except ZeroDivisionError:
         if ignore_zero_division:
              return float('inf')
         else:
              raise

To work, we need to add 4 spaces in front of the first else:

def safe_division(number, divisor,
                           ignore_overflow,
                           ignore_zero_division):
    try:
         return number / divisor
    except OverflowError:
         if ignore_overflow:
              return 0
         else:
              raise
    except ZeroDivisionError:
         if ignore_zero_division:
              return float('inf')
         else:
              raise

Also, if ignore_zero_divison is True, I expected the function to return -inf if number < 0 and divisor = 0. This can be obtained by premultiplying float('inf') by number:

def safe_division(number, divisor,
                           ignore_overflow,
                           ignore_zero_division):
    try:
         return number / divisor
    except OverflowError:
         if ignore_overflow:
              return 0
         else:
              raise
    except ZeroDivisionError:
         if ignore_zero_division:
              return number * float('inf')
         else:
              raise

The latter issue (always inf and not -inf for negative numerator and zero denominator) arises a couple of paragraph later and can be fixed in the same way:

def safe_division_e(numerator, denominator, /,
                    ndigits=10, *,               # Changed
                    ignore_overflow=False,
                    ignore_zero_division=False):
    try:
        fraction = numerator / denominator       # Changed
        return round(fraction, ndigits)          # Changed
    except OverflowError:
        if ignore_overflow:
            return 0
        else:
            raise
    except ZeroDivisionError:
        if ignore_zero_division:
            return numerator * float('inf')
        else:
            raise

Apart from these minor issues, excellent book, very enjoyable to read!

bslatkin commented 1 month ago

Thank you for the report! This is an issue that happened in the ebook version. Will work this out in post-production.

bslatkin commented 1 month ago

Duplicate of #63