Module inkfill.filters
Common helper functions.
Expand source code
"""Common helper functions."""
# std
from datetime import datetime
from decimal import Decimal
from typing import List
from typing import Literal
# pkg
from .numerals import to_cardinal as say_number
from .numerals import to_nth
## Dates
def day_of_month(dt: datetime) -> str:
"""Return date as `{nth} day of {month} {year}`."""
return f"{to_nth(dt.day)} day of {dt.strftime('%B %Y')}"
## English
FANBOYS = Literal["for", "and", "nor", "but", "or", "yet", "so"]
"""Common coordinating conjunctions."""
def compound(
clauses: List[str],
conjunction: FANBOYS = "and",
oxford: bool = True,
) -> str:
"""Return `clauses` connected with `conjunction` and Oxford comma (optional)."""
L = len(clauses)
if L == 0:
return ""
if L == 1:
return clauses[0]
if L == 2:
return f" {conjunction} ".join(clauses)
first = ", ".join(clauses[0:-1])
last = clauses[-1]
return f"{first}{',' if oxford else ''} {conjunction} {last}"
## Money
def USD(num: float, cents: bool = False) -> str:
"""Return formatted US Dollars."""
if cents:
if 0 < num < 0.01:
return f"US${num}"
return f"US${num:,.2f}"
return f"US${num:,}"
def dollars(num: float) -> str:
"""Return spelled-out dollars. Commonly used in contracts."""
dec = Decimal(str(num))
whole = int(dec)
part = dec % 1
if Decimal("0") < part < Decimal("0.01"): # sub-cent
return USD(num, cents=True)
result = ""
if whole or num == 0:
result += f"{say_number(whole)} dollar{'s' if whole != 1 else ''}"
if whole and part:
result += " and "
if part:
part *= 100
result += f"{say_number(int(part))} cent{'s' if part != 1 else ''}"
elif num != 0:
result += " exactly"
result += f" ({USD(num, cents=part > 0 or num < 10)})"
return result
Global variables
var FANBOYS
-
Common coordinating conjunctions.
Functions
def day_of_month(dt: datetime.datetime) ‑> str
-
Return date as
{nth} day of {month} {year}
.Expand source code
def day_of_month(dt: datetime) -> str: """Return date as `{nth} day of {month} {year}`.""" return f"{to_nth(dt.day)} day of {dt.strftime('%B %Y')}"
def compound(clauses: List[str], conjunction: Literal['for', 'and', 'nor', 'but', 'or', 'yet', 'so'] = 'and', oxford: bool = True) ‑> str
-
Return
clauses
connected withconjunction
and Oxford comma (optional).Expand source code
def compound( clauses: List[str], conjunction: FANBOYS = "and", oxford: bool = True, ) -> str: """Return `clauses` connected with `conjunction` and Oxford comma (optional).""" L = len(clauses) if L == 0: return "" if L == 1: return clauses[0] if L == 2: return f" {conjunction} ".join(clauses) first = ", ".join(clauses[0:-1]) last = clauses[-1] return f"{first}{',' if oxford else ''} {conjunction} {last}"
def USD(num: float, cents: bool = False) ‑> str
-
Return formatted US Dollars.
Expand source code
def USD(num: float, cents: bool = False) -> str: """Return formatted US Dollars.""" if cents: if 0 < num < 0.01: return f"US${num}" return f"US${num:,.2f}" return f"US${num:,}"
def dollars(num: float) ‑> str
-
Return spelled-out dollars. Commonly used in contracts.
Expand source code
def dollars(num: float) -> str: """Return spelled-out dollars. Commonly used in contracts.""" dec = Decimal(str(num)) whole = int(dec) part = dec % 1 if Decimal("0") < part < Decimal("0.01"): # sub-cent return USD(num, cents=True) result = "" if whole or num == 0: result += f"{say_number(whole)} dollar{'s' if whole != 1 else ''}" if whole and part: result += " and " if part: part *= 100 result += f"{say_number(int(part))} cent{'s' if part != 1 else ''}" elif num != 0: result += " exactly" result += f" ({USD(num, cents=part > 0 or num < 10)})" return result