summaryrefslogtreecommitdiff
path: root/string_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'string_utils.py')
-rw-r--r--string_utils.py78
1 files changed, 75 insertions, 3 deletions
diff --git a/string_utils.py b/string_utils.py
index 83575ff..7ad9c42 100644
--- a/string_utils.py
+++ b/string_utils.py
@@ -1,7 +1,9 @@
#!/usr/bin/env python3
+import datetime
from itertools import zip_longest
import json
+import logging
import random
import re
import string
@@ -9,6 +11,11 @@ from typing import Any, List, Optional
import unicodedata
from uuid import uuid4
+import dateparse.dateparse_utils as dp
+
+
+logger = logging.getLogger(__name__)
+
NUMBER_RE = re.compile(r"^([+\-]?)((\d+)(\.\d+)?([e|E]\d+)?|\.\d+)$")
HEX_NUMBER_RE = re.compile(r"^([+|-]?)0[x|X]([0-9A-Fa-f]+)$")
@@ -247,7 +254,6 @@ def _add_thousands_separator(in_str: str, *, separator_char = ',', places = 3) -
return ret
-
# Full url example:
# scheme://username:[email protected]:8042/folder/subfolder/file.extension?param=value&param2=value2#hash
def is_url(in_str: Any, allowed_schemes: Optional[List[str]] = None) -> bool:
@@ -354,13 +360,14 @@ def number_to_suffix_string(num: int) -> Optional[str]:
d = 0.0
suffix = None
for (sfx, size) in NUM_SUFFIXES.items():
- if num > size:
+ if num >= size:
d = num / size
suffix = sfx
break
if suffix is not None:
return f"{d:.1f}{suffix}"
- return None
+ else:
+ return f'{num:d}'
def is_credit_card(in_str: Any, card_type: str = None) -> bool:
@@ -807,6 +814,45 @@ def to_bool(in_str: str) -> bool:
return in_str.lower() in ("true", "1", "yes", "y", "t")
+def to_date(in_str: str) -> Optional[datetime.date]:
+ try:
+ d = dp.DateParser()
+ d.parse(in_str)
+ return d.get_date()
+ except dp.ParseException:
+ logger.warning(f'Unable to parse date {in_str}.')
+ return None
+
+
+def valid_date(in_str: str) -> bool:
+ try:
+ d = dp.DateParser()
+ _ = d.parse(in_str)
+ return True
+ except dp.ParseException:
+ logger.warning(f'Unable to parse date {in_str}.')
+ return False
+
+
+def to_datetime(in_str: str) -> Optional[datetime.datetime]:
+ try:
+ d = dp.DateParser()
+ dt = d.parse(in_str)
+ if type(dt) == datetime.datetime:
+ return dt
+ except ValueError:
+ logger.warning(f'Unable to parse datetime {in_str}.')
+ return None
+
+
+def valid_datetime(in_str: str) -> bool:
+ _ = to_datetime(in_str)
+ if _ is not None:
+ return True
+ logger.warning(f'Unable to parse datetime {in_str}.')
+ return False
+
+
def dedent(in_str: str) -> str:
"""
Removes tab indentation from multi line strings (inspired by analogous Scala function).
@@ -869,3 +915,29 @@ def sprintf(*args, **kwargs) -> str:
ret += str(arg)
ret += end
return ret
+
+
+def is_are(n: int) -> str:
+ if n == 1:
+ return "is"
+ return "are"
+
+
+def pluralize(n: int) -> str:
+ if n == 1:
+ return ""
+ return "s"
+
+
+def thify(n: int) -> str:
+ digit = str(n)
+ assert is_integer_number(digit)
+ digit = digit[-1:]
+ if digit == "1":
+ return "st"
+ elif digit == "2":
+ return "nd"
+ elif digit == "3":
+ return "rd"
+ else:
+ return "th"