Repository: Project-MONAI/MONAI

Issue:
cannot import name 'PILLOW_VERSION' from 'PIL'
The issue is found when trying to fix #4011 , and it is raised due to `torchvision==0.2.2` is installed (the version is too old).
conda test TestHandlerMetricsSaver
**Describe the bug**
```
======================================================================
FAIL: test_content (tests.test_handler_metrics_saver.TestHandlerMetricsSaver)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/runner/work/MONAI/MONAI/tests/test_handler_metrics_saver.py", line 69, in test_content
    self.assertEqual(row, [f"filepath{i}\t{float(i)}\t{float(i + 1)}\t{i + 0.5}"])
AssertionError: Lists differ: ['filepath1\t1e+00\t2.0\t1.5'] != ['filepath1\t1.0\t2.0\t1.5']

First differing element 0:
'filepath1\t1e+00\t2.0\t1.5'
'filepath1\t1.0\t2.0\t1.5'

- ['filepath1\t1e+00\t2.0\t1.5']
?               ^^^

+ ['filepath1\t1.0\t2.0\t1.5']
?               ^


----------------------------------------------------------------------
```


Discussion:

Patch:
diff --git a/monai/handlers/utils.py b/monai/handlers/utils.py
--- a/monai/handlers/utils.py
+++ b/monai/handlers/utils.py
@@ -121,7 +121,10 @@ class    mean    median    max    5percentile 95percentile  notnans
             with open(os.path.join(save_dir, f"{k}_raw.csv"), "w") as f:
                 f.write(f"filename{deli}{deli.join(class_labels)}\n")
                 for i, b in enumerate(v):
-                    f.write(f"{images[i] if images is not None else str(i)}{deli}{deli.join([str(c) for c in b])}\n")
+                    f.write(
+                        f"{images[i] if images is not None else str(i)}{deli}"
+                        f"{deli.join([f'{c:.4f}' if isinstance(c, (int, float)) else str(c) for c in b])}\n"
+                    )
 
             if summary_ops is not None:
                 supported_ops = OrderedDict(


Test patch:
diff --git a/tests/test_handler_metrics_saver.py b/tests/test_handler_metrics_saver.py
--- a/tests/test_handler_metrics_saver.py
+++ b/tests/test_handler_metrics_saver.py
@@ -66,7 +66,7 @@ def _save_metrics(engine):
                 f_csv = csv.reader(f)
                 for i, row in enumerate(f_csv):
                     if i > 0:
-                        self.assertEqual(row, [f"filepath{i}\t{float(i)}\t{float(i + 1)}\t{i + 0.5}"])
+                        self.assertEqual(row, [f"filepath{i}\t{float(i):.4f}\t{float(i + 1):.4f}\t{i + 0.5:.4f}"])
             self.assertTrue(os.path.exists(os.path.join(tempdir, "metric3_summary.csv")))
             # check the metric_summary.csv and content
             with open(os.path.join(tempdir, "metric4_summary.csv")) as f:
diff --git a/tests/test_handler_metrics_saver_dist.py b/tests/test_handler_metrics_saver_dist.py
--- a/tests/test_handler_metrics_saver_dist.py
+++ b/tests/test_handler_metrics_saver_dist.py
@@ -95,7 +95,7 @@ def _all_gather(engine):
                 f_csv = csv.reader(f)
                 for i, row in enumerate(f_csv):
                     if i > 0:
-                        expected = [f"{fnames[i-1]}\t{float(i)}\t{float(i + 1)}\t{i + 0.5}"]
+                        expected = [f"{fnames[i-1]}\t{float(i):.4f}\t{float(i + 1):.4f}\t{i + 0.5:.4f}"]
                         self.assertEqual(row, expected)
             self.assertTrue(os.path.exists(os.path.join(tempdir, "metric3_summary.csv")))
             # check the metric_summary.csv and content
diff --git a/tests/test_write_metrics_reports.py b/tests/test_write_metrics_reports.py
--- a/tests/test_write_metrics_reports.py
+++ b/tests/test_write_metrics_reports.py
@@ -45,7 +45,7 @@ def test_content(self):
                 f_csv = csv.reader(f)
                 for i, row in enumerate(f_csv):
                     if i > 0:
-                        self.assertEqual(row, [f"filepath{i}\t{float(i)}\t{float(i + 1)}\t{i + 0.5}"])
+                        self.assertEqual(row, [f"filepath{i}\t{float(i):.4f}\t{float(i + 1):.4f}\t{i + 0.5:.4f}"])
             self.assertTrue(os.path.exists(os.path.join(tempdir, "metric3_summary.csv")))
             # check the metric_summary.csv and content
             with open(os.path.join(tempdir, "metric3_summary.csv")) as f: