Search code examples
pythonerror-handlingdivide-by-zero

Completely disabling / substituting ZeroDivisionError in Python


Good day. I have been searching through related posts without getting the ideal solution I would like to find. Let me describe my problem:

I am analyzing texts from a corpus, and extracting features from those texts, then storing the features in an array. Some of these features involve ratios, for example the ratio of masculine pronoun "he" to femenine pronoun "she". The thing is, for some of the variables, the value will be zero, and they will raise ZeroDivisionError.

Since I calculate about 100 of these ratios, wrapping a try / catch exception around every ratio calculation sounds like too cumbersome.

I found out that I can do

#16,RATIO_masculine_femenine
feature_map.append(numOfHe / numOfShe if numOfShe else 0)

But it is still a bit too much laborious. I was wondering if there is a way to state at the beggining of the script that any ZeroDivisionError should be substituted by NaN or 0, or whatever other value that may suit.

Thanks


Solution

  • The pythonic answer is to wrap it in a function, e.g.:

    def ratio(a, b):
        if b == 0:
            return 0
        else:
            return a / b
    
    feature_map.append(ratio(numOfHe, numOfShe))
    

    The exact form of the function depends on the rest of you code, but if you're writing a line like that hundreds of times, then you should probably be wrapping it in a function, or at least using a loop. Also, variable names like numOfHe and numOfShe hint that you might be better served by a dict.

    UPDATE

    I see from your code link that each calc is actually totally different, so you probably can't easily loop it. Since the calcs are still relatively simple, you could try a trick with eval like this:

    calcs = [
        ...
        (12, 'h + ha + hw + hy'),
        (13, '(h + ha) / (hw + hy)'),
        ...
    ]
    
    for index, calc in calcs:
        try:
            v = eval(calc, locals())
        except ZeroDivisionError:
            v = 0
        feature_map.append(v)
    

    You could also add other info to calcs, and use a namedtuple instead. You could also do use classes instead to evaluate the calcs dynamically as you need them, if that helps.