Why my reversing bits code written in Python gets this error? - python

I get this problem in Leetcode:
https://leetcode.com/problems/reverse-bits/
So the input will be a decimal integer and I have to turn it into binary 32 bits.
And then I reverse it and turn it back to decimal.
For example:
Input:
8 (whose binary == 1000)
Output:
1 (whose binary == 0001)
Here is my code:
# n is input number
str1 = str('{0:0{1}b}'.format(n,32))
len_str = len(str1)
index_swap = len_str - 1
result = [0] * len_str
for i, char in enumerate(str1):
result[index_swap-i] = char
return int(str(''.join(result)),2)
If I run this code in Leetcode online Judge, I will get this error:
TypeError: sequence item 0: expected string, int found
This error is raised by the input 0.
I have no idea why it will raise this error. My code seems to works well!

result = [0] * len_str
len_str is an int but a string was expected.
What should happen in that Line? Maybe:
result = ['' for x in xrange(len_str)]
which initialize an empty string of size len_str

# There ...
a = 8
b = "{0:b}".format(8)[::-1]
print(type(b), b)
# and back again.
c = int(b[::-1], base=2)
print(type(c), c)
Output
<class 'str'> 0001
<class 'int'> 8
See also Reverse a string in Python

Related

How to convert float to int by dropping "0" and ","?

I have a float variable with a value of 0.9533. How can I convert it to an int variable so that the value becomes 9553?
a = ((i.left + i.right) / 2)
a = ("{:.4f}".format(a)) //get a: float = 0.9533
print(f"Result 1: {a}")
b = int(a * 10000) //get b: int
print(f"Result 2: {b}")
I get an error:
Result 1: 0.9533
ValueError: invalid literal for int() with base 10: '0.95330.95330...95330'
This should work!
a: float = 0.9533 # Get the number here.
b: int = int(str(a).split('.')[1])
This converts the float to a string, then uses Python's split method for string to split it by the '.' character, then gets the second element of the returned array (index 1), and converts that back into an int, super simple! Hope this helps!
Here is a more general solution that will work with any number.
import decimal
def to_int(num):
d = decimal.Decimal(str(num))
exponent = d.as_tuple().exponent * -1
return int(num * (10 ** (exponent)))
to_int(0.9553) # 9553
Initially, the number was 0.953381023.. . It was necessary to round to 4 digits after the dot, so I used formatting.
This solution helped me:
b = int((a * 10000)[2:6])
a = .0004251
b,c = map(str,map(int,str(a).split('.',1)))
print(int(b+c))
Output:
4251

Converting hexstr to signed integer - Python

I have this hexstr 0xfffffffffffffffffffffffffffffffffffffffffffffffffffdf05d84162877, in decimal terms it should give -580140491462537. However doing the below leads to bad answers. Can someone help?
In: test = '0xfffffffffffffffffffffffffffffffffffffffffffffffffffdf05d84162877'
In: int(test,16)
Out: 11579208923731619542357098500868790785326998466564056403945758342777263817739
First convert the string to bytes. You'll have to remove the leading "0x".
Then use int.from_bytes and specify that it's signed and big-endian.
In: int.from_bytes(bytes.fromhex(test[2:]), byteorder="big", signed=True)
Out: -580140491462537
I've adapted this answer
# hex string to signed integer
def htosi(val):
uintval = int(val, 16)
bits = 4 * len(val)
indicative_binary = 2 ** (bits)
indicative_binary_1 = 2 ** (bits-1)
if uintval >= indicative_binary_1:
uintval = int(0 - (indicative_binary - uintval))
return uintval
This does require a pure hex string:
test1 = 'fffffffffffffffffffffffffffffffffffffffffffffffffffdf05d84162877'
print(htosi(test1))
-580140491462537

Reverse int as hex

I have int in python that I want to reverse
x = int(1234567899)
I want to result will be 3674379849
explain : = 1234567899 = 0x499602DB and 3674379849 = 0xDB029649
How to do that in python ?
>>> import struct
>>> struct.unpack('>I', struct.pack('<I', 1234567899))[0]
3674379849
>>>
This converts the integer to a 4-byte array (I), then decodes it in reverse order (> vs <).
Documentation: struct
If you just want the result, use sabiks approach - if you want the intermediate steps for bragging rights, you would need to
create the hex of the number (#1) and maybe add a leading 0 for correctness
reverse it 2-byte-wise (#2)
create an integer again (#3)
f.e. like so
n = 1234567899
# 1
h = hex(n)
if len(h) % 2: # fix for uneven lengthy inputs (f.e. n = int("234",16))
h = '0x0'+h[2:]
# 2 (skips 0x and prepends 0x for looks only)
bh = '0x'+''.join([h[i: i+2] for i in range(2, len(h), 2)][::-1])
# 3
b = int(bh, 16)
print(n, h, bh, b)
to get
1234567899 0x499602db 0xdb029649 3674379849

Python: How to increment a special-purpose string?

Consider a special-purpose string of length 8, say "A00000XY". The string has following restrictions.
Length = 8.
Last two chars have special meaning and should remain as it is.
A-Z and 0-9 are only valid characters. Thus the regular expression "^[A-Z0-9]{6}XY$" defines the string.
How can I implement a function, say increment, that when called increments the string by one. Thus subsequent calls should look like following:
>>> A = "A00000XY"
>>> print increment(A)
"A00000XY"
>>> print increment(A)
"A00001XY"
>>> print increment(A)
"A00002XY"
...
>>> print increment(A)
"A00009XY"
>>> print increment(A)
"A0000AXY"
>>> print increment(A)
"A0000BXY"
...
>>> print increment(A)
"A0000YXY"
>>> print increment(A)
"A0000ZXY"
>>> print increment(A)
"A00010XY"
>>> print increment(A)
"A00011XY"
...
>>> print increment(A)
"ZZZZZZXY"
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def digit_helper(num):
while num > 0:
yield digits[num % 36]
num = num / 36
def increment(string):
incremented = int(string[:-2], base=36) + 1
return "".join(reversed(list(digit_helper(incremented)))) + "XY"
Temptation was too high. However, not very suitable as homework answer, I'm afraid :D
Update: it's Python 2. In Python 3 division should be num // 36.
So what you really want is a base 36 number. You will need to build a class that works similar to how hex to decimal and decimal to hex conversions work. With your 8 character limit, you have values from 0 to 36^8 - 1 values, or 2821109907455.
9223372036854775807 is the max integer in python , so the good news is that you can represent your value as an integer.
To convert from your string value to the integer:
intValue = 0
Loop through each of the first eight characters in the string.
Pass the character to a function that returns an integer equivalent between 0 and 35. We'll call this charValue
intValue += intValue*36 + charValue
To convert from the integer to your string value:
stringValue = specialCharacters
curDigit = intValue % 36
intValue = intValue / 36
find string equivalent of intValue (0 to Z)
Append to front of stringValue
Repeat until intValue < 36. Any remaining characters would be 0
Obviously you would build the increment and decrement methods as well.
Inspired from #avysk response.
The #avysk reply has two issues.
Handling for ZZZZZZXY. It should wrap around and return 000000XY. It shouldn't overflow. However I missed covering this part in my question itself.
000000XY isn't handled properly to return 000001XY. It instead
returns 1XY.
Fixing these issue in following code that borrows most from #avysk's response.
digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def digit_helper(num):
while num > 0:
yield Tape.digits[num % 36]
num = num / 36
# This function, using the utility digit_helper, increments the string by 1.
# It produces string in following order:
# "A00000XY", "A00000XY", "A00001XY", "A00002XY", ...,
# "A00009XY", "A0000AXY", "A0000BXY", ...,
# "A0000YXY", "A0000ZXY", "A00010XY", "A00011XY", ...,
# "ZZZZZZXY", "000000XY", "000001XY", ...
# Logic:
# 1. Strip the string of last two chars.
# 2. Convert to base 36 equivalent integer and increment by one.
# 3. Convert back to Base 36 representation of incremented value.
# 3.1. [0:6] handles the overflow. Overflow happens after "ZZZZZZXY" and produces "1000000XY".
# 3.2. [::-1] reverses the string.
# 3.3. zfill(6) handles underflow, like converting integer 1 to "000001XY".
def increment(string):
incremented = int(string[:-2], base=36) + 1
return "".join(Tape.digit_helper(incremented))[0:6][::-1].zfill(6) + string[-2:]

Convert hex to binary

I have ABC123EFFF.
I want to have 001010101111000001001000111110111111111111 (i.e. binary repr. with, say, 42 digits and leading zeroes).
How?
For solving the left-side trailing zero problem:
my_hexdata = "1a"
scale = 16 ## equals to hexadecimal
num_of_bits = 8
bin(int(my_hexdata, scale))[2:].zfill(num_of_bits)
It will give 00011010 instead of the trimmed version.
import binascii
binary_string = binascii.unhexlify(hex_string)
Read
binascii.unhexlify
Return the binary data represented by the hexadecimal string specified as the parameter.
Convert hex to binary
I have ABC123EFFF.
I want to have 001010101111000001001000111110111111111111 (i.e. binary
repr. with, say, 42 digits and leading zeroes).
Short answer:
The new f-strings in Python 3.6 allow you to do this using very terse syntax:
>>> f'{0xABC123EFFF:0>42b}'
'001010101111000001001000111110111111111111'
or to break that up with the semantics:
>>> number, pad, rjust, size, kind = 0xABC123EFFF, '0', '>', 42, 'b'
>>> f'{number:{pad}{rjust}{size}{kind}}'
'001010101111000001001000111110111111111111'
Long answer:
What you are actually saying is that you have a value in a hexadecimal representation, and you want to represent an equivalent value in binary.
The value of equivalence is an integer. But you may begin with a string, and to view in binary, you must end with a string.
Convert hex to binary, 42 digits and leading zeros?
We have several direct ways to accomplish this goal, without hacks using slices.
First, before we can do any binary manipulation at all, convert to int (I presume this is in a string format, not as a literal):
>>> integer = int('ABC123EFFF', 16)
>>> integer
737679765503
alternatively we could use an integer literal as expressed in hexadecimal form:
>>> integer = 0xABC123EFFF
>>> integer
737679765503
Now we need to express our integer in a binary representation.
Use the builtin function, format
Then pass to format:
>>> format(integer, '0>42b')
'001010101111000001001000111110111111111111'
This uses the formatting specification's mini-language.
To break that down, here's the grammar form of it:
[[fill]align][sign][#][0][width][,][.precision][type]
To make that into a specification for our needs, we just exclude the things we don't need:
>>> spec = '{fill}{align}{width}{type}'.format(fill='0', align='>', width=42, type='b')
>>> spec
'0>42b'
and just pass that to format
>>> bin_representation = format(integer, spec)
>>> bin_representation
'001010101111000001001000111110111111111111'
>>> print(bin_representation)
001010101111000001001000111110111111111111
String Formatting (Templating) with str.format
We can use that in a string using str.format method:
>>> 'here is the binary form: {0:{spec}}'.format(integer, spec=spec)
'here is the binary form: 001010101111000001001000111110111111111111'
Or just put the spec directly in the original string:
>>> 'here is the binary form: {0:0>42b}'.format(integer)
'here is the binary form: 001010101111000001001000111110111111111111'
String Formatting with the new f-strings
Let's demonstrate the new f-strings. They use the same mini-language formatting rules:
>>> integer = 0xABC123EFFF
>>> length = 42
>>> f'{integer:0>{length}b}'
'001010101111000001001000111110111111111111'
Now let's put this functionality into a function to encourage reusability:
def bin_format(integer, length):
return f'{integer:0>{length}b}'
And now:
>>> bin_format(0xABC123EFFF, 42)
'001010101111000001001000111110111111111111'
Aside
If you actually just wanted to encode the data as a string of bytes in memory or on disk, you can use the int.to_bytes method, which is only available in Python 3:
>>> help(int.to_bytes)
to_bytes(...)
int.to_bytes(length, byteorder, *, signed=False) -> bytes
...
And since 42 bits divided by 8 bits per byte equals 6 bytes:
>>> integer.to_bytes(6, 'big')
b'\x00\xab\xc1#\xef\xff'
bin(int("abc123efff", 16))[2:]
>>> bin( 0xABC123EFFF )
'0b1010101111000001001000111110111111111111'
Use Built-in format() function and int() function
It's simple and easy to understand. It's little bit simplified version of Aaron answer
int()
int(string, base)
format()
format(integer, # of bits)
Example
# w/o 0b prefix
>> format(int("ABC123EFFF", 16), "040b")
1010101111000001001000111110111111111111
# with 0b prefix
>> format(int("ABC123EFFF", 16), "#042b")
0b1010101111000001001000111110111111111111
# w/o 0b prefix + 64bit
>> format(int("ABC123EFFF", 16), "064b")
0000000000000000000000001010101111000001001000111110111111111111
See also this answer
"{0:020b}".format(int('ABC123EFFF', 16))
Here's a fairly raw way to do it using bit fiddling to generate the binary strings.
The key bit to understand is:
(n & (1 << i)) and 1
Which will generate either a 0 or 1 if the i'th bit of n is set.
import binascii
def byte_to_binary(n):
return ''.join(str((n & (1 << i)) and 1) for i in reversed(range(8)))
def hex_to_binary(h):
return ''.join(byte_to_binary(ord(b)) for b in binascii.unhexlify(h))
print hex_to_binary('abc123efff')
>>> 1010101111000001001000111110111111111111
Edit: using the "new" ternary operator this:
(n & (1 << i)) and 1
Would become:
1 if n & (1 << i) or 0
(Which TBH I'm not sure how readable that is)
This is a slight touch up to Glen Maynard's solution, which I think is the right way to do it. It just adds the padding element.
def hextobin(self, hexval):
'''
Takes a string representation of hex data with
arbitrary length and converts to string representation
of binary. Includes padding 0s
'''
thelen = len(hexval)*4
binval = bin(int(hexval, 16))[2:]
while ((len(binval)) &lt thelen):
binval = '0' + binval
return binval
Pulled it out of a class. Just take out self, if you're working in a stand-alone script.
I added the calculation for the number of bits to fill to Onedinkenedi's solution. Here is the resulting function:
def hextobin(h):
return bin(int(h, 16))[2:].zfill(len(h) * 4)
Where 16 is the base you're converting from (hexadecimal), and 4 is how many bits you need to represent each digit, or log base 2 of the scale.
Replace each hex digit with the corresponding 4 binary digits:
1 - 0001
2 - 0010
...
a - 1010
b - 1011
...
f - 1111
hex --> decimal then decimal --> binary
#decimal to binary
def d2b(n):
bStr = ''
if n < 0: raise ValueError, "must be a positive integer"
if n == 0: return '0'
while n > 0:
bStr = str(n % 2) + bStr
n = n >> 1
return bStr
#hex to binary
def h2b(hex):
return d2b(int(hex,16))
# Python Program - Convert Hexadecimal to Binary
hexdec = input("Enter Hexadecimal string: ")
print(hexdec," in Binary = ", end="") # end is by default "\n" which prints a new line
for _hex in hexdec:
dec = int(_hex, 16) # 16 means base-16 wich is hexadecimal
print(bin(dec)[2:].rjust(4,"0"), end="") # the [2:] skips 0b, and the
Just use the module coden (note: I am the author of the module)
You can convert haxedecimal to binary there.
Install using pip
pip install coden
Convert
a_hexadecimal_number = "f1ff"
binary_output = coden.hex_to_bin(a_hexadecimal_number)
The converting Keywords are:
hex for hexadeimal
bin for binary
int for decimal
_to_ - the converting keyword for the function
So you can also format:
e. hexadecimal_output = bin_to_hex(a_binary_number)
Another way:
import math
def hextobinary(hex_string):
s = int(hex_string, 16)
num_digits = int(math.ceil(math.log(s) / math.log(2)))
digit_lst = ['0'] * num_digits
idx = num_digits
while s > 0:
idx -= 1
if s % 2 == 1: digit_lst[idx] = '1'
s = s / 2
return ''.join(digit_lst)
print hextobinary('abc123efff')
The binary version of ABC123EFFF is actually 1010101111000001001000111110111111111111
For almost all applications you want the binary version to have a length that is a multiple of 4 with leading padding of 0s.
To get this in Python:
def hex_to_binary( hex_code ):
bin_code = bin( hex_code )[2:]
padding = (4-len(bin_code)%4)%4
return '0'*padding + bin_code
Example 1:
>>> hex_to_binary( 0xABC123EFFF )
'1010101111000001001000111110111111111111'
Example 2:
>>> hex_to_binary( 0x7123 )
'0111000100100011'
Note that this also works in Micropython :)
i have a short snipped hope that helps :-)
input = 'ABC123EFFF'
for index, value in enumerate(input):
print(value)
print(bin(int(value,16)+16)[3:])
string = ''.join([bin(int(x,16)+16)[3:] for y,x in enumerate(input)])
print(string)
first i use your input and enumerate it to get each symbol. then i convert it to binary and trim from 3th position to the end. The trick to get the 0 is to add the max value of the input -> in this case always 16 :-)
the short form ist the join method. Enjoy.
HEX_TO_BINARY_CONVERSION_TABLE = {
'0': '0000',
'1': '0001',
'2': '0010',
'3': '0011',
'4': '0100',
'5': '0101',
'6': '0110',
'7': '0111',
'8': '1000',
'9': '1001',
'a': '1010',
'b': '1011',
'c': '1100',
'd': '1101',
'e': '1110',
'f': '1111'}
def hex_to_binary(hex_string):
binary_string = ""
for character in hex_string:
binary_string += HEX_TO_BINARY_CONVERSION_TABLE[character]
return binary_string
when I time hex_to_binary("123ade")
%timeit hex_to_binary("123ade")
here is the result:
316 ns ± 2.52 ns per loop
Alternatively, you could use "join" method:
def hex_to_binary_join(hex_string):
hex_array=[]
for character in hex_string:
hex_array.append(HEX_TO_BINARY_CONVERSION_TABLE[character])
return "".join(hex_array)
I timed this too:
%timeit hex_to_binary_join("123ade")
397 ns ± 4.64 ns per loop
a = raw_input('hex number\n')
length = len(a)
ab = bin(int(a, 16))[2:]
while len(ab)<(length * 4):
ab = '0' + ab
print ab
import binascii
hexa_input = input('Enter hex String to convert to Binary: ')
pad_bits=len(hexa_input)*4
Integer_output=int(hexa_input,16)
Binary_output= bin(Integer_output)[2:]. zfill(pad_bits)
print(Binary_output)
"""zfill(x) i.e. x no of 0 s to be padded left - Integers will overwrite 0 s
starting from right side but remaining 0 s will display till quantity x
[y:] where y is no of output chars which need to destroy starting from left"""
def conversion():
e=raw_input("enter hexadecimal no.:")
e1=("a","b","c","d","e","f")
e2=(10,11,12,13,14,15)
e3=1
e4=len(e)
e5=()
while e3<=e4:
e5=e5+(e[e3-1],)
e3=e3+1
print e5
e6=1
e8=()
while e6<=e4:
e7=e5[e6-1]
if e7=="A":
e7=10
if e7=="B":
e7=11
if e7=="C":
e7=12
if e7=="D":
e7=13
if e7=="E":
e7=14
if e7=="F":
e7=15
else:
e7=int(e7)
e8=e8+(e7,)
e6=e6+1
print e8
e9=1
e10=len(e8)
e11=()
while e9<=e10:
e12=e8[e9-1]
a1=e12
a2=()
a3=1
while a3<=1:
a4=a1%2
a2=a2+(a4,)
a1=a1/2
if a1<2:
if a1==1:
a2=a2+(1,)
if a1==0:
a2=a2+(0,)
a3=a3+1
a5=len(a2)
a6=1
a7=""
a56=a5
while a6<=a5:
a7=a7+str(a2[a56-1])
a6=a6+1
a56=a56-1
if a5<=3:
if a5==1:
a8="000"
a7=a8+a7
if a5==2:
a8="00"
a7=a8+a7
if a5==3:
a8="0"
a7=a8+a7
else:
a7=a7
print a7,
e9=e9+1
no=raw_input("Enter your number in hexa decimal :")
def convert(a):
if a=="0":
c="0000"
elif a=="1":
c="0001"
elif a=="2":
c="0010"
elif a=="3":
c="0011"
elif a=="4":
c="0100"
elif a=="5":
c="0101"
elif a=="6":
c="0110"
elif a=="7":
c="0111"
elif a=="8":
c="1000"
elif a=="9":
c="1001"
elif a=="A":
c="1010"
elif a=="B":
c="1011"
elif a=="C":
c="1100"
elif a=="D":
c="1101"
elif a=="E":
c="1110"
elif a=="F":
c="1111"
else:
c="invalid"
return c
a=len(no)
b=0
l=""
while b<a:
l=l+convert(no[b])
b+=1
print l

Categories

Resources