In your code, simply remove this line as you are immediately reassigning over the functions input argument
binary = []
As a more concise alternative
def binatodeci(binary):
return sum(val*(2**idx) for idx, val in enumerate(reversed(binary)))
Example
>>> binatodeci([1,1,0,1])
13
Answer from Cory Kramer on Stack OverflowIn your code, simply remove this line as you are immediately reassigning over the functions input argument
binary = []
As a more concise alternative
def binatodeci(binary):
return sum(val*(2**idx) for idx, val in enumerate(reversed(binary)))
Example
>>> binatodeci([1,1,0,1])
13
As stated in Cory Kramer's answer, simply remove the line binary = [] at the beginning of your code and it will work perfectly.
Here is an alternative algorithm, given as food for thought:
def binatointeger(binary):
number = 0
for b in binary:
number = (2 * number) + b
return number
Important note
Note that the resulting number is not in decimal. It's a python integer. Internally in the computer, python integers are stored in binary. The conversion to decimal representation, i.e., to a string of digits, happens when calling the function print, str, or repr, to print the number to screen.
How to Convert list of binary number to decimal in python without using any inbuilt function?
Algorithm to convert a 2d binary list to decimal numbers in Python - Stack Overflow
Convert a binary number in a list back to its decimal form in python? - Stack Overflow
python - Converting binary to decimal integer output - Stack Overflow
For example: [1,0,0,1] should give output 9
Just collect bits of integer value instead of string-int transformations: (pseudocode)
for every row:
value = 0
for every col:
value = (value << 1) | biglist[row][col][0] # bitwise shift left and OR
#equivalent operation:
value = value * 2 + biglist[row][col][0]
First, using string to int conversion with join is convenient, but slow. Compute the value from the powers of 2 classicaly, using sum, enumerate and bit shift on the ones (skip the zeroes)
Second, you should use collections.Counter for this
In one line:
result = collections.Counter(sum(v[0]<<(len(k)-i-1) for i,v in enumerate(k) if v[0]) for k in biglist)
this code runs 30% faster as your original code on my machine.
You can use int and set the base to 2 (for binary):
>>> binary = raw_input('enter a number: ')
enter a number: 11001
>>> int(binary, 2)
25
>>>
However, if you cannot use int like that, then you could always do this:
binary = raw_input('enter a number: ')
decimal = 0
for digit in binary:
decimal = decimal*2 + int(digit)
print decimal
Below is a demonstration:
>>> binary = raw_input('enter a number: ')
enter a number: 11001
>>> decimal = 0
>>> for digit in binary:
... decimal = decimal*2 + int(digit)
...
>>> print decimal
25
>>>
Binary to Decimal
int(binaryString, 2)
Decimal to Binary
format(decimal ,"b")
ps: I understand that the author doesn't want a built-in function. But this question comes up on the google feed even for those who are okay with in-built function.
A few additional points for your learning experience.
You're not using sys, so the import line is unnecessary.
In range(...), the default start is 0,
so instead of range(0, x) you can write simply range(x).
Don't use pointless comments like this:
# Return 1 if exponent is 0 if exponent == 0: return 1
Instead if this:
power = base for j in range(1, exponent): power *= base
It would be better this way:
power = 1
for j in range(exponent):
power *= base
Because in this version base is referenced only once,
and range is simplified by dropping 1 to use the default 0.
action="store" is unnecessary here:
parser.add_argument('binary_number', action="store")
main is not a good name for that function does.
It would be better to rename it to binary_to_decimal, for example.
And while at it,
it would be better to move the content from the if __name__ ... inside a new main method, like this:
def main():
parser = argparse.ArgumentParser(description='Converts a binary to a decimal number.')
parser.add_argument('binary_number')
args = parser.parse_args()
binary_to_decimal(args.binary_number)
if __name__ == '__main__':
main()
Many people miss this point, actually.
The reason to do it this way is that code in the if __name__ ... block is in the global namespace.
So variables with the same name in the rest of the code will shadow those variables,
which can lead to nasty bugs.
By moving that code to a method,
this cannot happen.
PEP8
PEP8 is the official style guide of Python, and you have a few violations:
Put 2 blank lines before each method definition and you only put 1.
Put 2 spaces in front of
# inline commentsLines should not be longer than 79 characters
That is nice-looking code, but it's also quite long for the problem that you are solving. The simple solution would be print(int(binary_number, 2)).
Assuming that you want to solve the problem the hard way as an exercise, it's a good idea to separate your calculation routines from your input/output routines. You need a binary_to_int(binary_string) function. It can be implemented using a much simpler algorithm.
def binary_to_int(binary_string):
n = 0
for char in binary_string:
n *= 2
if char == '1':
n += 1
return n