# Path: bluechips/model/user.py
# class User(object):
#     def __init__(self, username, name=u"", resident=True):
#         self.username = username
#         self.name = name
#         self.resident = resident
#     
#     def __repr__(self):
#         return '<User: %s>' % (self.username)
# 
#     def __unicode__(self):
#         return self.name
# 
# Path: bluechips/model/split.py
# class Split(object):
#     def __init__(self, expenditure=None, user=None, share=Currency(0)):
#         self.expenditure = expenditure
#         self.user = user
#         self.share = share
#     
#     def __repr__(self):
#         return '<Split: expense: %s user: %s share: %s>' % (self.expenditure,
#                                                             self.user,
#                                                             self.share)
# 
# Path: bluechips/model/meta.py

# 
# Path: bluechips/model/types.py
# class Currency(object):
#     """
#     Store currency values as an integral number of cents
#     """
#     __metaclass__ = SmartSubclass(int)
#     __old_values__ = WeakValueDictionary()
#     def __new__(cls, value):
#         if value is None:
#             value = 0
#         elif isinstance(value, str):
#             value = int(float(value) * 100)
#         else:
#             value = int(value)
#         
#         if value not in cls.__old_values__:
#             new_object = super(cls, cls).__new__(cls)
#             new_object.value = value
#             cls.__old_values__[value] = new_object
#             return new_object
#         else:
#             return cls.__old_values__[value]
#     
#     def __int__(self):
#         """
#         If I don't define this, SmartSubclass will return
#         Currency(int(self.value))
#         """
#         return self.value
#     def __float__(self):
#         """
#         If I don't define this, SmartSubclass will return
#         Currency(float(self.value))
#         """
#         return float(self.value)
#     def __long__(self):
#         """
#         If I don't define this, SmartSubclass will return
#         Currency(long(self.value))
#         """
#         return long(self.value)
#     
#     def __cmp__(self, other):
#         """
#         This is overridden for when validators compare a Currency to
#         ''
#         """
#         if other == '':
#             return 1
#         else:
#             return self.value.__cmp__(int(other))
#     
#     def __mul__(self, other):
#         """
#         If I don't define this, SmartSubclass will convert the other
#         argument to an int
#         """
#         return Currency(self.value * other)
#     def __rmul__(self, other):
#         """
#         If I don't define this, SmartSubclass will convert the other
#         argument to an int
#         """
#         return self.__mul__(other)
#     def __div__(self, other):
#         """
#         If I don't define this, SmartSubclass will convert the other
#         argument to an int
#         """
#         return Currency(self.value / other)
#     def __truediv__(self, other):
#         """
#         If I don't define this, SmartSubclass will convert the other
#         argument to an int
#         """
#         return Currency(self.value / other)
#     
#     def __repr__(self):
#         return '%s("%s")' % (self.__class__.__name__, str(self))
#     def __str__(self):
#         return locale.currency(self.value / 100., grouping=True)


