如何在 python 函数中添加数学函数作为参数
How to add mathematical function as argument in python function
我知道关于将函数传递给函数也有类似的问题,但我不清楚针对我的特定问题的有效解决方案。
以下函数有效,但公式是静态的。它仅适用于固定函数,即(在数学伪代码中)f(a) = 3^a mod 17 = b
其中 f(11) = 7
def get_a(b):
'''
Get preimage a from A for f(a) = b where b in B
'''
a = 1
while(1):
x = pow(3, a) % 17
if x == b:
return a
if a > 10000:
return -1
a += 1
def main():
b = 7
a = get_a(7)
print(F'The preimage a of b={b} is: {a}')
if __name__ == '__main__':
main()
我想让用户传入任何给定的函数。首先,我实现了一些更复杂但仍然非常简单的东西。
def get_a_variable(b, base, mod):
'''
Get preimage a from A for f(a) = b where b in B
'''
a = 1
while(1):
# print(F'a:{a}, b{b}')
x = pow(base, a) % mod
# print(F'x:{x}')
if x == b:
return a
if a > 10000:
return -1
a += 1
def main():
b = 7
a = get_a(7)
print(F'The preimage a of b={b} is: {a}')
a = get_a_variable(7,3,17)
print(F'Again, the preimage a of b={b} is: {a}')
这行得通,但我想让它更有活力。
为了尝试实现这一点,我创建了一个可以作为参数传递的新函数:
def power_mod_function(base, x, mod):
return power(base, x) % mod
我不太确定试验值 arg x 应该如何处理,或者它是否应该在这个函数中。
然后我“分叉”了我相信接受回调的“get_a(b)”函数
def get_a_dynamic(b, crypt_func):
'''
Get preimage a from A for f(a) = b where b in B
'''
a = 1
while(1):
x = crypt_func() # Not sure how to manage the arg passing here
if x == b:
return a
if a > 10000:
return -1
a += 1
然后我更新了 main():
def main():
b = 7
a = get_a(7)
print(F'The preimage a of b={b} is: {a}')
a = get_a_dynamic(b, power_mod_function(3, x, 17)) # Not sure how to pass my middle arg!!
print(F'Again the preimage a of b={b} is: {a}')
我收到以下错误消息:
python pre_img_finder.py
The preimage a of b=7 is: 11
Traceback (most recent call last):
File "pre_img_finder.py", line 45, in <module>
main()
File "pre_img_finder.py", line 41, in main
a = get_a_dynamic(b, power_mod_function(3, x, 17))
NameError: name 'x' is not defined
我不知道如何正确设置它并进行变量传递,以便我可以在 main 中传递一次静态变量,中间测试变量 x 将始终递增并最终找到我想要的结果。
也许我只需要接收一个函数,该函数以充当一种开关的“类型”参数开头,然后根据类型采用可变数量的参数。例如,我们可以将上面的函数称为 base-power-mod 函数或 (bpm),其中“power”是我们正在寻找的答案,即 a 在技术术语中是 b 的原像。然后打电话
main():
a = get_a_dynamic(7, ("bpm", 3,17))
然后这样实现?
感谢您的帮助!
使用 *args
向函数传递额外的任意数量的参数。
def get_a_dynamic(b, crypt_func, *args):
'''
Get preimage a from A for f(a) = b where b in B
'''
a = 1
while(1):
x = crypt_func(*args)
if x == b:
return a
if a > 10000:
return -1
a += 1
然后像这样在主程序中调用它
def main():
b = 7
a = get_a(7)
print(F'The preimage a of b={b} is: {a}')
a = get_a_dynamic(b, power_mod_function, 3, x, 17)
print(F'Again the preimage a of b={b} is: {a}')
生成带有部分定义参数的动态函数的方法是... functools.partial
from functools import partial
def get_a_variable_with_func(b, func):
'''
Get preimage a from A for f(a) = b where b in B
'''
a = 1
while(1):
x = func(a)
if x == b:
return a
if a > 10000:
return -1
a += 1
b = 7
def power_mod_function(base, mod, x):
return (base ** x) % mod
partial_func = partial(power_mod_function, 3, 17)
a = get_a_variable_with_func(7, partial_func)
print(a)
>>>
11
顺便说一下,这更像 pythonic:
from functools import partial
def get_a_variable_with_func(b, func):
'''
Get preimage a from A for f(a) = b where b in B
'''
for a in range(10001):
if func(a) == b:
return a
return -1
def power_mod_function(base, mod, x):
return (base ** x) % mod
a = get_a_variable_with_func(7, partial(power_mod_function, 3, 17))
print(a)
你做这样的事情:
def get_a_dynamic(b, function, argtuple):
# …
x = function(*argtuple) # star-operator unpacks a sequence
# … et cetera
…本质上。然后,您可以在传递它时始终检查 argtuple
的范围,或者对您的调用约定保持谨慎 - 但我认为,明星运营商解包位是您正在寻找的关键。
如果您想将函数名称作为字符串传递(根据您的示例),您可以执行以下操作:
function = globals()["bpm"] # insert your passed string argument therein
…但这有点粗略,我不推荐这样做——在这种情况下,最好预先填充一个字典,将函数字符串名称映射到函数本身。
当你这样做时:
a = get_a_dynamic(b, power_mod_function(3, x, 17))
您不将 power_mod_function
传递给 get_a_dynamic
,而是传递其结果
反而。要传递函数,您只需传递函数名称即可。
因此,因为该函数需要一个 get_a_dynamic
的内部值(x arg)以及两个外部参数(3 和 17),您必须分别将这两个参数传递给 get_a_dynamic它能够使用三个所需的参数调用传递的函数。
为此,可以使用 AnkurSaxena 的建议,尤其是在参数数量可以变化的情况下。但你也可以这样声明:
def get_a_dynamic(b, crypt_func, pow, mod):
然后像这样使用它:
a = get_a_dynamic(b, power_mod_function, 3, 17))
我知道关于将函数传递给函数也有类似的问题,但我不清楚针对我的特定问题的有效解决方案。
以下函数有效,但公式是静态的。它仅适用于固定函数,即(在数学伪代码中)f(a) = 3^a mod 17 = b
其中 f(11) = 7
def get_a(b):
'''
Get preimage a from A for f(a) = b where b in B
'''
a = 1
while(1):
x = pow(3, a) % 17
if x == b:
return a
if a > 10000:
return -1
a += 1
def main():
b = 7
a = get_a(7)
print(F'The preimage a of b={b} is: {a}')
if __name__ == '__main__':
main()
我想让用户传入任何给定的函数。首先,我实现了一些更复杂但仍然非常简单的东西。
def get_a_variable(b, base, mod):
'''
Get preimage a from A for f(a) = b where b in B
'''
a = 1
while(1):
# print(F'a:{a}, b{b}')
x = pow(base, a) % mod
# print(F'x:{x}')
if x == b:
return a
if a > 10000:
return -1
a += 1
def main():
b = 7
a = get_a(7)
print(F'The preimage a of b={b} is: {a}')
a = get_a_variable(7,3,17)
print(F'Again, the preimage a of b={b} is: {a}')
这行得通,但我想让它更有活力。
为了尝试实现这一点,我创建了一个可以作为参数传递的新函数:
def power_mod_function(base, x, mod):
return power(base, x) % mod
我不太确定试验值 arg x 应该如何处理,或者它是否应该在这个函数中。
然后我“分叉”了我相信接受回调的“get_a(b)”函数
def get_a_dynamic(b, crypt_func):
'''
Get preimage a from A for f(a) = b where b in B
'''
a = 1
while(1):
x = crypt_func() # Not sure how to manage the arg passing here
if x == b:
return a
if a > 10000:
return -1
a += 1
然后我更新了 main():
def main():
b = 7
a = get_a(7)
print(F'The preimage a of b={b} is: {a}')
a = get_a_dynamic(b, power_mod_function(3, x, 17)) # Not sure how to pass my middle arg!!
print(F'Again the preimage a of b={b} is: {a}')
我收到以下错误消息:
python pre_img_finder.py
The preimage a of b=7 is: 11
Traceback (most recent call last):
File "pre_img_finder.py", line 45, in <module>
main()
File "pre_img_finder.py", line 41, in main
a = get_a_dynamic(b, power_mod_function(3, x, 17))
NameError: name 'x' is not defined
我不知道如何正确设置它并进行变量传递,以便我可以在 main 中传递一次静态变量,中间测试变量 x 将始终递增并最终找到我想要的结果。
也许我只需要接收一个函数,该函数以充当一种开关的“类型”参数开头,然后根据类型采用可变数量的参数。例如,我们可以将上面的函数称为 base-power-mod 函数或 (bpm),其中“power”是我们正在寻找的答案,即 a 在技术术语中是 b 的原像。然后打电话
main():
a = get_a_dynamic(7, ("bpm", 3,17))
然后这样实现? 感谢您的帮助!
使用 *args
向函数传递额外的任意数量的参数。
def get_a_dynamic(b, crypt_func, *args):
'''
Get preimage a from A for f(a) = b where b in B
'''
a = 1
while(1):
x = crypt_func(*args)
if x == b:
return a
if a > 10000:
return -1
a += 1
然后像这样在主程序中调用它
def main():
b = 7
a = get_a(7)
print(F'The preimage a of b={b} is: {a}')
a = get_a_dynamic(b, power_mod_function, 3, x, 17)
print(F'Again the preimage a of b={b} is: {a}')
生成带有部分定义参数的动态函数的方法是... functools.partial
from functools import partial
def get_a_variable_with_func(b, func):
'''
Get preimage a from A for f(a) = b where b in B
'''
a = 1
while(1):
x = func(a)
if x == b:
return a
if a > 10000:
return -1
a += 1
b = 7
def power_mod_function(base, mod, x):
return (base ** x) % mod
partial_func = partial(power_mod_function, 3, 17)
a = get_a_variable_with_func(7, partial_func)
print(a)
>>>
11
顺便说一下,这更像 pythonic:
from functools import partial
def get_a_variable_with_func(b, func):
'''
Get preimage a from A for f(a) = b where b in B
'''
for a in range(10001):
if func(a) == b:
return a
return -1
def power_mod_function(base, mod, x):
return (base ** x) % mod
a = get_a_variable_with_func(7, partial(power_mod_function, 3, 17))
print(a)
你做这样的事情:
def get_a_dynamic(b, function, argtuple):
# …
x = function(*argtuple) # star-operator unpacks a sequence
# … et cetera
…本质上。然后,您可以在传递它时始终检查 argtuple
的范围,或者对您的调用约定保持谨慎 - 但我认为,明星运营商解包位是您正在寻找的关键。
如果您想将函数名称作为字符串传递(根据您的示例),您可以执行以下操作:
function = globals()["bpm"] # insert your passed string argument therein
…但这有点粗略,我不推荐这样做——在这种情况下,最好预先填充一个字典,将函数字符串名称映射到函数本身。
当你这样做时:
a = get_a_dynamic(b, power_mod_function(3, x, 17))
您不将 power_mod_function
传递给 get_a_dynamic
,而是传递其结果
反而。要传递函数,您只需传递函数名称即可。
因此,因为该函数需要一个 get_a_dynamic
的内部值(x arg)以及两个外部参数(3 和 17),您必须分别将这两个参数传递给 get_a_dynamic它能够使用三个所需的参数调用传递的函数。
为此,可以使用 AnkurSaxena 的建议,尤其是在参数数量可以变化的情况下。但你也可以这样声明:
def get_a_dynamic(b, crypt_func, pow, mod):
然后像这样使用它:
a = get_a_dynamic(b, power_mod_function, 3, 17))