update getting final results

main
DustyP 9 months ago
parent 71a77454c8
commit c2a40b8e3e

@ -603,7 +603,7 @@ func (db *DB) getLaneData(lane int, racerID int64, heatNum int, groupID int64) (
// GetFinalResults calculates the final results for a group // GetFinalResults calculates the final results for a group
// The final time is the average of the fastest 3 times, discarding the slowest time // 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) { func (db *DB) GetFinalResults(groupID int64) ([]models.FinalResult, error) {
// Get all racers in the group // Get all racers in the group
racers, err := db.GetRacersByGroup(groupID) 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) 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 // Map to store times for each racer
racerTimes := make(map[int64][]float64) racerTimes := make(map[int64][]float64)
@ -632,19 +619,38 @@ func (db *DB) GetFinalResults(groupID int64) ([]models.FinalResult, error) {
racerTimes[racer.ID] = []float64{} 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() { for rows.Next() {
var heatNum int var heatNum int
var lane1ID, lane2ID, lane3ID, lane4ID sql.NullInt64 var lane1ID, lane2ID, lane3ID, lane4ID sql.NullInt64
var lane1Time, lane2Time, lane3Time, lane4Time sql.NullFloat64 var lane1Time, lane2Time, lane3Time, lane4Time sql.NullFloat64
err := rows.Scan(&heatNum, &lane1ID, &lane1Time, &lane2ID, &lane2Time, err := rows.Scan(
&lane3ID, &lane3Time, &lane4ID, &lane4Time) &heatNum,
&lane1ID, &lane2ID, &lane3ID, &lane4ID,
&lane1Time, &lane2Time, &lane3Time, &lane4Time,
)
if err != nil { 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 { if lane1ID.Valid && lane1Time.Valid {
racerTimes[lane1ID.Int64] = append(racerTimes[lane1ID.Int64], lane1Time.Float64) racerTimes[lane1ID.Int64] = append(racerTimes[lane1ID.Int64], lane1Time.Float64)
} }
@ -670,48 +676,70 @@ func (db *DB) GetFinalResults(groupID int64) ([]models.FinalResult, error) {
continue continue
} }
// Check if racer has DNF (time of 9.999) // Make a copy of times for display (original array will be modified by sort)
dnf := false displayTimes := make([]float64, len(times))
copy(displayTimes, times)
// Check if all times are DNF
allDNF := true
for _, time := range times { for _, time := range times {
if time >= 9.999 { if time < 9.999 {
dnf = true allDNF = false
break break
} }
} }
var avgTime float64 var avgTime float64
if dnf { if allDNF {
// If DNF, set average time to a high value for sorting // If all runs are DNF, mark as DNF
avgTime = 999.999 avgTime = 999.999
} else { } else {
// Sort times to find fastest // Filter out DNF times for calculation
sort.Float64s(times) 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) // Calculate average of fastest 3 times (or fewer if not enough runs)
numTimes := len(times) numTimes := len(validTimes)
if numTimes >= 4 { if numTimes >= 4 {
// Discard the slowest time // 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 { } 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 { } 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 { } else {
avgTime = times[0] // No valid times (all DNF)
avgTime = 999.999
allDNF = true
} }
} }
results = append(results, models.FinalResult{ results = append(results, models.FinalResult{
Racer: racer, Racer: racer,
Times: times, Times: displayTimes,
AverageTime: avgTime, AverageTime: avgTime,
DNF: dnf, DNF: allDNF,
}) })
} }
// Sort results by average time (DNF racers will be at the end) // Sort results by average time (DNF racers will be at the end)
sort.Slice(results, func(i, j int) bool { 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 return results[i].AverageTime < results[j].AverageTime
}) })

Loading…
Cancel
Save