From 88fe61017c6baf16ab3cee041c654a7ea2bea191 Mon Sep 17 00:00:00 2001 From: Laurent Guerard Date: Tue, 6 May 2025 15:05:03 +0200 Subject: [PATCH 1/4] Add function to convert size from bytes to a more readable format --- src/imcflibs/imagej/misc.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/imcflibs/imagej/misc.py b/src/imcflibs/imagej/misc.py index 20b02540..928e31b2 100644 --- a/src/imcflibs/imagej/misc.py +++ b/src/imcflibs/imagej/misc.py @@ -790,3 +790,23 @@ def save_script_parameters(destination, save_file_name="script_parameters.txt"): f.write("%s: %s\n" % (key, str(val))) timed_log("Saved script parameters to: %s" % out_path) + +def convert_bytes(size): + """Convert size from bytes to a readable value + + Parameters + ---------- + size : int + Byte size + + Returns + ------- + str + Easy to read value with the correct unit + """ + for x in ["bytes", "KB", "MB", "GB", "TB"]: + if size < 1024.0: + return "%3.1f %s" % (size, x) + size /= 1024.0 + + return size From 073a1f7492d89c7ffe12abbc568266eacda12518 Mon Sep 17 00:00:00 2001 From: Laurent Guerard Date: Tue, 6 May 2025 15:09:10 +0200 Subject: [PATCH 2/4] Fix Ruff linting --- src/imcflibs/imagej/misc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/imcflibs/imagej/misc.py b/src/imcflibs/imagej/misc.py index 928e31b2..ce00ada9 100644 --- a/src/imcflibs/imagej/misc.py +++ b/src/imcflibs/imagej/misc.py @@ -792,7 +792,7 @@ def save_script_parameters(destination, save_file_name="script_parameters.txt"): timed_log("Saved script parameters to: %s" % out_path) def convert_bytes(size): - """Convert size from bytes to a readable value + """Convert size from bytes to a readable value. Parameters ---------- From a5cd2b1e0222c5a9a1870e07c63fee785dd285be Mon Sep 17 00:00:00 2001 From: Laurent Guerard Date: Wed, 21 Jan 2026 15:13:59 +0100 Subject: [PATCH 3/4] feat(misc): Rename bytes to human-readable conversion function - Implemented `bytes_to_human_readable` function to convert byte sizes into a more readable format. - Added unit tests for the new function to ensure accuracy across various sizes. --- src/imcflibs/imagej/misc.py | 32 +++++++++++++++++++++----------- tests/test_misc.py | 16 ++++++++++++++++ 2 files changed, 37 insertions(+), 11 deletions(-) create mode 100644 tests/test_misc.py diff --git a/src/imcflibs/imagej/misc.py b/src/imcflibs/imagej/misc.py index ce00ada9..0c612a87 100644 --- a/src/imcflibs/imagej/misc.py +++ b/src/imcflibs/imagej/misc.py @@ -10,15 +10,13 @@ from ij import IJ # pylint: disable-msg=import-error from ij.plugin import Duplicator, ImageCalculator, StackWriter +from org.scijava.widget import TextWidget, WidgetStyle from .. import pathtools from ..log import LOG as log from . import bioformats as bf from . import prefs -from org.scijava.widget import WidgetStyle -from org.scijava.widget import TextWidget - def show_status(msg): """Update the ImageJ status bar and issue a log message. @@ -533,7 +531,9 @@ def write_ordereddict_to_csv(out_file, content): dict_writer.writerows(content) -def save_image_in_format(imp, format, out_dir, series, pad_number, split_channels, suffix=""): +def save_image_in_format( + imp, format, out_dir, series, pad_number, split_channels, suffix="" +): """Save an ImagePlus object in the specified format. This function provides flexible options for saving ImageJ images in various @@ -791,22 +791,32 @@ def save_script_parameters(destination, save_file_name="script_parameters.txt"): timed_log("Saved script parameters to: %s" % out_path) -def convert_bytes(size): - """Convert size from bytes to a readable value. + +def bytes_to_human_readable(size): + """Convert a byte count to a human-readable string using binary units. Parameters ---------- size : int - Byte size + Byte size (number of bytes). Returns ------- str - Easy to read value with the correct unit + Human-friendly size string, e.g. `"512.0 bytes"`, `"2.0 KB"`, + `"1.0 MB"`. + + Notes + ----- + - Uses powers of 1024 (KB = 1024 bytes). + - Always returns a string with one decimal place and the unit. """ - for x in ["bytes", "KB", "MB", "GB", "TB"]: + + for unit in ["bytes", "KB", "MB", "GB", "TB"]: if size < 1024.0: - return "%3.1f %s" % (size, x) + return "%3.1f %s" % (size, unit) size /= 1024.0 - return size + # If the value is larger than the largest unit, fall back to TB with + # the current value (already divided accordingly). + return "%3.1f %s" % (size, "TB") diff --git a/tests/test_misc.py b/tests/test_misc.py new file mode 100644 index 00000000..e9fe56f2 --- /dev/null +++ b/tests/test_misc.py @@ -0,0 +1,16 @@ +"""Tests for `imcflibs.imagej.misc` utility functions.""" + +from imcflibs.imagej.misc import bytes_to_human_readable + + +def test_bytes_to_human_readable_simple(): + assert bytes_to_human_readable(500) == "500.0 bytes" + assert bytes_to_human_readable(2048) == "2.0 KB" + assert bytes_to_human_readable(1024 * 1024) == "1.0 MB" + assert bytes_to_human_readable(5 * 1024**3) == "5.0 GB" + + +def test_bytes_to_human_readable_large(): + # 1.5 TB in bytes should format as 1.5 TB + size = int(1.5 * (1024**4)) + assert bytes_to_human_readable(size) == "1.5 TB" From 2f7d7197896764ff4b3e3a31e64f1e8f659bdc21 Mon Sep 17 00:00:00 2001 From: Laurent Guerard Date: Wed, 21 Jan 2026 15:16:07 +0100 Subject: [PATCH 4/4] test: Add docstrings to byte conversion tests * Ensure common sizes are formatted into human-readable strings. * Verify formatting for large sizes such as terabytes. --- tests/test_misc.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_misc.py b/tests/test_misc.py index e9fe56f2..cabe80e6 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -4,6 +4,7 @@ def test_bytes_to_human_readable_simple(): + """Ensure common sizes are formatted into human-readable strings.""" assert bytes_to_human_readable(500) == "500.0 bytes" assert bytes_to_human_readable(2048) == "2.0 KB" assert bytes_to_human_readable(1024 * 1024) == "1.0 MB" @@ -11,6 +12,7 @@ def test_bytes_to_human_readable_simple(): def test_bytes_to_human_readable_large(): + """Verify formatting for large sizes such as terabytes.""" # 1.5 TB in bytes should format as 1.5 TB size = int(1.5 * (1024**4)) assert bytes_to_human_readable(size) == "1.5 TB"