Decimal to binary self challenge - python-3.x

I have tried to write a small program that converts a decimal to binary that doesn't use the inbuilt function that do that. My program won't convert anything over 12287. 12288 just spits out an infinite loop. Where have I gone wrong? why can't I get above 12287?
while (number != 1) or (number != 0):
a = number // 2
b = number % 2
number = a
if b == 0:
output = "0" + output
if number == 1:
output = "1" + output
break
else:
output = "1" + output

You just need to change the condition from:
while (number != 1) or (number != 0):
To:
while number != 0:
Other than that, your code looks OK. Here is a more streamlined version of the same basic idea:
output = ""
while number:
number, b = divmod(number, 2)
output = str(b) + output

For 12288, number eventually becomes 0. This means while condition is always True.
Note that b becomes 0, so number will stay at 0.

Related

How do I write a python function to count consecutive zeros in a binary representation of a number?

Given a number N, the function should convert the number to binary form, count the number of consecutive zero (the binary gap), and return the maximum binary gap. For example, 9 = 1001, the binary gap of length 2. The number 529 = 1000010001, has 2 binary gaps with length 4 and 3. If the number has 2 or more binary gaps, the function should return the maximum binary gap i.e. 4 in the case of N = 529.
I tried this function:
def solution(N):
binaryN = bin(N)[2:]
n = len(binaryN)
binaryGap = []
for i in range(n):
if binaryN[i] == 0 and binaryN[i + 1] == 0:
m = len(binaryN)
else:
return 0
binaryGap = binaryGap.append(m)
return max(binaryGap)
The function returns 0 for all values of N which is incorrect. How do I debug/improve the code to produce the accurate result?
Check out the below code. It would solve your problem.
The code is self-explanatory, yet let me know in-case of any doubts.
The Code:
import sys
num = int(sys.argv[1])
# Function to get the binary gap.
def binaryGapFinder(num):
binnum = bin(num).replace("0b", "") # binnum is binary form of the given number.
i = 0
x = 0
x_list = []
while i <= len(binnum)-1:
if binnum[i] == "0":
x += 1
if i == len(binnum)-1: # This loop will also consider if binary form is ending with 0. for example: 12 -> 1100
x_list.append(x)
else:
x_list.append(x)
x = 0
i += 1
return f"The Number: {num}\nIt's Binary Form: {binnum}\nMaximum Consecutive 0's: {max(x_list)}"
print(binaryGapFinder(num))
The Output:
python3 /the/path/to/your/script/binarygap.py 529
The Number: 529
It's Binary Form: 1000010001
Maximum Consecutive 0's: 4
python3 /the/path/to/your/script/binarygap.py 12
The Number: 12
It's Binary Form: 1100
Maximum Consecutive 0's: 2
python3 /the/path/to/your/script/binarygap.py 512
The Number: 512
It's Binary Form: 1000000000
Maximum Consecutive 0's: 9
There's a few issues here worth mentioning to aid you. (Just a side note to start with is that, in Python, it's recommended/best practice to use all lower case for variable names, so I'll replace them in my examples below.)
The bin() built in function returns a string. So you should be checking for equality with "0" (or '0') instead of an integer. e.g.
if binaryN[i] == "0" and binaryN[i + 1] == "0":
With Python you don't need to bother with checking for lengths of strings (or any other iterables) to use in a for loop in scenarios like this. e.g. You can replace:
n = len(binaryN)
for i in range(n):
with the more "Pythonic" way:
for bit in binary_number:
You can then use the variable bit (call it whatever you want of course, bearing in mind that good variable names make code more readable) instead of binary_number[index]. In this case, with each iteration of the for loop, bit will be replaced with the next character in the binary_number string.
From there on in your code:
m = len(binaryN)
will always be the same value, which is the total length of the string binaryN. e.g. 4 for '1001'.) This is not what you intended.
The first statement in your else block of code return 0 will terminate your function immediately and return 0 and thus your binaryGap = binaryGap.append(m) code will never, ever execute as it's unreachable due to that preceding return stopping any further execution of code in that suite.
You've got the right idea(s) and heading towards the right track for a solution but I don't think your code, even when the issues above are corrected, will match all possible binary numbers you may encounter. So, another possible alternative (and yet roughly sticking with the solution I think that you had in mind yourself) would be something like this which I hope will help you:
def solution(n):
binary_no = bin(n)[2:]
binary_gaps = []
gap_counter = 0
for bit in binary_no:
if bit == "0":
gap_counter += 1
else:
# Encountered a 1 so add current count of 0's -- if any -- to list and reset gap_counter
if gap_counter > 0:
binary_gaps.append(gap_counter)
gap_counter = 0
else:
# A for else suite (block of code) is run when all iterables have been exhausted.
if gap_counter > 0:
binary_gaps.append(gap_counter)
if binary_gaps: # If there is at least one element in the list
if len(binary_gaps) > 1:
return max(binary_gaps)
else:
return binary_gaps[0]
else:
# The list is empty, so no gaps were found at all. i.e. Binary number was all 1's.
return 0
print(solution(529))

