Applying distributive law for two strings in Python
Question:
I am trying to apply the distributive law for two strings, e.g. "ab+ac" returns "a(b+c)". I managed to do that. But the problem I am facing is with longer texts. e.g. "aabbcd+aabbgf" it should return "aabb(cd+gf)".
Where is the problem in my code?
inputString = input("Enter Regular Expression: ")
def destributionOfAnExpression():
if "+" not in inputString:
return inputString
else:
h = inputString.split("+")
y = h[0]
z = h[1]
similar = ""
for i in y:
for j in z:
while i==j:
similar+=i
break
break
print(similar+"("+y.strip(similar)+"+"+z.strip(similar)+")")
Answers:
change the while loop for an if statement and remove the last break
def destributionOfAnExpression(inputString):
if "+" not in inputString:
return None
else:
h = inputString.split("+")
y = h[0]
z = h[1]
similar = ''
for i in y:
for j in z:
if i == j:
similar += i
break
print(similar+"("+y.strip(similar)+"+"+z.strip(similar)+")")
I also made some changes to your function that should prevent future errors
Your main problem is here:
for i in y:
for j in z:
You don’t want to compare every symbol in y
with every symbol in z
(Cartesian product), but to compare symbols in sync, i.e. at the same position:
for i in range(min(len(y), len(z))):
if y[i] == z[i]:
similar += y[i]
else:
break
Note: No other break
in your code.
The second issue consists in applying the .strip()
method, which strips given substring from both ends of the string, which is error-prone.
Use .lstrip()
("left" strip) instead, or – even better – use y[i+1:]
and z[i+1:0]
:
print(similar + "(" + y[i+1:] + "+" + z[i+1:] +")")
But concatenating more than two strings with +
is horrible – use f-string instead:
first = y[i+1:]
second = z[i+1:]
print(f"{similar}({first}+{second})")
Some notes:
-
It is not a good practice to use a variable (inputString
) from the global scope in the body of your function. Provide it as a parameter:
def destributionOfAnExpression(inputString):
-
It is not a good practice to print the result in the body of the function. Return it instead:
return f"{similar}({first}+{second})"
Users of your function may decide themselves, if they want to print it, or use it in other way.
-
Names of your variables are important. y
or z
describe nothing, similar
is confusing – what about common
instead?
-
Instead of
h = inputString.split("+")
y = h[0]
z = h[1]
you may use
y, z = inputString.split("+") # so called "unpacking" list (or tuple)
-
Your prompt "Enter Regular Expression: " is confusing. You don’t expect a regular expression, but an algebraic expression, do you?
-
Use names in concordance with PEP 8 – Style Guide for Python Code, i.e. not
destributionOfAnExpression
but
distribution_of_an_expression
(all lowercase, the underscore as a word delimiter, a.k.a "snake_case").
I am trying to apply the distributive law for two strings, e.g. "ab+ac" returns "a(b+c)". I managed to do that. But the problem I am facing is with longer texts. e.g. "aabbcd+aabbgf" it should return "aabb(cd+gf)".
Where is the problem in my code?
inputString = input("Enter Regular Expression: ")
def destributionOfAnExpression():
if "+" not in inputString:
return inputString
else:
h = inputString.split("+")
y = h[0]
z = h[1]
similar = ""
for i in y:
for j in z:
while i==j:
similar+=i
break
break
print(similar+"("+y.strip(similar)+"+"+z.strip(similar)+")")
change the while loop for an if statement and remove the last break
def destributionOfAnExpression(inputString):
if "+" not in inputString:
return None
else:
h = inputString.split("+")
y = h[0]
z = h[1]
similar = ''
for i in y:
for j in z:
if i == j:
similar += i
break
print(similar+"("+y.strip(similar)+"+"+z.strip(similar)+")")
I also made some changes to your function that should prevent future errors
Your main problem is here:
for i in y:
for j in z:
You don’t want to compare every symbol in y
with every symbol in z
(Cartesian product), but to compare symbols in sync, i.e. at the same position:
for i in range(min(len(y), len(z))):
if y[i] == z[i]:
similar += y[i]
else:
break
Note: No other break
in your code.
The second issue consists in applying the .strip()
method, which strips given substring from both ends of the string, which is error-prone.
Use .lstrip()
("left" strip) instead, or – even better – use y[i+1:]
and z[i+1:0]
:
print(similar + "(" + y[i+1:] + "+" + z[i+1:] +")")
But concatenating more than two strings with +
is horrible – use f-string instead:
first = y[i+1:]
second = z[i+1:]
print(f"{similar}({first}+{second})")
Some notes:
-
It is not a good practice to use a variable (
inputString
) from the global scope in the body of your function. Provide it as a parameter:def destributionOfAnExpression(inputString):
-
It is not a good practice to print the result in the body of the function. Return it instead:
return f"{similar}({first}+{second})"
Users of your function may decide themselves, if they want to print it, or use it in other way.
-
Names of your variables are important.
y
orz
describe nothing,similar
is confusing – what aboutcommon
instead? -
Instead of
h = inputString.split("+") y = h[0] z = h[1]
you may use
y, z = inputString.split("+") # so called "unpacking" list (or tuple)
-
Your prompt "Enter Regular Expression: " is confusing. You don’t expect a regular expression, but an algebraic expression, do you?
-
Use names in concordance with PEP 8 – Style Guide for Python Code, i.e. not
destributionOfAnExpression
but
distribution_of_an_expression
(all lowercase, the underscore as a word delimiter, a.k.a "snake_case").