Can someone explain to me how this works? I keep looking at it but I just don't understand. It seems to work just fine but to the life of me this makes no sense. Somebody please help.
# Convert a decimal to a hex as a string
def decimalToHex(decimalValue):
hex = ""
while decimalValue != 0:
hexValue = decimalValue % 16
hex = toHexChar(hexValue) + hex
decimalValue = decimalValue // 16
return hex
# Convert an integer to a single hex digit in a character
def toHexChar(hexValue):
if 0 <= hexValue <= 9:
return chr(hexValue + ord('0'))
else: # 10 <= hexValue <= 15
return chr(hexValue - 10 + ord('A'))
def main():
# Prompt the user to enter a decimal integer
decimalValue = eval(input("Enter a decimal number: "))
print("The hex number for decimal",
decimalValue, "is", decimalToHex(decimalValue))
main() # Call the main function
Printing characters
Alright, im gonna try to explain it a bit. First, lets see the function that converts a number from 0-15 to 0123...ABCDEF:
def toHexChar(hexValue):
if 0 <= hexValue <= 9:
return chr(hexValue + ord('0'))
else: # 10 <= hexValue <= 15
return chr(hexValue - 10 + ord('A'))
You can see, its handling two cases: one, where the number 0-9 need to get converted into a text character from '0' to '9', another one where the number 10-16 need to get converted into a text character from 'A' to 'F'. It will return characters based on their ASCII-Code. For example, ord('A') returns 65.. chr() will convert an integer from 65 back to the ascii char 'A'.
Thats it about the print function. Now the loop:
Iterating number until all hex-chars are made
while decimalValue != 0:
This loop will run until not 16er chunk can be fetched
hexValue = decimalValue % 16
Normal modulo. It extracts a chunk from the decimal (hexValue will be 0-15)
hex = toHexChar(hexValue) + hex
Builds up a string. As HEX is standardtized to have bigger parts of the number on the left side, it is prepending the converted character.
decimalValue = decimalValue // 16
Preparing for the next loop: remove this 16er chunk by using a floordiv(a, b) (written as a // b).
Example
Lets understand how that works. Lets assume we want to convert the number 255 into a HexString. It will start by calling modulo 255 % 16 = 15. Then it will get converted toHexChar(15) = 'F'.
Next step is to remove that 16er chunk. If we would use normal division, we would get 255 / 16 = 15.9375. However, this would be rounded up because its above .5 after decimalpoint Causing a wrong behaviour (result would be 0x1FF).. Thats why we have to use a floordivsion which is floor(255/16) = 15 or shortly: 255 // 16 = 15.
I hope this explains it a bit better, especially why the // is needed.
I will have a go explaining using an example decimal number 11 to start with.
11 decimal is 0xB
11 modulo 16 is 11. Agreed? That means hexValue becomes the integer 11.
So the integer 11 gets passed to toHexChar.
so we have:
toHexChar(11)
11 is greater than 9, so the else path is called.
11 - 10 is of course 1.
The ascii value 'A' is 65 or 0x41, so ord('A') yields 65
1 + 65 = 66.
chr() function converts an integer value to an ASCII character. ascii 66 is 'B'. so toHexChar returns 'B'
Therefore, hex = 'B'
Now, decimalValue // 16, remember this is integer division, results in zero and hence we break out of the while loop and therefore decimalToHex(11) returns 'B'.
Example number 17.
17 modulo 16 = 1 - we have a string '1'
17 / 16 = 1 also. So we loop round one more time.
on the next iteration 1 % 16 yields 1, toHexChar returns '1' as a result.
hex = toHexChar(hexValue) + hex
will then mean that:
hex = toHexChar(1) + '1'
hex = '1' + '1'
results in "11"
Think it through with a few example numbers. Substituting as you go.
The basis of it is modulo 16 to get a remainder. The remainder cannot immediately be used because if the number is between 10 and 16 then you need to use the A-F characters, hence use of toHexChar function.
Then you divide by 16 and continue taking the remainder of what's left.
Related
We have a program that changes decimals to binary.
And the goal is to run the program, input a value, and outputs the value in binary.
The problem with my code is that it has trailing zeros when outputting the binary.
I need to achieve this without using external libraries like "math", so please stick to the built-in functions.
Current output:
Insert a value:
5
The number fits in 1 byte and is in binary:
00000101
Insert a value:
100
The number fits in 1 byte and is in binary:
01100100
Insert a value:
280
The number fits in 16 bits and is in binary:
0000000100011000
Expected output:
Insert a value:
5
The number fits in 1 byte and is in binary:
101
Insert a value:
100
The number fits in 1 byte and is in binary:
1100100
Insert a value:
280
The number fits in 16 bits and is in binary:
100011000
Current code:
def dec2bin(value, number_bits):
result = ''
while number_bits > 0:
bit_value = 2 ** (number_bits - 1)
if value >= bit_value:
result = result + '1'
value = value - bit_value
else:
result = result + '0'
number_bits = number_bits - 1
print(result)
input_ok = False
userinput = 0
while not input_ok:
print('Insert a value:')
userinput = int(input())
if userinput > 65535:
print('invalid, cant handle that big numbers, try again')
else:
input_ok = True
if userinput < 256:
print('The number fits in 1 byte and is in binary:')
dec2bin(userinput, 8)
else:
print('The number fits in 16 bits and is in binary:')
dec2bin(userinput, 16)
It easy with string formatting functions (see Pranav's comment). But perhaps in this case you want the algorithm to take care of it, and see treating it as a string is cheating.
def dec2bin(value, number_bits):
result = ''
starting = True
while number_bits > 0:
bit_value = 2 ** (number_bits - 1)
if value >= bit_value:
result = result + '1'
value = value - bit_value
starting = False
elif not starting:
result = result + '0'
number_bits = number_bits - 1
print(result)
Since you are storing the value as a string you can use
result.lstrip('0')
to remove the leading zeros from your answer.
This question already has answers here:
Sum the digits of a number
(11 answers)
Closed 10 months ago.
A simple python code for getting sum of every digit in n integer. I tried a while to get the number of digit and for loop to get the sum. Sometime it's working. But sometime it's giving one less. like 22222 should be 10. But i am getting 9.
import math
def number_adder():
number = int(input('Enter a natural number: ', )) #Inputs user value. Specifically a natural number
sum = 0
number_of_digit = 0
for digit in str(number):
number_of_digit += 1 # getting number of digit in the input value
number = number * 10 ** (-number_of_digit + 1)
sum += math.floor(number)
number -= math.floor(number)
for digit in range(number_of_digit - 1):
number = number * 10
sum += math.floor(number)
number -= math.floor(number)
print('The sum of all digits of the value is, ', sum)
number_adder()
You are making this way too complicated.
Just do:
>>> n=22222
>>> sum(int(x) for x in str(n))
10
And
>>> n=12345
>>> sum(int(x) for x in str(n))
15
Explanation:
sum(int(x) for x in str(n))
^ turn the number into a string
^ strings are iterable character by character
^ ^ ^ a comprehension loop to loop over those
^ ^ ^ characters
^ each character assigned to x
^ turn x back into a integer
^ sum all those digits together
Here is a less terse example:
n=123456
total=0
for ch in str(n):
print(f'{ch:>3}')
total+=int(ch)
print(f'===\n{total:>3}')
Prints:
1
2
3
4
5
6
===
21
You could do it even more compactly by using the map() function which in this case, applies the int function to every string representation of each digit, then each int digit is being summed by the sum() function.
Sidenote: Please don't use sum as a variable name because it's a built-in function, and you are shadowing it.
def number_adder():
#Inputs user value. Specifically a natural number
number = int(input('Enter a natural number: '))
num_sum = sum(map(int, str(number)))
print('The sum of all digits of the value is', num_sum)
number_adder()
Output (with an input of 22222):
Enter a natural number: 22222
The sum of all digits of the value is 10
The problem
def number_adder():
# [...]
sum += math.floor(number)
number -= math.floor(number)
print(number)
# Prints: 0.22219999999999995
# [...]
I added a print statement to check the value of number out and given the input 22222 the output for number at that point was: 0.22219999999999995. That happens because Python doesn't execute floating point operations with infinite precision, so that's the most precise value it can get for the substraction given sum and number.
(Check Python error in basic subtraction? and Python error in basic subtraction? as examples).
Naturally, when looping through the decimals of number the following happens:
for digit in range(number_of_digit - 1):
number = number * 10
sum += math.floor(number)
number -= math.floor(number)
0.2221999...5 <-- Adds a 2
0.221999...5 <-- Adds a 2
0.21999...5 <-- Adds a 2
0.19999...5 <-- Adds a 1
And that's the reason why you get 9 as the final number (Adding up to the previous value of 2).
Possible solution:
Replace number -= math.floor(number) in the two lines that I point out with number = round(number - math.floor(number), number_of_digit - 1) to get back the original decimal values by rounding
import math
def number_adder():
# [...]
sum += math.floor(number)
# Round number to `number_of_digit - 1` decimals
# This will yield: `0.2222` for the original input `22222`
number = round(number - math.floor(number), number_of_digit - 1) # (1) <---
for digit in range(number_of_digit - 1):
number = number * 10
sum += math.floor(number)
# Round `number` again here as this is a new floating point operation
# (number_of_digit - digit - 2) are the remaining decimal points
number = round(number - math.floor(number), number_of_digit - digit - 2) # (2) <---
print("The sum of all digits of the value is, ", sum)
I'm relatively new to Python, and coding in general (first-semester, intro computer science, I'm not a comp sci major.), and a homework assignment has me trying to figure out how many numbers between two numbers contain "5" (Such as between 105 and 168 there are 16 numbers that contain 5.) I started my code with:
def give_me_five(start, end):
ctr = start
max = end
numberoffives = 0
while ctr <= end:
print (ctr)
if ctr % 5 == 0 and (ctr % 10 != 0):
elif ctr % 5 == 0 and (ctr % 10 == (somethingsomethingmultiplesof5)
numberoffives += 1
if ctr // 10 == 5:
numberoffives += 1
ctr += 1
return numberoffives
The problem I'm encountering is that I can't use this to check for numbers in the 50s, 150s, etc... I tried using the ctr % 5 == 0 and (ctr % 10 == ) bit there to try and include them but now I can't figure out a way to proceed at all, and frankly I feel like I'm overcomplicating things. Does anyone have any advice for how to make my code actually work?
Since the digit 5 can be anywhere in a number it's easiest to convert each integer between the two numbers to a string instead so that you can use the in operator to check if 5 is a substring:
def give_me_five(start, end):
return sum('5' in str(i) for i in range(start, end + 1))
or if you prefer to do it with math, you can keep dividing a given number by 10 while checking if the remainder is 5 until the quotient becomes 0:
def give_me_five(start, end):
count = 0
for i in range(start, end + 1):
while i > 0:
if i % 10 == 5:
count += 1
break
i //= 10
return count
so that:
give_me_five(105, 168)
returns: 16
If I am understanding correctly, we want to do: for each number x in range, check to see if any of its digits digit is equal to 5.
How do we do this?
One thing we could do is cast the digit => string, and then check to see if the substring '5' exists. But this is a naive solution, requiring more memory and time to store all the digits into a string (rather than the few bytes necessary to represent the existing int).
So a smarter way would be to continually extract the least significant digit (digit = x % 10), check if digit == 5, and then divide out the least significant digit to repeat (x //= 10 WHILE x > 0).
I'm trying to create a Python program that converts a decimal to binary.
Currently I have
working = int(input("Please select a non-negative decimal number to convert to binary. "))
x = ()
while working !=0:
remainder = working % 2
working = working // 2
if remainder == 0:
x = remainder + 0
print (working, x)
else:
x = remainder + 1
print (working, x)
print ("I believe your binary number is " ,x)
The while works on it's own if I print after that, but the if/else doesn't. I am trying to create a string that is added to with each successive division. Currently, if my starting int is 76, my output is
38 0
38 0
19 0
19 0
9 2
4 2
2 0
2 0
1 0
1 0
0 2
I am trying to get my output to instead be
38 0
19 00
9 100
4 1100
2 01100
1 001100
0 1001100
This is my first attempt at string concatenation and I've tried a few variations of the above code to similar results.
There are a few issues with the code you’ve provided:
x starts with a value of (), and in any case, rather than concatenating strings to it, you’re adding numbers within the loop.
You’re trying to append the numbers rather than prepend, so the result would be reversed if it worked.
Your second print is not inside the conditional, so the output is duplicated.
What you need to do is initialize x with an empty string and then prepend strings to it:
working = int(input("Please enter a non-negative decimal number to convert to binary: "))
x = ""
while working != 0:
remainder = working % 2
working = working // 2
if remainder == 0:
x = "0" + x
else:
x = "1" + x
print (working, x)
print ("I believe your binary number is", x)
Output:
λ python convert-to-binary.py
Please enter a non-negative decimal number to convert to binary: 76
38 0
19 00
9 100
4 1100
2 01100
1 001100
0 1001100
I believe your binary number is 1001100
The problem is that you are not working with strings. You are first creating an empty tuple for x, and then overwriting that with an integer value later.
To do what you are attempting, you need to treat x as a string, and append the string literals '0' and '1' to it.
Try this instead:
working = int(input("Please select a non-negative decimal number to convert to binary. "))
x = ''
while working !=0:
remainder = working % 2
working = working // 2
if remainder == 0:
x += '0'
print (working, x)
else:
x += '1'
print (working, x)
print ("I believe your binary number is " , x[::-1])
Note how x is initially declared as an empty string '' instead of the empty tuple (). This makes it so that when you use the += operator later to append 0 or 1 to it, that it is treated as string concatenation instead of addition.
It should be
working = int(input("Please select a non-negative decimal number to convert to binary. "))
x = ""
while working !=0:
remainder = working % 2
working = working // 2
if remainder == 0:
x = x + str(remainder)
print (working, x)
else:
x = x + str(remainder)
print (working, x)
print ("I believe your binary number is " ,x[::-1])
Change your code to below:
if remainder == 0:
x = str(remainder) + '0'
print (working, x)
else:
x = str(remainder) + '1'
print (working, x)
in your code, python interprets as an int you have to cast it to string.
another way is using built-in function bin(working), directly converts from number to binary value.
This is my first time using this QnA site... I had this task in my class which asks me to convert numbers from any basis into decimal using method... I'm very confused about converting alphabets contained in a hex number. Here is the program which I type:
def base_n_to_dec(num_string, base):
dec = 0
index = len(num_string) - 1
for digit in num_string:
dec += int(digit) * (base ** index)
index -= 1
return dec
Could anyone please help me to modify this program so it could recognize the alphabets contained in hex numbers, so it could convert the characters to decimal basis? Please don't use built-in functions, because it's not allowed. (I already submitted the task, so I don't mean asking someone to finish my assignment) sorry for the bad english...
alphabet = '0123456789ABCDEF'
def base_n_to_dec(num_string, base):
'''
:param num_string: string containing number in base10
:param base: integer between 2 and 16
:returns: num_string based base as a string
'''
b10_num = 0
for digit in num_string:
b10_num *= 10
b10_num += alphabet.index(digit)
if b10_num == 0:
return '0'
result = ''
while b10_num > 0:
result = alphabet[b10_num % base] + result
b10_num /= base
return result