labnotes 0.0.64__tar.gz → 0.0.65__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. {labnotes-0.0.64 → labnotes-0.0.65}/PKG-INFO +1 -1
  2. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/list_experiments.py +3 -3
  3. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/static/experiment.js +0 -5
  4. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/static/labnotes.css +0 -47
  5. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/summarize_config.py +0 -1
  6. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/templates/experiment.html +1 -12
  7. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/templates/index.html +1 -18
  8. labnotes-0.0.64/src/labnotes/cell_progress.py +0 -22
  9. labnotes-0.0.64/src/labnotes/experiment_progress.py +0 -27
  10. labnotes-0.0.64/src/labnotes/templates/macros.html +0 -10
  11. {labnotes-0.0.64 → labnotes-0.0.65}/.gitignore +0 -0
  12. {labnotes-0.0.64 → labnotes-0.0.65}/CHANGELOG.md +0 -0
  13. {labnotes-0.0.64 → labnotes-0.0.65}/MIGRATIONS.md +0 -0
  14. {labnotes-0.0.64 → labnotes-0.0.65}/README.md +0 -0
  15. {labnotes-0.0.64 → labnotes-0.0.65}/pyproject.toml +0 -0
  16. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/__init__.py +0 -0
  17. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/asset_url.py +0 -0
  18. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/check_counts.py +0 -0
  19. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/cli.py +0 -0
  20. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/context.md +0 -0
  21. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/context_guide.py +0 -0
  22. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/count_runs.py +0 -0
  23. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/create_app.py +0 -0
  24. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/create_experiment.py +0 -0
  25. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/create_note.py +0 -0
  26. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/data_html.py +0 -0
  27. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/default_config_text.py +0 -0
  28. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/default_counts.py +0 -0
  29. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/drain_watch.py +0 -0
  30. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/experiment_notes.py +0 -0
  31. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/experiment_runs.py +0 -0
  32. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/experiments.py +0 -0
  33. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/file_changes.py +0 -0
  34. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/format_duration.py +0 -0
  35. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/format_value.py +0 -0
  36. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/group_runs.py +0 -0
  37. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/init.py +0 -0
  38. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/invocation_started.py +0 -0
  39. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/is_positive_int.py +0 -0
  40. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/list_runs.py +0 -0
  41. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/load_config.py +0 -0
  42. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/load_experiment.py +0 -0
  43. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/models.py +0 -0
  44. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/modes.py +0 -0
  45. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/nests_runs.py +0 -0
  46. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/notebook_kernel.py +0 -0
  47. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/output_html.py +0 -0
  48. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/parse_run_view.py +0 -0
  49. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/print_rows.py +0 -0
  50. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/python_blocks.py +0 -0
  51. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/read_config.py +0 -0
  52. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/read_path.py +0 -0
  53. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/render_markdown.py +0 -0
  54. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/__init__.py +0 -0
  55. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/describe_event.py +0 -0
  56. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/execute_run.py +0 -0
  57. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/hold_folder.py +0 -0
  58. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/new_param_run_id.py +0 -0
  59. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/new_run_id.py +0 -0
  60. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/new_stamped_run_id.py +0 -0
  61. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/param_args.py +0 -0
  62. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/param_grid.py +0 -0
  63. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/param_run_name.py +0 -0
  64. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/plan_runs.py +0 -0
  65. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/read_experiment_config.py +0 -0
  66. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/run_experiment.py +0 -0
  67. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/run_folder.py +0 -0
  68. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/run_headless.py +0 -0
  69. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/runs_parent.py +0 -0
  70. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/shell_command.py +0 -0
  71. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/start_experiment.py +0 -0
  72. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/stop_then_kill.py +0 -0
  73. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/wait_for_group.py +0 -0
  74. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/runner/write_run_json.py +0 -0
  75. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/save_conflict_copy.py +0 -0
  76. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/save_note.py +0 -0
  77. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/saved_outputs.py +0 -0
  78. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/serve_app.py +0 -0
  79. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/server.py +0 -0
  80. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/sort_href.py +0 -0
  81. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/sql_quote.py +0 -0
  82. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/static/new-note.js +0 -0
  83. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/static/note-edit.js +0 -0
  84. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/static/note-editor.js +0 -0
  85. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/static/row-link.js +0 -0
  86. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/static/run-cell.js +0 -0
  87. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/static/view-toggle.js +0 -0
  88. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tables/__init__.py +0 -0
  89. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tables/experiment_rows.py +0 -0
  90. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tables/file_prefix.py +0 -0
  91. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tables/iso_time.py +0 -0
  92. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tables/list_experiment_runs.py +0 -0
  93. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tables/open_tables.py +0 -0
  94. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tables/path_glob.py +0 -0
  95. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tables/path_pattern.py +0 -0
  96. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tables/read_experiment.py +0 -0
  97. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tables/read_file.py +0 -0
  98. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tables/read_run.py +0 -0
  99. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tables/summarize_experiments.py +0 -0
  100. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/templates/base.html +0 -0
  101. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/templates/editor_imports.html +0 -0
  102. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tui/__init__.py +0 -0
  103. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tui/dim.py +0 -0
  104. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tui/format_elapsed.py +0 -0
  105. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tui/run_app.py +0 -0
  106. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tui/run_tui.py +0 -0
  107. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/tui/runs_table.py +0 -0
  108. {labnotes-0.0.64 → labnotes-0.0.65}/src/labnotes/wait_for_note.py +0 -0
  109. {labnotes-0.0.64 → labnotes-0.0.65}/testing-conventions.toml +0 -0
  110. {labnotes-0.0.64 → labnotes-0.0.65}/tests/integration/conftest.py +0 -0
  111. {labnotes-0.0.64 → labnotes-0.0.65}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: labnotes
