Formatting
coola.formatting ¶
Contain functions that turn values into text for messages, repr
and reports.
The package exports nothing: import a function from its module.
coola.formatting.structure:str_*andrepr_*of sequences and mappings, and indentation.coola.formatting.quantity: human-readable byte sizes and durations, andmake_bar.coola.formatting.text:count_lines,remove_empty_lines,slugify,truncate_strandchar_diff_summary.coola.formatting.secret:mask_secret.coola.formatting.diff:unified_diff.
The functions are pure: the same input gives the same string.
coola.formatting.diff ¶
Provide utilities to display differences between two texts.
coola.formatting.diff.unified_diff ¶
unified_diff(
text_a: str,
text_b: str,
label_a: str = "previous",
label_b: str = "latest",
context_lines: int = 3,
) -> str
Compute a unified diff between two texts, similar to git
diff.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text_a
|
str
|
The original text (baseline). |
required |
text_b
|
str
|
The updated text to compare against |
required |
label_a
|
str
|
Label shown in the diff header for |
'previous'
|
label_b
|
str
|
Label shown in the diff header for |
'latest'
|
context_lines
|
int
|
Number of unchanged lines to show around each
change for context. Must be non-negative.
Defaults to |
3
|
Returns:
| Type | Description |
|---|---|
str
|
A unified diff string, or an empty string if the two texts are |
str
|
identical. A last line without a trailing newline is followed |
str
|
by |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Example
>>> from coola.formatting.diff import unified_diff
>>> print(unified_diff("hello\nworld\n", "hello\nearth\n"))
--- previous
+++ latest
@@ -1,2 +1,2 @@
hello
-world
+earth
<BLANKLINE>
coola.formatting.quantity ¶
Implement some utility functions to compute string representations of quantities (byte sizes, durations, ratios).
coola.formatting.quantity.find_best_byte_unit ¶
find_best_byte_unit(size: int) -> str
Return the best byte unit given the byte size.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
size
|
int
|
The size in bytes. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The best unit. The supported units are: |
Raises:
| Type | Description |
|---|---|
ValueError
|
if size is negative. |
Example
>>> from coola.formatting.quantity import find_best_byte_unit
>>> find_best_byte_unit(2)
'B'
>>> find_best_byte_unit(2048)
'KB'
>>> find_best_byte_unit(2097152)
'MB'
coola.formatting.quantity.make_bar ¶
make_bar(value: float, length: int = 10) -> str
Create a progress bar string for a given value between 0 and 1.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
float
|
A float between 0 and 1 representing the metric value. |
required |
length
|
int
|
The length of the progress bar. Must be a positive integer. |
10
|
Returns:
| Type | Description |
|---|---|
str
|
A string representing the progress bar. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Example
>>> from coola.formatting.quantity import make_bar
>>> make_bar(0.6)
'[██████░░░░]'
>>> make_bar(0.1)
'[█░░░░░░░░░]'
>>> make_bar(1.0)
'[██████████]'
>>> make_bar(0.0)
'[░░░░░░░░░░]'
coola.formatting.quantity.str_human_byte_size ¶
str_human_byte_size(
size: int, unit: str | None = None
) -> str
Get a human-readable representation of the byte size.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
size
|
int
|
The size in bytes. |
required |
unit
|
str | None
|
The unit to use to show the byte size. If |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The byte size in a human-readable format. |
Raises:
| Type | Description |
|---|---|
ValueError
|
if size is negative or unit is not supported. |
Example
>>> from coola.formatting.quantity import str_human_byte_size
>>> str_human_byte_size(2)
'2.00 B'
>>> str_human_byte_size(2048)
'2.00 KB'
>>> str_human_byte_size(2097152)
'2.00 MB'
>>> str_human_byte_size(2048, unit="B")
'2,048.00 B'
>>> str_human_byte_size(2**50)
'1.00 PB'
coola.formatting.quantity.str_time_human ¶
str_time_human(seconds: float) -> str
Return a number of seconds in an easier format to read
hh:mm:ss.
If the number of seconds is bigger than 1 day, this representation also encodes the number of days.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
seconds
|
float
|
The number of seconds. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The number of seconds in a string format ( |
Raises:
| Type | Description |
|---|---|
ValueError
|
if |
Example
>>> from coola.formatting.quantity import str_time_human
>>> str_time_human(1.2)
'0:00:01.200000'
>>> str_time_human(61.2)
'0:01:01.200000'
>>> str_time_human(3661.2)
'1:01:01.200000'
>>> str_time_human(-5)
'-0:00:05'
coola.formatting.secret ¶
Define utility functions for secrets.
coola.formatting.secret.mask_secret ¶
mask_secret(
secret: str, show_first: int = 3, show_last: int = 4
) -> str
Mask the content of the secret with *.
Note
This is for display/logging only, not encryption: the shown characters are leaked, and the length of the secret is preserved.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
secret
|
str
|
The secret to mask. |
required |
show_first
|
int
|
The number of first values to show. |
3
|
show_last
|
int
|
The number of last values to show. |
4
|
Returns:
| Type | Description |
|---|---|
str
|
The masked secret. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Example
>>> from coola.formatting.secret import mask_secret
>>> secret = "abcdefghijklmnopqrstuvwxyz"
>>> mask_secret(secret)
'abc*******************wxyz'
>>> mask_secret(secret, show_first=0)
'**********************wxyz'
>>> mask_secret(secret, show_last=0)
'abc***********************'
>>> mask_secret(secret, show_first=0, show_last=0)
'**************************'
coola.formatting.structure ¶
Implement some utility functions to compute string representations of sequences and mappings.
coola.formatting.structure.repr_indent ¶
repr_indent(
original: object, *, num_spaces: int = 2
) -> str
Add indentations if the original string is a multi-lines string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
original
|
object
|
The original string. If the input is not a
string, it will be converted to a string with the function
|
required |
num_spaces
|
int
|
The number of spaces used for the indentation. |
2
|
Returns:
| Type | Description |
|---|---|
str
|
The indented string. |
Raises:
| Type | Description |
|---|---|
ValueError
|
if num_spaces is negative. |
Example
>>> from coola.formatting.structure import repr_indent
>>> print(repr_indent("string1\nstring2\n string3", num_spaces=4))
string1
string2
string3
coola.formatting.structure.repr_mapping ¶
repr_mapping(
mapping: Mapping[Any, Any],
*,
sorted_keys: bool = False,
num_spaces: int = 2,
) -> str
Compute a string representation of a mapping.
This function was designed for flat dictionary. If you have a nested dictionary, you may consider other functions. Note that this function works for nested dict but the output may not be nice.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mapping
|
Mapping[Any, Any]
|
The mapping. |
required |
sorted_keys
|
bool
|
If |
False
|
num_spaces
|
int
|
The number of spaces used for the indentation. |
2
|
Returns:
| Type | Description |
|---|---|
str
|
The string representation of the mapping. |
Example
>>> from coola.formatting.structure import repr_mapping
>>> print(repr_mapping({"key1": "abc", "key2": "something\nelse"}))
(key1): abc
(key2): something
else
coola.formatting.structure.repr_mapping_line ¶
repr_mapping_line(
mapping: Mapping[Any, Any],
*,
sorted_keys: bool = False,
separator: str = ", ",
) -> str
Compute a single line string representation of the given mapping.
This function is designed for flat dictionary. If you have a nested dictionary, you may consider other functions. Note that this function works for nested dict but the output may not be nice.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mapping
|
Mapping[Any, Any]
|
The mapping. |
required |
sorted_keys
|
bool
|
If |
False
|
separator
|
str
|
The separator to use between each key-value pair. |
', '
|
Returns:
| Type | Description |
|---|---|
str
|
The string representation of the mapping. |
Example
>>> from coola.formatting.structure import repr_mapping_line
>>> print(repr_mapping_line({"key1": "abc", "key2": "meow", "key3": 42}))
key1='abc', key2='meow', key3=42
coola.formatting.structure.repr_sequence ¶
repr_sequence(
sequence: Sequence[Any], *, num_spaces: int = 2
) -> str
Compute a string representation of a sequence.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sequence
|
Sequence[Any]
|
The sequence. |
required |
num_spaces
|
int
|
The number of spaces used for the indentation. |
2
|
Returns:
| Type | Description |
|---|---|
str
|
The string representation of the sequence. |
Example
>>> from coola.formatting.structure import repr_indent
>>> print(repr_sequence(["abc", "something\nelse"]))
(0): abc
(1): something
else
coola.formatting.structure.repr_sequence_line ¶
repr_sequence_line(
sequence: Sequence[Any], *, separator: str = ", "
) -> str
Compute a single line string representation of a sequence.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sequence
|
Sequence[Any]
|
The sequence. |
required |
separator
|
str
|
The separator to use between each item. |
', '
|
Returns:
| Type | Description |
|---|---|
str
|
The string representation of the sequence. |
Example
>>> from coola.formatting.structure import repr_sequence_line
>>> print(repr_sequence_line(["abc", "meow", 42]))
'abc', 'meow', 42
coola.formatting.structure.str_indent ¶
str_indent(original: object, *, num_spaces: int = 2) -> str
Add indentations if the original string is a multi-lines string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
original
|
object
|
The original string. If the input is not a
string, it will be converted to a string with the function
|
required |
num_spaces
|
int
|
The number of spaces used for the indentation. |
2
|
Returns:
| Type | Description |
|---|---|
str
|
The indented string. |
Raises:
| Type | Description |
|---|---|
ValueError
|
if num_spaces is negative. |
Example
>>> from coola.formatting.structure import str_indent
>>> print(str_indent("string1\nstring2\n string3", num_spaces=4))
string1
string2
string3
coola.formatting.structure.str_mapping ¶
str_mapping(
mapping: Mapping[Any, Any],
*,
sorted_keys: bool = False,
num_spaces: int = 2,
) -> str
Compute a string representation of a mapping.
This function was designed for flat dictionary. If you have a nested dictionary, you may consider other functions. Note that this function works for nested dict but the output may not be nice.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mapping
|
Mapping[Any, Any]
|
The mapping. |
required |
sorted_keys
|
bool
|
If |
False
|
num_spaces
|
int
|
The number of spaces used for the indentation. |
2
|
Returns:
| Type | Description |
|---|---|
str
|
The string representation of the mapping. |
Example
>>> from coola.formatting.structure import str_mapping
>>> print(str_mapping({"key1": "abc", "key2": "something\nelse"}))
(key1): abc
(key2): something
else
coola.formatting.structure.str_mapping_line ¶
str_mapping_line(
mapping: Mapping[Any, Any],
*,
sorted_keys: bool = False,
separator: str = ", ",
) -> str
Compute a single line string representation of the given mapping.
This function is designed for flat dictionary. If you have a nested dictionary, you may consider other functions. Note that this function works for nested dict but the output may not be nice.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
mapping
|
Mapping[Any, Any]
|
The mapping. |
required |
sorted_keys
|
bool
|
If |
False
|
separator
|
str
|
The separator to use between each key-value pair. |
', '
|
Returns:
| Type | Description |
|---|---|
str
|
The string representation of the mapping. |
Example
>>> from coola.formatting.structure import str_mapping_line
>>> print(str_mapping_line({"key1": "abc", "key2": "meow", "key3": 42}))
key1=abc, key2=meow, key3=42
coola.formatting.structure.str_sequence ¶
str_sequence(
sequence: Sequence[Any], *, num_spaces: int = 2
) -> str
Compute a string representation of a sequence.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sequence
|
Sequence[Any]
|
The sequence. |
required |
num_spaces
|
int
|
The number of spaces used for the indentation. |
2
|
Returns:
| Type | Description |
|---|---|
str
|
The string representation of the sequence. |
Example
>>> from coola.formatting.structure import str_sequence
>>> print(str_sequence(["abc", "something\nelse"]))
(0): abc
(1): something
else
coola.formatting.structure.str_sequence_line ¶
str_sequence_line(
sequence: Sequence[Any], *, separator: str = ", "
) -> str
Compute a single line string representation of a sequence.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sequence
|
Sequence[Any]
|
The sequence. |
required |
separator
|
str
|
The separator to use between each item. |
', '
|
Returns:
| Type | Description |
|---|---|
str
|
The string representation of the sequence. |
Example
>>> from coola.formatting.structure import str_sequence_line
>>> print(str_sequence_line(["abc", "meow", 42]))
abc, meow, 42
coola.formatting.text ¶
Contain utility functions to process strings.
coola.formatting.text.char_diff_summary ¶
char_diff_summary(before: str, after: str) -> str
Compute a human-readable character count difference string.
Returns a formatted string describing the character counts before and after a text transformation, including the signed difference and percentage change relative to the original length.
The sign of the diff reflects whether the transformation grew or
shrank the text: negative means fewer characters, positive means
more. Handles empty input gracefully: the percentage is 0.0% if
both texts are empty, and n/a if the text grew from an empty
text (the change relative to zero is undefined).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
before
|
str
|
The text before transformation. |
required |
after
|
str
|
The text after transformation. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A formatted string with the character count difference. |
Example
>>> from coola.formatting.text import char_diff_summary
>>> char_diff_summary("<p>Hello</p>", "Hello")
'12 -> 5 chars (-7 chars, -58.3%).'
>>> char_diff_summary("", "abc")
'0 -> 3 chars (+3 chars, n/a).'
coola.formatting.text.count_lines ¶
count_lines(text: str) -> int
Count the number of lines in a string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The input string to count lines in. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The number of lines in the input string. |
Example
>>> from coola.formatting.text import count_lines
>>> count_lines("Hello\nWorld")
2
>>> count_lines("Hello\nWorld\nFoo")
3
coola.formatting.text.remove_empty_lines ¶
remove_empty_lines(text: str) -> str
Remove empty lines from a string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The input string from which empty lines will be removed. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A new string with all empty or whitespace-only lines removed. |
Example
>>> from coola.formatting.text import remove_empty_lines
>>> remove_empty_lines("Hello\n\nWorld\n\n\nFoo")
'Hello\nWorld\nFoo'
>>> remove_empty_lines("\n\nOnly empty lines\n\n")
'Only empty lines'
coola.formatting.text.slugify ¶
slugify(text: str) -> str
Convert arbitrary text into a URL/filesystem-safe slug.
Lowercases the text, strips accents, replaces any run of characters that aren't alphanumerics with a single hyphen, and trims leading or trailing hyphens. Works on any string -- titles, names, tags, filenames, model names, etc. -- not just a specific kind of text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The raw text to slugify (e.g. an article title, a tag, a file name, or a model name). |
required |
Returns:
| Type | Description |
|---|---|
str
|
A lowercase, hyphen-separated slug safe to use as a filename,
URL path segment, or dict key. If the text has letters,
digits or other non-ASCII characters (e.g. an emoji) but
none can be written in ASCII (e.g. |
Example
>>> from coola.formatting.text import slugify
>>> slugify("Hello, World!")
'hello-world'
>>> slugify("Claude Sonnet 4.6")
'claude-sonnet-4-6'
>>> slugify("meta-llama/Llama-3.1-8B-Instruct")
'meta-llama-llama-3-1-8b-instruct'
>>> slugify(" Café con Leche ")
'cafe-con-leche'
coola.formatting.text.truncate_str ¶
truncate_str(
s: str, max_len: int = 100, suffix: str = "..."
) -> str
Return a truncated string if the string exceeds the maximum length.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
s
|
str
|
The string to truncate. |
required |
max_len
|
int
|
The maximum number of characters. Must be greater than
or equal to the length of |
100
|
suffix
|
str
|
The suffix to append when truncation occurs.
Defaults to |
'...'
|
Returns:
| Type | Description |
|---|---|
str
|
The original string if it is within |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Example
>>> from coola.formatting.text import truncate_str
>>> truncate_str("hello world")
'hello world'
>>> truncate_str("hello world", max_len=8)
'hello...'
>>> truncate_str("hello world", max_len=8, suffix="…")
'hello w…'