1
\$\begingroup\$

This is the adder method of my binary calculator. I did not cover for the case that someone passes a non binary number into the calculator yet.

I am pretty sure I have covered every other edge case for the calculator. I am trying to learn refactoring and how to look for simpler ways to do things. I know that I have a bunch of if's, but I don't know any other way I could have made the logic for this. Could someone mentor me through how they would refactor my code and why?

class BinaryCalculator:

    def bit_adder(self, number1, number2):
        num_a = self.num_to_list(number1)
        num_b = self.num_to_list(number2)
        maxx = max(len(num_a), len(num_b))
        minn = min(len(num_a), len(num_b))

        if minn == len(num_b):
            smaller = num_b
            num_b = [0] * (maxx - minn)
            for i in smaller:
                num_b.append(i)
        else:
            smaller = num_a
            num_a = [0] * (maxx - minn)
            for i in smaller:
                num_a.append(i)

        print " ",''.join(map(str, num_a))
        print "+",''.join(map(str, num_b))
        print '----------'
        carry_bit = 0
        answer = [0] * (maxx + 1)

        for bit in xrange(maxx - 1, -1, -1):
            sum_bit = 0
            if num_a[bit] == num_b[bit]:
                if num_a[bit] == 1:
                    if carry_bit == 0:
                        carry_bit += 1
                    else:
                        sum_bit = 1
                else:
                    if carry_bit == 1:
                        sum_bit = 1
                        carry_bit -= 1

            else:
                if carry_bit == 1:
                    sum_bit == 0
                else:
                    sum_bit = 1
            answer[bit + 1] = sum_bit

        if carry_bit == 1:
            answer[0] = 1

        print ''.join(map(str, answer))


    def num_to_list(self, num):
        num = str(num)
        list_to_return = []
        for bit in range(len(num)):
            list_to_return.append(int(num[bit]))
        return list_to_return


c = BinaryCalculator()

c.bit_adder(10011001, 1001)
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

There are some issues with your code concerning the code design.

Why do you use a class for your BinaryCalculator? You don't have multiple instances of the class, you do not even give the class a meaningful constructor. This task should not be solved with OOP, but just with regular functions.

You can easily drop the class and define the two functions as top level functions, e.g:

def num_to_list(num):
    ..... your code goes here ...

def bit_adder(a, b):
    ..... your bit adder goes here ....

if __name__ == '__main__':
    res = bit_adder(111101, 1011)
    print(res)

Second, you can reduce your code significantly with some utility functions, e.g for your num_to_list function:

def num_to_list(x):
    return [int(n) for n in reversed(str(x))]

Third, for your bit_adder the function zip_longest from the package itertools comes in handy. This just zips two lists like a regular zip, but fills up the shorter list with default values.

That's why I reversed the bit order in the num_to_list function earlier.

With this function you can reduce your bit_adder to a more compact version:

# zip the two revered bit lists with a default fillvalue of 0
z = itertools.zip_longest(a, b, fillvalue=0)
# add each bit, this results of a list that could look like [1, 0, 2, 1]
added = [n + k for n, k in z]

# we still have to get rid of the two's, so we iterate through the list
# and take care of the overflows, similarly to your approach
carry = 0
for n, v in enumerate(added):
    if v != 2 and carry == 0:
        continue
    elif v == 0 and carry == 1:
        added[n] = v + carry
        carry = 0
    else:
        added[n] = 0
        carry = 1

if carry == 1:
    added.append(carry)

The main advantage of this version, is that you don't have to care about the smaller or bigger number.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.