Counting 9's in numbers from 1 to n

I'm trying to count all 9's in numbers from 1 to n, including repeating digits such as in 99. My code (python 3) works and returns the corrects answer for most cases except for very large numbers (like 20 digit numbers). Could someone help and let me know how this is possible?
Thanx.
def count_nines(n):
count = 0
num = [i for i in str(n)]
while len(num) > 0:
if len(num) == 1:
if num[0] == '9':
count += 1
else:
count += int(num[0]) * int(str(len(num)-1).ljust(len(num)-1, '0'))
if num[0] == '9':
count += int(''.join(num[1:]))+1
num.pop(0)
return count
The problem is in this expression:
int(str(len(num)-1).ljust(len(num)-1, '0'))
This works fine as long as str(len(num)-1) is one character, but when len(num) > 10, this is no longer the case, and then ljust will add fewer zeroes than needed. In fact, you always want to append len(num)-2 zeroes. So change this expression to:
int(str(len(num)-1) + '0' * (len(num)-2))
Simply:
def count_nines(n):
count = 0
for i in range(n+1):
if "9" in [*str(i)]:
count = count + str(i).count('9')
return count
sum((str(i).count('9') for i in range(1, n+1)))

Variable not changing after trying to update it

I'm trying to make a variable update after a line of the code is passed. The problem I'm having is that, once that line of the code is passed and then printed again, the variable is the default one, in this case 10.
I don't know if I'm doing something wrong or anything, but I just can't see where I'm failing, maybe because I'm a beginner. Tried everything I could think of before asking for help but at this point I'm desperate. Thanks.
number = 10
def numberFun(question,valid=("ADD","REM")):
while (answer := input(question)) and answer not in valid:
print(f"Please, choose between {valid}.")
return answer
print(f"{number}: before updating.")
numberAction = numberFun("You want to add or remove one?\n")
if numberAction == "ADD":
print(number + 1)
elif numberAction == "REM":
print(number - 1)
print(f"{number} : after updating.")
This is because you aren't updating the value stored in number. My guess is that you are trying to do so in your if/elif clauses; if that is the case, this should work:
number = 10
def numberFun(question,valid=("ADD","REM")):
while (answer := input(question)) and answer not in valid:
print(f"Please, choose between {valid}.")
return answer
print(f"{number}: before updating.")
numberAction = numberFun("You want to add or remove one?\n")
if numberAction == "ADD":
number += 1 # equivalent to 'number = number + 1'
elif numberAction == "REM":
number -= 1 # equivalent to 'number = number - 1'
print(number)
print(f"{number} : after updating.")
Originally, you were only printing number after some operation. In order for the value in number to change, you would need to reassign some value to the variable.
Notice how I perform a computation where you performed output. I moved output below the computations.
number = 10
def numberFun(question,valid=("ADD","REM")):
while (answer := input(question)) and answer not in valid:
print(f"Please, choose between {valid}.")
return answer
print(f"{number}: before updating.")
numberAction = numberFun("You want to add or remove one?\n")
if numberAction == "ADD":
number = number + 1
elif numberAction == "REM":
number = number - 1
print(number)
print(f"{number} : after updating.")
To add or subtract 1 from the variable num you need to do addition or subtraction operation on the value and store that in the same variable to "update" it.
In your code, in line 12 and line 14, you do the addition, subtraction respectively but you print the result instead of storing the result in the variable number which would "update" the prestored value which in this case is 10.
So, replacing print(number + 1) from line 12 with number += 1 to add 1 to the previous value and replacing print(number - 1) from line 14 with number -= 1 to subtract one to "update" the stored value based on the user's choice.
Then, in the last line when you print the number variable it will display the "updated" value of the variable number
number = 10
def numberFun(question,valid=("ADD","REM")):
while (answer := input(question)) and answer not in valid:
print(f"Please, choose between {valid}.")
return answer
print(f"{number}: before updating.")
numberAction = numberFun("You want to add or remove one?\n")
if numberAction == "ADD":
number += 1
elif numberAction == "REM":
number -= 1
print(f"{number} : after updating.")

