def update_portfolio(returns, withdrawal, stock_allocation, balance):
    """Update a portfolio based on performance in a single year.

    Parameters
    ----------
    returns : dict
        Stock and bond returns for a single year.
    withdrawal : float
        Amount to withdraw from the portfolio. The withdrawal
        is assumed to take place at the end of the year after
        adjusting for inflation.
    stock_allocation : float
        The fraction of the portfolio to allocate to equities.
        The update calculations assume the portfolio is rebalanced
        annually.
    balance : float
        Portfolio balance at the beginning of the year.

    Returns
    -------
    balance : float
        The balance at the and of the year after accounting for
        all market gains and withdrawals.
    """
    return (
        # stocks plus appreciation and dividends
        balance * stock_allocation * (1 + returns['stocks'])
        # bonds plus bond income
        + balance * (1 - stock_allocation) * (1 + returns['bonds'])
        # end of year withdrawal
        - withdrawal
    )