Extract LSB bit from a Byte in python - python-3.x

I have a byte in variable 'DATA'. I want to extract the LSB bit out of it and print it.
I'm very new to python, I found many articles with complex bitwise addition logic and all which was very tough to understand.
I'm looking for a simple logic like we do with the strings eg DATA[7:1]
Please help me out...

Is your "byte" an int? If so, just take bitwise AND (&) with 1 (or, if you want to be more explicit, the binary literal 0b1) to get the least significant bit.
>>> x = 14
>>> x & 1
0
>>> x = 15
>>> x & 1
1
Is your "byte" a bytes object? If so, just index into it and take bitwise AND.
>>> y = bytes([14, 15])
>>> y[0] & 1
0
>>> y[1] & 1
1

Simplest and probably fastest:
least_significant_bit_of_x = x & -x
You can find more tricks here: https://www.informit.com/articles/article.aspx?p=1959565
Although the go-to reference for bitwise "black magic" is Knuth's "The Art of Computer Programming, vol. 1".

Right shift by the number n and take the last bit by and 1
num >> n &1

Related

Making one string the anagram of other

I have a problem where two strings of same length are given, and I have to tell how many letters I have to change in the first string to make it an anagram of the second.
Here is what I did:
count = 0
Mutable_str = ''.join(sorted("hhpddlnnsjfoyxpci"))
Ref_str = ''.join(sorted("ioigvjqzfbpllssuj"))
i = 0
while i < len(Mutable_str):
if Mutable_str[i] != Ref_str[i]:
count += 1
i += 1
print(count)
My algorithm in this case returned 16 as result. But the correct answer is 10. Can someone tell me what is wrong in my code?
Thank you very much!
You need to use str.count
So you need to add up the differences between the number of occurrences of each character in the different strings. This can be done with str.count(c) where c is each distinct character in the second string (got with set()). We then need to use max() on the difference with 0 so that if the difference is negative this doesn't effect the total differences.
So as you can see, it boils down to one neat little one-liner:
def changes(s1, s2):
return sum(max(0, s2.count(c) - s1.count(c)) for c in set(s2))
and some tests:
>>> changes("hhpddlnnsjfoyxpci", "ioigvjqzfbpllssuj")
10
>>> changes("abc", "bcd")
1
>>> changes("jimmy", "bobby")
4

How to turn a random 3 digit input (numbers) to 3 seperate integers in Python 3

So as the title says, I need to take a user input (e.g. 456) and seperate those numbers so I end up with 4, 5 and 6. The input won't ever be more than 3 digits, however it could be any 3 digits, and it is always going to be numbers. I am very new to Python and coding in general, so my code is sloppy, messy and probably (very) wrong.
The code I have currently is as follows:
`
myint=input
mystr=str(myint)
print(mystr)
mystr[0]
mystr[1]
mystr[2]
int(mystr[0])
int(mystr[1])
int(mystr[2])
globals() mystr[0] = a mystr[1] = b mystr[2] = c
`
This all takes place within my first function
x = raw_input("Please enter a number")
y = [int(x[0]), int(x[1]), int(x[2])]
You can access the different digits using y[0], y[1] and y[2]
create a string from the input like: str(number)
and then iterate through
number = 456
number = str(number)
for i in range(len(number)):
print(number[i])
you should take a look at "strings" "lists" and "arrays" in python and how to handle them. It's pretty basic stuff
You should always remember that a string is an array of chars. That is how Python handles them and you can always call a position of the array.
In order to separate an integer into separate digits, you can use this one-liner:
digits = [int(i) for i in str(original_number)]
This way is more flexible than the accepted answer above, which hard-codes the indexes. Not that it's wrong, but just not as flexible in the case that you have a much larger amount of numbers. At some point, you'll want to do it more programmatically. Hope this helps too!

Reversing a number using recursion

