Parse data into three logs In the bit of code below:


How can I make add_day, add_ week and add_month work as a single function? They are almost copy-paste of one another. I'm trying to follow the DRY rule.
How can I set this so that I don't use the variables day/week/cur_day?




import datetime
from collections import defaultdict

class ParsedData:
    def __init__(self, date, score, status, item_name):
        year, month, self.day = date.split("-")
        self.month = datetime.date(int(year), int(month), int(self.day)).strftime("%B")
        self.score = int(score)
        self.status = status
        self.item_name = item_name


class Log:
    def __init__(self):
        self.day = {}
        self.week = {}
        self.month = {}
        self.counter = {}

        self.default_data 

    def add_day(self, day, status, item_name, score):
        day = 'Day %i' % day
        if day not in self.day:
            self.day[day] = {"Comp": defaultdict(int),
                         "Miss": defaultdict(int),
                         "Post": defaultdict(int),
                         "Add": defaultdict(int),
                         "Score": 0}

        self.day[day][status][item_name] += 1
        self.day[day]['Score'] = score

    def add_week(self, week, status, item_name, score):
        week = 'Week %i' % week
        if week not in self.week:
            self.week[week] = {"Comp": defaultdict(int),
                         "Miss": defaultdict(int),
                         "Post": defaultdict(int),
                         "Add": defaultdict(int),
                         "Score": 0}

        self.week[week][status][item_name] += 1
        self.week[week]['Score'] = score

    def add_month(self, month, status, item_name, score):
        if month not in self.month:
            self.month[month] = {"Comp": defaultdict(int),
                         "Miss": defaultdict(int),
                         "Post": defaultdict(int),
                         "Add": defaultdict(int),
                         "Score": 0}

        self.month[month][status][item_name] += 1
        self.month[month]['Score'] = score


def update_views(log_file):
    log = Log()
    day = 0
    cur_day = None
    week = 1

    for line in log_file:
        parsed = ParsedData(*line.strip().split(","))

        if cur_day != parsed.day:
            cur_day = parsed.day
            day += 1
            if day % 7 == 0:
                week += 1

        log.add_day(day, parsed.status, parsed.item_name, parsed.score)
        log.add_week(week, parsed.status, parsed.item_name, parsed.score)
        log.add_month(parsed.month, parsed.status, parsed.item_name, parsed.score)


log_file =   """2015-01-1,0,Add,DW_05
                2015-01-2,-1,Post,CR_02
                2015-01-3,-1,Comp,DIY_01
                2015-01-3,-1,Post,CD_01
                2015-01-4,-1,Miss,D_03
                2015-01-4,0,Miss,D_03
                2015-01-4,-1,Miss,CD_01
                2015-01-4,0,Miss,LS_04
                2015-01-5,1,Comp,DW_05
                2015-01-6,1,Comp,ANI_06
                2015-01-6,1,Comp,LS_04
                2015-01-7,1,Comp,NMW_07
                2015-01-7,1,Post,DW_05
                2015-01-7,1,Miss,LP_08
                2015-01-8,2,Post,CR_02
                2015-01-8,2,Miss,SEV_09
                2015-01-10,3,Comp,M_10
                2015-01-10,3,Add,NID_11
                2015-01-11,2,Add,ANI_06
                2015-01-12,1,Add,VF_12
                2015-01-12,0,Miss,DIY_01
                2015-01-12,1,Add,NID_11
                2015-01-12,0,Miss,D_03
                2015-01-13,1,Miss,SEV_09
                2015-01-13,2,Add,DW_05
                2015-01-13,1,Comp,NMW_07
                2015-01-13,1,Add,CPC_12""".splitlines()

update_views(log_file)
To avoid repetitive code, make the Log class do only one of the three things it currently does, and create three instances instead:

class Log(object):
    def __init__(self, name):
        self.name = name
        self.data = {}

    def add_item(self, key, status, item_name, score):
        key = '%s %i' % (self.name, key)
        if key not in self.data:
            self.data[key] = {"Comp": defaultdict(int),
                         "Miss": defaultdict(int),
                         "Post": defaultdict(int),
                         "Add": defaultdict(int),
                         "Score": 0}

        self.data[key][status][item_name] += 1
        self.data[key]['Score'] = score

def update_views(log_file):
    daily_log = Log('Day')
    weekly_log = Log('Week')
    monthly_log = Log('Month')
    ...