''' Created on Feb 18, 2012 @author: aman ''' from copy import copy, deepcopy class Share: def __init__(self, id, paid=0.0, percent=None, share=None): self.id = id self.paid = paid self.share = share self.percent = percent def to_pay(self): return self.share - self.paid def pay_back(self): return self.paid - self.share class Txn: def __init__(self): self.parties = [] self.total = 0.0 #self.avg = 0.0 def calc(self): self.calc_percent() self.total = 0.0 #self.avg = 0.0 #avg = 0.0 if len(self.parties) == 0: return for party in self.parties: self.total = self.total + party.paid #self.avg = self.total / len(self.parties) #avg = self.total / len(self.parties) for party in self.parties: if party.share == None: #party.share = self.avg #party.share = avg party.share = (self.total * party.percent) / 100.0 def calc_percent(self): assigned_percent = 0 assigned_count = 0 for party in self.parties: if party.percent != None: assigned_percent = party.percent assigned_count = assigned_count + 1 unassigned_percent = 100.0 - assigned_percent unassigned_count = len(self.parties) - assigned_count none_percent = unassigned_percent / unassigned_count if abs(unassigned_percent) > 0.0001 and unassigned_count == 0: print "Total percentage does not add up to 100% - auto adjusting percentage " for party in self.parties: party.percent = (party.percent * 100.0) / assigned_percent elif unassigned_count > 0: for party in self.parties: if party.percent == None: party.percent = none_percent def addShare(map, share): if share.id in map: total = map[share.id] total.share = total.share + share.share total.paid = total.paid + share.paid else: total = deepcopy(share) map[total.id] = total def split(txns): total_share = dict() for txn in txns: txn.calc() for party in txn.parties: addShare(total_share, party) share_list = [] for id in total_share: share = total_share[id] share_list.append(share) share_list = sorted(share_list, key=lambda share: (share.paid - share.share)) for share in share_list: print ' %s : Total : %f, Paid : %f, To Pay : %f ' % (share.id, share.share, share.paid, share.share - share.paid) # decide shares order in ascending summary_txns = [] pay_back = [] #ti = 0 bi = len(share_list) for i in range(len(share_list)): top = share_list[i] for j in reversed(range(bi)): bi = j+1 bot = share_list[j] # i pays to j if top.to_pay() <= 0.0: # paid his share break if bot.pay_back() <= 0.0: # got his share continue if top.to_pay() < bot.pay_back(): summary_txn = Txn() summary_txn.parties.append(Share(top.id)) summary_txn.parties.append(Share(bot.id, top.to_pay(), 0.0)) summary_txn.calc() summary_txns.append(summary_txn) pay_back.append('%s pays %f to %s' % (top.id, top.to_pay(), bot.id)) bot.paid = bot.paid - top.to_pay() top.paid = top.share break elif top.to_pay() > bot.pay_back(): summary_txn = Txn() summary_txn.parties.append(Share(top.id)) summary_txn.parties.append(Share(bot.id, bot.pay_back(), 0.0)) summary_txn.calc() summary_txns.append(summary_txn) pay_back.append('%s pays %f to %s' % (top.id, bot.pay_back(), bot.id)) top.paid = top.paid + bot.pay_back() bot.paid = bot.share continue else: summary_txn = Txn() summary_txn.parties.append(Share(top.id)) summary_txn.parties.append(Share(bot.id, top.to_pay(), 0.0)) summary_txn.calc() summary_txns.append(summary_txn) pay_back.append('%s pays %f to %s' % (top.id, top.to_pay(), bot.id)) top.paid = top.share bot.paid = bot.share #bi = j - 1 break for s in pay_back: print s return summary_txns if __name__ == "__main__": txns = [] txn = Txn() txn.parties.append(Share('A', 100.0)) txn.parties.append(Share('B')) txn.parties.append(Share('C')) txns.append(txn) txn = Txn() txn.parties.append(Share('A')) txn.parties.append(Share('B', 50.0)) txns.append(txn) txn = Txn() txn.parties.append(Share('A')) txn.parties.append(Share('D', 150.0)) txns.append(txn) txn = Txn() txn.parties.append(Share('A', 100.0)) txn.parties.append(Share('E')) txns.append(txn) txn = Txn() txn.parties.append(Share('Q', 1000.0)) txn.parties.append(Share('D')) txn.parties.append(Share('A')) txn.parties.append(Share('B')) txn.parties.append(Share('C')) txns.append(txn) txn = Txn() txn.parties.append(Share('A', 1500)) txn.parties.append(Share('C')) txns.append(txn) # split summary_txns = split(txns) for txn1 in summary_txns: print '**********TXN**********' for share in txn1.parties: print "%s : to pay : %.2f" % (share.id, share.to_pay())
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