Esempio n. 1
0
 def get_user_data(self,day=today()):
     """
     By default returns today's user data.
     If other date is set in day parameter tries to return that day user data.
     If no user data is created for this date it returns a new object, 
     if no other user_data is in the db it sets weight and waist to 0,
     else it sets weigth and waist to values from the latest user_data 
     """
     try:
         data = self.user.userdata_set.get(date=day)
         return data
     except UserData.DoesNotExist:
         # get the latest data
         approximated_weight = approximate_user_data_for_date(self.user.userdata_set.all(),"weight",day)
         if not approximated_weight: approximated_weight = 0
         return UserData(user=self.user, weight=approximated_weight, waist=0, date=day)
Esempio n. 2
0
def approximate_user_data_for_date(user_data_list, field = 'weight', day = today()):
    """
    Gets an approximation of user weight on a particular date.
    Either it returns true weight, or estimated one
    """
    
    if len(user_data_list) == 0: return None

    min_day = min(user_data_list).date
    index = (day - min_day).days
    approximated_data = approximate_user_data(user_data_list, field)
    
    if index < 0: index = 0
    if index > len(approximated_data)-1: index = len(approximated_data)-1 
    
    return approximated_data[index]
    
Esempio n. 3
0
 def __getattr__(self, name):
     if name.startswith("diff"):
         type, param, number, unit = name.split("_")
         if type == "diff": return self.get_diff(today(), param, int(number), unit)
     else:
         return super.__getattr__(name)
Esempio n. 4
0
def approximate_user_data(user_data_list, field = 'weight', extend_to=0, current_date = today()):
    """
    Gets a user data list witch doesn't have to be consistent and transforms it into
    consisten values list with either weight, bmi or waist values
    
    Approximates only gaps in data, if there's no data in the beginning or in the end it leavs them
    """
    
    if len(user_data_list) == 0: return None

    min_date = min(user_data_list).date
    max_date = max(user_data_list).date
    
    extend_right = (current_date - max_date).days
    if extend_right < 0: extend_to = extend_to + abs(extend_right)
    
    # print min_date, max_date
    # print 'extend_to', extend_to    
    # print 'extend_right', extend_right
        
    days = (max_date - min_date).days+1
    values = [ 0 for i in range(days) ]
    
    # build consistent value list with zeroes where there's no data
    for ud in user_data_list:
        index = (ud.date - min_date).days
        val = getattr(ud, field)
        if val and val != 0: values[index] = val
    
    # determine consistent no values areas
    approximation_areas = []
    current_area = []
    for i,v in enumerate(values):

        if v == 0:  # checking if theres lack of data
            if current_area == []: current_area.append(i)
            else:
                if current_area[len(current_area)-1]+1 == i: # consistent area
                    current_area.append(i)
                else:
                    approximation_areas.append(current_area)
                    current_area = [i]

    # adding last area
    if current_area != []: approximation_areas.append(current_area)
    
    min_index = 0 
    max_index = days-1
    
    # now doing the linear approximation
    for approximation_area in approximation_areas:
        #approximating all areas except for those  with begining index or ending index
        border_values = filter(lambda e: e in [min_index, max_index], approximation_area)        
        if border_values == []:
            size = len(approximation_area)  # area size
            start_value = values[approximation_area[0]-1] 
            end_value = values[approximation_area[size-1]+1]
            approximation_step = (end_value - start_value)/(size+1)
            
            for i,index in enumerate(approximation_area):
                values[index] = start_value + approximation_step*(i+1)
        elif border_values == [min_index]:
            # set first weight
            weight = values[approximation_area[len(approximation_area)-1]+1]
            for index in approximation_area: values[index] = weight
        elif border_values == [max_index]:
            # set last weight
            weight = values[approximation_area[0]-1]
            for index in approximation_area: values[index] = weight
            pass 
        
    # appending approximated values after last value
    if extend_right:
        extended_values = [ values[len(values)-1] for i in range(extend_right) ]
        values.extend(extended_values)
    
    # appending approximated values before first value    
    if extend_to and len(values) < extend_to:
        extended_values = [ values[0] for i in range(extend_to-len(values)) ]
        for v in values: extended_values.append(v)
        values =  extended_values
    
    '''
    We have entire approximated history in values variable and we must return extend_to long sequence ending in requested day so:
    if the sequence is too long ( user has more data in his history then we want to show ) we nead to return a subsequence of values
    '''
    print len(values)
    if len(values) >= extend_to and extend_to:
        if extend_right < 0:
            '''
            End day is somewhere inside the sequence 
            '''
            return values[max(0,len(values)-extend_to+extend_right):len(values)+extend_right]
        else:
            '''
            End day is the end of the sequence
            '''
            return values[len(values)-extend_to:]
    else:
        return values