In binary search, why is my loop infinite?

I run a while loop with a function to check if a variable i is higher than the len of the list. I placed it there as a way to stop the loop, but it does not check it. Since it doesn't end on it's own I had to place an if condition inside that returns false.
def binarySearch(numberlist, number):
first = 0
last = len(numberlist)-1
found = False
i=0
while found == False or i <= len(numberlist):
i = i + 1
mid = (first + last) // 2
print(numberlist[mid])
if i > len(numberlist)+1:
return False
if mid < first or mid > last or mid < 0:
return False
if number == numberlist[mid] or number == numberlist[first] or number == numberlist[last] :
return True
elif number < numberlist[mid]:
last = mid
elif number > numberlist[mid]:
first = mid
return False
The error lies in the following lines.
elif number < numberlist[mid]:
last = mid
elif number > numberlist[mid]:
first = mid
Consider the case where we are looking for a number which is not in the list.
The pointers first, last and mid will eventually all converge to some index. In that case one of the two last conditions will be True, but since all three values are already equal, the pointers are not updated anymore and we enter an infinite loop.
To makes sure this does not happen, we must make sure the interval always decreases in size by setting first to mid + 1 or last to mid - 1, depending on the condition. We can then stop looping if first becomes greater than last.
def binary_search(numberlist, number):
first, last = 0, len(numberlist) - 1
while first <= last:
mid = (first + last) // 2
if numberlist[mid] == number:
return True
elif numberlist[mid] > number:
last = mid - 1
else:
first = mid + 1
return False

how to convert decimal to binary by using repeated division in python

how to convert decimal to binary by using repeated division in python?
i know i have to use a while loop, and use modulus sign and others {%} and {//} to do this...but i need some kind of example for me to understand how its done so i can understand completely.
CORRECT ME, if I'm wrong:
number = int(input("Enter a numberto convert into binary: "))
result = ""
while number != 0:
remainder = number % 2 # gives the exact remainder
times = number // 2
result = str(remainder) + result
print("The binary representation is", result)
break
Thank You
Making a "break" without any condition, makes the loop useless, so the code only executes once no matter what.
-
If you don't need to keep the original number, you can change "number" as you go.
If you do need to keep the original number, you can make a different variable like "times".
You seem to have mixed these two scenarios together.
-
If you want to print all the steps, the print will be inside the loop so it prints multiple times.
If you only want to print the final result, then the print goes outside the loop.
while number != 0:
remainder = number % 2 # gives the exact remainder
number = number // 2
result = str(remainder) + result
print("The binary representation is", result)
-
The concatenation line:
Putting the print inside the loop might help you see how it works.
we can make an example:
the value in result might be "11010" (a string, with quotes)
the value in remainder might be 0 (an integer, no quotes)
str(remainder) turns the remainder into a string = "0" instead of 0
So when we look at the assignment statement:
result = str(remainder) + result
The right side of the assignment operator = is evaulated first.
The right side of the = is
str(remainder) + result
which, as we went over above has the values:
"0" + "11010"
This is string concatenation. It just puts one string on the end of the other one. The result is:
"0 11010"
"011010"
That is the value evaluated on the right side of the assignment statement.
result = "011010"
Now that is the value of result.
B_Number = 0
cnt = 0
while (N != 0):
rem = N % 2
c = pow(10, cnt)
B_Number += rem * c
N //= 2
# Count used to store exponent value
cnt += 1
return B_Number

Resources