Solve single variable equation using if, else and while statements in python - 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.

Related

This python code is not solving equations

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

Regular expression for validation of inequality inputted by user

I searched for an answer but I couldn't find a clear one. Please, bear with me as I'm kind of a noob in regex, and this is my first question too. I'm using Python 3, but will also be needing this for Javascript too.
What I'm trying to do is validate an input by the user. The input is an inequality (spaces removed), and the variables are named by the user and given beforehand.
For example, let's say I have this inequality:
x+y+6p<=z+1
The variables x, y, p, z will be given. The problem now if the inequality is like this:
xp+yp+6p<=z+1
The given variables are xp, yp, p, and z.
I'm trying to write a regular expression to match any inequality with such a format, given no spaces in the inequality. I cannot figure out how to check for alternative strings. For example I wrote the following expression:
^([\+\-]?[0-9]*([xpypz]|[0-9]+))+[<>]=([\+\-]?[0-9]*([xpypz]|[0-9]+))+$
I know this is completely wrong and that's not how the parentheses are used, but I don't have a feasible expression and I wanted to show you what I want to achieve. Now I need to know three things (at least, I hope) to fix it:
How to check specifically for xp, and yp as they are literally instead of all characters in the set xypz?
How to make 0-9 after xpypz work as [0-9]+? Meaning that any number can occur instead of a variable?
How can I repeat make the whole group repeated
I'm trying to write this expression to check if the user is adding undeclared variables. I believe this can be done differently without using regex, but it would be nice to do it in a single line. Can you please help me figure out those three point? Thanks.
try this pattern
(^(?=.)(?:(?:[+-]?\d*(?:xp|yp|p|z)*)+)[<>]=(?=.)(?:(?:[+-]?\d*(?:xp|yp|p|z)*)+)$)
Demo
[0-9]*(xp|yp|p|z)*([+-][0-9]*(xp|yp|p|z)*)*(<|>|<=|>=)[0-9]*(xp|yp|p|z)*([+-][0-9]*(xp|yp|p|z)*)*
This is ugly and won't catch mistakes like 1++x<p nor does it allow for other functions like sin or exponents. It matches on xp+yp+6p<=z+1 but does not on xp+yp+6x<=z+1 if xp, yp, p, and z are the variables given.
As Greg Ball mentioned, though, the best thing would be to use parsing if possible. Then you could catch more syntax errors besides using wring variables and you could do so more reliably.

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.

Python- stuck trying to create a "free hand" calculator

I'm trying to create a calculator program in which the user can type an equation and get an answer. I don't want the full code for this, I just need help with a specific part.
The approach I am trying to take is to have the user input the equation as a string (raw_input) and then I am trying to convert the numbers from their input to integers. After that I need to know how I can get the operands to do what I want them to do depending on which operand the user uses and where it is in the equation.
What are some methods I might use to accomplish this task?
Here is basically what I have right now:
equation_number = raw_input("\nEnter your equation now: ")
[int(d) for d in equation_number if d.isdigit()]
Those lines are just for collecting input and attempting to convert the numbers into integers. Unfortunately, it does not seem to be working very well and .isdigit will only work for positive numbers anyway.
Edit- aong152 mentioned recursive parsing, which I looked into, and it appears to have desirable results:
http://blog.erezsh.com/how-to-write-a-calculator-in-70-python-lines-by-writing-a-recursive-descent-parser/
However, I do not understand the code that the author of this post is using, could anyone familiarize me with the basics of recursive parsing?
The type of program you are trying to make is probably more complicated than you think
The first step would be separating the string into each argument.
Let's say that the user inputs:
1+2.0+3+4
Before you can even convert to ints, you are going to need to split the string up into its components:
1
+
2.0
+
3
+
4
This will require a recursive parser, which (seeing as you are new to python) maybe be a bit of a hurdle.
Assuming that you now have each part seperately as strings,
float("2.0") = 2.0
int(2.0) = 2
Here is a helper function
def num (s):
try:
return int(s)
except exceptions.ValueError:
return int(float(s))
instead of raw_input just use input because raw_input returns a string and input returns ints
This is a very simple calculator:
def calculate():
x = input("Equation: ")
print x
while True:
calculate()
the function takes the input and prints it then the while loop executes it again
im not sure if this is what you want but here you go and also you should make a way to end the loop
After using raw_input() you can use eval() on the result to compute the value of this string. eval() evaluates any valid Python expression and returns the outcome.
But I think this is not to your liking. You probably want to do more by yourself.
So I think you should have a look at the re module to split the input using regular expressions into tokens (sth like numbers and operators). After this you should write a parser which gets the token stream as input. You should decide whether this parser shall just return the computed value (e. g. a number) or maybe an abstract syntax tree, i. e. a data structure which represents the expression in an object-oriented (instead of character-oriented) way. Such an Absy could then be evaluated to get the final result.
Are you familiar with regular expressions? If not, it's probably a good idea to first learn about them. They are the weak, non-recursive cousin of parsing. Don't go deep, just understand the building blocks — A then B, A many times, A or B.
The blog post you found is hard because it implements the parsing by hand. It's using recursive descent, which is the only way to write a parser by hand and keep your sanity, but it's still tricky.
What people do most of the time is only write a high level grammar and use a library (or code generator) to do the hard work of parsing.
Indeed he had an earlier post where he uses a library:
http://blog.erezsh.com/how-to-write-a-calculator-in-50-python-lines-without-eval/
At least the beginning should be very easy. Things to pay attention to:
How precedence arises from the structure of the grammar — add consists of muls, not vice versa.
The moment he adds a rule for parentheses:
atom: neg | number | '(' add ')';
This is where it really becomes recursive!
6-2-1 should parse as (6-2)-1, not 6-(2-1). He doesn't discuss it, but if you look
carefully, it also arises from the structure of the grammar. Don't waste tome on this; just know for future reference that this is called associativity.
The result of parsing is a tree. You can then compute its value in a bottom-up manner.
In the "Calculating!" chapter he does that, but the in a sort of magic way.
Don't worry about that.
To build a calculator yourself, I suggest you strip the problem as much as possible.
Recognizing where numbers end etc. is a bit messy. It could be part of the grammar, or done by a separate pass called lexer or tokenizer.
I suggest you skip it — require the user to type spaces around all operators and parens. Or just assume you're already given a list of the form [2.0, "*", "(", 3.0, "+", -1.0, ")"].
Start with a trivial parser(tokens) function that only handles 3-element expressions — [number, op, number].
Return a single number, the result of the computation. (I previously said parsers output a tree which is processed later. Don't worry about that, returning a number is simpler.)
Write a function that expects either a number or parentheses — in the later case it calls parser().
>>> number_or_expr([1.0, "rest..."])
(1.0, ["rest..."])
>>> number_or_expr(["(", 2.0, "+", 2.0, ")", "rest..."])
(4.0, ["rest..."])
Note that I'm now returning a second value - the remaining part of the input. Change parser() to also use this convention.
Now Rewrite parser() to call number_or_expr() instead of directly assuming tokens[0] and tokens[2] are numbers.
Viola! You now have a (mutually) recursive calculator that can compute anything — it just has to be written in verbose style with parens around everything.
Now stop and admire your code, for at least a day :-) It's still simple but has the essential recursive nature of parsing. And the code structure reflects the grammar 1:1 (which is the nice property of recursive descent. You don't want to know how the other algorithms look).
From here there many improvements possible — support 2+2+2, allow (1), precedence... — but there are 2 ways to go about it:
Improve your code step by step. You'll have to refactor a lot.
Stop working hard and use a parsing library, e.g. pyparsing.
This will allow you to experiment with grammar changes faster.

