This python code is not solving equations - python

I have a chat bot for an Instant messenger and I am trying to make a math solver for it but it can't send the solution of equation to the Instant messenger, it sends equation instead.
If someone from Instant messenger sends "solve: 2+2", this program should send them "4" not "2+2".
Main problem:
if (parser.getPayload().lower()[:6]=="solve:"):
parser.sendGroupMessage(parser.getTargetID(), str(parser.getPayload()[7:]))
output:
it's sending same input again not the answer of equation
Test:
I tested something and that's working properly. If I add this code, program will send solution of equation:
if (parser.getPayload().lower()=="test"):
parser.sendGroupMessage(parser.getTargetID(), str(2 + 2 -3 + 8 * 7))
Output:
Working perfectly

Your test code
str(2 + 2 -3 + 8 * 7)
is distinct from your production code
str(parser.getPayload()[7:])
which gets expanded into
str("2 + 2 -3 + 8 * 7")
assuming you pass in the same equotation. Good thing is you have the plumbing working, now you need to implement the actual math solver like
str(solve_math(parser.getPayload()[7:]))
def solve_math(expr : str) -> float:
"""
Parses and evaluates math expression `expr` and returns its result.
"""
Here you need to first parse the expression string into some structure representing the data, the operators / functions and the evaluation order. So your "2 + 2" expression gets turned into something like Addition(Const(2), Const(2)) while expression "2 + 2 * 3" gets turned into somethng like Addition(Const(2), Multiplication(Const(2), Const(3))) and then you need to just evaluate it which should be fairly simple.
I recommend pyparsing to help you with that.

What you need to do this evaluating math expressions in string form.
However, user inputs are dangerous if you are just eval things whatever they give you. Security of Python's eval() on untrusted strings?
You can use ast.literal_eval to lower the risk.
Or you can use a evaluator from answers of following question
Evaluating a mathematical expression in a string

Related

Why do I get a ValueError: could not convert string to float in Python? [duplicate]

This question already has answers here:
Evaluating a mathematical expression in a string
(14 answers)
Closed 2 years ago.
I do not understand why I get a ValueError when I want to transform a calcul string into float. I would like an issue because I am stuck up.
(The aim of my code is to create random equations with increasing level depending on question number.)(I am still a beginner, sorry if my code is unmethodical (and in french too).)
:)
There is my code:
(input)
from random import *
def Numéro_Question():
global NuméroQuestion
NuméroQuestion+=1
print("\t~ Question {} ~\t\n".format(NuméroQuestion))
def Calcul2():
PremierChiffre=randint(0, NuméroQuestion*5+5)
Question=str(PremierChiffre)
for i in range(1,NuméroQuestion+1):
SigneDeCalcul=["+","*","-"]
SigneChoisi=str(choice(SigneDeCalcul))
x=str(randint(0, NuméroQuestion*5+5))
Question=Question+SigneChoisi+x
print(type(Question))
QuestionNumérique=float(QuestionNumérique)
QuestionEcrite=Question+" = "
Question=float
Réponse=input(QuestionEcrite)
NuméroQuestion=0
Raté=0
while Raté<3:
Numéro_Question()
Calcul2()
print("\n\n")
(output)
(The output changes each time you execute the program because it gives random number)
~ Question 1 ~
<class 'str'>
Traceback (most recent call last):
File "main.py", ligne 26, in <module>
Calcul2()
File "mai,.py", ligne 17, in Calcul2
QuestionNumérique=float(QuestionNumérique)
ValueError: could not convert string to float: '3*6'
It's because when you use float(my_string) it will only work if my_string can be cast as an actual float. It cannot do the multiplication for you.
Luckily, there is a very useful python function that accepts strings and runs them as code. It is called eval.
For example, eval("12 + 3") will return 15.
Just use eval instead of float, like this:
QuestionNumérique=eval(QuestionNumérique)
In summary, you want to "evaluate" (eval) the Numeric Question, not to "cast" (float) it.
A caveat: As others point out, eval is "unsafe". In general, evaluating arbitrary strings as code is unsafe.
UPDATE: I was thinking about this while eating chips earlier and I had a crazy idea.
OK, so, in Python you can execute shell commands in a subprocess and pipe the results. (os.popen - see here) . Assuming the machine running python has Bash as its shell, we can use Bash's arithmetic expression which (I think) might be easier to safeguard against arbitrary input.
Here is what it would look like:
import os
QuestionNumérique = "117 * 3 + 23 * 3"
shell_command = f"echo $(({QuestionNumérique}))"
piped_shell_result = os.popen(shell_command).read()
stripped_result = piped_shell_result.strip()
result_as_number = float(stripped_result)
This code is still dangerous! You would have to make sure the QuestionNumérique string contains "globally closed" ( and ) brackets, since someone could easily provide evil input like this:
QuestionNumérique = "117 * 3)); mkdir 'YOU HAVE BEEN H&CK3D'; echo $(("
If you can definitely make sure the input string has properly closed brackets then this should be safer than eval, since bash arithmetic expression will only do arithmetic.

