生成可评估的python代码:析取范式的所有功能组合 [英] Generating evalable python code: all combinations of functions in disjunctive normal form
问题描述
(A,B,C) = (100, 200, 300)
def f1(p): return p+50
def f2(p): return p*1.5
def f3(p): return p*p
vars_ = (A,B,C)
funcs_ = [f1, f2, f3]
logic_ = ["and","or"]
vol_lmt_ = [200, 300]
op_ = [">","<","="]
我想为eval()生成断言代码字符串以测试有效性,以下面的示例为例:
I want generate the assert code string for eval() to test the validity, take below one for example:
"f1(A)>200 and f1(B)>200 and f1(C)>200" # True
-^-------------^-------------^------------: funcs_
----^-------------^-------------^---------: vars_
------^-------------^-------------^-------: op_
--------^-------------^-------------^-----: vol_lmt_
------------^-------------^---------------: logic_
我的问题是:
-
如何根据上述变量生成我想要的代码字符串?
how to generate the code string I wanted based on those vars above?
如何列举以上(A,B,C)
的所有测试逻辑可能性?例如:
how to enumerate all test logic possibility for above (A,B,C)
? For example:
"f1(A)>200 and f1(B)>200 and f1(C)>200"
"f1(A)<300 and f2(B)=200 or f3(C)>200"
在生成代码时是否可以将函数名称替换为列表项?
is it possible to replace the the name of function to the list entry when generate the code?
"f(A)>200 and f1(B)>200 and f1(C)>200"
收件人
"funcs_[0](A)>200 and funcs_[0](B)>200 and funcs_[0](C)>200"
推荐答案
也许这可以总结您想要做的事情(使用python2语法):
Maybe this can summaries what you are trying to do (using python2 syntax):
import itertools
arguments = ('A', 'B', 'C', 'D')
funcs_ = [f1, f2, f3, f4]
logic_ = ["and","or"]
op_ = [">","<","="]
vol_lmt_ = [200, 300]
num_func = len(funcs_)
assert num_func == len(arguments), ("The number of argument should be the same as "
"the number of function.")
operands = itertools.product(["funcs_[%d]" % i for i in range(num_func)],
arguments,
op_,
vol_lmt_)
def comp(operands):
templ = "{func}({arg}){op}{val}"
for operand in operands:
yield templ.format(func=operand[0], arg=operand[1],
op=operand[2], val=operand[3])
new_operands = map(comp, itertools.tee(operands, num_func))
# construct the argument to pass to itertools.product.
args = []
for operand in new_operands:
args.append(operand)
args.append(logic_)
args.pop() # Remove the last logic operator.
res = itertools.product(*args)
print " ".join(res.next())
# funcs_[0](A)>200 and funcs_[0](A)>200 and funcs_[0](A)>200 and funcs_[0](A)>200
...
在这种方法中,我只是用('A','B','C')替换了vars_
而作弊.除此之外,我认为它应该可以工作.
In this method i just cheated by replacing vars_
with ('A', 'B', 'C'). beside that i think it should work.
如果您不喜欢通过硬编码vars_
列表和funcs_
名称来欺骗我的作弊方式,则可以从
If you don't like my way of cheating by hard coding the the vars_
list and the funcs_
name you can get the name of your variable from the globals dictionary something like this:
def get_name(obj):
"""Get the name of an object (variable) from the globals dict.
Argument:
- obj : The variable that we want to get the name of.
Return:
- A string representing the name of the object if it was found else return None.
"""
for name, value in globals().items():
if value is obj:
return name
这篇关于生成可评估的python代码:析取范式的所有功能组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!