from bluechips.model.user import User
from bluechips.model.split import Split
from bluechips.model import meta
from bluechips.model.types import Currency
from decimal import Decimal
from datetime import datetime
import random
        Percentages will be normalized to sum to 100%.
        
        If the split leaks or gains money due to rounding errors, the
        pennies will be randomly distributed to a subset of the users.
        
        I mean, come on. You're already living together. Are you really
        going to squabble over a few pennies?
        """
        
        map(meta.Session.delete, meta.Session.query(Split).\
                filter_by(expenditure_id=self.id))
        
        total = sum(split_dict.itervalues())
        
        for user, share in split_dict.items():
            if share == 0:
                del split_dict[user]
            
        amounts_dict = dict()
        
        for user, share in split_dict.iteritems():
            amounts_dict[user] = Currency((share * self.amount) / total)
        
        difference = self.amount - sum(amounts_dict.itervalues())

        winners = random.sample(amounts_dict.keys(), abs(int(difference)))
        for winner in winners:
            amounts_dict[winner] += Currency(1) if difference > 0 else Currency(-1)
        
        for user, share in amounts_dict.iteritems():

# Path: bluechips/model/user.py
# class User(object):
#     def __init__(self, username, name=u"", resident=True):
#         self.username = username
#         self.name = name
#         self.resident = resident
#     
#     def __repr__(self):
#         return '<User: %s>' % (self.username)
# 
#     def __unicode__(self):
#         return self.name
# 
# Path: bluechips/model/split.py
# class Split(object):
#     def __init__(self, expenditure=None, user=None, share=Currency(0)):
#         self.expenditure = expenditure
#         self.user = user
#         self.share = share
#     
#     def __repr__(self):
#         return '<Split: expense: %s user: %s share: %s>' % (self.expenditure,
#                                                             self.user,
#                                                             self.share)
# 
# Path: bluechips/model/meta.py

# 
# Path: bluechips/model/types.py
# class Currency(object):
#     """
#     Store currency values as an integral number of cents
#     """
#     __metaclass__ = SmartSubclass(int)
#     __old_values__ = WeakValueDictionary()
#     def __new__(cls, value):
#         if value is None:
#             value = 0
#         elif isinstance(value, str):
#             value = int(float(value) * 100)
#         else:
#             value = int(value)
#         
#         if value not in cls.__old_values__:
#             new_object = super(cls, cls).__new__(cls)
#             new_object.value = value
#             cls.__old_values__[value] = new_object
#             return new_object
#         else:
#             return cls.__old_values__[value]
#     
#     def __int__(self):
#         """
#         If I don't define this, SmartSubclass will return
#         Currency(int(self.value))
#         """
#         return self.value
#     def __float__(self):
#         """
#         If I don't define this, SmartSubclass will return
#         Currency(float(self.value))
#         """
#         return float(self.value)
#     def __long__(self):
#         """
#         If I don't define this, SmartSubclass will return
#         Currency(long(self.value))
#         """
#         return long(self.value)
#     
#     def __cmp__(self, other):
#         """
#         This is overridden for when validators compare a Currency to
#         ''
#         """
#         if other == '':
#             return 1
#         else:
#             return self.value.__cmp__(int(other))
#     
#     def __mul__(self, other):
#         """
#         If I don't define this, SmartSubclass will convert the other
#         argument to an int
#         """
#         return Currency(self.value * other)
#     def __rmul__(self, other):
#         """
#         If I don't define this, SmartSubclass will convert the other
#         argument to an int
#         """
#         return self.__mul__(other)
#     def __div__(self, other):
#         """
#         If I don't define this, SmartSubclass will convert the other
#         argument to an int
#         """
#         return Currency(self.value / other)
#     def __truediv__(self, other):
#         """
#         If I don't define this, SmartSubclass will convert the other
#         argument to an int
#         """
#         return Currency(self.value / other)
#     
#     def __repr__(self):
#         return '%s("%s")' % (self.__class__.__name__, str(self))
#     def __str__(self):
#         return locale.currency(self.value / 100., grouping=True)


# Path: bluechips/model/expenditure.py
from bluechips.model.user import User
from bluechips.model.split import Split
from bluechips.model import meta
from bluechips.model.types import Currency
from decimal import Decimal
from datetime import datetime
import random

        Percentages will be normalized to sum to 100%.
        
        If the split leaks or gains money due to rounding errors, the
        pennies will be randomly distributed to a subset of the users.
        
        I mean, come on. You're already living together. Are you really
        going to squabble over a few pennies?
        """
        
        map(meta.Session.delete, meta.Session.query(Split).\
                filter_by(expenditure_id=self.id))
        
        total = sum(split_dict.itervalues())
        
        for user, share in split_dict.items():
            if share == 0:
                del split_dict[user]
            
        amounts_dict = dict()
        
        for user, share in split_dict.iteritems():
            amounts_dict[user] = Currency((share * self.amount) / total)
        
        difference = self.amount - sum(amounts_dict.itervalues())

        winners = random.sample(amounts_dict.keys(), abs(int(difference)))
        for winner in winners:
            amounts_dict[winner] += Currency(1) if difference > 0 else Currency(-1)
        
        for user, share in amounts_dict.iteritems():

            s = Split(self, user, share)