2

I am trying to implement a function for balancing parentheses of a given math equation as a string. It should be changing the string, not just checking if it is balanced.

Because the math equation can contain trigonometric functions, I want to add radians() after such functions, because in Python, trigonometric functions take input as radians, while I want degrees.

So tan(65) becomes tan(radians(65)).
cos(65) + sin(35) becomes cos(radians(65)) + sin(radians(35))
cos((30 - 10) * 2) becomes cos(radians((30 - 10) * 2))

So far, what I've done is using replace() to replace cos( with cos(radians(, sin( with sin(radians( and the same thing goes for all the rest trigonometric functions. But the problem is, the string (which is a math equation) becomes parentheses-unbalanced.

How do I write a function to solve this problem?

First Last
  • 200
  • 3
  • 11

2 Answers2

2

You can replace cos with cosdeg and define:

def cosdeg(x):
   return cos(radians(x))

Or (lambda version):

cosdeg = lambda x : cos(radians(x))

And in a similar way with the other trig functions.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
jp48
  • 1,186
  • 10
  • 17
  • I like this answer as it shows a better way than what OP had already taken for granted as solution. – trincot Aug 19 '17 at 10:57
  • Very nice answer. However, in my program, the input is evaluated by the `eval()` function. For the sake of time and user-friendliness, I cannot define a new function. – First Last Aug 19 '17 at 11:15
1

Here is an outline of an algorithm to both insert radians( at the proper place and keep the parentheses balanced. This will work if the parentheses are indeed balanced beforehand and if there are no unbalanced parentheses in string literals such as len("abc(d"). It does not seem terribly pythonic, however.

Do not just use replace(). Instead, use find() to find a usage of cos( or other trig function. Set a counter to zero. Then scan the string from immediately after that opening parenthesis [the ( in cos(] to the right. When you encounter an opening parenthesis, increment the counter by one; when you encounter a closing parenthesis, decrement the counter by one. When your counter reaches -1 you have found the close parenthesis for your trig function. Insert a new close parenthesis at that location, then insert your radians( just after the trig function.

Continue this until you have treated all the trig functions in your string.

Rory Daulton
  • 21,934
  • 6
  • 42
  • 50
  • There is a problem with this approach: `cos (0)` is valid but not detected (there's a space between `cos` and `(`). Probably a regular expression would be needed. – jp48 Aug 19 '17 at 10:58
  • @jp48: I thought of that but the OP did not consider that possibility in his attempted algorithm. I assumed that the string has been pre-processed in some way to remove such possibilities or that he is replacing the `cos` with `cos(radians` or some such. Perhaps I should have included such details in my answer, but I decided to leave them out and call my answer "an outline of an algorithm." I am working on having the right amount of detail in my answers and I sometimes overshoot or undershoot. – Rory Daulton Aug 19 '17 at 11:21
  • @jp48: I know a little about regular expressions and I do not know how to find both the function and its paired closing parentheses. How can that be done? That would be worth a full answer. – Rory Daulton Aug 19 '17 at 11:24
  • @RoryDaulton Exactly. I do pre-process the string to eliminate all the space characters. – First Last Aug 19 '17 at 11:26
  • @RoryDaulton Well, it actually requires *recursive* regular expressions, not supported by `re`; instead the `regex` module should be installed. I believe they are not actually 'regular expressions' as formally defined by theoretical CompSci. See: https://stackoverflow.com/a/12280660/2180200 and https://stackoverflow.com/q/26385984/2180200 ; and also https://stackoverflow.com/q/2255403/2180200 – jp48 Aug 19 '17 at 11:59