mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-09 23:10:24 +01:00
metrics: diff: introduce --precision (#4026)
Rounding to 5 digits by default. Fixes #3904
This commit is contained in:
+34
-7
@@ -7,6 +7,9 @@ from dvc.exceptions import BadMetricError, DvcException
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
DEFAULT_PRECISION = 5
|
||||
|
||||
|
||||
def show_metrics(
|
||||
metrics, all_branches=False, all_tags=False, all_commits=False
|
||||
):
|
||||
@@ -63,11 +66,20 @@ class CmdMetricsShow(CmdBase):
|
||||
return 0
|
||||
|
||||
|
||||
def _show_diff(diff, markdown=False, no_path=False, old=False):
|
||||
def _show_diff(diff, markdown=False, no_path=False, old=False, precision=None):
|
||||
from collections import OrderedDict
|
||||
|
||||
from dvc.utils.diff import table
|
||||
|
||||
if precision is None:
|
||||
precision = DEFAULT_PRECISION
|
||||
|
||||
def _round(val):
|
||||
if isinstance(val, float):
|
||||
return round(val, precision)
|
||||
|
||||
return val
|
||||
|
||||
rows = []
|
||||
for fname, mdiff in diff.items():
|
||||
sorted_mdiff = OrderedDict(sorted(mdiff.items()))
|
||||
@@ -75,9 +87,9 @@ def _show_diff(diff, markdown=False, no_path=False, old=False):
|
||||
row = [] if no_path else [fname]
|
||||
row.append(metric)
|
||||
if old:
|
||||
row.append(change.get("old"))
|
||||
row.append(change["new"])
|
||||
row.append(change.get("diff", "diff not supported"))
|
||||
row.append(_round(change.get("old")))
|
||||
row.append(_round(change["new"]))
|
||||
row.append(_round(change.get("diff", "diff not supported")))
|
||||
rows.append(row)
|
||||
|
||||
header = [] if no_path else ["Path"]
|
||||
@@ -108,7 +120,11 @@ class CmdMetricsDiff(CmdBase):
|
||||
logger.info(json.dumps(diff))
|
||||
else:
|
||||
table = _show_diff(
|
||||
diff, self.args.show_md, self.args.no_path, self.args.old
|
||||
diff,
|
||||
self.args.show_md,
|
||||
self.args.no_path,
|
||||
self.args.old,
|
||||
precision=self.args.precision,
|
||||
)
|
||||
if table:
|
||||
logger.info(table)
|
||||
@@ -189,8 +205,10 @@ def add_parser(subparsers, parent_parser):
|
||||
)
|
||||
metrics_show_parser.set_defaults(func=CmdMetricsShow)
|
||||
|
||||
METRICS_DIFF_HELP = "Show changes in metrics between commits"
|
||||
" in the DVC repository, or between a commit and the workspace."
|
||||
METRICS_DIFF_HELP = (
|
||||
"Show changes in metrics between commits in the DVC repository, or "
|
||||
"between a commit and the workspace."
|
||||
)
|
||||
metrics_diff_parser = metrics_subparsers.add_parser(
|
||||
"diff",
|
||||
parents=[parent_parser],
|
||||
@@ -255,4 +273,13 @@ def add_parser(subparsers, parent_parser):
|
||||
default=False,
|
||||
help="Show old metric value.",
|
||||
)
|
||||
metrics_diff_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_diff_parser.set_defaults(func=CmdMetricsDiff)
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import json
|
||||
import logging
|
||||
|
||||
import yaml
|
||||
|
||||
from dvc.main import main
|
||||
|
||||
|
||||
def test_metrics_diff_simple(tmp_dir, scm, dvc, run_copy_metrics):
|
||||
def _gen(val):
|
||||
@@ -170,3 +173,26 @@ def test_metrics_diff_dirty(tmp_dir, scm, dvc, run_copy_metrics):
|
||||
expected = {"m.yaml": {"": {"old": 3, "new": 4, "diff": 1}}}
|
||||
|
||||
assert dvc.metrics.diff() == expected
|
||||
|
||||
|
||||
def test_metrics_diff_cli(tmp_dir, scm, dvc, run_copy_metrics, caplog, capsys):
|
||||
def _gen(val):
|
||||
tmp_dir.gen({"m_temp.yaml": f"foo: {val}"})
|
||||
run_copy_metrics("m_temp.yaml", "m.yaml", metrics=["m.yaml"])
|
||||
dvc.scm.commit(str(val))
|
||||
|
||||
_gen(1.23456789)
|
||||
_gen(2.34567891011)
|
||||
_gen(3.45678910111213)
|
||||
|
||||
caplog.clear()
|
||||
assert main(["metrics", "diff", "HEAD~2", "--old"]) == 0
|
||||
(info,) = [
|
||||
msg
|
||||
for name, level, msg in caplog.record_tuples
|
||||
if name.startswith("dvc") and level == logging.INFO
|
||||
]
|
||||
assert info == (
|
||||
"Path Metric Old New Change\n"
|
||||
"m.yaml foo 1.23457 3.45679 2.22222"
|
||||
)
|
||||
|
||||
@@ -20,6 +20,8 @@ def test_metrics_diff(dvc, mocker):
|
||||
"--show-md",
|
||||
"--no-path",
|
||||
"--old",
|
||||
"--precision",
|
||||
"10",
|
||||
]
|
||||
)
|
||||
assert cli_args.func == CmdMetricsDiff
|
||||
@@ -123,13 +125,27 @@ def test_metrics_show(dvc, mocker):
|
||||
)
|
||||
|
||||
|
||||
def test_metrics_diff_prec():
|
||||
assert _show_diff(
|
||||
{"other.json": {"a.b": {"old": 0.0042, "new": 0.0043, "diff": 0.0001}}}
|
||||
) == textwrap.dedent(
|
||||
def test_metrics_diff_precision():
|
||||
diff = {
|
||||
"other.json": {
|
||||
"a.b": {
|
||||
"old": 0.1234567,
|
||||
"new": 0.765432101234567,
|
||||
"diff": 0.641975401234567,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert _show_diff(diff) == textwrap.dedent(
|
||||
"""\
|
||||
Path Metric Value Change
|
||||
other.json a.b 0.0043 0.0001"""
|
||||
other.json a.b 0.76543 0.64198"""
|
||||
)
|
||||
|
||||
assert _show_diff(diff, precision=10) == textwrap.dedent(
|
||||
"""\
|
||||
Path Metric Value Change
|
||||
other.json a.b 0.7654321012 0.6419754012"""
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user