I have a Bitarray and want to read from a certain position to another position.
I have the int variable length in a for loop, so for example I have:
length = 2
and my Bitarray looks something like:
msgstr = bitstring.BitArray(0b11110011001111110)
I then want to read the first two bits and convert them into an int, so that I have:
id == 3
And for the next round when length has changed in value it should start from the third bit etc.
id = bitstring.BitArray()
m = 0
while 5 != m:
/////////////
Length changes in value part of Code
/////////////
x = 0
if m == 0:
while length != x:
id.append = msgstr[x] #msgstr is the BitArray that needs to be read
x = x + 1
m = m + 1
What you want here is called slicing.
for i in range(0,len(msgstr),length):
print msgstr[i:i+length].uint
This code will get you what you are asking for. It will take the first two bits and convert them into an int, then will take the third and fourth bits and convert them to an int, etc.
Related
Project: 2048 Microservice with flask and python, where the grid is a concatenation of digits into a string (this is mandatory).
exG = ‘02000201600040000’
How can I parse this string for powers of 2? My idea is to use a switch case on the leading number:
if leading number starts with 2:
check for 2048
check for 256
if not, it is 2 and can be assigned
if leading number starts with 1:
check for 1024
if not, it is 128....
What I would like to get is
newList = {‘0’, ‘2’, ‘0’, ‘0’, ‘0’, ‘2’, '0', ‘16’, ‘0’, ‘0’, ‘0’, ‘4’, ‘0’, ‘0’, ‘0’, ‘0’}
However, my brain is missing something when working with two digit+ numbers. Thanks in advance.
Based on the assumptions in the question that:
0 is a power of 2 (it is not)
1 is NOT a power of 2 (it is)
We do not want duplicates, so for a number like "64", we only want "64" and not "4".
import math
exG = "02000201600040000"
check = "" #current string of values you need to check.
newList = []
for str_digit in exG:
check += str_digit
if check == "0": # 2 is NOT a power of 2, but OP wants it to be included
newList.append(check)
check = ""
elif check == "1": # 2 IS a power of 2, but OP wants it to be excluded
continue
elif math.log(int(check), 2).is_integer(): #math.log() returns a float, so if the float is an integer, then the number is a power of 2
newList.append(check)
check = ""
# else, number is NOT a power of 2 and is not 0.
# Then, we want to test the current number concatenated with the next number, so we don't reset check
print(newList)
I'm not sure if this is what you want, but here's my attempt:
import re
import itertools
import math
a="01000201600040000"
_2048=re.split("(2048)",a)
_1024=[re.split("(1024)",x) for x in _2048]
normalized_1024=list(itertools.chain(*_1024))
final_split=[list(filter(None,re.split("(0)",x))) if (len(x)!=4 or x.startswith("0")) else x for x in normalized_1024 ]
op=[]
for i in final_split:
if isinstance(i,list):
for _i in i:
if (_i != "1") and (int(_i) & (int(_i) - 1)) == 0:
op.append(_i)
elif isinstance(i,str):
#print(i)
if (i != "1") and (int(i) & (int(i) - 1)) == 0:
op.append(i)
print(op)
we first look for 2048 then split, similarly for 1024 and finally 0s. and finally we check if the number is a power of 2. the check includes 0 but excludes 1.
Also, while splitting, we keep the separator.
I have this code. Everything is okay but it is not printing the desired values.
I think something is wrong in calling function but I can't figure it out.
this code is removing the middle element if the list length is odd, or the middle two elements if the length is even.
This is the code,
One_Ten = [1,2,3,4,5,6,7,8,9,10]
def removeMiddle(data:list)-> list:
index = 0
size = len(data)
index = size // 2
if (size % 2 == 0 ):
data = data[:index-1] + data[index+1:]
if (size % 2 == 1):
data.pop(index)
return data
data = list(One_Ten)
removeMiddle(data)
print("After removing the middle element (s):why ", data)
so the desired output should look like
[1,2,3,4,7,8,9,10]
You just need to assign data it's new value,
data = removeMiddle(data)
Altertnately you can me the function inplace by editing the first conditions
if (size % 2 == 0):
data.pop(index)
data.pop(index-1)
I need to use a certain program, to validate some of my results. I am relatively new in Python. The output is so different for each entry, see a snippit below:
SEQENCE ID TM SP PREDICTION
YOL154W_Q12512_Saccharomyces_cerevisiae 0 Y n8-15c20/21o
YDR481C_P11491_Saccharomyces_cerevisiae 1 0 i34-53o
YAL007C_P39704_Saccharomyces_cerevisiae 1 Y n5-20c25/26o181-207i
YAR028W_P39548_Saccharomyces_cerevisiae 2 0 i51-69o75-97i
YBL040C_P18414_Saccharomyces_cerevisiae 7 0 o6-26i38-56o62-80i101-119o125-143i155-174o186-206i
YBR106W_P38264_Saccharomyces_cerevisiae 1 0 o28-47i
YBR287W_P38355_Saccharomyces_cerevisiae 8 0 o12-32i44-63o69-90i258-275o295-315i327-351o363-385i397-421o
So, I need the last transmembrane region, in this case its always the last numbers between o and i or vise versa. if TM = 0, there is no transmembrane region, so I want the numbers if TM > 0
output I need:
34-53
181-207
75-97
186-206
28-47
397-421
preferably in seperate values, like:
first_number = 34
second_number = 53
Because I will be using a loop the values will be overwritten anyway. To summarize: I need the last region between the o and i or vise versa, with very variable strings (both in length and composition).
Trouble: If I just search (for example with regular expression) for the last region between o and i, I will sometimes pick the wrong region.
If the Phobius output is stored in a file, change 'Phobius_output' to the path, then the following code should give the expected result:
with open('Phobius_output') as file:
for line in file.readlines()[1:]:
if int(line.split()[1]) > 0:
prediction = line.split()[3]
i_idx, o_idx = prediction.rfind('i'), prediction.rfind('o')
last_region = prediction[i_idx + 1:o_idx] if i_idx < o_idx else prediction[o_idx + 1:i_idx]
first_number, second_number = map(int, last_region.split('-'))
print(last_region)
I want to read bits in 64 bit data put into corresponding bitfields of the Register class, I don't want to use bit array module, is there any traditional approach in python to achieve this.
I researched on this topic i got the following link -- [1]: How to read bits from a file? [bit field read link][1] but it doesn't help, Example code snippet is highly appreciated.Thanks in advance.
class Register(object):
def __init__(self, x):
self.BitField7= 0
self.BitField6= 0
self.BitField5= 0
self.BitField4= 0
self.BitField3= 0
self.BitField2= 0
self.BitField1= 0
self.fieldwidths = (6,12,6,4,12,8,16)
self.field_names=["BitField1","BitField2","BitField3","BitField4","BitField5","BitField6","BitField7"]
obj= Register('0b11011101110111011101110111011101110011001100110011001100110011001011101110111011101110111011101110101010101010101010101010101010') # input is 0xAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD
print obj # should print 0xAAAAAAAABBBBBBBB
Thanks in advance
The following code will load the requested portions of the binary number into the fields:
class Register(object):
def __init__(self,x):
self.fieldwidths = [6,12,6,4,12,8,16]
## Reverse the input string then convert it to an integer
x = int(x[2:][::-1],2)
## To keep code size down, store fields in a list (+ laziness)
## [BitField1, BitField2, ...,BitField7]
self.fields = [0,0,0,0,0,0,0]
for i,width in enumerate(self.fieldwidths):
## You can change the variables this stores the values in to
## your liking, but this is the basic procedure
## Store the last "width" number of bits in the current field
## e.g. 0b1000101 & 0b111 (or (2**3)-1) yields 0b101
self.fields[i] = x & ((2**width)-1)
## Chop off the last "width" number of bits from x
## e.g. 0b1010 >> 1 would result in 0b101
x = x >> width
obj = Register('0b11011101110111011101110111011101110011001100110011001100110011001011101110111011101110111011101110101010101010101010101010101010')
Which will result in:
BitField1 = 0b111011
BitField2 = 0b111011101110
BitField3 = 0b101110
BitField4 = 0b1011
BitField5 = 0b1100111011
BitField6 = 0b110011
BitField7 = 0b11001100110011
The results may not be what you wanted because of the fact that the data you provided is not 64 bits but rather 128 bits, which would mean that the 64 most significant bits of the input data will be ignored by the program.
EDIT:
If you wanted to just hardcode variable names and fieldwidths, you could just expand the for loop and assign the variables:
class Register(object):
def __init__(self,x):
## Reverse the input string then convert it to an integer
x = int(x[2:][::-1],2)
self.Bitfield1 = x & ((2**6)-1)
x = x >> 6
self.Bitfield2 = x & ((2**12)-1)
x = x >> 12
self.Bitfield3 = x & ((2**6)-1)
x = x >> 6
self.Bitfield4 = x & ((2**4)-1)
x = x >> 4
self.Bitfield5 = x & ((2**12)-1)
x = x >> 12
self.Bitfield6 = x & ((2**8)-1)
x = x >> 8
self.Bitfield7 = x & ((2**16)-1)
obj = Register('0b11011101110111011101110111011101110011001100110011001100110011001011101110111011101110111011101110101010101010101010101010101010')
We're supposed to write a "simple" program that converts from binary string. It's also supposed to return 0 when given an empty string. I apologize in advance to my lack of knowledge. I'm completely new to this.
Here's my attempt:
def b(binaryString):
if binaryString[0] !=0 or binaryString[1] !=1:
return 0
else:
x = int(binaryString[1])
a = (len(binaryString)) - 1
return x * 2**a + b(binaryString[1:])
Sample Input: b('1101')
Expected Output: 13
Actual Output: IndexError: string index out of range
Probably not the most elegant solution... however, here are my two cents
def b(binaryString):
if len(binaryString):
try:
return sum([int(num)*2**(idx) for idx,num in enumerate(reversed(binaryString))])
except ValueError:
return "Your input might be incorrect"
else:
return "0"
print(b("111")) #returns 7
print(b("")) #returns 0
print (b("11111101111")) #returns 2031
def b(binaryString):
if len(binaryString) == 0: return 0
rest, lsb = binaryString[:-1], binaryString[-1]
lsb = 1 if lsb == '1' else 0 # Alternatively, lsb = int(lsb)
return (b(rest) << 1) + lsb # Alternatively, return b(rest) * 2 + lsb
Where:
print b('1101') # 13
print b('') # 0
print b('11111111') # 255
print b('10') # 2
print b('01') # 1
The code splits the input string into two variables rest and lsb.
rest contains the input string, up to but excluding the last bit.
lsb contains the least significant bit (last bit in string). It's converted to an int in the following line.
The return value of the function is b(rest) shifted up 1 bit (= *2) plus the integer value of lsb.
Worth noting is that you could "cheat" with something as simple as:
def b(binaryString):
return int('0' + binaryString, base=2)