Solution which is handling all my scenarios
from itertools import groupby,accumulate
def pctDiff(A,B):
return abs(A-B)*200/(A+B)
def main():
D={}
dict ={'acct_number':10202,'acct_name':'abc','v1_rev':100,'v2_rev':110,'v4_rev':2,'v5_rev':200,'v6_rev':210,'v7_rev':60000000,'v3_rev':2000}
# dict ={'acct_number':10202,'acct_name':'abc','v1_rev':200,'v2_rev':210,'v4_rev':2,'v5_rev':200,'v6_rev':210,'v7_rev':60000000,'v3_rev':200}
#dict = {'acct_number': 10202, 'acct_name': 'abc', 'v1_rev': 100, 'v2_rev': None, 'v4_rev': None, 'v5_rev': None,'v6_rev': None, 'v7_rev': None, 'v3_rev': None}
#dict = {'acct_number': 10202, 'acct_name': 'abc', 'v1_rev': 100,'v2_rev':110,'v3_rev':300}
vendors_revenue_list =['v1_rev','v2_rev','v4_rev','v5_rev','v6_rev','v8_rev' ,'v3_rev', 'v7_rev']
#prepared list of vendorsof
for k in vendors_revenue_list:
if k in dict.keys() and dict[k] is not None:
D.update({k: dict[k]})
print(f'D {D}')
find_winner_percentage_based(D)
def pctDiff(A, B):
return abs(A - B) * 200 / (A + B)
def find_winner_percentage_based(D):
keys = sorted(D, key=D.get) # sorting keys in value ascending order
print(f'keys {keys}')
*values, = map(D.get, keys) # ordered values (for binary search)
print(f'values {values}')
if len(keys) ==1 : # only one vendor has provided data
groups=keys
else:
for z in zip(values[:1] + values, values):
print(z)
print('1********')
from itertools import groupby, accumulate
G = accumulate(pctDiff(*z) >= 30 for z in zip(values[:1] + values, values)) # zip returns iterator that generates tuples of length
#next returns the next item from the iterator.
#Underscore is a Python convention to name an unused variable
#Syntax: itertools.groupby(iterable, key_func)
groups = [tuple(g) for _, (*g,) in groupby(keys, lambda _: next(G)) if len(g) > 1]
print('3********')
print(groups)
if len(groups)> 1 :
result=groups.pop()
print(f'result {result}')
print('4********')
print(list(result))
#keys=sorted(k for k in D if k in result) for now commenting it we don need this
*values, = map(D.get, result) # ordered values (for binary search)
print('6********')
print(values.pop())
if __name__ == '__main__':
main()
only line which I am trying to understand is
groups = [tuple(g) for _, (*g,) in groupby(keys, lambda _: next(G)) if len(g) > 1]
print('3********')