Python Recipe: Calculate adjusted monthly values

By

Here's a function I wrote earlier today that should calculate an adjusted monthly average, prorating a monthly number as if the month was 30 days in length. The idea is to compare numbers from different months against each other and prevent longer months from returning higher values simply because they contain more days.

The script is included with a variety of other math tools I've collected on Github under the name python-math.

Per usual, if I screwed something up, just let me know. We'll get it ironed out.

import calendar
import datetime

def adjusted_monthly_value(value, dt):
    """
    Accepts a value and a datetime object, and
    then prorates the value to a 30-day figure
    depending on how many days are in the month.
    
    This can be useful for month-to-month comparisons
    in circumstances where fluctuations in the number
    of days per month may skew the analysis. 
    
    For instance, February typically has only 28 days, in 
    comparison to March, which has 31.
    
    h3. Example usage
    
        >> import calculate
        >> calculate.adjusted_monthly_value(10, datetime.datetime(2009, 4, 1))
        10.0
        >> calculate.adjusted_monthly_value(10, datetime.datetime(2009, 2, 17))
        10.714285714285714
        >> calculate.adjusted_monthly_value(10, datetime.datetime(2009, 12, 31))
        9.67741935483871
	
    h3. Documentation
	
        "calendar module":http://docs.python.org/library/calendar.html
	
    """
    # Test to make sure the first input is a number
    if not isinstance(value, (int,long,float)):
        return ValueError('Input values should be a number, your input is a %s' % type(value))
	
    # Test to make sure the second input is a date
    if not isinstance(dt, (datetime.datetime, datetime.date)):
        return ValueError('The submitted month should be a date or datetime value, you input a %s' % type(dt))
	
    # Get the length of the month
    length_of_month = calendar.monthrange(dt.year, dt.month)[1]
    
    # Determine the adjustment necessary to pro-rate the value to 30 days.
    adjustment = 30.0/length_of_month
    
    # Multiply the value against the adjustment and return the result
    return value * adjustment
en
290