all time conserv same bytes in python - python

I wouldlike to have same digit/bytes all time (8 bytes)
Example : My first number have 5 decimals after comma : 95.12345 so 8 bytes
If this number is now 100.12345, I have got 9 bytes. Is it possible to delete the last number to conserv all time 8 bytes like this :
100.12345 ===> 100.1234
1000.1234 ===> 1000.123
Thanks for your help !

x = 95.12345
print(str(x)[:8])
95.12345
and, to avoid problem with too short strings, you might do:
x = 1.00
print("{:0>8s}".format(str(x)[:8]))
000001.0

d = 100.12345
print(d, str(d)[:8], sep=' => ')
100.12345 => 100.1234
But 1 digit is not 1 byte, it's true only for string.

Related

combine two bytes to form signed value (16 bit)

I want to combine two bytes (8 bit) to form a signed value (one bit for sign and 15 for the value) according to the two complement's method.
I receive MSbyte (note that the most left bit of MSByte is for the sign) and the LSbyte. So I write a function by shifting the MSByte to the left by 8 bit then I add it with the LSByte to form a binary sequence of 16 bit. Then, I calculate the ones'complement, and I finally add 1 to the result. However, it does not work.
def twos_comp_two_bytes(msb, lsb):
a= (msb<<8)+ lsb
r = ~(a)+1
return r
For example 0b0b1111110111001001 is -567 however with the above function I get -64969.
EDIT : call of the function
twos_comp_two_bytes(0b11111101,0b11001001) => -64969
Python uses integers which may have any lenght - they are not restricted to 16bits so to get -567 it would need rather
r = a - (256*256)
but it need more code for other values
def twos_comp_two_bytes(msb, lsb):
a = (msb<<8) + lsb
if a >= (256*256)//2:
a = a - (256*256)
return a
print(twos_comp_two_bytes(0b11111101, 0b11001001))
print(twos_comp_two_bytes(0b0, 0b0))
print(twos_comp_two_bytes(0b0, 0b1))
print(twos_comp_two_bytes(0b10000000, 0b0))
print(twos_comp_two_bytes(0b10000000, 0b1))
Results:
-567
0
1
-32768
-32767
It would be better to use special module struct for this
import struct
def twos_comp_two_bytes(msb, lsb):
return struct.unpack('>h', bytes([msb, lsb]))[0]
#return struct.unpack('<h', bytes([lsb, msb]))[0] # different order `[lsb, msb]`
#return struct.unpack( 'h', bytes([lsb, msb]))[0] # different order `[lsb, msb]`
print(twos_comp_two_bytes(0b11111101, 0b11001001))
print(twos_comp_two_bytes(0b0, 0b0))
print(twos_comp_two_bytes(0b0, 0b1))
print(twos_comp_two_bytes(0b10000000, 0b0))
print(twos_comp_two_bytes(0b10000000, 0b1))
Results:
-567
0
1
-32768
-32767
Letter h means short integer (signed int with 2 bytes).
Char >, < describes order of bytes.
See more in Format Characters

add str to start of each row value

