mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-10 07:18:27 +01:00
Organize metrics as table (#4706)
* WIP fixes #4621 * changes to all_branch if condition * flatten_dict changes * fix one test * minor changes * minor changes * add precision * tests and added precision to arguments Co-authored-by: indh8717 <[email protected]>
This commit is contained in:
+49
-13
@@ -12,33 +12,60 @@ DEFAULT_PRECISION = 5
|
||||
|
||||
|
||||
def _show_metrics(
|
||||
metrics, all_branches=False, all_tags=False, all_commits=False
|
||||
metrics,
|
||||
all_branches=False,
|
||||
all_tags=False,
|
||||
all_commits=False,
|
||||
precision=None,
|
||||
):
|
||||
from dvc.utils.diff import format_dict
|
||||
from dvc.utils.diff import format_dict, table
|
||||
from dvc.utils.flatten import flatten
|
||||
|
||||
# When `metrics` contains a `None` key, it means that some files
|
||||
# specified as `targets` in `repo.metrics.show` didn't contain any metrics.
|
||||
missing = metrics.pop(None, None)
|
||||
with_rev = any([all_branches, all_tags, all_commits])
|
||||
header_set = set()
|
||||
rows = []
|
||||
|
||||
lines = []
|
||||
for branch, val in metrics.items():
|
||||
if all_branches or all_tags or all_commits:
|
||||
lines.append(f"{branch}:")
|
||||
if precision is None:
|
||||
precision = DEFAULT_PRECISION
|
||||
|
||||
for fname, metric in val.items():
|
||||
def _round(val):
|
||||
if isinstance(val, float):
|
||||
return round(val, precision)
|
||||
return val
|
||||
|
||||
for _branch, val in metrics.items():
|
||||
for _fname, metric in val.items():
|
||||
if not isinstance(metric, dict):
|
||||
lines.append("\t{}: {}".format(fname, str(metric)))
|
||||
header_set.add("")
|
||||
continue
|
||||
for key, _val in flatten(format_dict(metric)).items():
|
||||
header_set.add(key)
|
||||
header = sorted(header_set)
|
||||
for branch, val in metrics.items():
|
||||
for fname, metric in val.items():
|
||||
row = []
|
||||
if with_rev:
|
||||
row.append(branch)
|
||||
row.append(fname)
|
||||
if not isinstance(metric, dict):
|
||||
row.append(str(metric))
|
||||
rows.append(row)
|
||||
continue
|
||||
flattened_val = flatten(format_dict(metric))
|
||||
|
||||
lines.append(f"\t{fname}:")
|
||||
for key, value in flatten(format_dict(metric)).items():
|
||||
lines.append(f"\t\t{key}: {value}")
|
||||
for i in header:
|
||||
row.append(_round(flattened_val.get(i)))
|
||||
rows.append(row)
|
||||
header.insert(0, "Path")
|
||||
if with_rev:
|
||||
header.insert(0, "Revision")
|
||||
|
||||
if missing:
|
||||
raise BadMetricError(missing)
|
||||
|
||||
return "\n".join(lines)
|
||||
return table(header, rows, markdown=False)
|
||||
|
||||
|
||||
class CmdMetricsBase(CmdBase):
|
||||
@@ -211,6 +238,15 @@ def add_parser(subparsers, parent_parser):
|
||||
"metrics files."
|
||||
),
|
||||
)
|
||||
metrics_show_parser.add_argument(
|
||||
"--precision",
|
||||
type=int,
|
||||
help=(
|
||||
"Round metrics to `n` digits precision after the decimal point. "
|
||||
f"Rounds to {DEFAULT_PRECISION} digits by default."
|
||||
),
|
||||
metavar="<n>",
|
||||
)
|
||||
metrics_show_parser.set_defaults(func=CmdMetricsShow)
|
||||
|
||||
METRICS_DIFF_HELP = (
|
||||
|
||||
@@ -982,7 +982,7 @@ class TestShouldDisplayMetricsOnReproWithMetricsOption(TestDvc):
|
||||
)
|
||||
self.assertEqual(0, ret)
|
||||
|
||||
expected_metrics_display = f"{metrics_file}: {metrics_value}"
|
||||
expected_metrics_display = f"Path\n{metrics_file} {metrics_value}\n"
|
||||
self.assertIn(expected_metrics_display, self._caplog.text)
|
||||
|
||||
|
||||
|
||||
@@ -226,9 +226,107 @@ def test_metrics_show_with_valid_falsey_values():
|
||||
all_branches=True,
|
||||
) == textwrap.dedent(
|
||||
"""\
|
||||
branch_1:
|
||||
\tmetrics.json:
|
||||
\t\ta: 0
|
||||
\t\tb.ad: 0.0
|
||||
\t\tb.bc: 0.0"""
|
||||
Revision Path a b.ad b.bc
|
||||
branch_1 metrics.json 0 0.0 0.0"""
|
||||
)
|
||||
|
||||
|
||||
def test_metrics_show_with_no_revision():
|
||||
assert _show_metrics(
|
||||
{"branch_1": {"metrics.json": {"a": 0, "b": {"ad": 0.0, "bc": 0.0}}}},
|
||||
all_branches=False,
|
||||
) == textwrap.dedent(
|
||||
"""\
|
||||
Path a b.ad b.bc
|
||||
metrics.json 0 0.0 0.0"""
|
||||
)
|
||||
|
||||
|
||||
def test_metrics_show_with_non_dict_values():
|
||||
assert _show_metrics(
|
||||
{"branch_1": {"metrics.json": 1}}, all_branches=True,
|
||||
) == textwrap.dedent(
|
||||
"""\
|
||||
Revision Path
|
||||
branch_1 metrics.json 1"""
|
||||
)
|
||||
|
||||
|
||||
def test_metrics_show_with_multiple_revision():
|
||||
assert _show_metrics(
|
||||
{
|
||||
"branch_1": {"metrics.json": {"a": 1, "b": {"ad": 1, "bc": 2}}},
|
||||
"branch_2": {"metrics.json": {"a": 1, "b": {"ad": 3, "bc": 4}}},
|
||||
},
|
||||
all_branches=True,
|
||||
) == textwrap.dedent(
|
||||
"""\
|
||||
Revision Path a b.ad b.bc
|
||||
branch_1 metrics.json 1 1 2
|
||||
branch_2 metrics.json 1 3 4"""
|
||||
)
|
||||
|
||||
|
||||
def test_metrics_show_with_one_revision_multiple_paths():
|
||||
assert _show_metrics(
|
||||
{
|
||||
"branch_1": {
|
||||
"metrics.json": {"a": 1, "b": {"ad": 0.1, "bc": 1.03}},
|
||||
"metrics_1.json": {"a": 2.3, "b": {"ad": 6.5, "bc": 7.9}},
|
||||
}
|
||||
},
|
||||
all_branches=True,
|
||||
) == textwrap.dedent(
|
||||
"""\
|
||||
Revision Path a b.ad b.bc
|
||||
branch_1 metrics.json 1 0.1 1.03
|
||||
branch_1 metrics_1.json 2.3 6.5 7.9"""
|
||||
)
|
||||
|
||||
|
||||
def test_metrics_show_with_different_metrics_header():
|
||||
assert _show_metrics(
|
||||
{
|
||||
"branch_1": {"metrics.json": {"b": {"ad": 1, "bc": 2}, "c": 4}},
|
||||
"branch_2": {"metrics.json": {"a": 1, "b": {"ad": 3, "bc": 4}}},
|
||||
},
|
||||
all_branches=True,
|
||||
) == textwrap.dedent(
|
||||
"""\
|
||||
Revision Path a b.ad b.bc c
|
||||
branch_1 metrics.json — 1 2 4
|
||||
branch_2 metrics.json 1 3 4 —"""
|
||||
)
|
||||
|
||||
|
||||
def test_metrics_show_precision():
|
||||
metrics = {
|
||||
"branch_1": {
|
||||
"metrics.json": {
|
||||
"a": 1.098765366365355,
|
||||
"b": {"ad": 1.5342673, "bc": 2.987725527},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert _show_metrics(metrics, all_branches=True,) == textwrap.dedent(
|
||||
"""\
|
||||
Revision Path a b.ad b.bc
|
||||
branch_1 metrics.json 1.09877 1.53427 2.98773"""
|
||||
)
|
||||
|
||||
assert _show_metrics(
|
||||
metrics, all_branches=True, precision=4
|
||||
) == textwrap.dedent(
|
||||
"""\
|
||||
Revision Path a b.ad b.bc
|
||||
branch_1 metrics.json 1.0988 1.5343 2.9877"""
|
||||
)
|
||||
|
||||
assert _show_metrics(
|
||||
metrics, all_branches=True, precision=7
|
||||
) == textwrap.dedent(
|
||||
"""\
|
||||
Revision Path a b.ad b.bc
|
||||
branch_1 metrics.json 1.0987654 1.5342673 2.9877255"""
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user