2 """Data encoder that handles simple,text, and extended encodings
3
4 Based on javascript encoding algorithm and pygooglecharts"""
5 - def __init__(self, encoding=None, scale=None):
6 if not encoding:
7 encoding = 'text'
8 assert(encoding in ('simple','text','extended')),\
9 'Unknown encoding: %s'%encoding
10 self.encoding = encoding
11 self.scale = scale
12 coding = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
13 ecoding = coding + '-.'
14 if self.encoding == 'simple':
15 self.coding = coding
16 self.max_value = 61
17 self.char = ','
18 self.dchar = ''
19 self.none = '_'
20 self.value = lambda x: coding[x]
21 elif self.encoding == 'text':
22 self.coding = ''
23 self.max_value = 100
24 self.none = '-1'
25 self.char = '|'
26 self.dchar = ','
27 self.value = lambda x: '%.1f'%float(x)
28 elif self.encoding == 'extended':
29 self.coding = ecoding
30 self.max_value = 4095
31 self.none = '__'
32 self.dchar = ''
33 self.char = ','
34 self.value = lambda x: '%s%s'% \
35 (ecoding[int(float(x)/64)], ecoding[int(x%64)])
36
38 return value
39 if self.encoding != 'text' and self.scale and type(value) in (type(0), type(.0)):
40 if type(self.scale) == type(()):
41 lower,upper = self.scale
42 else:
43 lower,upper = 0,float(self.scale)
44 value = int(round(float(value - lower) * self.max_value / upper))
45 return min(value, self.max_value)
46
47 - def encode(self, *args, **kwargs):
48 """Encode wrapper for a dataset with maximum value
49
50 Datasets can be one or two dimensional
51 Strings are ignored as ordinal encoding"""
52 if type(args[0]) in (type(''),):
53 return self.encode([args[0]],**kwargs)
54 elif type(args[0]) in (type(0), type(.0)):
55 return self.encode([[args[0]]],**kwargs)
56 if len(args)>1:
57 dataset = args
58 else:
59 dataset = args[0]
60 typemap = list(map(type,dataset))
61 code = self.encoding[0]
62 if type('') in typemap:
63 data = ','.join(map(str,dataset))
64 elif type([]) in typemap or type(()) in typemap:
65 data = self.char.join([self.encodedata(data) for data in dataset])
66 elif len(dataset) == 1 and hasattr(dataset[0], '__iter__'):
67 data = self.encodedata(dataset[0])
68 else:
69 data = self.encodedata(dataset)
70 if not '.' in data and code == 't':
71 code = 'e'
72 return code +':'+ data
73
75 sub_data = []
76 enc_size = len(self.coding)
77 for value in data:
78 if value in (None,'None'):
79 sub_data.append(self.none)
80 elif type(value) == type(''):
81 sub_data.append(value)
82 elif value >= -1:
83 try:
84 sub_data.append(self.value(self.scalevalue(value)))
85 except ValueError:
86 raise ValueError('cannot encode value: %s' % value)
87 return self.dchar.join(sub_data)
88
90 e = astr[0]
91 dec_data = []
92 for data in astr[2:].split(self.char):
93 sub_data = []
94 if e == 't':
95 sub_data.extend([float(value) for value in data.split(',')])
96 elif e == 'e':
97 flag = 0
98 index = self.coding.index
99 for i in range(len(data)):
100 if not flag:
101 this,next = index(data[i]),index(data[i+1])
102 flag = 1
103 sub_data.append((64 * this) + next)
104 else: flag = 0
105 elif e == 's':
106 sub_data.extend([self.coding.index(value) for value in data])
107 dec_data.append(sub_data)
108 return dec_data
109
111
112 for q,a,d,s in [
113 ('simple','s:Ab9',[0,27,61],61),
114 ('text','t:0.0,10.0,100.0,-1.0,-1.0',[0,10,100,-1,-1],(0,100)),
115 ('extended','e:AH-HAA..',[7,3975,0,4095],4095)
116 ]:
117 E = Encoder(q,s)
118 data = [d]
119 test = E.encode(data)
120 assert(E.decode(test) == data)
121 assert(a == test)
122
123
124 if __name__=='__main__': test()
125