2
\$\begingroup\$

Any ideas how I could improve this? I already know that there is no checking for anything other than a 1, so you can enter a 2 or an a or a b and it will be interpreted as a 0, not interfering with the program's functionality. What I would like to know is if anyone has any suggestions for improving the logic.

def main():

  #Input
  binary = input("Enter a line of binary: ")

  #Reverses input
  toCalc = binary[::-1]

  #Finds length of input
  binLen = len(binary)

  #Variables
  total = 0
  exp = 0 #Exponent

  #loop while current character place is less than input length
  while exp < binLen:
    if toCalc[exp] == "1": #If current char is a '1', add 2^exp to the total
        total += 2 ** int(exp)
    exp += 1
  print (total)
  main()


main()

Here is a link to a working version of the script.

\$\endgroup\$
  • \$\begingroup\$ Are you intentionally trying to avoid python's built-in way to do this? If you are that is fine, I just want to make sure. \$\endgroup\$ – TheBlackCat Jun 28 '16 at 18:16
  • \$\begingroup\$ If so, this question should have the "reinventing-the-wheel" tag \$\endgroup\$ – syb0rg Jun 28 '16 at 18:21
  • \$\begingroup\$ Yeah that was the point, thanks for the tag suggestion. \$\endgroup\$ – Confettimaker Jun 28 '16 at 18:39
3
\$\begingroup\$

This algorithm could pretty easily be converted to a one-liner. Let's walk through the logic:

  1. You want to work over each element of a string. You can just iterate over the string, rather than keeping track of an index.
  2. You also need the index of that element, so you can use enumerate to get both.
  3. You want to apply a mathematical operation if and only if the integer is not 0. This can be done using int(val), which converts the value to the number it represents.
  4. You want to add all the values at the end. This can be done with sum.

To get error checking, you can convert the string to a set, and make sure the set is equal to a set with only 0 and 1 in it.

Also, you probably want the input handling in a while loop to avoid the recursion, which will fill up your memory, and then have a separate function to handle the actual conversion.

Also, I would only run main if the code is run as a script.

And keep in mind python has a built-in way to do binary to decimal conversion: int(binstr, 2), which can be used to test your implementation at the very least.

So here is how I would implement it:

def bin2int(binstr):
    if set(binstr) != {'0', '1'}:
        raise ValueError('String is not binary: "%s"' % binstr)

    return sum(int(x)*2**i for i, x in enumerate(a[::-1]))


def main():
    while True:
        binary = input("Enter a line of binary, enter 'q' to quit: ")

        if binary.lower() == 'q':
            break

        try:
            print(bin2int(binary))
        except ValueError as err:
            print(err)


if __name__ == "__main__":
    main()
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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