By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,204 Members | 1,161 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,204 IT Pros & Developers. It's quick & easy.

String function parameter replacing

P: 2
Hi guys!

I would like to ask your help. I have started learning python, and there are a task that I can not figure out how to complete. So here it is.

We have a input.txt file containing the next 4 rows:

Expand|Select|Wrap|Line Numbers
  1. f(x, 3*y) * 54 = 64 / (7 * x) + f(2*x, y-6)
  2.  
  3. x + f(21*y, x - 32/y) + 4 = f(21 ,y)
  4.  
  5. 86 - f(7 + x*10, y+ 232) = f(12*x-4, 2*y-61)*32 + f(2, x)
  6.  
  7. 65 - 3* y = f(2*y/33 , x + 5)
The task is to change the "f" function and it's 2 parameters into dividing. There can be different amount of spaces between the two parameters. For example f(2, 5) is the same as f(2 , 5) and should be (2 / 5) with exactly one space before and after the divide mark after the running of the code. Also, if one of the parameters are a multiplification or a divide, the parameter must go into bracket. For example: f(3, 5*7) should become (3 / (5*7)). And there could be any number of function in one row. So the output should look like this:

Expand|Select|Wrap|Line Numbers
  1. (x / (3*y)) * 54 = 64 / (7 * x) + ((2*x) / (y-6))
  2.  
  3. x + ((21*y) / (x - 32/y)) + 4 = (21 / y)
  4.  
  5. 86 - ((7 + x*10) / (y+ 232)) = ((12*x-4) / (2*y-61))*32 + (2 / x)
  6.  
  7. 65 - 3* y = ((2*y/33) / (x + 5))
I would be very happy if anyone could help me.

Thank you in advance,
David
May 12 '14 #1

✓ answered by bvdet

Actually, I did not need to use start and end variables. That was causing the missed third match. The search method will find the first occurrence of the match string. After redefining the string using the previous match, the next match will be found. I modified a few other things so it would work.
Expand|Select|Wrap|Line Numbers
  1. import re
  2.  
  3. s = "86 - f(7 + x*10, y+ 232) = f(12*x-4, 2*y-61)*32 + f(2, x) - 12*6"
  4. patt = re.compile(r"(f\((.[^)]+)\))")
  5.  
  6. while True:
  7.     m = patt.search(s)
  8.     if m:
  9.         s1 = m.group(1)
  10.         s2 = m.group(2)
  11.         a,b = [ss.strip() for ss in s2.split(",")]
  12.         if "+" in b or "-" in b or "*" in b or "/" in b:
  13.             b = "(%s)" % b     
  14.         if "+" in a or "-" in a or "*" in a or "/" in a:
  15.             a = "(%s)" % a 
  16.         s = s.replace(s1, "(%s / %s)" % (a,b), 1)
  17.     else:
  18.         break
  19. print s
Hopefully inline code will display properly:
patt = re.compile(r'(f\((.[^)]+)\))')

Share this Question
Share on Google+
4 Replies


bvdet
Expert Mod 2.5K+
P: 2,851
Here's a simplified version using a re solution showing unconditional formatting of the replacement string. I'll leave it up to you to finalize the formatting.
Expand|Select|Wrap|Line Numbers
  1. import re
  2.  
  3. s = "86 - f(7 + x*10, y+ 232) = f(12*x-4, 2*y-61)*32 + f(2, x) - 12*6"
  4. patt = re.compile(r'(f\((.[^)]+)\))')
  5.  
  6. start = 0
  7. end = len(s)
  8. while True:
  9.     m = patt.search(s, start, end)
  10.     if m:
  11.         s1 = m.group(1)
  12.         s2 = m.group(2)
  13.         a,b = [ss.strip() for ss in s2.split(",")]
  14.         s = s.replace(s1, "(%s) / (%s)" % (a,b), 1)
  15.         start = m.end()+1
  16.     else:
  17.         break
