From c2a40b8e3ea12fe6f011abf38775b9e25a54b60e Mon Sep 17 00:00:00 2001 From: Dustin Pianalto Date: Fri, 7 Mar 2025 20:41:07 -0900 Subject: [PATCH] update getting final results --- db/db.go | 96 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 34 deletions(-) diff --git a/db/db.go b/db/db.go index b3744e8..8529e97 100644 --- a/db/db.go +++ b/db/db.go @@ -603,7 +603,7 @@ func (db *DB) getLaneData(lane int, racerID int64, heatNum int, groupID int64) ( // GetFinalResults calculates the final results for a group // The final time is the average of the fastest 3 times, discarding the slowest time -// Racers with a time of 9.999 are marked as DNF and placed at the end +// Racers with all times as 9.999 are marked as DNF and placed at the end func (db *DB) GetFinalResults(groupID int64) ([]models.FinalResult, error) { // Get all racers in the group racers, err := db.GetRacersByGroup(groupID) @@ -611,19 +611,6 @@ func (db *DB) GetFinalResults(groupID int64) ([]models.FinalResult, error) { return nil, fmt.Errorf("failed to get racers: %w", err) } - // Get all heat results for the group - rows, err := db.Query(` - SELECT heat_number, lane1_id, lane1_time, lane2_id, lane2_time, - lane3_id, lane3_time, lane4_id, lane4_time - FROM heat_results - WHERE group_id = ? - ORDER BY heat_number - `, groupID) - if err != nil { - return nil, fmt.Errorf("failed to query heat results: %w", err) - } - defer rows.Close() - // Map to store times for each racer racerTimes := make(map[int64][]float64) @@ -632,19 +619,38 @@ func (db *DB) GetFinalResults(groupID int64) ([]models.FinalResult, error) { racerTimes[racer.ID] = []float64{} } - // Process each heat result + // Get all heats and heat results for the group + rows, err := db.Query(` + SELECT + h.heat_num, + h.lane1_id, h.lane2_id, h.lane3_id, h.lane4_id, + hr.lane1_time, hr.lane2_time, hr.lane3_time, hr.lane4_time + FROM heats h + LEFT JOIN heat_results hr ON h.group_id = hr.group_id AND h.heat_num = hr.heat_number + WHERE h.group_id = ? + ORDER BY h.heat_num + `, groupID) + if err != nil { + return nil, fmt.Errorf("failed to query heats and results: %w", err) + } + defer rows.Close() + + // Process each heat and its results for rows.Next() { var heatNum int var lane1ID, lane2ID, lane3ID, lane4ID sql.NullInt64 var lane1Time, lane2Time, lane3Time, lane4Time sql.NullFloat64 - err := rows.Scan(&heatNum, &lane1ID, &lane1Time, &lane2ID, &lane2Time, - &lane3ID, &lane3Time, &lane4ID, &lane4Time) + err := rows.Scan( + &heatNum, + &lane1ID, &lane2ID, &lane3ID, &lane4ID, + &lane1Time, &lane2Time, &lane3Time, &lane4Time, + ) if err != nil { - return nil, fmt.Errorf("failed to scan heat result: %w", err) + return nil, fmt.Errorf("failed to scan heat and result: %w", err) } - // Add times for each lane if a racer was assigned + // Add times for each lane if a racer was assigned and has a time if lane1ID.Valid && lane1Time.Valid { racerTimes[lane1ID.Int64] = append(racerTimes[lane1ID.Int64], lane1Time.Float64) } @@ -670,48 +676,70 @@ func (db *DB) GetFinalResults(groupID int64) ([]models.FinalResult, error) { continue } - // Check if racer has DNF (time of 9.999) - dnf := false + // Make a copy of times for display (original array will be modified by sort) + displayTimes := make([]float64, len(times)) + copy(displayTimes, times) + + // Check if all times are DNF + allDNF := true for _, time := range times { - if time >= 9.999 { - dnf = true + if time < 9.999 { + allDNF = false break } } var avgTime float64 - if dnf { - // If DNF, set average time to a high value for sorting + if allDNF { + // If all runs are DNF, mark as DNF avgTime = 999.999 } else { - // Sort times to find fastest - sort.Float64s(times) + // Filter out DNF times for calculation + validTimes := []float64{} + for _, time := range times { + if time < 9.999 { + validTimes = append(validTimes, time) + } + } + + // Sort valid times to find fastest + sort.Float64s(validTimes) // Calculate average of fastest 3 times (or fewer if not enough runs) - numTimes := len(times) + numTimes := len(validTimes) if numTimes >= 4 { // Discard the slowest time - avgTime = (times[0] + times[1] + times[2]) / 3.0 + avgTime = (validTimes[0] + validTimes[1] + validTimes[2]) / 3.0 } else if numTimes == 3 { - avgTime = (times[0] + times[1] + times[2]) / 3.0 + avgTime = (validTimes[0] + validTimes[1] + validTimes[2]) / 3.0 } else if numTimes == 2 { - avgTime = (times[0] + times[1]) / 2.0 + avgTime = (validTimes[0] + validTimes[1]) / 2.0 + } else if numTimes == 1 { + avgTime = validTimes[0] } else { - avgTime = times[0] + // No valid times (all DNF) + avgTime = 999.999 + allDNF = true } } results = append(results, models.FinalResult{ Racer: racer, - Times: times, + Times: displayTimes, AverageTime: avgTime, - DNF: dnf, + DNF: allDNF, }) } // Sort results by average time (DNF racers will be at the end) sort.Slice(results, func(i, j int) bool { + if results[i].DNF && !results[j].DNF { + return false + } + if !results[i].DNF && results[j].DNF { + return true + } return results[i].AverageTime < results[j].AverageTime })