Python binary to decimal converter (without using built-ins)

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.

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()