Methods for entering equations while programming in C/C++ , Python or Fortran

I am writing a code which had long mathematical equations with many trigonometric and other identities. Is there a way of visualising the same expression in latex and making a C or python expression from it or the other way around.
How do you enter and check mathematical expressions to see if the brackets etc are in the right position and use them in latex documents?
Thanks in advance
Have you looked at Sympy? It has a module for generating LaTeX from python code, but it's actually quite a bit more.
Sympy, as you can probably guess from the name, is a python library for symbolic computation.
The Sympy library also includes it's own built-in interpreter (cd to the sympy directory in site-packages, and type ipython at a shell prompt).
With the sympy interpeter you can do things like this:
In [1]: (1/cos(x)).series(x, 0, 10)
Out[1]:
2 4 6 8
x 5⋅x 61⋅x 277⋅x
1 + ── + ──── + ───── + ────── + O(x**10)
2 24 720 8064
In [2]: ((x+y)**2).expand()
Out[2]:
2 2
x + 2⋅x⋅y + y
In [3]: (1/cos(x)).series(x, 0, 10)
Out[3]:
2 4 6 8
x 5⋅x 61⋅x 277⋅x
1 + ── + ──── + ───── + ────── + O(x**10)
2 24 720 8064
# not quite LaTeX--but Sympy can easily generate LaTeX from python code:
>>> from sympy import Integral, latex
>>> from sympy.abc import x
>>> latex(x**2)
'x^{2}'
>>> latex(x**2, mode='inline')
'$x^{2}$'
>>> latex(x**2, mode='equation')
'\\begin{equation}x^{2}\\end{equation}'
I also wanted to generally recommend the Sympy Library--under active development for about four years now and it's improved substantially each year; it's an excellent, mature library for symbolic computation with excellent docs, and an active and helpful community. (Aside from submitting a couple of patches, I am not a Sympy dev/committer, just a user.)
Edit: It seems that for certain equations it is definitely possible to automate the process, see below. Original answer left intact!
Based on many painful hours fighting LaTeX equation settings and my own failures to notice missing elements in huge equation blocks: while is almost certainly possible to convert LaTeX to python or vice versa, it will probably be more painful than just doing it by hand, and you'll likely need to spend time tidying the results anyway.
That said, similar questions have been asked and answered,
How to convert Math Formula to Python code?
Converting a python numeric expression to LaTeX
Maybe you can get started there.
edit
I took a look through previous questions, and tested a combination of comments (1 2 3). All credit to the authors of those comments!
import sympy
def python_to_latex(expression, simplify=False):
sym_expr = sympy.sympify(expression)
if simplify: sym_expr = sympy.simplify(sym_expr)
return sympy.latex(sym_expr)
if __name__ == '__main__':
print python_to_latex(raw_input("Enter a python math expression: "), simplify=True)
The best tool I know of for this is the sage project. It supports symbolic computation, and can pretty-print any equation to the terminal as ASCII or the terminal as LaTeX code or straight to PDF using LaTeX. It supersedes some of the other suggestions as it also offers interfaces to MATLAB, Mathmatica, Maple, etc.
If you have Mathematica, it can import LaTeX code to a Mathematica expression, which can then be exported to C or MATLAB code, possibly FORTRAN as well.
It is fairly simple to convert MATLAB to Python syntax, I've done it in the past by search-and-replace, but a simple script could probably do it even quicker.

Categories