python - Readable try except handling with calculations -
i have program have quite lot of calculations need do, input can incomplete (so cannot calculate results), in fine, gives issues readability of code:
def try_calc(): = {'1': 100, '2': 200, '3': 0, '4': -1, '5': none, '6': 'a'} try: a['10'] = float(a['1'] * a['2']) except (zerodivisionerror, keyerror, typeerror, valueerror) e: a['10'] = none try: a['11'] = float(a['1'] * a['5']) except (zerodivisionerror, keyerror, typeerror, valueerror) e: a['11'] = none try: a['12'] = float(a['1'] * a['6']) except (zerodivisionerror, keyerror, typeerror, valueerror) e: a['12'] = none try: a['13'] = float(a['1'] / a['2']) except (zerodivisionerror, keyerror, typeerror, valueerror) e: a['13'] = none try: a['14'] = float(a['1'] / a['3']) except (zerodivisionerror, keyerror, typeerror, valueerror) e: a['14'] = none try: a['15'] = float((a['1'] * a['2']) / (a['3'] * a['4'])) except (zerodivisionerror, keyerror, typeerror, valueerror) e: a['15'] = none return in [39]: %timeit try_calc() 100000 loops, best of 3: 11 µs per loop
so works well, high performing unreadable. came 2 other methods handle this. 1: use specialized functions handle issues internally
import operator def div(list_of_arguments): try: result = float(reduce(operator.div, list_of_arguments, 1)) except (zerodivisionerror, keyerror, typeerror, valueerror) e: result = none return result def mul(list_of_arguments): try: result = float(reduce(operator.mul, list_of_arguments, 1)) except (zerodivisionerror, keyerror, typeerror, valueerror) e: result = none return result def add(list_of_arguments): try: result = float(reduce(operator.add, list_of_arguments, 1)) except (zerodivisionerror, keyerror, typeerror, valueerror) e: result = none return result def try_calc2(): = {'1': 100, '2': 200, '3': 0, '4': -1, '5': none, '6': 'a'} a['10'] = mul([a['1'], a['2']]) a['11'] = mul([a['1'], a['5']]) a['12'] = mul([a['1'], a['6']]) a['13'] = div([a['1'], a['2']]) a['14'] = div([a['1'], a['3']]) a['15'] = div([ mul([a['1'], a['2']]), mul([a['3'], a['4']]) ]) return in [40]: %timeit try_calc2() 10000 loops, best of 3: 20.3 µs per loop
twice slow , still not readable honest. option 2: encapsulate inside eval statements
def eval_catcher(term): try: result = float(eval(term)) except (zerodivisionerror, keyerror, typeerror, valueerror) e: result = none return result def try_calc3(): = {'1': 100, '2': 200, '3': 0, '4': -1, '5': none, '6': 'a'} a['10'] = eval_catcher("a['1'] * a['2']") a['11'] = eval_catcher("a['1'] * a['5']") a['12'] = eval_catcher("a['1'] * a['6']") a['13'] = eval_catcher("a['1'] / a['2']") a['14'] = eval_catcher("a['1'] / a['3']") a['15'] = eval_catcher("(a['1'] * a['2']) / (a['3'] * a['4'])") return in [41]: %timeit try_calc3() 10000 loops, best of 3: 130 µs per loop
so slow (compared other alternatives is), @ same time readable one. aware of issues (keyerror, valueerror) handled pre-processing dictionary ensure availability of keys still leave none (typeerror) , zerodivisionerrors anyway, not see advantage there
my question(s): - missing other options? - crazy trying solve way? - there more pythonic approach? - think best solution , why?
how storing calculations lambdas? can loop through of them, using single try-except block.
def try_calc(): = {'1': 100, '2': 200, '3': 0, '4': -1, '5': none, '6': 'a'} calculations = { '10': lambda: float(a['1'] * a['2']), '11': lambda: float(a['1'] * a['5']), '12': lambda: float(a['1'] * a['6']), '13': lambda: float(a['1'] / a['2']), '14': lambda: float(a['1'] / a['3']), '15': lambda: float((a['1'] * a['2']) / (a['3'] * a['4'])) } key, calculation in calculations.iteritems(): try: a[key] = calculation() except (zerodivisionerror, keyerror, typeerror, valueerror) e: a[key] = none
by way, don't recommend doing if order of calculations matter, if had in original code:
a['3'] = float(a['1'] * a['2']) a['5'] = float(a['3'] * a['4'])
since dicts unordered, don't have guarantee first equation execute before second. a['5']
might calculated using new value of a['3']
, or might use old value. (this isn't issue calculations in question, since keys 1 through 6 never assigned to, , keys 10 through 15 never used in calculation.)
Comments
Post a Comment