// This is a main entry point. // Convert the record structure to slices and maps suitable for use in the user interface. func processFitLap(runLaps []fit.Lap, toEnglish bool) (LapDist []float64, LapTime []string, LapCal []float64, LapPace []string) { for _, item := range runLaps { dist := unitCvt(item.Total_distance, "distance", toEnglish) cal := float64(item.Total_calories) // Seconds to "min:sec" laptime_str := strutil.DecimalTimetoMinSec(float64(item.Total_elapsed_time / 60.0)) // Calculate pace string. pace := item.Total_elapsed_time / 60.0 / dist //pace = unitCvt(pace, "pace", toEnglish) pace_str := strutil.DecimalTimetoMinSec(pace) LapDist = append(LapDist, dist) LapCal = append(LapCal, cal) LapPace = append(LapPace, pace_str) LapTime = append(LapTime, laptime_str) } return LapDist, LapTime, LapCal, LapPace }
// Create the summary statistics strings. func createStats(toEnglish bool, DispDistance []float64, TimeStamps []int64, LapCal []float64) (totalDistance string, totalPace string, elapsedTime string, totalCal string, avgPower string, startDateStamp string, endDateStamp string) { // Calculate run start and end times. startDateStamp = time.Unix(TimeStamps[0], 0).Format(time.UnixDate) endDateStamp = time.Unix(TimeStamps[len(TimeStamps)-1], 0).Format(time.UnixDate) // Calculate overall distance. totalDistance = strconv.FormatFloat(DispDistance[len(DispDistance)-1], 'f', 2, 64) if toEnglish { totalDistance += " mi" } else { totalDistance += " km" } // Calculate mm:ss for totalPace. timeDiffinMinutes := (float64(TimeStamps[len(TimeStamps)-1]) - float64(TimeStamps[0])) / 60.0 decimalPace := float64(timeDiffinMinutes) / DispDistance[len(DispDistance)-1] totalPace = strutil.DecimalTimetoMinSec(decimalPace) if toEnglish { totalPace += " min/mi" } else { totalPace += " min/km" } // Calculate hh:mm:ss for elapsedTime. elapsedTime = strutil.DecimalTimetoHourMinSec(float64(timeDiffinMinutes)) // Sum up the lap calories totcal := 0.0 for _, calorie := range LapCal { totcal += calorie } totalCal = strconv.Itoa(int((math.Floor(totcal)))) + " kcal" // Calculate power expended based on Garmin calculated calories power := totcal * 4186.8 / (timeDiffinMinutes * 60.0) avgPower = strconv.FormatFloat(power, 'f', 2, 64) + " Watts" return }
// Do a prediction based on this run. func createAnalysis(toEnglish bool, useSegment bool, DispDistance []float64, TimeStamps []int64, splitdist float64, splithours, splitmins, splitsecs int64, racedist float64, racehours, racemins, racesecs int64, ) (PredictedRaceTimes map[string]string, VDOT float64, VO2Max float64, RunScore float64, TrainingPaces map[string]string) { // Need to assign variables based on whether the user has selected the entire // run or just a run segment (e.g. a split time and distance) to basis the // prediction on. // Do the type conversions to get the inputs into forms expected by PredictRaces. var d, dist, tStart, tEnd, elapsedTime float64 if useSegment != true { d = DispDistance[len(DispDistance)-1] // Need distance back in meters as PredictRaces demands metric units. if toEnglish { dist = d / metersToMiles } else { dist = d / metersToKm } tStart = float64(TimeStamps[0]) tEnd = float64(TimeStamps[len(TimeStamps)-1]) elapsedTime = (tEnd - tStart) / 60.0 } else { dist = splitdist elapsedTime = (float64(splithours) * 60.0) + float64(splitmins) + (float64(splitsecs) / 60.0) } // Calculate the equivalent race times for this run (segment or complete). PredictedTimes, v, _ := predict.PredictRaces(dist, elapsedTime) VDOT = v // Calculate the % of VO2max for this run relative to the provided race information. elapsedTimeRace := (float64(racehours) * 60.0) + float64(racemins) + (float64(racesecs) / 60.0) velocityRace := racedist / elapsedTimeRace VO2Max = predict.CalcVO2max(velocityRace, elapsedTimeRace) RunScore = VDOT / VO2Max * 100.0 // Calculate the training paces. easyPace, maraPace, thresholdPace, intervalPace, repPace := predict.TrainingPaces(VO2Max) TrainingPaces = make(map[string]string) if toEnglish { easyPace = 1609.34 / easyPace maraPace = 1609.34 / maraPace thresholdPace = 1609.34 / thresholdPace intervalPace = 1609.34 / intervalPace repPace = 1609.34 / repPace } else { easyPace = 1000.0 / easyPace maraPace = 1000.0 / maraPace thresholdPace = 1000.0 / thresholdPace intervalPace = 1000.0 / intervalPace repPace = 1000.0 / repPace } TrainingPaces["Easy"] = strutil.DecimalTimetoMinSec(easyPace) TrainingPaces["Marathon"] = strutil.DecimalTimetoMinSec(maraPace) TrainingPaces["Threshold"] = strutil.DecimalTimetoMinSec(thresholdPace) TrainingPaces["Interval"] = strutil.DecimalTimetoMinSec(intervalPace) TrainingPaces["Repeats"] = strutil.DecimalTimetoMinSec(repPace) // Convert the times from decimal minutes to hh:mm:ss for the user. PredictedRaceTimes = make(map[string]string) for key, val := range PredictedTimes { PredictedRaceTimes[key] = strutil.DecimalTimetoHourMinSec(val) } return }