Use bitshifting and addition:
bytes = b"\x00\x00\x02\x01"
i = 0
for b in bytes:
i <<= 7
i += b # Or use (b & 0x7f) if the last bit might not be zero.
print(i)
Result:
257
Answer from Mark Byers on Stack OverflowWorking with bytes and binary data in Python - Stack Overflow
working with bytes in python - Stack Overflow
Working with the email library and parsing bytes types
How to read CSV file from memory ?
You could try just reading the file and creating a StringIO object:
import StringIO csv_fo = StringIO.StringIO(request.FILES['csv_file'].read()) file_content = extract_data(csv_fo)More on reddit.com
Use bitshifting and addition:
bytes = b"\x00\x00\x02\x01"
i = 0
for b in bytes:
i <<= 7
i += b # Or use (b & 0x7f) if the last bit might not be zero.
print(i)
Result:
257
Using the bitarray module, you can do it a lot quicker for big numbers:
Benchmarks (factor 2.4x speedup!):
janus@Zeus /tmp % python3 -m timeit -s "import tst" "tst.tst(10000)"
10 loops, best of 3: 251 msec per loop
janus@Zeus /tmp % python3 -m timeit -s "import tst" "tst.tst(100)"
1000 loops, best of 3: 700 usec per loop
janus@Zeus /tmp % python3 -m timeit -s "import sevenbittoint, os" "sevenbittoint.sevenbittoint(os.urandom(10000))"
10 loops, best of 3: 73.7 msec per loop
janus@Zeus /tmp % python3 -m timeit -s "import quick, os" "quick.quick(os.urandom(10000))"
10 loops, best of 3: 179 msec per loop
quick.py (from Mark Byers):
def quick(bites):
i = 0
for b in bites:
i <<= 7
i += (b & 0x7f)
#i += b
return i
sevenbittoint.py:
import bitarray
import functools
def inttobitarray(x):
a = bitarray.bitarray()
a.frombytes(x.to_bytes(1,'big'))
return a
def concatter(accumulator,thisitem):
thisitem.pop(0)
for i in thisitem.tolist():
accumulator.append(i)
return accumulator
def sevenbittoint(bajts):
concatted = functools.reduce(concatter, map(inttobitarray, bajts), bitarray.bitarray())
missingbits = 8 - len(concatted) % 8
for i in range(missingbits): concatted.insert(0,0) # zeropad
return int.from_bytes(concatted.tobytes(), byteorder='big')
def tst():
num = 32768
print(bin(num))
print(sevenbittoint(num.to_bytes(2,'big')))
if __name__ == "__main__":
tst()
tst.py:
import os
import quick
import sevenbittoint
def tst(sz):
bajts = os.urandom(sz)
#for i in range(pow(2,16)):
# if i % pow(2,12) == 0: print(i)
# bajts = i.to_bytes(2, 'big')
a = quick.quick(bajts)
b = sevenbittoint.sevenbittoint(bajts)
if a != b: raise Exception((i, bin(int.from_bytes(bajts,'big')), a, b))
An idiomatic translation is going to work in a completely different way.
In the original code, you do a bunch of bit-twiddling to convert two byte values into a single numeric value. In Python, there is built-in functionality for this: use the struct module. As it turns out, this module is already built for reading several values at a time.
Also, use forward slashes for file names - it's easier, and guaranteed to work. Use a with-block to ensure that the file is properly closed automatically, and a list comprehension to simplify the looping - stop trying to tell Python how to build a list, and just ask for the list you want.
This gives us:
import struct
with open('C:/Users/CNA/sketchbook/_SRTM/data/N59E010.hgt', 'rb') as data:
elevation = [
list(struct.unpack('>1201H', data.read(1201 * 2)))
for row in range(1201)
]
maxheight = max(max(cell for cell in row if cell < 32000) for row in elevation)
and you're done. Welcome to Python :)
In Python values like 'hello'[2] are also strings (in this case == 'l'). You need to convert them to integers using ord and back to string using chr.
elevation = [[],[]]
maxheight=0
b = open("C:\\Users\\CNA\\sketchbook\\_SRTM\\data\\N59E010.hgt","rb")
fin = b.read() # you probably need to read more than 1 byte, this will read whole file
print(len(fin))
ix = 0
for row in range(0,1201):
for col in range(0,1201):
hi = (ord(fin[ix]) + 0xff) # ord returns unsigned integer, so you probably don't need to convert it
lo = (ord(fin[ix+1]) + 0xff)
el = (hi << 8) | lo
See: http://docs.python.org/library/functions.html