3
- Version: 0.0.64
3
+ Version: 0.0.65
4
4
  Summary: Browse experiment designs, notes, and run data from a folder.
5
5
  Project-URL: Repository, https://github.com/thekevinscott/labnotes
6
6
  Author-email: Kevin Scott <me@thekevinscott.com>
@@ -4,7 +4,7 @@ from typing import cast
4
4
  from dirsql import DirSQL
5
5
 
6
6
  from labnotes.check_counts import check_counts
7
- from labnotes.experiment_progress import experiment_progress
7
+ from labnotes.count_runs import count_runs
8
8
  from labnotes.experiment_runs import experiment_runs
9
9
  from labnotes.summarize_config import summarize_config
10
10
 
@@ -21,8 +21,8 @@ async def list_experiments(tables: DirSQL, mode: str) -> list[dict[str, object]]
21
21
  varies = cast(dict[str, list[object]], summary["varies"])
22
22
  source = experiment_runs(name, list(varies))
23
23
  summary = await check_counts(tables, source, summary)
24
- progress = await experiment_progress(tables, source, summary)
24
+ [totals] = await count_runs(tables, source, str(summary["completed_run"]))
25
25
  listed.append(
26
- {"name": name, "display_name": row["display_name"], **summary, **progress}
26
+ {"name": name, "display_name": row["display_name"], **summary, **totals}
27
27
  )
28
28
  return listed
