Skip to content

Commit 4e56a19

Browse files
robobrycebrycelelbachclaude
authored
Show full-precision scores; add submissions show --no-code (#63)
* Show full-precision scores and add `submissions show --no-code` Two small quality-of-life fixes to the submissions views: - Print scores at full f64 precision in both `submissions list` and `submissions show`. They were formatted with `{:.4}`, which rounds the geomean leaderboard score to 4 decimals (e.g. 0.0017 for two distinct submissions that actually scored 0.0017318 vs 0.0017449) — enough to make near-tied submissions indistinguishable. `f64::to_string()` emits the shortest decimal that round-trips, so no rounding and no trailing zero noise. - Add a `--no-code` flag to `submissions show` to omit the (often large) code block, for when you only want the metadata and per-run scores. Default behavior is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Extract format_score helper and add unit tests Pull the score-rendering logic (shared by `list` and `show`) into a `format_score` helper and cover it with unit tests, so the precision change has patch coverage (codecov/patch was 0%). Also adds a small `truncate` test. No behavior change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Bryce Adelstein Lelbach <brycelelbach@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 1f4cd4e commit 4e56a19

2 files changed

Lines changed: 62 additions & 13 deletions

File tree

src/cmd/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ enum SubmissionsAction {
9393
Show {
9494
/// Submission ID
9595
id: i64,
96+
97+
/// Do not print the submission's code
98+
#[arg(long)]
99+
no_code: bool,
96100
},
97101
/// Delete a submission
98102
Delete {
@@ -255,7 +259,9 @@ pub async fn execute(cli: Cli) -> Result<()> {
255259
SubmissionsAction::List { leaderboard, limit } => {
256260
submissions::list_submissions(cli_id, leaderboard, Some(limit)).await
257261
}
258-
SubmissionsAction::Show { id } => submissions::show_submission(cli_id, id).await,
262+
SubmissionsAction::Show { id, no_code } => {
263+
submissions::show_submission(cli_id, id, no_code).await
264+
}
259265
SubmissionsAction::Delete { id, force } => {
260266
submissions::delete_submission(cli_id, id, force).await
261267
}

src/cmd/submissions.rs

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,13 @@ pub async fn list_submissions(
3636
gpus.join(",")
3737
};
3838

39-
// Get best score (lowest)
39+
// Get best score (lowest).
4040
let best_score = sub
4141
.runs
4242
.iter()
4343
.filter_map(|r| r.score)
4444
.min_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
45-
let score_display = best_score
46-
.map(|s| format!("{:.4}", s))
47-
.unwrap_or_else(|| "-".to_string());
45+
let score_display = format_score(best_score);
4846

4947
let time = truncate(&sub.submission_time, 19);
5048

@@ -64,7 +62,7 @@ pub async fn list_submissions(
6462
}
6563

6664
/// Show a specific submission with full details
67-
pub async fn show_submission(cli_id: String, submission_id: i64) -> Result<()> {
65+
pub async fn show_submission(cli_id: String, submission_id: i64, no_code: bool) -> Result<()> {
6866
let client = service::create_client(Some(cli_id))?;
6967
let sub = service::get_user_submission(&client, submission_id).await?;
7068

@@ -85,10 +83,7 @@ pub async fn show_submission(cli_id: String, submission_id: i64) -> Result<()> {
8583
if !sub.runs.is_empty() {
8684
println!("\nRuns:");
8785
for run in &sub.runs {
88-
let score_str = run
89-
.score
90-
.map(|s| format!("{:.4}", s))
91-
.unwrap_or_else(|| "-".to_string());
86+
let score_str = format_score(run.score);
9287
let status = if run.passed { "passed" } else { "failed" };
9388
let secret_marker = if run.secret { " [secret]" } else { "" };
9489
let time_info = match (&run.start_time, &run.end_time) {
@@ -103,9 +98,11 @@ pub async fn show_submission(cli_id: String, submission_id: i64) -> Result<()> {
10398
}
10499
}
105100

106-
println!("\nCode:");
107-
println!("{}", "-".repeat(60));
108-
println!("{}", sub.code);
101+
if !no_code {
102+
println!("\nCode:");
103+
println!("{}", "-".repeat(60));
104+
println!("{}", sub.code);
105+
}
109106

110107
Ok(())
111108
}
@@ -167,3 +164,49 @@ fn truncate(s: &str, max_len: usize) -> String {
167164
format!("{}...", &s[..max_len - 3])
168165
}
169166
}
167+
168+
/// Render a score for display: full f64 precision (the shortest string that
169+
/// round-trips) rather than a rounded `{:.4}`, or "-" when there is no score.
170+
fn format_score(score: Option<f64>) -> String {
171+
score
172+
.map(|s| s.to_string())
173+
.unwrap_or_else(|| "-".to_string())
174+
}
175+
176+
#[cfg(test)]
177+
mod tests {
178+
use super::*;
179+
180+
#[test]
181+
fn test_format_score_full_precision() {
182+
// Full precision, not rounded to 4 decimals: two near-tied scores stay
183+
// distinguishable (the bug this replaces rendered both as "0.0017").
184+
assert_eq!(
185+
format_score(Some(0.001731805142084383)),
186+
"0.001731805142084383"
187+
);
188+
assert_eq!(
189+
format_score(Some(0.0017448536290123567)),
190+
"0.0017448536290123567"
191+
);
192+
}
193+
194+
#[test]
195+
fn test_format_score_no_trailing_zeros() {
196+
// Shortest round-tripping form: no padding to 4 decimals.
197+
assert_eq!(format_score(Some(1.5)), "1.5");
198+
assert_eq!(format_score(Some(0.0)), "0");
199+
}
200+
201+
#[test]
202+
fn test_format_score_none_is_dash() {
203+
assert_eq!(format_score(None), "-");
204+
}
205+
206+
#[test]
207+
fn test_truncate() {
208+
assert_eq!(truncate("short", 19), "short");
209+
assert_eq!(truncate("submission.py", 19), "submission.py");
210+
assert_eq!(truncate("0123456789", 8), "01234...");
211+
}
212+
}

0 commit comments

Comments
 (0)