def save(self, *args, **kwargs): self.kesto_h = coalesce(self.kesto_h, 0) self.kesto_min = coalesce(self.kesto_min, 0) self.kesto = duration_to_decimal(self.kesto_h, self.kesto_min) self.vauhti_min_km = speed_min_per_km(self.vauhti_min, self.vauhti_s) if self.vauhti_min_km is not None and self.vauhti_min_km != 0: self.vauhti_km_h = 60 / self.vauhti_min_km super(Teho, self).save(*args, **kwargs)
def save(self, *args, **kwargs): self.aika_id = self.pvm.strftime('%Y%m%d') self.kesto_h = coalesce(self.kesto_h, 0) self.kesto_min = coalesce(self.kesto_min, 0) self.kesto = duration_to_decimal(self.kesto_h, self.kesto_min) self.vauhti_min_km = speed_min_per_km(self.vauhti_min, self.vauhti_s) if self.vauhti_min_km is None and self.vauhti_km_h is not None and self.vauhti_km_h != 0: self.vauhti_min_km = 60 / self.vauhti_km_h self.vauhti_min = int(self.vauhti_min_km) self.vauhti_s = round((self.vauhti_min_km * 60) % 60, 0) elif self.vauhti_min_km is not None and self.vauhti_min_km != 0 and self.vauhti_km_h is None: self.vauhti_km_h = 60 / self.vauhti_min_km super(Harjoitus, self).save(*args, **kwargs)
def hours_year_to_date(user_id): current_day = datetime.now().date() hours = Harjoitus.objects.filter(user=user_id, aika__vuosi=current_day.year, aika__pvm__lte=current_day).aggregate( Sum('kesto'))['kesto__sum'] hours = float(utils.coalesce(hours, 0)) return hours
def avg_feeling_per_period(user_id, start_date, end_date): feeling = Harjoitus.objects.filter( user=user_id, aika__pvm__gte=start_date, aika__pvm__lte=end_date, ).aggregate(Avg('tuntuma'))['tuntuma__avg'] feeling = float(utils.coalesce(feeling, 0)) return feeling
def hours_past_year_to_date(user_id): current_day = datetime.now().date() current_day_minus_365 = pd.Timestamp(current_day - timedelta(days=365)) hours = Harjoitus.objects.filter( user=user_id, aika__vuosi=current_day.year - 1, aika__pvm__lte=current_day_minus_365).aggregate( Sum('kesto'))['kesto__sum'] hours = float(utils.coalesce(hours, 0)) return hours
def trainings_to_df(user_id, columns, startdate=None, enddate=None, sport='Kaikki', restdays=True, duration_format='str', date_format='%Y-%m-%d'): """ Fetch training data from database and return cleaned pandas dataframe of it """ if not Harjoitus.objects.filter(user=user_id): return None startdate = int( coalesce(startdate, first_training_date(user_id).strftime('%Y%m%d'))) enddate = int(coalesce(enddate, datetime.now().date().strftime('%Y%m%d'))) join_type = 'left' if restdays is True else 'inner' days = Aika.objects.filter(vvvvkkpp__gte=startdate, vvvvkkpp__lte=enddate).values_list( 'pvm', 'vvvvkkpp', 'viikonpaiva_lyh', 'vko') days_df = pd.DataFrame(days, columns=['Pvm', 'vvvvkkpp', 'Viikonpäivä', 'Vko']) trainings = Harjoitus.objects.filter(user=user_id).values_list( 'id', 'id', 'aika_id', 'kesto', 'kesto_h', 'kesto_min', 'laji__laji_nimi', 'matka', 'vauhti_km_h', 'keskisyke', 'tuntuma', 'kommentti') trainings_df = pd.DataFrame(trainings, columns=[ 'edit', 'delete', 'vvvvkkpp', 'Kesto', 'h', 'min', 'Laji', 'Matka (km)', 'Vauhti (km/h)', 'Keskisyke', 'Tuntuma', 'Kommentti' ]) trainings_df['details'] = np.nan trainings_df = days_df.merge(trainings_df, how=join_type, left_on='vvvvkkpp', right_on='vvvvkkpp') # cleaning data trainings_df['Laji'].fillna('Lepo', inplace=True) trainings_df['Pvm'] = pd.to_datetime( trainings_df['Pvm']).dt.strftime(date_format) trainings_df[['Matka (km)', 'Vauhti (km/h)' ]] = trainings_df[['Matka (km)', 'Vauhti (km/h)']].astype(float).round(1) trainings_df[['delete', 'edit', 'Keskisyke', 'Tuntuma']] = trainings_df[[ 'delete', 'edit', 'Keskisyke', 'Tuntuma' ]].fillna(-1).astype(int).astype(str).replace('-1', np.nan) trainings_df['Päivä'] = trainings_df[['Pvm', 'Viikonpäivä' ]].apply(lambda x: ' '.join(x), axis=1) if duration_format == 'str': trainings_df['Kesto'] = trainings_df.apply( lambda row: duration_to_string(row['h'], row['min']), axis=1) # calculate duration per zone zones = Teho.objects.filter(harjoitus_id__user=user_id).values_list( 'harjoitus_id', 'tehoalue_id__tehoalue', 'kesto', 'kesto_h', 'kesto_min') if zones: zones_df = pd.DataFrame(zones, columns=['id', 'teho', 'kesto', 'h', 'min']).fillna(np.nan) zones_df['kesto'] = zones_df['kesto'].astype(float) zones_df = zones_df.groupby(['id', 'teho']).sum().reset_index() if duration_format == 'str': zones_df['kesto'] = zones_df.apply( lambda row: duration_to_string(row['h'], row['min']), axis=1) zones_df = zones_df.pivot(index='id', columns='teho', values='kesto') zones_df.index = zones_df.index.map(str) trainings_df = trainings_df.merge(zones_df, how='left', left_on='edit', right_index=True) # filter by sport if sport != 'Kaikki': user_sports = sports_to_dict(user_id) if sport in user_sports.keys(): trainings_df = trainings_df[trainings_df['Laji'].isin( user_sports[sport])] else: trainings_df = trainings_df[trainings_df['Laji'] == sport] trainings_df.sort_values(by='vvvvkkpp', ascending=False, inplace=True) return trainings_df[columns]
def test_not_none(self): x = 'koira' val = 'kissa' self.assertEqual(coalesce(x, val), 'koira')
def test_nan(self): x = np.nan val = 'kissa' self.assertEqual(coalesce(x, val), 'kissa')
def total_hours_per_year(user_id, year): hours = Harjoitus.objects.filter(user=user_id, aika__vuosi=year).aggregate( Sum('kesto'))['kesto__sum'] hours = float(utils.coalesce(hours, 0)) return hours
def trainings_view(request): """ List of trainings """ user_id = request.user.id current_day = datetime.now().date() startdate = utils.coalesce(cl.first_training_date(user_id), current_day).strftime('%d.%m.%Y') enddate = current_day.strftime('%d.%m.%Y') sports = tr.sports_to_dict(user_id) sport = 'Kaikki' zones = tr.zone_areas_to_list(user_id) table_headers = [ 'details', 'Vko', 'Päivä', 'Laji', 'Kesto', 'Keskisyke', 'Matka (km)', 'Vauhti (km/h)', 'Tuntuma' ] + zones + ['Kommentti', 'edit', 'delete'] if request.method == "POST": if 'polar' in request.POST: return redirect('accesslink_trainings') sport = request.POST['sport'] startdate = request.POST['startdate'] enddate = request.POST['enddate'] if 'lepo' in request.POST: restdays = True else: restdays = False export_columns = [ 'Vko', 'Pvm', 'Viikonpäivä', 'Kesto', 'Laji', 'Matka (km)', 'Vauhti (km/h)', 'Keskisyke', 'Tuntuma', 'Kommentti' ] + zones trainings_df = tr.trainings_to_df( user_id=user_id, columns=export_columns, startdate=datetime.strptime(startdate, '%d.%m.%Y').strftime('%Y%m%d'), enddate=datetime.strptime(enddate, '%d.%m.%Y').strftime('%Y%m%d'), sport=sport, restdays=restdays, duration_format='decimal', date_format='%d.%m.%Y') if trainings_df is None or trainings_df.empty: messages.add_message(request, messages.ERROR, 'Ei harjoituksia') else: try: if 'export_csv' in request.POST: return utils.dataframe_to_csv(trainings_df) if 'export_xls' in request.POST: return utils.dataframe_to_excel(trainings_df) except Exception as e: messages.add_message(request, messages.ERROR, 'Lataus epäonnistui: {}'.format(str(e))) return render(request, 'trainings.html', context={ 'sport': sport, 'sports': sports, 'startdate': startdate, 'enddate': enddate, 'table_headers': table_headers })