Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Setting a timeout for Calculator code: How to handle high number calculations and prevent freezing

I’m making a Calculator and the Code freezes when you try to calculate a high number (like 9⁹⁹⁹⁹⁹⁹) To counter this, I want to set a Timeout and if the calculation takes longer than 3 seconds, the result is just "NAN".
the Code snipped where the results are calculated looks like this, but it doesn’t work. If the calculation takes longer than 3 seconds, the task is not being canceled.

async def do_calculation(realcalculation, X, Y, A, B, C):
    try:
        result = str(numerize(sympy.sympify(realcalculation).subs(dict(X=X, Y=Y, A=A, B=B, C=C))))
    except:
        result = "NAN"
        raise
    return result

async def calculate(realcalculation, X, Y, A, B, C):
    loop = asyncio.get_running_loop()
    task = loop.create_task(do_calculation(realcalculation, X, Y, A, B, C))
    try:
        result = await asyncio.wait_for(task, timeout=3)
    except asyncio.TimeoutError:
        task.cancel()
        result = "NAN"
    return result

result = await calculate(realcalculation, X, Y, A, B, C)

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

There isn’t really a good solution for this. The issue is that really big numbers, those that can’t be stored in a regular float, automatically switch over to BigNum math (per PEP 237). While arithmetic with regular floats is a nearly constant time operation, BigNum math usually takes polynomial time. So, math with really big numbers just takes a long time.

The reason you can’t cancel your task is that there’s no point in do_calculation where you give asyncio a chance to cancel it. As the docs put it,

When a task is cancelled, asyncio.CancelledError will be raised in the task at the next opportunity.

That "opportunity" would be while you’re await-ing something. Because do_calculation is never await-ing for something, it can never be canceled.

To counteract this, I’d just add an upper bound to which numbers can be entered. If the number is too high at the beginning, then just return NaN. Because no upper bound is assured to keep it under 3 seconds on systems of all specifications, you’ll need to experiment with what is best for your machine.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading