如何在代数的 "if" 语句中使用变量?

How to use variables in an "if" statement for algebra?

import time

equation = input("type any equation having variables x and y")
text_file = open("testdf.txt", "w+")

for x in range(-1000,1000):
    for y in range(-1000,1000):
        if equation:
             result=x,y
             print(result)
             text_file.write(str(result)+"\n") #for storing results

我在 python 中制作了一个简单的代数计算器,但是当我测试它时,该文件忽略了存储在变量方程中的方程。我正在制作两个 python 文件来保存它们的结果,然后 python 使用它们的共同点来获得结果。我能够让 powershell 创建一个具有变量的 python 文件。但是有什么方法可以使 python 文件能够做到这一点,如果有办法处理单个 python 文件会更好。

用powershell制作的文件(也许可以很容易地回答我的问题):

echo "the format of typing equation is a*x+b*y==c"
echo ""
echo "type ** for ^"
echo ""
echo "there is a limit of -1000 and 1000 so you can't find solution after that"
echo ""
= Read-host "type first equation"
= Read-host "type second equation"

"text_file = open('result1.txt', 'w+')
import time
for x in range(-1000,1000):
    for y in range(-1000,1000):
        if  :
             result=x,y
             text_file.write(str(result)+'\n')       
time.sleep(5)" >> equation1.py



"text_file = open('result2.txt', 'w+')
import time
for x in range(-1000,1000):
    for y in range(-1000,1000):
        if  :
             result=x,y
             text_file.write(str(result)+'\n')       
time.sleep(5)" >> equation2.py

start equation1.py
start equation2.py
pause
pause
pause
$objects = @{
  ReferenceObject = (Get-Content -Path C:\Users\Hp\Desktop\result1.txt)
  DifferenceObject = (Get-Content -Path C:\Users\Hp\Desktop\result2.txt)
}
 = Compare-Object @objects -IncludeEqual -ExcludeDifferent

= | where {$_.SideIndicator -eq "=="} | 
              Format-Table -Property InputObject -AutoSize -HideTableHeaders
 > common.txt


=Get-Content common.txt

timeout /t 1
del equation1.py
del equation2.py
del common.txt
del result1.txt
del result2.txt
pause

第一个解决方案

您可以使用 eval() 方法,用于将字符串解释为 python 代码。 小心这个!使用此方法将允许任何人使用您的程序以及它在您的计算机上拥有的权限为所欲为。

eval() documentation

第二种解决方案

另一种方法是重写您自己的计算器。 我为您编写了以下代码,可让您计算表达式。您可以修改它以接受 xy 参数,并使它们发生变化。

import re


def add(a,b):
    return a + b

def substract(a,b):
    return a-b

def multiply(a,b):
    return a*b

def devide(a,b):
    return a/b

def euclid(a,b):
    return a//b

def power(a,b):
    return a**b

def modulo(a,b):
    return a%b

SYMBOLS = {
    '/' : devide,
    '//': euclid,
    '*' : multiply,
    '^' : power,
    '%' : modulo,
    '+' : add,
    '-' : substract,
}

order = ['^', '/', '//', '*', '%', '+', '-']

equation = "3.4*2 + 4 - 10 / 5^2" 


regex = '\d*\.\d+|\d+'
numbers = [float(x) for x in re.findall(regex, equation)]
symbols = re.findall('[\+\-\/*%()^]+', equation)



print(symbols)
print(numbers)

for symbol in order:
    present = True
    while present:
        try:
            index = symbols.index(symbol)
            calculation = SYMBOLS[symbol](numbers[index], numbers[index+1])
            numbers.pop(index+1)
            symbols.pop(index)
            numbers[index] = calculation
        except ValueError:
            present = False

print("result : {}".format(numbers[0]))

输出:

['*', '+', '-', '/', '^']
[3.4, 2.0, 4.0, 10.0, 5.0, 2.0]
result : 10.4

这个系统的缺陷:

  • 真的很慢
  • 您需要实现每个操作、括号处理等

您可以通过重构我的代码来解决 "really slow" 问题,使用 numpy 模块功能进行并行计算,一次完成所有计算。

draw graphs with numpy

numpy doc

第三种解决方案

第三种方法是调用计算 API 来解析字符串并为您完成工作。问题是,如果你想在你的图表上有 1000 个图,你将对 API 进行 1000 次调用,并禁止 IP。

祝你好运!

我正在写第二个答案,因为第一个开始有点大了。

您可以使用eval功能,并在this guide之后尝试保护它。 我写了一个使用这种技术的小脚本,并通过使用正则表达式检查输入字符串中是否存在潜在的非法字符来增加一点安全性:

测试正则表达式 here


import re
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from math import *

from matplotlib import cm

def func3d(x, y):
    global equation
    authorized_globals = {
        'x'     : y,
        'y'     : x,
        'cos'   : cos,
        'sin'   : sin,
        'tan'   : tan,
        'acos'  : acos,
        'asin'  : asin,
        'atan'  : atan,
        'atan2' : atan2,
        'atanh' : atanh,
        'ceil'  : ceil,
        'cosh'  : cosh,
        'sinh'  : sinh,
        'factorial' : factorial,
        'floor' : floor,
        'exp'   : exp,
        'log'   : log,
        'log2'  : log2,
        'log10' : log10,
        'sin'   : sin,
        'sinh'  : sinh,
        'sqrt'  : sqrt,
        'pi'    : pi,
        'e'     : e,
        'tau'   : tau,
        'inf'   : inf,
        'tanh'  : tanh

        }
    return eval(equation, authorized_globals, {})

equation = input("Type any equation having variables x and y")

pattern = re.compile('^([\d\+\-.\/*%()a-z ]*)$')
func3d_vectorized = np.vectorize(func3d)

if pattern.match(equation) is not None:
    x_points = np.linspace(-5, 5, num=100)
    y_points = np.linspace(-5, 5, num=100)
    X, Y = np.meshgrid(x_points, y_points)
    Z = func3d_vectorized(X, Y)

    fig = plt.figure()
    ax = fig.gca(projection='3d')


    surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, linewidth=0, antialiased=False)

    # Customize the z axis.
    ax.set_zlim(np.min(Z), np.max(Z))

    # Add a color bar which maps values to colors.
    fig.colorbar(surf, shrink=0.5, aspect=5)
    plt.show()
else:
    print("Illegal characters found !")

当用输入 sin(sqrt(x**2+y**2)) 调用它时,输出是以下 3D 曲线:

然后您可以将 X、Y、Z 保存在一个文件中以满足您的需要;)