Iterate repeated code blocks with data

This is a fragment of code we deployed at a large bank to calculate year-on-year growth of balance:

    data['yoy_CDAB'] = map(
        calculate_calender_yoy,
        data['TOTAL_CDAB_x'],
        data['TOTAL_CDAB_y'])

On 29 Aug, the client added more metrics:

This led to:

    data['yoy_CDAB'] = map(
        calculate_calender_yoy,
        data['TOTAL_CDAB_x'],
        data['TOTAL_CDAB_y'])
    data['yoy_MDAB'] = map(
        calculate_calender_yoy,
        data['TOTAL_MDAB_x'],
        data['TOTAL_MDAB_y'])
    data['yoy_MEB'] = map(
        calculate_calender_yoy,
        data['TOTAL_MEB_x'],
        data['TOTAL_MEB_y'])

On 31 Aug, the client wanted to see this for different areas:

This led to:

    data['yoy_CDAB'] = map(
        calculate_calender_yoy,
        data['TOTAL_CDAB_x'],
        data['TOTAL_CDAB_y'])
    data['yoy_MDAB'] = map(
        calculate_calender_yoy,
        data['TOTAL_MDAB_x'],
        data['TOTAL_MDAB_y'])
    data['yoy_MEB'] = map(
        calculate_calender_yoy,
        data['TOTAL_MEB_x'],
        data['TOTAL_MEB_y'])

    total_data['yoy_CDAB'] = map(
        calculate_calender_yoy,
        total_data['TOTAL_CDAB_x'],
        total_data['TOTAL_CDAB_y'])
    total_data['yoy_MDAB'] = map(
        calculate_calender_yoy,
        total_data['TOTAL_MDAB_x'],
        total_data['TOTAL_MDAB_y'])
    total_data['yoy_MEB'] = map(
        calculate_calender_yoy,
        total_data['TOTAL_MEB_x'],
        total_data['TOTAL_MEB_y'])

    etb_data['yoy_CDAB'] = map(
        calculate_calender_yoy,
        etb_data['TOTAL_CDAB_x'],
        etb_data['TOTAL_CDAB_y'])
    etb_data['yoy_MDAB'] = map(
        calculate_calender_yoy,
        etb_data['TOTAL_MDAB_x'],
        etb_data['TOTAL_MDAB_y'])
    etb_data['yoy_MEB'] = map(
        calculate_calender_yoy,
        etb_data['TOTAL_MEB_x'],
        etb_data['TOTAL_MEB_y'])

The above code that actually deployed in production.

Loops avoid duplication.

Whenever you see code copy-pasted with a few changes, use loops.

    for area in [data, total_data, etb_data]:
        for val in ['CDAB', 'MDAB', 'MEB']:
            area['yoy_' + val] = map(
                calculate_calendar_yoy,
                area['TOTAL_' + val + '_x'],
                area['TOTAL_' + val + '_y'])

This reduces 39 lines to 7 - and makes it easier to add more areas and metrics.