/timm's /charming /python /tricks

a12.py

Download a12.py.
Read more on How to be Charming (in Python).


01: import random
02: from base import *
03: from lib  import *
04: 
05: def a12old(lst1,lst2,rev=True):
06:   "how often is x in lst1 more than y in lst2?"
07:   more = same = 0.0
08:   for x in lst1:
09:     for y in lst2:
10:       if   x==y : same += 1
11:       elif rev     and x > y : more += 1
12:       elif not rev and x < y : more += 1
13:   return (more + 0.5*same) / (len(lst1)*len(lst2))
14: 
15: def a12cmp(x,y):
16:   if y - x > 0 : return 1
17:   if y - x < 0 : return -1
18:   else: return 0
19: 
20: def a12(lst1,lst2, gt= a12cmp):
21:   "how often is x in lst1 more than y in lst2?"
22:   def loop(t,t1,t2): 
23:     while t1.i < t1.n and t2.i < t2.n:
24:       h1 = t1.l[t1.i]
25:       h2 = t2.l[t2.i]
26:       h3 = t2.l[t2.i+1] if t2.i+1 < t2.n else None 
27:       if gt(h1,h2) < 0:
28:         t1.i  += 1; t1.gt += t2.n - t2.i
29:       elif h1 == h2:
30:         if h3 and gt(h1,h3) < 0:
31:             t1.gt += t2.n - t2.i  - 1
32:         t1.i  += 1; t1.eq += 1; t2.eq += 1
33:       else:
34:         t2,t1  = t1,t2
35:     return t.gt*1.0, t.eq*1.0
36:   #--------------------------
37:   lst1 = sorted(lst1, cmp=gt)
38:   lst2 = sorted(lst2, cmp=gt)
39:   n1   = len(lst1)
40:   n2   = len(lst2)
41:   t1   = Thing(l=lst1,i=0,eq=0,gt=0,n=n1)
42:   t2   = Thing(l=lst2,i=0,eq=0,gt=0,n=n2)
43:   gt,eq= loop(t1, t1, t2)
44:   #print gt,eq,n1,n2
45:   return gt/(n1*n2) + eq/2/(n1*n2)
46: 
47: def a12large(lst1, lst2): return a12(lst1,lst2)  > 0.71 
48: def a12medium(lst1,lst2): return a12(lst1,lst2) >  0.64
49: def a12small(lst1, lst2): return a12(lst1,lst2) <= 0.56
50: 
51: def _ab0():
52:   x = a12([4,5,6,7],[7,9,3])
53:   print ':expect',0.,375,':got',x
54: 
55: def _ab1():
56:   x = a12([20, # 5
57:           19,  # 5
58:           18,  # 4   1
59:           17,  # 3   1
60:           16], # 2   1
61:           [18,17,16,15,14])
62:   print ':expect',0.82,':got',x
63: 
64: def _ab2():
65:   random.seed(1)
66:   l1 = [random.random() for x in range(1000)]
67:   l2 = [random.random() for x in range(1000)]
68:   t1 = msecs(lambda : a12(l1,l2))
69:   t2 = msecs(lambda : a12old(l1,l2))
70:   print ':new',t1,':old',t2
71: 
72: if __name__ == '__main__' : 
73:   eval(cmd('_ab0()'))
74: 

This file is part of Timm's charming Python tricks.
© 2014, Tim Menzies: tim.menzies@gmail.com, http://menzies.us.

Timm's charming Python tricks are free software: you can redistribute it and/or modify it under the terms of the GNU Lesser Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

Timm's charming Python tricks are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU Lesser Public License along with Foobar. If not, see http://www.gnu.org/licenses.