Expand and simplify an expression based on a string input

I have an input like "2(5x+4) + 3(2x-1)" in plain text and I need to expand and simplify it. It appears sympy requires it to be entered as a python object made up of python types. Is there a way to automatically parse it / a library that doesn't require it so I can give it the string and it gives me the answer in a human readable format?
sympy already has such a parser built-in under sympy.parsing.sympy_parser.parse_expr. To get the results you want with your input statement you also have to add the implicit_multiplication transformation (since sympy otherwise won't generate statements that make sense for 2( and 5x):
from sympy.parsing.sympy_parser import (
parse_expr,
standard_transformations,
implicit_multiplication,
)
parse_expr("2(5x+4) + 3(2x-1)", transformations=standard_transformations + (implicit_multiplication,))
You want to use sympify function, for your expression it's gonna be like this:
sympify('2*(5*x+4) + 3*(2*x-1)')

Solve single variable equation using if, else and while statements in python

I am tutoring a 7th grade student in basic programming and mathematics. One of the problems the students needs to complete for a class assignment is "create a program to solve a given single variable linear equation". The student is required to use python and only use if, else and while statements. The program can include user defined functions and lists but cannot import any libraries like regex, sympy, numpy, etc.
The program should be able to solve these example equations:
2*x - 5 = 8
4*x + 3 = 3*x - 10
11*x = 2 - (1/5)*x
4*(x + 2) = 5*(x + 9)
I tried: For each character in the string note the numerals, operators, equals to sign and variable. Copy the variable and its coefficient into a new string and the constants with their signs to another string. My hope was that I would eventually extract the integers from each string and solve the equation for x. But I wasn't correctly capturing numbers with multiple digits. And the equation with parentheses completely stumped me. Not being able to use regex or sympy is painful!
I am looking for a pythonic solution to this problem if it exists.
I feel this is a very difficult question for a 7th grader because my grad and undergrad friends haven't been able to come up with a solution. Any advice on how to proceed will help if a programmatic solution isn't available.
Thank you.
Although it is completely possible to build a finite automaton solve an expression, it is not an easy task.
I myself had lots of assignments related to build a semantic or syntax parser, but it is usually done in C: https://codereview.stackexchange.com/questions/112620/simple-expression-calculator-in-c.
Nonetheless, if you accept a clever/dangerous/bad-practice solution:
def solve_expression(expr, var="x"):
expr = expr.replace(var, "1j")
left, right = map(eval, expr.split("="))
return (right.real-left.real)/(left.imag-right.imag)
print(solve_expression("2*x - 5 = 8"))
print(solve_expression("4*x + 3 = 3*x - 10"))
print(solve_expression("11*x = 2 - (1/5)*x"))
print(solve_expression("4*(x + 2) = 5*(x + 9)"))
The idea is to convert the free variable to the imaginary unit and let python interpreter do the rest.

Python - calculator program and strings

I am new to Python and am trying to write a calculator program. I have been trying to do the following but with no success, so please point me in the right direction:
I would like to input an equation as a user, for example:
f(t) = 2x^5 + 8
the program should recognize the different parts of a string and in this case make a variable f(t) and assign 2x^5 + 8 to it.
Though, if I input an equation followed by an equals sign, for example
2x^5 + 8 =
the program will instead just output the answer.
I am not asking how to code for the math-logic of solving the equation, just how to get the program to recognize the different parts of a string and make decisions accordingly.
I am sorry I don't have any code to show as an attempt as I'm not sure how to go about this and am looking for a bit of help to get started.
Thank you.
For a little bit of context: The problem you're describing is more generally known as parsing, and it can get rather complicated, depending on the grammar. The grammar is the description of the language; the language, in your case, is the set of all valid formulas for your calculator.
The first recommended step, even before you start coding, is to formalize your grammar. This is mainly for your own benefit, as it will make the programming easier. A well established way to do this is to describe the grammar using EBNF, and there exist tools like PLY for Python that you can use to generate parsers for such languages.
Let's try a simplified version of your calculator grammar:
digit := "0" | "1" # our numbers are in binary
number := digit | number digit # these numbers are all nonnegative
variable := "x" | "y" # we recognize two variable names
operator := "+" | "-" # we could have more operators
expression := number | variable | "(" expression operator expression ")"
definition := variable "=" expression
evaluation := expression "="
Note that there are multiple problems with this grammar. For example:
What about whitespace?
What about negative numbers?
What do you do about inputs like x = x (this is a valid definition)?
The first two are probably problems with the grammar itself, while the last one might need to be handled at a later stage (is the language perhaps context sensitive?).
But anyway, given such a grammar a tool like PLY can generate a parser for you, but leaving it up to you to handle any additional logic (like x = x). First, however, I'd suggest you try to implement it on your own. One idea is to write a so called Top Down Parser using recursion.

Reading user input in python 2.4, putting it into a queue

So I'm writing a differential calculator program in python 2.4 (I know it's out of date, it's a school assignment and our sysadmin doesn't believe in updating anything) that accepts a user input in prefix notation (i.e. input = [+ - * x^2 2x 3x^2 x], equivalent to x^2 + 2x - 3x^2 * x) and calculates the differential.
I'm trying to find a way to read the command line user input and put the mathematical operators into a queue, but I can't figure it out! apparently, the X=input() and x=raw_input() commands aren't working, and I can find literally 0 documentation on how to read user input in python 2.4. My question is: How do I read in user input in python 2.4, and how do I put that input into a queue? Here is what I am trying:
1 formula = input("Enter Formula:")
2
3 operatorQueue=[]
4
5 int i = len(formula)
6
7 for x in formula:
8 if formula[x] == '*', '+', '-', '/':
9 operatorQueue.append(formula[x])
0
11 print "operator A:", operatorQueue.pop(0)
12
Which is not working (I keep getting errors like "print: command not found" and "formula:command not found")
Any help would be appreciated
#miku already answered with this being your initial problem, but I thought I would add some more.
The "sh-bang" line is required by command line scripts so that the proper process is used to interpret the language, whether it be bash, perl, python,etc. So in your case you would need: /usr/bin/env python
That being said, once you get it running you are going to hit a few other issues. raw_input should be used instead of input, because it will give you back a raw string. input is going to try and eval your string which will mostly likely give you problems.
You may need to review python syntax a bit more. Assignments in python don't require that you declare the variable type: int a = 1. It is dynamic and the compiler will handle it for you.
Also, you will need to review how to do your if elif else tests to properly handle the cases of your formula. That too wont work doing it all on one line with multiple params.
If you're on a unix-ish platform, put a
#!/usr/bin/env python
on top of your program. The shell does not seem to recognize that you are running a python script.

Categories