import struct import random import time def _cdata(data): return [chr(int(x*100)) for x in data] def tobin(val, n=8): #return str(val) return ('{0:0%sb}'%(n)).format(val) def fun1(data): cdata = _cdata(data) struct.pack('%sc'%(len(data)), *cdata) return ['0'] * 64 def fun1_withindex(data): cdata = _cdata(data) index = ['0'] * 64 index_val = int(''.join(index), 2) return struct.pack('Q%sc'%(len(data)), index_val, *cdata) def fun2_withindex(data): cbdata = binpair_compress(data) index = ['0'] * 64 index_val = int(''.join(index), 2) return struct.pack('Q%sc'%(len(cbdata)), index_val, *cbdata) def fun2(data): data = data + [0] * (64 - len(data)) cbdata = binpair_compress(data) return struct.pack('%sc'%(len(cbdata)),*cbdata) def binpair_compress(data): MAX_GAP = 14 PASS = 15 sorted_data = [int(x * 100) for x in sorted(data)[::-1]] #print "sorted data: ", sorted_data bindata = [0] # First value is always biggest number first = sorted_data[0] bindata[0] = tobin(first, 8) # 8th byte of first is zero if next one is relative, else 1 #b8 = '1' if first - sorted_data[1] > MAX_GAP else '0' #bindata[0] = b8 + bindata[0] last_was_fullpair = False #if last bindata was binpair with two valid gaps (no PASS) last_was_fullbyte = True # if last bindata was a gap value using all bit (full byte). #Iterate next values """ The rules are if current - prev > MAX_GAP, store it as a full byte (using all 8bits), mark previous one (if it is a fullbyte as well) setting its MSB to 1, and continue with next one else if the gap < MAX_GAP try to form a binpair with current and next one, this is, using 4bits to store the first gap (current - prev), and the next 4bits to the second gap (current - current+1), and continue with current+2. Otherwise, if the second gap is too big (> MAX_GAP) then store a PASS value in those 4 bits and continue with the next one. The rule of thumb is that every time a fullbyte gap (using all 8bits) is stored in bindata is because the gap is too big. Also previous bindata should be marked someway to interpret the next one as a fullbyte. This is done by marking the MSB in a fullbyte or storing PASS in a binpair. Value 255 is ignored and the next value is treated as a fullbyte. """ i = 1 while i < len(sorted_data) : #print "i: ", i gap = sorted_data[i-1] - sorted_data[i] #print "gap is", gap if gap > MAX_GAP: #print "gap > Max_GAP" if last_was_fullpair == True: bindata.append(tobin(255, 8)) bindata.append(tobin(sorted_data[i], 8)) else: if last_was_fullbyte: bindata[-1] = '1' + bindata[-1][1:]#Mark MSB as 1 to interpret current bindata as a fullbyte as well bindata.append(tobin(sorted_data[i], 8)) last_was_fullbyte = True last_was_fullpair = False i += 1 else: last_was_fullbyte = False #print "gap minor MAx_GAP" binpair = ['', ''] binpair[0] = tobin(gap, 4) if i+1 == len(sorted_data): #Last value binpair[1] =tobin(PASS, 4) bindata.append(''.join(binpair)) break gapnext = sorted_data[i] - sorted_data[i+1] #print "gapnext", gapnext if gapnext > MAX_GAP: #print "gapnext > MAX_GAP" binpair[1] = tobin(PASS,4) i += 1 last_was_fullpair = False else: binpair[1] = tobin(gapnext, 4) i += 2 last_was_fullpair = True #print "binpair is ", binpair bindata.append(''.join(binpair)) #print "bindata so far: ", bindata #print "final bindata", bindata cbdata = [chr(int(x, 2)) for x in bindata] return cbdata num_cars = 16 data = [round(random.random(),2) for x in range(num_cars)] #data = [0.97, 0.96, 0.90, 0.80] print ', '.join([str(x) for x in data]) print "LEN: ", len(data) print "fun 1: ", len(fun1(data)) print "fun 1 with index: ", len(fun1_withindex(data)) print "fun 2:", len(fun2(data)) print "fun 2 with index:",len(fun2_withindex(data))
Run
Reset
Share
Import
Link
Embed
Language▼
English
中文
Python Fiddle
Python Cloud IDE
Follow @python_fiddle
Browser Version Not Supported
Due to Python Fiddle's reliance on advanced JavaScript techniques, older browsers might have problems running it correctly. Please download the latest version of your favourite browser.
Chrome 10+
Firefox 4+
Safari 5+
IE 10+
Let me try anyway!
url:
Go
Python Snippet
Stackoverflow Question