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)+")") 
Asked By: saad

||

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

Answered By: FelixFelixFelix

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:

  1. 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):
    
  2. 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.

  3. Names of your variables are important. y or z describe nothing, similar is confusing – what about common instead?

  4. Instead of

    h = inputString.split("+")
    y = h[0]
    z = h[1]
    

    you may use

    y, z = inputString.split("+")         # so called "unpacking" list (or tuple)
    
  5. Your prompt "Enter Regular Expression: " is confusing. You don’t expect a regular expression, but an algebraic expression, do you?

  6. 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").

Answered By: MarianD
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.