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
// 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
})

Loading…
Cancel
Save