I have a pandas dataframe
df = pd.DataFrame({'num_legs': [1, 34, 34, 104 , 6542, 6542 , 48383]})
I want to append a str before each row`s value.
The str is ZZ00000
The catch is that the row data must always = 7 characters in total
so the desired output will be
df = num_legs
0 ZZ00001
1 ZZ00034
2 ZZ00034
3 ZZ00104
4 ZZ06542
5 ZZ06542
6 ZZ48383
As the column is of type int I was thinking of changing to a str type and then possibly using regex and some str manipulation to achieve my desired outcome..
Is there a more streamlined way possibly using a function with pandas?
Use
df['num_legs'] = "ZZ" + df['num_legs'].astype(str).str.rjust(5, "0")
You could use string concatenation here:
df["num_legs"] = 'ZZ' + ('00000' + str(df["num_legs"]))[-5:]
The idea here is that, given a num_legs integer value of say 6542, we first form the following string:
000006542
Then we retain the right 5 characters, leaving 06542.
You could also pad using the following:
'ZZ' + df['num_legs'].astype(str).str.pad(width=5, side='left', fillchar='0')
Here you pad your current number (converted to string) on the left with zeros up to a width of 5 and conctatenate that to your 'ZZ' string.
Use pythons .zfill()
df['num_legs']='zz'+df['num_legs'].astype(str).str.zfill(7)
You could try this - using a regex, and a for loop: for strings, for loops are more efficient, usually, than pandas String methods :
import re
variable = "ZZ00000"
df["new_val"] = [re.sub("\d" + f"{{{len(num)}}}$", num, variable)
for num in df.num_legs.astype(str)]
df
num_legs new_val
0 1 ZZ00001
1 34 ZZ00034
2 34 ZZ00034
3 104 ZZ00104
4 6542 ZZ06542
5 6542 ZZ06542
6 48383 ZZ48383
out = []
for nl in df["num_legs"]:
out.append(f'ZZ{nl:05d}')
The rest is up to your output manipulation

Encode data to HEX and get an L at the end in Python 2.7. Why?

I ask a Measurement Device to give me some Data. At first it tells me how many bytes of data are in the storage. It is always 14. Then it gives me the data which i have to encode into hex. It is Python 2.7 canĀ“t use newer versions. Line 6 to 10 tells the Device to give me the measured data.
Line 12 to 14 is the encoding to Hex. In other Programs it works. but when i print result(Line 14) then i get a Hex number with 13 Bytes PLUS 1 which can not be correct because it has an L et the end. I guess it is some LONG or whatever. and i dont need the last Byte. but i do think it changes the Data too, which is picked out from Line 15 and up. at first in Hex. Then it is converted into Int.
Is it possible that the L has an effect on the Data or not?
How can i fix it?
1 ap.write(b"ML\0")
rmemb = ap.read(2)
print(rmemb)
rmemb = int(rmemb)+1
5 rmem = rmemb #must be and is 14 Bytes
addmem = ("MR:%s\0" % rmem)
# addmem = ("MR:14\0")
ap.write(addmem.encode())
10 time.sleep(1)
test = ap.read(rmem)
result = hex(int(test.encode('hex'), 16))
print(result)
15 ftflash = result[12:20]
ftbg = result[20:28]
print(ftflash)
print(ftbg)
ftflash = int(ftflash, 16)
20 # print(ftflash)
ftbg = int(ftbg, 16)
# print(ftbg)
OUTPUT:
14
0x11bd5084c0b000001ce00000093L
b000001c
e0000009
Python 2 has two built-in integer types, int and long. hex returns a string representing a Python hexadecimal literal, and in Python 2, that means that longs get an L at the end, to signify that it's a long.

Why some values make struct.pack and struct.unpack to fail on Windows?

When I use struct.pack() to convert a python integer to C structs (and write it to a file) and then struct.unpack() to reverse the conversion I get usually the original value...but not always. Why? Are there some unmanageable values?
Example:
import struct
fileName ='C:/myFile.ext'
formatCode = 'H'
nBytes = 2
tries = range(8,12)
for value in tries:
newFile = open(fileName, mode='w+')
myBinary = struct.pack( formatCode, value )
newFile.write(myBinary)
newFile.close()
infile = open(fileName,'rb')
bytesRead = infile.read(nBytes)
newValue = struct.unpack( formatCode, bytesRead )
print value, 'equal', newValue[0]
infile.close()
returns:
8 equal 8
9 equal 9
10 equal 2573
11 equal 11
12 equal 12
It happens not only with integer (2 bytes: format 'H') but also with other types and values. Value 10 gives this 'error' if I pack as integer, but not as float, but working with float I get errors with other values.
If the problem is that I cannot convert int number 10 to this packed struct, what alternative do I have to write this value in the file (packed)?
You forgot to specify binary mode when writing. wb+ not w+.

How can I create a decremented numberPyramid(num) in Python?

I'm trying to create a pyramid that looks like the picture below(numberPyramid(6)), where the pyramid isn't made of numbers but actually a black space with the numbers around it. The function takes in a parameter called "num" and which is the number of rows in the pyramid. How would I go about doing this? I need to use a for loop but I'm not sure how I implement it. Thanks!
666666666666
55555 55555
4444 4444
333 333
22 22
1 1
def pyramid(num_rows, block=' ', left='', right=''):
for idx in range(num_rows):
print '{py_layer:{num_fill}{align}{width}}'.format(
py_layer='{left}{blocks}{right}'.format(
left=left,
blocks=block * (idx*2),
right=right),
num_fill=format((num_rows - idx) % 16, 'x'),
align='^',
width=num_rows * 2)
This works by using python's string format method in an interesting way. The spaces are the string to be printed, and the number used as the character to fill in the rest of the row.
Using the built-in format() function to chop off the leading 0x in the hex string lets you build pyramids up to 15.
Sample:
In [45]: pyramid(9)
999999999999999999
88888888 88888888
7777777 7777777
666666 666666
55555 55555
4444 4444
333 333
22 22
1 1
Other pyramid "blocks" could be interesting:
In [52]: pyramid(9, '_')
999999999999999999
88888888__88888888
7777777____7777777
666666______666666
55555________55555
4444__________4444
333____________333
22______________22
1________________1
With the added left and right options and showing hex support:
In [57]: pyramid(15, '_', '/', '\\')
ffffffffffffff/\ffffffffffffff
eeeeeeeeeeeee/__\eeeeeeeeeeeee
dddddddddddd/____\dddddddddddd
ccccccccccc/______\ccccccccccc
bbbbbbbbbb/________\bbbbbbbbbb
aaaaaaaaa/__________\aaaaaaaaa
99999999/____________\99999999
8888888/______________\8888888
777777/________________\777777
66666/__________________\66666
5555/____________________\5555
444/______________________\444
33/________________________\33
2/__________________________\2
/____________________________\
First the code:
max_depth = int(raw_input("Enter max depth of pyramid (2 - 9): "))
for i in range(max_depth, 0, -1):
print str(i)*i + " "*((max_depth-i)*2) + str(i)*i
Output:
(numpyramid)macbook:numpyramid joeyoung$ python numpyramid.py
Enter max depth of pyramid (2 - 9): 6
666666666666
55555 55555
4444 4444
333 333
22 22
1 1
How this works:
Python has a built-in function named range() which can help you build the iterator for your for-loop. You can make it decrement instead of increment by passing in -1 as the 3rd argument.
Our for loop will start at the user supplied max_depth (6 for our example) and i will decrement by 1 for each iteration of the loop.
Now the output line should do the following:
Print out the current iterator number (i) and repeat it itimes.
Figure out how much white space to add in the middle.
This will be the max_depth minus the current iterator number, then multiply that result by 2 because you'll need to double the whitespace for each iteration
Attach the whitespace to the first set of repeated numbers.
Attach a second set of repeated numbers: the current iterator number (i) repeated itimes
When your print characters, they can be repeated by following the character with an asterisk * and the number of times you want the character to be repeated.
For example:
>>> # Repeats the character 'A' 5 times
... print "A"*5
AAAAA

Categories

Resources