Как использовать переменные в выражении «если» для алгебры? - PullRequest
1 голос
/ 19 июня 2020
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 ""
$1= Read-host "type first equation"
$2= 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 $1 :
             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 $2 :
             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)
}
$32 = Compare-Object @objects -IncludeEqual -ExcludeDifferent

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


$3=Get-Content common.txt
$3
timeout /t 1
del equation1.py
del equation2.py
del common.txt
del result1.txt
del result2.txt
pause

Ответы [ 2 ]

0 голосов
/ 20 июня 2020

Я пишу второй ответ, потому что первый начинает быть немного огромным.

Вы можете использовать функцию eval и попытаться защитить ее, следуя этому руководству . Я написал небольшой скрипт, использующий эту технику, и добавил немного безопасности, проверив входную строку на предмет потенциальных недопустимых символов с помощью регулярного выражения:

Протестируйте регулярное выражение здесь .


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-кривая: output

Затем вы можете сохранить X, Y, Z в файл под ваши нужды;)

0 голосов
/ 19 июня 2020

Первое решение

Вы можете использовать метод eval(), используемый для интерпретации строки как python кода. Будьте осторожны с этим! Использование этого метода позволит любому делать с вашей программой все, что угодно, и с правами, которые она имеет на вашем компьютере.

документация eval ()

Второе решение

Другой способ сделать это - переписать свой калькулятор. Я написал для вас следующий код, который позволяет вам вычислить выражение. Вы можете изменить его, чтобы принимать параметры x и y, и заставлять их изменять.

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

Fl aws этой системы:

  • Действительно медленно
  • Вам необходимо реализовать каждую операцию, обработку скобок и т. Д. c

Вы можете go обойти проблему «очень медленно» путем рефакторинга моего кода для одновременного выполнения всех вычислений с использованием возможности модуля numpy для выполнения параллельных вычислений.

рисовать графики с numpy

numpy do c

Третье решение

Третий способ - вызвать вычислительный API для анализа строк и выполнения работы за вас. Проблема будет в том, что если вы хотите иметь 1000 графиков на своем графике, вы выполните 1000 вызовов API и получите запрет на IP.

Удачи!

...