I have some conditions/comparisons stored as strings. How can I check these conditions? A very simple example is given below. I want the conditions as strings because I want to print them in case they fail.
I think I'll need to make a parser for this but that would be a really stupid idea to make a complete Python parser for a small thing. Any ideas what can be done?
def rev_num(num):
if num < 0:
return -int(str(-num)[::-1])
else:
return int(str(num)[::-1])
conditions = ['rev_num(-34) != -43', 'rev_num(34) != 43']
for i in conditions:
if something-needs-to-come-here(i):
print(i)
I know this is a weird idea but please tag along if you can.
I caused some confusion to user2357112. He pointed out that what I am trying to do is called unit-testing. Thanks for that.
To avoid any further confusion I'll add the code that I am trying to improve. The change that I want to make is to print the condition in the function correctness which made it return False.
def rev_num(num):
if num < 0:
return -int(str(-num)[::-1])
else:
return int(str(num)[::-1])
if __name__ == "__main__":
from timeit import Timer
import random
def correctness(f):
print("Correctness Test")
if f(-34) != -43 or f(34) != 43:
return False
print('Correct')
print('-----------')
return True
def timing(f, times):
def test1(f):
f(random.randint(1, 1000))
def test2(f):
f(random.randint(100000, 1000000))
print("Timing Test")
print(Timer(lambda: test1(f)).timeit(number = times))
print(Timer(lambda: test2(f)).timeit(number = times))
print('-----------')
def tests(f,times):
print(f.__name__)
print('-----------')
if correctness(f) is True:
timing(f, times)
repeat = 100000
tests(rev_num, repeat)
You could use eval, but I wouldn't suggest to do so. If you already know that you want to perform several calls to rev_num(x) != y, just create an auxiliary function and use a list of tuples to store the arguments:
def check_condition(x, y):
return rev_num(x) != y
conditions = [(-34, -43), (34, 43)]
for i in conditions:
if check_condition(*i):
print('rev_num({}) != {}'.format(*i))
You can do that using eval(cond_string):
for i in conditions:
if eval(i):
print(i)
Edit: yes, as several have pointed out, eval can be dangerous if you can't be absolutely certain about the content of the strings you're evaluating. For that reason, using eval is often seen as bad general practice, even though it may be the simplest way to achieve what you're aiming for here.
If your purpose is to perform sanity checks for code maintenance purposes, you could also take a look at the unittest module.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With