@@ -19,11 +19,6 @@ const expand = (group, open) => {
19
19
  document.addEventListener("click", (event) => {
20
20
  const header = event.target.closest(".group-row");
21
21
  if (header) expand(header.parentElement, !header.parentElement.classList.contains("open"));
22
- const row = event.target.closest(".run-row");
23
- if (!row || getSelection().toString()) return;
24
- const record = row.nextElementSibling;
25
- record.hidden = !record.hidden;
26
- row.setAttribute("aria-expanded", String(!record.hidden));
27
22
  });
28
23
 
29
24
  const filters = document.querySelector("#run-filters");
@@ -54,8 +54,6 @@ code, pre, .mono { font-family: var(--mono); font-size: 0.86em; }
54
54
  code { background: var(--chip); padding: 0.1em 0.35em; border-radius: 4px; }
55
55
 
56
56
  .num { font-variant-numeric: tabular-nums; }
57
- .muted { color: var(--ink-3); }
58
- .of { color: var(--ink-3); }
59
57
 
60
58
  .masthead {
61
59
  display: flex;
@@ -120,24 +118,6 @@ h3 {
120
118
  background: var(--surface);
121
119
  }
122
120
 
123
- /* Meter: one hue, track drawn from the same ramp. */
124
- .meter {
125
- display: block;
126
- position: relative;
127
- height: 4px;
128
- min-width: 3rem;
129
- border-radius: 2px;
130
- background: var(--track);
131
- overflow: hidden;
132
- }
133
- .meter-fill {
134
- position: absolute;
135
- inset: 0 auto 0 0;
136
- width: calc(var(--share) * 100%);
137
- border-radius: 2px;
138
- background: var(--accent);
139
- }
140
-
141
121
  /* Index ledger */
142
122
  .ledger {
143
123
  width: 100%;
@@ -167,15 +147,6 @@ h3 {
167
147
  .title-link { font-family: var(--serif); font-size: 1.15rem; text-decoration: none; white-space: nowrap; }
168
148
  .ledger .study { white-space: nowrap; }
169
149
 
170
- .design { color: var(--ink-2); font-size: 0.88rem; }
171
- .factor { white-space: nowrap; line-height: 1.9; }
172
- .factor b { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
173
- .times { color: var(--ink-3); margin-left: 0.45rem; }
174
-
175
- .progress-col { width: 30%; }
176
- .progress-line { display: grid; grid-template-columns: 1fr auto 3rem; align-items: center; gap: 0.9rem; }
177
- .progress-line .num { text-align: right; }
178
- .pct { color: var(--ink-2); }
179
150
 
180
151
  .chip {
181
152
  font-family: var(--mono);
@@ -313,11 +284,8 @@ h3 {
313
284
  .runs-table .filters .pick input { width: auto; }
314
285
  .runs-table .filters input:focus, .runs-table .filters select:focus { outline: none; border-color: var(--accent); }
315
286
  .runs-table tbody tr:last-child td { border-bottom: 0; }
316
- .run-row { cursor: pointer; }
317
287
  .run-row td { max-width: 24rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
318
288
  .run-row:hover { background: color-mix(in srgb, var(--accent) 4%, transparent); }
319
- .run-row[aria-expanded="true"] { background: color-mix(in srgb, var(--accent) 6%, transparent); }
320
- .record-row td { background: var(--paper); }
321
289
  .group-row { cursor: pointer; background: var(--paper); }
322
290
  .group-row td { font-weight: 600; white-space: nowrap; }
323
291
  .group-row .good { color: var(--good); }
@@ -379,18 +347,6 @@ h3 {
379
347
  .status.bad { color: var(--bad); }
380
348
  .counts-error { color: var(--bad); }
381
349
 
382
- .record {
383
- display: grid;
384
- grid-template-columns: max-content minmax(0, 1fr);
385
- gap: 0.45rem 1.5rem;
386
- margin: 0;
387
- padding: 0.5rem 0 0.75rem 2.25rem;
388
- }
389
- .record dt { font-family: var(--mono); font-size: 0.78rem; color: var(--ink-3); }
390
- .record dd { margin: 0; min-width: 0; }
391
- .record code { background: none; padding: 0; word-break: break-word; }
392
- .record pre { margin: 0; white-space: pre-wrap; word-break: break-word; max-height: 22rem; overflow: auto; font-size: 0.78rem; color: var(--ink-2); }
393
-
394
350
  /* Index view toggle */
395
351
  .view-toggle {
396
352
  float: right;
@@ -431,14 +387,11 @@ h3 {
431
387
  }
432
388
  .ledger[data-view="cards"] tbody tr:hover { background: var(--surface); border-color: var(--accent); }
433
389
  .ledger[data-view="cards"] td { display: block; padding: 0; border: 0; text-align: left; }
434
- .ledger[data-view="cards"] .progress-col { width: auto; }
435
390
  .ledger[data-view="cards"] td[data-label]::before { content: attr(data-label) " "; color: var(--ink-3); font-size: 0.82rem; }
436
391
 
437
392
  @media (max-width: 52rem) {
438
393
  main, .masthead { padding-left: 1.1rem; padding-right: 1.1rem; }
439
394
  h1 { font-size: 2rem; }
440
- .ledger .design { display: none; }
441
- .progress-col { width: auto; }
442
395
  }
443
396
 
444
397
  /* Runnable python blocks in notes */
@@ -21,7 +21,6 @@ def summarize_config(config: dict[str, object] | None, mode: str) -> dict[str, o
21
21
  "varies": varies,
22
22
  "cell_count": cells,
23
23
  "runs_per_cell": repeats,
24
- "target": cells * repeats if repeats is not None and fill else None,
25
24
  "completed_run": counts if isinstance(counts, str) else DEFAULT_COUNTS,
26
25
  "mode": "fill" if fill else "adhoc",
27
26
  "other": {} if command is None else {"command": command},
@@ -86,21 +86,10 @@
86
86
  </tr>
87
87
  </thead>
88
88
  {% macro run_rows(run) %}
89
- <tr class="run-row" aria-expanded="false">
89
+ <tr class="run-row">
90
90
  <td><span class="status {{ 'good' if run.labnotes_completed else 'bad' }}" title="{{ 'complete' if run.labnotes_completed else 'not complete' }}">{{ '✓' if run.labnotes_completed else '✕' }}</span></td>
91
91
  {% for column in e.run_columns %}{% if column == 'id' and nested %}<td class="mono">{{ run.id.partition('/')[2] or run.id }}</td><td></td>{% else %}<td class="{{ 'mono' if loop.first }}{{ 'num' if column == 'duration' }}">{{ run[column] | duration if column == 'duration' else run[column] | value }}</td>{% endif %}{% endfor %}
92
92
  </tr>
93
- <tr class="record-row" hidden>
94
- <td colspan="{{ width }}">
95
- <dl class="record">
96
- {% for key, value in run.items() if key != 'labnotes_completed' %}
97
- <dt>{{ key }}</dt>
98
- {% set shown = value | value %}
99
- <dd>{% if shown | length > 80 %}<pre>{{ shown }}</pre>{% else %}<code>{{ shown }}</code>{% endif %}</dd>
100
- {% endfor %}
101
- </dl>
102
- </td>
103
- </tr>
104
93
  {% endmacro %}
105
94
  {% if nested %}
106
95
  {% for group in e.run_groups %}
@@ -1,5 +1,4 @@
1
1
  {% extends "base.html" %}
2
- {% from "macros.html" import meter, percent %}
3
2
  {% block crumbs %}<span class="crumb">{{ folder }}</span>{% endblock %}
4
3
  {% block main %}
5
4
  <section class="intro">
@@ -19,9 +18,7 @@
19
18
  <thead>
20
19
  <tr>
21
20
  <th scope="col">Experiment</th>
22
- <th scope="col">Design</th>
23
21
  <th scope="col" class="num">Runs</th>
24
- <th scope="col" class="progress-col">Grid filled</th>
25
22
  </tr>
26
23
  </thead>
27
24
  <tbody>
@@ -30,23 +27,9 @@
30
27
  <td>
31
28
  <a class="title-link" href="{{ url_for('experiment', name=experiment.name) }}">{{ experiment.display_name }}</a>
32
29
  {% if experiment.display_name != experiment.name %}<div class="study">{{ experiment.name }}</div>{% endif %}
33
- </td>
34
- <td class="design">
35
- {% for key, values in experiment.varies.items() %}<span class="factor">{{ key }} <b>{{ values | length }}</b>{% if not loop.last or experiment.runs_per_cell %}<span class="times">×</span>{% endif %}</span> {% endfor %}
36
- {% if experiment.runs_per_cell %}<span class="factor">runs <b>{{ experiment.runs_per_cell }}</b></span>{% endif %}
30
+ {% if experiment.counts_error %}<div class="counts-error" title="{{ experiment.counts_error }}">counts rule doesn't work</div>{% endif %}
37
31
  </td>
38
32
  <td class="num" data-label="Runs">{{ experiment.runs }}</td>
39
- <td class="progress-col">
40
- {% if experiment.counts_error %}
41
- <span class="counts-error" title="{{ experiment.counts_error }}">counts rule doesn't work</span>
42
- {% elif experiment.filled is not none and experiment.target %}
43
- <div class="progress-line">
44
- {{ meter(experiment.filled, experiment.target) }}
45
- <span class="num">{{ experiment.filled }}<span class="of">/{{ experiment.target }}</span></span>
46
- <span class="pct num">{{ percent(experiment.filled, experiment.target) }}</span>
47
- </div>
48
- {% else %}<span class="muted">—</span>{% endif %}
49
- </td>
50
33
  </tr>
51
34
  {% endfor %}
52
35
  </tbody>
@@ -1,22 +0,0 @@
1
- from itertools import product
2
-
3
-
4
- def _key(value: object) -> object:
5
- return int(value) if isinstance(value, bool) else value
6
-
7
-
8
- def cell_progress(
9
- varies: dict[str, list[object]], counts: list[dict[str, object]]
10
- ) -> list[dict[str, object]]:
11
- by_cell = {tuple(_key(row[key]) for key in varies): row for row in counts}
12
- cells = []
13
- for values in product(*varies.values()):
14
- row = by_cell.get(tuple(_key(value) for value in values), {})
15
- cells.append(
16
- {
17
- "values": dict(zip(varies, values)),
18
- "runs": row.get("runs", 0),
19
- "completed": row.get("completed", 0),
20
- }
21
- )
22
- return cells
@@ -1,27 +0,0 @@
1
- from typing import cast
2
-
3
- from dirsql import DirSQL
4
-
5
- from labnotes.cell_progress import cell_progress
6
- from labnotes.count_runs import count_runs
7
-
8
-
9
- async def experiment_progress(
10
- tables: DirSQL, source: str, summary: dict[str, object]
11
- ) -> dict[str, object]:
12
- varies = cast(dict[str, list[object]], summary["varies"])
13
- completed_run = str(summary["completed_run"])
14
- runs_per_cell = summary["runs_per_cell"]
15
- [totals] = await count_runs(tables, source, completed_run)
16
- progress: dict[str, object] = {**totals, "filled": None, "cells": []}
17
- if runs_per_cell is None:
18
- return progress
19
- grouped = await count_runs(tables, source, completed_run, group_by=list(varies))
20
- cells = cell_progress(varies, grouped)
21
- progress["cells"] = cells
22
- if summary["target"] is None:
23
- return progress
24
- progress["filled"] = sum(
25
- min(cast(int, cell["completed"]), cast(int, runs_per_cell)) for cell in cells
26
- )
27
- return progress
@@ -1,10 +0,0 @@
1
- {% macro meter(value, total) -%}
2
- {%- set share = [value / total, 1] | min if total else 0 -%}
3
- <span class="meter" role="meter" aria-valuemin="0" aria-valuemax="{{ total }}" aria-valuenow="{{ value }}">
4
- <span class="meter-fill" style="--share: {{ '%.4f' | format(share) }}"></span>
5
- </span>
6
- {%- endmacro %}
7
-
8
- {% macro percent(value, total) -%}
9
- {{ '%.0f' | format(100 * value / total) if total else '—' }}%
10
- {%- endmacro %}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes