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
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.
I'm trying to replace a value entered by a user with a string to make the output cleaner
I thought an if statement would help, but I'm not sure how it would tie in with my intended output
def main() :
number = int(input("Enter your number: "))
base = int(input("Convert to\n" \
" Binary[2] - Octal[8] - Hexadecimal[16]: "))
if base == 2 :
"binary"
elif base == 8 :
"octal"
else:
"hexadecimal"
print("\n"+str(number) +" in "+ str(base) + " is: " + str(convert(number, 10, base)))
def convert(fromNum, fromBase, toBase) :
toNum = 0
power = 0
while fromNum > 0 :
toNum += fromBase ** power * (fromNum % toBase)
fromNum //= toBase
power += 1
return toNum
main()
What I'm trying to get:
if user enters 5 as their number and 2 as conversion. Output would be:
"5 in binary is: 101"
Try
def main() :
number = int(input("Enter your number: "))
base = int(input("Convert to\n" \
" Binary[2] - Octal[8] - Hexadecimal[16]: "))
base_string = "None"
if base == 2 :
base_string = "binary"
elif base == 8 :
base_string = "octal"
else:
base_string = "hexadecimal"
print("\n {} in {} is: {}".format(str(number), base_string, str(convert(number, 10, base))))
def convert(fromNum, fromBase, toBase) :
toNum = 0
power = 0
while fromNum > 0 :
toNum += fromBase ** power * (fromNum % toBase)
fromNum //= toBase
power += 1
return toNum
main()
Your issue was the "binary" part in the if-statement. It has virtually no effect neither on your code nor on your output. You have to store the literal representation ("binary",...) in some variable ("base_string"). Then you can use this variable in your output.
As an aside, it looks like your base conversion won't actually do what you want. You should look at How to convert an integer in any base to a string? to do the conversion properly (hexadecimal has letters A-F in it, those aren't handled by your code, for example).
To accept a name instead of a number, you need to change this line of code:
base = int(input("Convert to\n Binary[2] - Octal[8] - Hexadecimal[16]: "))
What's happening here? input() takes a line from stdin. In the interactive case, this means the user types something (hopefully a number) and then hits enter. We get that string. Then int converts that string to a number.
Your convert expects base to be a number. You want inputs like "binary" to correspond to base = 2. One way to achieve this is with a dict. It can map strings to numbers:
base_name_to_base = {'binary': 2, 'octal': 8, 'hexadecimal': 16}
base = base_name_to_base[input('Choose a base (binary, octal, hexadecimal): ')]
Note that base_name_to_base[x] can fail (raise KeyError) if x is not a key in the dict. So you want to handle this (what if the user enters "blah"?):
while True:
try:
base = base_name_to_base[input('Choose a base (binary, octal, hexadecimal): ')]
break
except KeyError:
pass
This will loop until we hit the break (which only happens when indexing into base_name_to_base doesn't raise the key error.
Additionally, you may want to handle different cases (ex. "BINARY") or arbitrary whitespace (ex. " binary "). You can do this by calling .lower() and .strip() on the string returned by input().
OK so this is my code, it's a base calculator that will convert base to base with no problem, but once the answer is over 9, I want the number to be represented as a letter, just like in base 16, 10 represent 'a', so I'm stuck on how can I do that just using Ascii tables. Right now the code is running well, if I type 1011,base2, I want to convert to base 16. So the output turns out to be 11, which is correct, but I want it to be 'b'
number = input("what's your number: ")
o_base = int(input("what is your oringal base: "))
base = int(input("what's the base you want to convert: "))
answer = ""
total = 0
for i, d in enumerate(reversed(number)):
total = total + int(d) * o_base ** i
while (total != 0):
answer += str(total % base)
total //= base
print (answer)
Python can first convert your number into a Python integer using int(number, base). Next all you need to do is convert it into you target base. This is often done using divmod() which combines doing a division of two numbers and getting their remainder into one function.
To convert each digit into the correct number or letter, the easiest way is to create an string holding all of your required symbols in order, and then use an index into this to give you the one you need, e.g. digits[0] here will return 0, and digits[10] would return A.
import string
number = input("What's your number: ")
o_base = int(input("What is your original base: "))
base = int(input("What is the base you want to convert to: "))
number = int(number, o_base)
digits = string.digits + string.ascii_uppercase # 0 to 9 + A to Z
output = []
while number:
number, remainder = divmod(number, base)
output.insert(0, digits[remainder])
print(''.join(output))
This example works up to base 36 (i.e. 0 to 9 and A to Z). You could obviously extend digits to give you more symbols for higher bases.
Using a list to create the output avoids doing repetitive string concatenation which is not very efficient.
I am a complete beginner to Python. I wrote some code to perform base conversion and I was wondering if there were better alternatives that were shorter to code (one-liners) or significantly faster. The code looks ugly and feels "non-Pythonic" though being a beginner I should not have any such opinion. Any feedback to improve the code would be appreciated. This is purely for learning purposes.
#!/usr/bin/env python
import math
def number_to_digits( number, radix ):
'Converts a number into a vector of digits in given radix'
digits = [0]*int(math.ceil(math.log(number,radix)))
for ii in range(len(digits)):
(number,digit) = divmod(number,radix)
digits[ii] = digit
return digits
def digits_to_number( digits, radix ):
'Converts a vector of non-negative digits in given radix into a number'
number = 0;
for ii in range(len(digits)-1,-1,-1):
number *= radix
number += digits[ii]
return number
if __name__ == '__main__':
try:
number = int(raw_input('Enter number: '))
if number <= 0: raise ValueError()
radix = int(raw_input('Enter radix: '))
if radix <= 0: raise ValueError()
digits = number_to_digits(number,radix)
print digits
number_again = digits_to_number(digits,radix)
if not number_again == number:
print 'test failed'
except ValueError:
print 'unexpected input'
A sample session on the terminal produces:
Enter number: 44
Enter radix: 6
[2, 1, 1]
It is easy to check that 2 + 1*6 + 1*6**2 == 44. Thanks!
Here's a nice recursive version that will convert up to hexadecimal from Problem Solving with Algorithms and Data Structures
def toStr(n,base):
convertString = "0123456789ABCDEF"
if n < base:
return convertString[n]
else:
return toStr(n//base,base) + convertString[n%base]
print(toStr(1453,16))
Python provides some built-in functions to convert a value represented in one Integer base to another Integer base. Integer is represented in four forms i.e. decimal, binary, octal, and hexadecimal form.
Python provides built-in bin() functions to convert from non-binary number to binary number, oct() function to convert from non-octal number to octal number and hex() function to convert from non-hexadecimal number to hexadecimal number. These functions return a string literal to represent the values.
You can learn these functions from the tutorial on Integer base Conversion Functions in Python
You can find (slightly) cleaner example in the following thread:
Python elegant inverse function of int(string,base).
Taking the top ranked example, you can clean it up a bit to:
def digit_to_char(digit):
if digit < 10:
return str(digit)
return chr(ord('a') + digit - 10)
def str_base(number, base):
while number > 0:
number, digit = divmod(number, base)
yield digit_to_char(digit)
Results in:
>>> list(str_base(44, 6))
['2', '1', '1']
If you don't care about bases larger than 10, it simplifies to:
def str_base(number, base):
if base > 10:
raise ValueError('Base must be less than 10')
while number > 0:
number, digit = divmod(number, base)
yield digit
>>> list(str_base(44, 6))
[2, 1, 1]
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.