I was tasked with reversing an integer recursively. I have an idea of how to formulate my base case but I'm unsure of what to put outside of the if statement. The parts I was unsure about are commented with question marks. With the first part, I don't know what to put and with the second part I'm unsure about whether it is correct or not.Thank you for the help.
Note: I'd like to avoid using external functions such as imports and things like these if possible.
def reverseDisplay(number):
if number < 10:
return number
return # ??????????
def main():
number = int(input("Enter a number: "))
print(number,end="") #???????????
reverseDisplay(number)
main()
I'm not going to give you the answer, but I'll give some hints. It looks like you don't want to convert it to a string -- this makes it a more interesting problem, but will result in some funky behavior. For example, reverseDisplay(100) = 1.
However, if you don't yet have a good handle on recursion, I would strongly recommend that you convert the input to a string and try to recursively reverse that string. Once you understand how to do that, an arithmetic approach will be much more straightforward.
Your base case is solid. A digit reversed is that same digit.
def reverseDisplay(n):
if n < 10:
return n
last_digit = # ??? 12345 -> 4
other_digits = # ??? You'll use last_digit for this. 12345 -> 1234
return last_digit * 10 ** ??? + reverseDisplay(???)
# ** is the exponent operator. If the last digit is 5, this is going to be 500...
# how many zeroes do we want? why?
If you don't want to use any string operations whatsoever, you might have to write your own function for getting the number of digits in an integer. Why? Where will you use it?
Imagine that you have a string 12345.
reverseDisplay(12345) is really
5 + reverseDisplay(1234) ->
4 + reverseDisplay(123) ->
3 + reverseDisplay(12) ->
2 + reverseDisplay(1) ->
1
Honestly, it might be a terrible idea, but who knows may be it will help:
Convert it to string.
Reverse the string using the recursion. Basically take char from the back, append to the front.
Parse it again.
Not the best performing solution, but a solution...
Otherwise there is gotta be some formula. For instance here:
https://math.stackexchange.com/questions/323268/formula-to-reverse-digits
Suppose you have a list of digits, that you want to turn into an int:
[1,2,3,4] -> 1234
You do this by 1*10^3 + 2*10^2 + 3*10^1 + 4.*10^0. The powers of 10 are exactly reversed in the case that you want to reverse the number. This is done as follows:
def reverse(n):
if n<10:
return n
return (n%10)*10**(int(math.log(n,10))) + reverse(n//10)
That math.log stuff simply determines the number of digits in the number, and therefore the power of 10 that should be multiplied.
Output:
In [78]: reverse(1234)
Out[78]: 4321
In [79]: reverse(123)
Out[79]: 321
In [80]: reverse(12)
Out[80]: 21
In [81]: reverse(1)
Out[81]: 1
In [82]: reverse(0)
Out[82]: 0
Does exactly what #GregS suggested in his comment. Key to reverse is to extract the last digit using the modulos operator and convert each extracted digit to a string, then simply join them back into the reverse of the string:
def reverseDisplay(number):
if number < 10:
return str(number)
return str(number % 10) + reverseDisplay(number / 10)
def main():
print (reverseDisplay(int(input("Enter a number: "))))
main()
Alternative method without using recursion:
def reverseDisplay(number):
return str(number)[::-1]

Parsing a string in MATLAB

I have a 32 bit string that I want to parse into 8 bits each. Then I want to change the 8 bit binary into a single integer, for example:
str = '00000001000000100000001100000100'
output = '1 2 3 4'
I know to use bin2dec, but I'm having difficulty parsing the string.
In Matlab every string is a matrix, so you can use this property. If 8 bits belong to one byte, reshape your data to have one byte per row:
reshape(str,8,[]).'
Doing so, you can apply bin2dec to get the output:
output=bin2dec(reshape(str,8,[]).')
This returns a vetor [1;2;3;4], use num2str(output.') if you want a char array instead.
Another possibility:
>> 2.^(7:-1:0)*reshape(str-'0',8,[])
>> ans =
1 2 3 4
Of course, apply num2str if you need the output in the form of a string.
A more esoteric way:
>> fliplr(typecast(uint32(2.^(31:-1:0)*(str-'0').'),'uint8'))
>> ans =
1 2 3 4
Seeing as how Ben Voigt didn't provide an answer to this question even though he pretty much answered the question in the comments, I will provide one for closure. As he said, you can segment your string into 8 characters each. Strings are essentially an array of characters. As such, split up your string into 8 characters each, then apply bin2dec on each of the strings.
str = '00000001000000100000001100000100';
byte1 = bin2dec(str(1:8));
byte2 = bin2dec(str(9:16));
byte3 = bin2dec(str(17:24));
byte4 = bin2dec(str(25:32));
output = num2str([byte1 byte2 byte3 byte4]);
>> output
output =
1 2 3 4
Looking at your example output, you desire output to be a string, and thus the num2str call in the last line of the code.

Python3 write string as binary

For a Python 3 programming assignment I have to work with Huffman coding. It's simple enough to generate the correct codes which result in a long string of 0's and 1's.
Now my problem is actually writings this string of as binary and not as text. I attempted to do this:
result = "01010101 ... " #really long string of 0's and 1's
filewrt = open(output_file, "wb") #appending b to w should write as binary, should it not?
filewrt.write(result)
filewrt.close()
however I'm still geting a large text file of 0 and 1 characters. How do I fix this?
EDIT: It seems as if I just simply don't understand how to represent an arbitrary bit in Python 3.
Based on this SO question I devised this ugly monstrosity:
for char in result:
filewrt.write( bytes(int(char, 2)) )
Instead of getting anywhere close to working, it outputted a zero'd file that was twice as large as my input file. Can someone please explain to me how to represent binary arbitrarily? And in the context of creating a huffman tree, how do I go about concatinating or joining bits based on their leaf locations if I should not use a string to do so.
def intToTextBytes(n, stLen=0):
bs = b''
while n>0:
bs = bytes([n & 0xff]) + bs
n >>= 8
return bs.rjust(stLen, b'\x00')
num = 0b01010101111111111111110000000000000011111111111111
bs = intToTextBytes(num)
print(bs)
open(output_file, "wb").write(bs)
EDIT: A more complicated, but faster (about 3 times) way:
from math import log, ceil
intToTextBytes = lambda n, stLen=0: bytes([
(n >> (i<<3)) & 0xff for i in range(int(ceil(log(n, 256)))-1, -1, -1)
]).rjust(stLen, b'\x00')

Resources