Resulting string:
Expand|Select|Wrap|Line Numbers
  1. >>> s
  2. '86 - (7 + x*10) / (y+ 232) = (12*x-4) / (2*y-61)*32 + (2) / (x) - 12*6'
May 12 '14 #2

P: 2
Thank you very much, you helped me out quite well. Now I get it more or less. This is kinda difficult to decode:
Expand|Select|Wrap|Line Numbers
  1. patt = re.compile(r'(f\((.[^)]+)\))')
.

However, I tried to give it some conditions, like if the left or right part of the f() call contains "+, -, *, /" marks, then replace it with a bracketed one. It only works for the first two call function but it leaves out the third one. I don't know why, I tried to print every useful information, and it looks like the search just can't find the 3rd one no matter where it starts. Could you help me out at this one as well? I'm sorry for being this problematic, but I really would like to understand how it works. Thank you in advance. Here's the code:

Expand|Select|Wrap|Line Numbers
  1. import re
  2.  
  3. s = "86 - f(7 + x*10, y+ 232) = f(12*x-4, 2*y-61)*32 + f(2, x) - 12*6"
  4. patt = re.compile(r'(f\((.[^)]+)\))')
  5.  
  6. start = 0
  7. end = len(s)
  8. while True:
  9.     m = patt.search(s, start, end)
  10.     if m:
  11.         s1 = m.group(1)
  12.         s2 = m.group(2)
  13.         a,b = [ss.strip() for ss in s2.split(",")]
  14.     if "+" in b or "-" in b or "*" in b or "/" in b:
  15.         b = b.replace(b, "(%s)" % b)
  16.     else:
  17.         print "Nothing.";
  18.  
  19.     if "+" in a or "-" in a or "*" in a or "/" in a:
  20.         a = a.replace(a, "(%s)" % a)
  21.     else:
  22.         print "Nothing.";
  23.  
  24.         s = s.replace(s1, "(%s / %s)" % (a,b), 1)
  25.         start = m.end()+1
  26.     else:
  27.         break
  28.  
  29. print s
May 13 '14 #3

bvdet
Expert Mod 2.5K+
P: 2,851
Actually, I did not need to use start and end variables. That was causing the missed third match. The search method will find the first occurrence of the match string. After redefining the string using the previous match, the next match will be found. I modified a few other things so it would work.
Expand|Select|Wrap|Line Numbers
  1. import re
  2.  
  3. s = "86 - f(7 + x*10, y+ 232) = f(12*x-4, 2*y-61)*32 + f(2, x) - 12*6"
  4. patt = re.compile(r"(f\((.[^)]+)\))")
  5.  
  6. while True:
  7.     m = patt.search(s)
  8.     if m:
  9.         s1 = m.group(1)
  10.         s2 = m.group(2)
  11.         a,b = [ss.strip() for ss in s2.split(",")]
  12.         if "+" in b or "-" in b or "*" in b or "/" in b:
  13.             b = "(%s)" % b     
  14.         if "+" in a or "-" in a or "*" in a or "/" in a:
  15.             a = "(%s)" % a 
  16.         s = s.replace(s1, "(%s / %s)" % (a,b), 1)
  17.     else:
  18.         break
  19. print s
Hopefully inline code will display properly:
patt = re.compile(r'(f\((.[^)]+)\))')
May 13 '14 #4

bvdet
Expert Mod 2.5K+
P: 2,851
Here's an attempt to explain the re pattern
r'(f\(([^)]+)\))'
Open parenthesis - start group 1
f - Match "f" character
backslash+( - Match "(" character
Open parenthesis - start group 2
[^)] - Match characters that are not ")"
+ - Greedily matches one or more of the previous expression
Close parenthesis - end group 2
backslash+) - Match ")" character
Close parenthesis - end group 1
May 13 '14 #5

Post your reply

Sign in to post your reply or Sign up for a free account.