Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

hackathon

import json from collections import defaultdict

class QuickSplit: def init(self): self.expenses = [] self.people = set()

def add_expense(self, payer, amount, participants, split_type='equal', custom_shares=None):
    """
    Add a new expense to the tracker
    
    Args:
        payer: Who paid for this expense
        amount: Total amount paid
        participants: List of people who share this expense
        split_type: 'equal' or 'custom'
        custom_shares: Required if split_type is 'custom' (dict of {person: share})
    """
    if split_type == 'equal':
        share = amount / len(participants)
        shares = {p: share for p in participants}
    elif split_type == 'custom':
        if not custom_shares or sum(custom_shares.values()) != amount:
            raise ValueError("Invalid custom shares")
        shares = custom_shares
    else:
        raise ValueError("Invalid split type")
        
    self.expenses.append({
        'payer': payer,
        'amount': amount,
        'shares': shares
    })
    self.people.update(participants)
    self.people.add(payer)

def calculate_balances(self):
    """Calculate net balance for each person"""
    balances = defaultdict(float)
    
    for expense in self.expenses:
        payer = expense['payer']
        shares = expense['shares']
        
        balances[payer] += expense['amount']
        for person, share in shares.items():
            balances[person] -= share
            
    return balances

def simplify_settlements(self, balances):
    """Simplify debts using graph theory to minimize transactions"""
    creditors = []
    debtors = []
    
    for person, balance in balances.items():
        if balance > 0:
            creditors.append((person, balance))
        elif balance < 0:
            debtors.append((person, -balance))
            
    creditors.sort(key=lambda x: x[1], reverse=True)
    debtors.sort(key=lambda x: x[1], reverse=True)
    
    settlements = []
    i = j = 0
    
    while i < len(creditors) and j < len(debtors):
        creditor, credit_amt = creditors[i]
        debtor, debt_amt = debtors[j]
        
        settlement_amt = min(credit_amt, debt_amt)
        settlements.append((debtor, creditor, settlement_amt))
        
        creditors[i] = (creditor, credit_amt - settlement_amt)
        debtors[j] = (debtor, debt_amt - settlement_amt)
        
        if creditors[i][1] == 0:
            i += 1
        if debtors[j][1] == 0:
            j += 1
            
    return settlements

def generate_report(self, settlements):
    """Generate a human-readable settlement report"""
    if not settlements:
        return "No settlements needed - all balances are even."
        
    report = ["\nSettlement Instructions:", "="*25]
    for debtor, creditor, amount in settlements:
        report.append(f"{debtor} should pay {creditor} ${amount:.2f}")
    
    return "\n".join(report)

def save_to_file(self, filename, data):
    """Save data to a JSON file"""
    with open(filename, 'w') as f:
        json.dump(data, f, indent=2)

def load_from_file(self, filename):
    """Load data from a JSON file"""
    with open(filename, 'r') as f:
        data = json.load(f)
        self.expenses = data.get('expenses', [])
        self.people = set(data.get('people', []))

def run_cli(self):
    """Command-line interface for QuickSplit"""
    print("QuickSplit - Expense Tracking & Splitting Tool")
    print("="*45)
    
    while True:
        print("\nMenu:")
        print("1. Add new expense")
        print("2. Show settlements")
        print("3. Save to file")
        print("4. Load from file")
        print("5. Exit")
        
        choice = input("Enter your choice: ")
        
        if choice == '1':
            payer = input("Who paid for this expense? ")
            amount = float(input("Amount paid: "))
            participants = input("Participants (comma separated): ").split(',')
            participants = [p.strip() for p in participants]
            
            split_type = input("Split type (equal/custom): ").lower()
            custom_shares = None
            
            if split_type == 'custom':
                custom_shares = {}
                print("Enter each person's share:")
                for p in participants:
                    share = float(input(f"{p}'s share: "))
                    custom_shares[p] = share
            
            self.add_expense(payer, amount, participants, split_type, custom_shares)
            print("Expense added successfully!")
        
        elif choice == '2':
            balances = self.calculate_balances()
            settlements = self.simplify_settlements(balances)
            print(self.generate_report(settlements))
        
        elif choice == '3':
            filename = input("Enter filename to save: ")
            data = {
                'expenses': self.expenses,
                'people': list(self.people)
            }
            self.save_to_file(filename, data)
            print(f"Data saved to {filename}")
        
        elif choice == '4':
            filename = input("Enter filename to load: ")
            self.load_from_file(filename)
            print(f"Data loaded from {filename}")
        
        elif choice == '5':
            print("Exiting QuickSplit. Goodbye!")
            break
        
        else:
            print("Invalid choice. Please try again.")

if name == "main": app = QuickSplit() app.run_cli()

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages