Do conversions once
As written, with the example input, str(binary_value)
will be called 22 times, with the same input value, and returning the same value each time. This is very inefficient; it is wasted work. It would be better to call it once, and store the result, and use this stored value:
def binary_to_decimal_converter(binary_value):
binary_value = str(binary_value)
# ... rest of function, without any more str(binary_value) calls
But ...
Representing Binary Numbers
As pointed out by harold in the comments, the literal 1111101100
is an integer value slightly larger than one billion in Python. You should use a string to represent a binary number to be converted.
# Calling the function
binary_to_decimal_converter("1111101100")
Since we're passing a string to the function, all of the calls to str(binary_value)
are now completely unnecessary.
String Constants
if str(binary_value)[loop_var] == str(1):
Again, using the example value, the expression str(1)
will be evaluated ten times; once for each digit of the input. This will convert the numerical value one into the string "1"
, which will be discarded immediately after use, only to be recreated on the next iteration. Why not just use the literal "1"
? Not only is it more efficient; it is 3 characters shorter.
Loop like a Native
See "Loop like a Native" by Ned Batchelder on YouTube for more details, motivation, etc.
Part 1
Our modified code now looks like this:
loop_var = 0
while loop_var < len(binary_value):
# ...
loop_var += 1
len(binary_value)
is computed once for each iteration through the loop; 11 times, including the last pass where the condition evaluates to False
and the loop terminates. Since the string doesn't change inside the loop, the length won't change either, so this value is a constant.
loop_var = 0
limit = len(binary_value)
while loop_var < limit:
# ...
loop_var += 1
Now that we've recognized that limit
is fixed, we can see this is actually a for
loop, that starts at zero, counts up by 1, and stops when it reaches limit
. Instead of manually adjusting the loop_var
by 1, and manually doing the comparison, we should simply use the for
loop, over the required range
, which is much more efficient:
for loop_var in range(len(binary_value)):
# ...
Part 2
Our loop now looks like:
for loop_var in range(len(binary_value)):
if binary_value[loop_var] == "1":
# ...
# ...
Indexing is expensive in Python. Anytime you see a for
loop, using a range(len(thing))
, and the loop variable is only used as a index into the thing
which the range is looping over, thing[loop_var]
, then we want to let Python do the indexing for us in the for
statement:
for digit in binary_value:
if digit == "1":
# ...
# ...
Return Value
return print(f"Decimal: {decimal_value}")
Is this function returning a value, or is it printing the result? Currently, it is taking the value which is returned by the print()
function, and returning that. Ie)
temporary = print(f"Decimal: {decimal_value}")
return temporary
But print()
returns None
, so this is effectively:
print(f"Decimal: {decimal_value}")
return None
And if the function ends without a return statement, it automatically returns None
anyway. So the return
can simply be omitted.
Note: It is better to return results from a function that does a calculation, without printing anything inside the function, and have the caller do the printing. This will create more flexible code in the future. Left to student.
Improved code
def binary_to_decimal_converter(binary_value):
print(f"Binary: {binary_value}")
decimal_value = 0
# power is power of number 2
# power must be less than string length because computer starts counting from 0th index
power = len(binary_value) - 1
for digit in binary_value:
if digit == "1":
decimal_value += 2 ** power
power -= 1
print(f"Decimal: {decimal_value}")
# Calling the function
binary_to_decimal_converter("1111101100")
str(binary_value)
\$\endgroup\$