Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中求解数学,无需任何内置求值函数或外部库_Python_Math - Fatal编程技术网

在python中求解数学,无需任何内置求值函数或外部库

在python中求解数学,无需任何内置求值函数或外部库,python,math,Python,Math,我需要编写一个程序,可以从这个非常有趣的问题中获取值。事实上,对你来说,这很简单。您可以使用ast模块解析整个源字符串,如下所示 import ast import operator functions = { "add": operator.add, "abs": operator.abs, "multiply": operator.mul } def recursive_evaluation(current_element): if isinstance(

我需要编写一个程序,可以从这个非常有趣的问题中获取值。事实上,对你来说,这很简单。您可以使用
ast
模块解析整个源字符串,如下所示

import ast
import operator

functions = {
    "add": operator.add,
    "abs": operator.abs,
    "multiply": operator.mul
}

def recursive_evaluation(current_element):
    if isinstance(current_element, ast.Module):
        return recursive_evaluation(current_element.body[0].value)
    elif isinstance(current_element, ast.Call):
        function = functions[current_element.func.id]
        args = [recursive_evaluation(item) for item in current_element.args]
        return function(*args)
    elif isinstance(current_element, ast.Num):
        return current_element.n
    else:
        raise ValueError("Unknown Element " + str(current_element))

source = "abs(add(add(9465,38),multiply(add(63303,146),46)))"
print recursive_evaluation(ast.parse(source))

source = "add(1, -2)"
print recursive_evaluation(ast.parse(source))

source = "abs(add(1, -2))"
print recursive_evaluation(ast.parse(source))
输出

2928157
-1
1

有趣的问题,这里有一个潜在的解决方案。毫无疑问,您可以使用库或lambda等来创建一个更加优雅的解决方案,就像他们在回答中所做的那样,但这似乎是可行的

我在底部做了一些测试用例,如果您想要调试信息,请将全局
verbose
设置为
True

# globals
verbose = False # set to True if you want debug info printed
max_iter = 1000 # this stops infinate loops incase the code does not allow for some input

def solve(problem_str):

    def multiply(arg_list):
        x = 1
        for i in arg_list:
            x *= i
        return x

    def find_innermost(x_str):
        a, b, c, i = [0], [0], 0, 0
        while True:
            i += 1
            start = a[-1]+1
            a.append(x_str.find('(', start)) # find next (
            b.append(x_str.find(',', start)) # find next ,
            c = x_str.find(')', start)       # find next )
            if (a[-1] > c) or (a[-1] == -1):
                if (b[-2] > a[-3]) and (b[-2] < a[-2]):
                    return x_str[b[-2]+1:c+1]
                else:
                    return x_str[a[-3]+1:c+1] 
            if i >= max_iter:
                raise Exception("Infinite loop")

    def do_sum(x_str):
        args = [int(x) for x in x_str[x_str.find('(')+1:x_str.find(')')].split(',')]
        task = x_str[:3].lower()
        if task == 'add':
            return sum(args)
        elif task == 'sub':
            return args[0] - sum(args[1:])
        elif task == 'abs':
            return abs(args.pop())
        elif task == 'mul':
            return multiply(args)
        else:
            print x_str + ': Task not recognised, please modify program or input'
            raise Exception("Invalid input")

    i = 0
    while True:
        i += 1
        if verbose: print 'debug: problem_str:', problem_str
        if problem_str.count('(') > 1:
            x_str = find_innermost(problem_str)
        else:
            x_str = problem_str
        if verbose: print '.'*6, 'x_str:\t', x_str
        x = do_sum(x_str)
        if verbose: print '.'*6, 'x:\t', x, '\n'
        problem_str = problem_str.replace(x_str, str(x))
        if problem_str.count('(') == 0:
            return int(problem_str)
        if i >= max_iter:
            raise Exception("Infinite loop")

if __name__ == '__main__':
    p1 = 'abs(add(add(9465,38),multiply(add(63303,146),46)))'
    p2 = 'abs(add(multiply(95,multiply(-1,multiply(13,18875))),multiply(-1,add(18293,26))))'
    p3 = 'abs(add(subtract(add(add(151,26875),122),254),subtract(237,multiply(-1,56497))))'
    r1, r2, r3 = solve(p1), solve(p2), solve(p3)
    print 'p1 evaluates to:', r1
    print 'p2 evaluates to:', r2
    print 'p3 evaluates to:', r3
#全局
verbose=False#如果要打印调试信息,请将其设置为True
max_iter=1000#如果代码不允许某些输入,则会停止内部循环
def解决(问题):
def倍增(参数列表):
x=1
对于arg_列表中的i:
x*=i
返回x
def find_最内层(x_str):
a、 b,c,i=[0],[0],0,0
尽管如此:
i+=1
开始=a[-1]+1
a、 追加(x_str.find(“(”,start))#查找下一个(
b、 追加(x_str.find(',,start))#查找下一步,
c=x_str.find('),start)#find next)
如果(a[-1]>c)或(a[-1]=-1):
如果(b[-2]>a[-3])和(b[-2]=最大值:
引发异常(“无限循环”)
def do_sum(x_str):
args=[int(x)表示x在x_str[x_str.find(')(')+1:x_str.find('))].split('),')]
task=x_str[:3]。下()
如果任务==“添加”:
返回和(args)
elif任务==“子任务”:
返回args[0]-和(args[1:])
elif任务==“abs”:
返回abs(args.pop())
elif任务==“mul”:
返回乘法(args)
其他:
打印x_str+':无法识别任务,请修改程序或输入'
引发异常(“无效输入”)
i=0
尽管如此:
i+=1
如果详细:打印“调试:问题”,问题
如果问题计数(“(”)>1:
x_str=查找最内层(问题_str)
其他:
x_str=问题_str
如果详细:打印“.”*6,'x_str:\t',x_str
x=do_和(x_str)
如果详细:打印“.”*6,'x:\t',x,'\n'
problem_str=problem_str.替换(x_str,str(x))
如果问题计数(“(”)==0:
返回整数(问题字符串)
如果i>=最大值:
引发异常(“无限循环”)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
p1='abs(加法(9465,38),乘法(加法(63303146,46))'
p2='abs(加(乘(95,乘(-1,乘(1318875))),乘(-1,加(18293,26)))'
p3='abs(加(减)(加(加)(15126875),122),254),减(237,乘(-156497)))'
r1,r2,r3=解算(p1),解算(p2),解算(p3)
打印“p1计算结果为:”,r1
打印“p2计算结果为:”,r2
打印“p3计算结果为:”,r3

如果您对代码有任何疑问,请告诉我。

您需要一个解析器:
ast.parse
我将如何实现它?您能给我一个例子吗?我发现这篇文章在开始表达式解析时非常有用。事实上,由于显式括号的缘故,您的案例比文章中处理的更容易。@user3274535请检查我的答案。非常感谢,这对这个问题有很大的帮助。我需要为一个url这样的数据做这件事:abs(add(add(9465,38),multiply(add(63303146,46)))abs(add(multiply(95,multiply(-1,multiply(1318875)),multiply(-1,add(18293,26)))abs(add(add(add)(add(15126875),122),254),减去(237,乘以(-156497)))这三个数字,然后生成新的URL,依此类推,将我引入一个爬虫程序,该爬虫程序将一直搜索,直到我到达一个端点(在问题中定义)@user3274535您的问题不太清楚。请您编辑您的问题并清楚地更新此信息好吗?@user3274535仍然不清楚。请您用一个例子更新一下好吗?@ChrisProssner非常感谢您的编程帮助。这项任务给了我很大的麻烦,非常感谢您的帮助。我正在尝试g用python编写一个爬虫程序的代码,该程序将遍历不同的url页面,并找到数学公式,如3条语句,以不断找到更多的网页。数学公式与web爬虫程序有何关系?您是否有一个示例url以及您试图在其中查找的内容?我希望能给您一个示例url,但它已被permis锁定假设一个网页上只有一组数学方程式。从那里我将使用我找到的数字将我路由到新的网页。从新的网页我将不得不继续做数学或到达一个带有字符串“finish”的网页。好的,没问题。如果有任何帮助,我已经在pastebin中为一个基本的网络爬虫编写了代码:。如果他们已经为您解决了问题,请您也将其中一个答案标记为已接受。我已在此处发布了一个更新版本:带有额外的注释等,以清晰明了并更新错误处理。