# pymince
[![CI](https://github.com/rmoralespp/pymince/workflows/CI/badge.svg)](https://github.com/rmoralespp/pymince/actions?query=event%3Arelease+workflow%3ACI)
[![pypi](https://img.shields.io/pypi/v/pymince.svg)](https://pypi.python.org/pypi/pymince)
[![versions](https://img.shields.io/pypi/pyversions/pymince.svg)](https://github.com/rmoralespp/pymince)
[![codecov](https://codecov.io/gh/rmoralespp/pymince/branch/main/graph/badge.svg)](https://app.codecov.io/gh/rmoralespp/pymince)
[![license](https://img.shields.io/github/license/rmoralespp/pymince.svg)](https://github.com/rmoralespp/pymince/blob/main/LICENSE)
[![Downloads](https://pepy.tech/badge/pymince)](https://pepy.tech/project/pymince)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Linter: ruff](https://img.shields.io/badge/linter-_ruff-orange)](https://github.com/charliermarsh/ruff)
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)
### About
pymince is a collection of useful tools that are "missing" from the Python standard library.
### Installation (via pip)
```pip install pymince```
### Tests
```
(env)$ pip install -r requirements.txt # Ignore this command if it has already been executed
(env)$ pytest tests/
(env)$ pytest --cov pymince # Tests with coverge
```
### Usage
| PyModules | Tools |
| :-------- | :----- |
| **algorithm.py** |[*fibonacci*](#fibonacci), [*luhn*](#luhn), [*sieve_of_eratosthenes*](#sieve_of_eratosthenes)|
| **boolean.py** |[*string2bool*](#string2bool)|
| **dates.py** |[*IsoWeekDay*](#IsoWeekDay), [*WeekDay*](#WeekDay), [*irange*](#irange), [*string2year*](#string2year)|
| **dictionary.py** |[*DigestGetter*](#DigestGetter), [*all_true_values*](#all_true_values), [*find_leaf_value*](#find_leaf_value), [*from_objects*](#from_objects), [*frozendict*](#frozendict), [*tree*](#tree)|
| **file.py** |[*decompress*](#decompress), [*ensure_directory*](#ensure_directory), [*get_valid_filename*](#get_valid_filename), [*is_empty_directory*](#is_empty_directory), [*match_from_zip*](#match_from_zip), [*replace_extension*](#replace_extension), [*xopen*](#xopen)|
| **functional.py** |[*caller*](#caller), [*classproperty*](#classproperty), [*identity*](#identity), [*once*](#once), [*pipe*](#pipe), [*retry_if_errors*](#retry_if_errors), [*retry_if_none*](#retry_if_none), [*set_attributes*](#set_attributes), [*suppress*](#suppress)|
| **iterator.py** |[*all_distinct*](#all_distinct), [*all_equal*](#all_equal), [*all_equals*](#all_equals), [*all_identical*](#all_identical), [*centroid*](#centroid), [*consume*](#consume), [*grouper*](#grouper), [*ibool*](#ibool), [*in_all*](#in_all), [*in_any*](#in_any), [*ipush*](#ipush), [*mul*](#mul), [*only_one*](#only_one), [*pad_end*](#pad_end), [*pad_start*](#pad_start), [*partition*](#partition), [*replacer*](#replacer), [*splitter*](#splitter), [*sub*](#sub), [*truediv*](#truediv), [*uniquer*](#uniquer), [*uniques*](#uniques)|
| **json.py** |[*JSONEncoder*](#JSONEncoder), [*dump_from_csv*](#dump_from_csv), [*dump_into*](#dump_into), [*dump_into_zip*](#dump_into_zip), [*idump_fork*](#idump_fork), [*idump_into*](#idump_into), [*idump_lines*](#idump_lines), [*load*](#load), [*load_from*](#load_from), [*load_from_zip*](#load_from_zip)|
| **logging.py** |[*ColoredFormatter*](#ColoredFormatter), [*ColoredLogger*](#ColoredLogger), [*StructuredFormatter*](#StructuredFormatter), [*timed_block*](#timed_block)|
| **std.py** |[*bind_json_std*](#bind_json_std)|
| **text.py** |[*are_anagram*](#are_anagram), [*get_random_secret*](#get_random_secret), [*get_random_string*](#get_random_string), [*is_binary*](#is_binary), [*is_email_address*](#is_email_address), [*is_int*](#is_int), [*is_negative_int*](#is_negative_int), [*is_palindrome*](#is_palindrome), [*is_payment_card*](#is_payment_card), [*is_percentage*](#is_percentage), [*is_positive_int*](#is_positive_int), [*is_roman*](#is_roman), [*is_url*](#is_url), [*multireplace*](#multireplace), [*multireplacer*](#multireplacer), [*normalize_newlines*](#normalize_newlines), [*remove_decimal_zeros*](#remove_decimal_zeros), [*remove_number_commas*](#remove_number_commas), [*replace*](#replace), [*slugify*](#slugify)|
| **warnings.py** |[*deprecated*](#deprecated)|
| **xml.py** |[*iterparse*](#iterparse)|
#### algorithm.py
##### fibonacci
```
fibonacci(n=None)
Returns a generator with fibonacci series up to n.
Runs indefinitely if n is specified as None.
:param Optional[int] n: Must be None or number.
:rtype: Generator[int]
```
##### luhn
```
luhn(value: str) -> bool
The Luhn algorithm or Luhn formula, also known as the "modulus 10" or "mod 10" algorithm,
named after its creator, IBM scientist Hans Peter Luhn,
is a simple checksum formula used to validate a variety of
identification numbers, such as credit card numbers, IMEI numbers, National Provider Identifier numbers
Based on: https://en.wikipedia.org/wiki/Luhn_algorithm
```
##### sieve_of_eratosthenes
```
sieve_of_eratosthenes(n)
Primes less than n.
Based on: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
:param int n: n an integer n > 1
:rtype: Generator[int]. All prime numbers from 2 through n.
Examples:
from pymince.algorithm import sieve_of_eratosthenes as primes
primes(30) # --> 2, 3, 5, 7, 11, 13, 17, 19, 23, 29
```
#### boolean.py
##### string2bool
```
string2bool(value, ignorecase=False)
Function to convert a string representation of
truth to True or False.
:param str value: value to convert.
:param bool ignorecase: Uppercase/lowercase letters of given "value" are ignored.
:raise: "ValueError" if "value" is anything else.
:rtype: bool
Examples:
from pymince.boolean import string2bool
string2bool("true") # --> True
string2bool("false") # --> False
string2bool("TRUE") # --> ValueError
string2bool("TRUE", ignorecase=True) # --> True
string2bool("FALSE") # --> ValueError
string2bool("FALSE", ignorecase=True) # --> False
```
#### dates.py
##### IsoWeekDay
```
IsoWeekDay(value, names=None, *, module=None, qualname=None, type=None, start=1)
Python Enum containing Days of the Week, according to ISO,
where Monday == 1 ... Sunday == 7.
Provides a 'of' method can be used to verbalize a datetime.datetime.isoweekday
return value.
Example:
from pymince.dates import IsoWeekDay
friday = datetime.datetime(2023, 2, 17)
IsoWeekDay.of(friday) # pymince.dates.IsoWeekDay.FRIDAY
```
##### WeekDay
```
WeekDay(value, names=None, *, module=None, qualname=None, type=None, start=1)
Python Enum containing Days of the Week,
where Monday == 0 ... Sunday == 6.
Provides a 'of' method can be used to verbalize a datetime.datetime.weekday
return value.
Example:
from pymince.dates import WeekDay
friday = datetime.datetime(2023, 2, 17)
WeekDay.of(friday) # pymince.dates.WeekDay.FRIDAY
```
##### irange
```
irange(start_date, stop_date=None, time_step=None)
Returns a generator that produces a sequence of datetime's from "start_date" (inclusive)
to "stop_date" (exclusive) by "time_step".
:param datetime.datetime start_date: Inclusive.
:param datetime.datetime stop_date: Exclusive. `utcnow` is used by default.
:param datetime.delta time_step: one-day `timedelta` is used by default.
Examples:
import datetime
from pymince.dates import irange
ini = datetime.datetime.fromisoformat("2022-10-31")
end = datetime.datetime.fromisoformat("2022-11-02")
day = datetime.timedelta(days=1)
it = irange(ini, stop_date=end, time_step=day)
next(it) # --> datetime.datetime(2022, 10, 31, 0, 0)
next(it) # --> datetime.datetime(2022, 11, 1, 0, 0)
next(it) # --> raise StopIteration
```
##### string2year
```
string2year(value, gte=None, lte=None, shift=None)
Function to convert a string year representation to integer year.
:param str value: Value to convert.
:param Optional[int] gte: if it is specified is required that: year >= gte
:param Optional[int] lte: if it is specified is required that: year <= lte
:param Optional[int] shift: use a two-digit year on shift
:raise: "ValueError" if "value" cannot be converted.
:rtype: int
Examples:
from pymince.dates import string2year
string2year("53", shift=None) # --> 2053
string2year("53", shift=1953) # --> 1953
string2year("52", shift=1953) # --> 2052
string2year("54", shift=1953) # --> 1954
string2year("1954") # --> 1954
string2year("123") # --> ValueError
string2year("1955", gte=1956) # --> ValueError
string2year("1955", lte=1954) # --> ValueError
```
#### dictionary.py
Useful functions that use dictionaries.
##### DigestGetter
```
DigestGetter(include_keys=None, exclude_keys=None)
Calculate a digest of a "jsonified" python dictionary.
:param include_keys: dictionary keys to exclude
:param exclude_keys: dictionary keys to include
:rtype: str
Examples:
from pymince.dictionary import DigestGetter
getter = DigestGetter(include_keys=("a",))
getter({"a": 1, "b": 1}) # --> bb6cb5c68df4652941caf652a366f2d8
getter({"a": 1}) # --> bb6cb5c68df4652941caf652a366f2d8
```
##### all_true_values
```
all_true_values(dictionary, keys)
Check if a dictionary has all the specified keys and if all its
evaluated key-related values are True.
:param dict dictionary:
:param keys: keys sequence
:rtype: bool
Examples:
from pymince.dictionary import all_true_values
all_true_values({"a": 1, "b": 2}, ("a", "b")) # --> True
all_true_values({"a": 1, "b": 0}, ("a", "b")) # --> False
all_true_values({"a": 1, "b": 0}, ("a",)) # --> True
```
##### find_leaf_value
```
find_leaf_value(key, dictionary)
Find leaf value in mapping.
:param Any key: key to find
:param dict dictionary:
Examples:
from pymince.dictionary import find_leaf_value
find_leaf_value('a', {}) # --> 'a'
find_leaf_value('a', {'a': 'b', 'b': 'c'}) # --> 'c'
find_leaf_value('a', {'a': 'a'}) # --> 'a'
```
##### from_objects
```
from_objects(iterable, key_getter, value_getter)
Create a new dictionary with elements generated from
the "key_getter" and "value_getter" callbacks applied to each element of the iterable.
:param Iterable[any] iterable:
:param Callable key_getter:
Dictionary keys getter.
It is called with each element of "iterable" passing it as an argument.
:param Callable value_getter:
Dictionary values getter.
It is called with each element of "iterable" passing it as an argument.
:raise: ValueError if any generated key is duplicate.
:rtype: dict
Examples:
from pymince.dictionary import from_objects
keygetter = operator.itemgetter(0)
valgetter = operator.itemgetter(1, 2)
values = iter([(1, "a", "b"), (2, "a", "b")])
from_objects(values, keygetter, valgetter) # --> {1: ('a', 'b'), 2: ('a', 'b')}
```
##### frozendict
```
frozendict(*args, **kwargs)
Returns a "MappingProxyType" from a dictionary built according to given parameters.
Add immutability only on a first level.
Examples:
from pymince.dictionary import frozendict
my_dict = frozendict(a=1, b=2)
my_dict["a"] # --> 1
list(my_dict.items()) # --> [("a", 1), ("b", 2)]
my_dict["c"] = 3 # --> TypeError
```
##### tree
```
tree()
Returns a dict whose defaults are dicts.
As suggested here: https://gist.github.com/2012250
Examples:
import json
from pymince.dictionary import tree
users = tree()
users['user1']['username'] = 'foo'
users['user2']['username'] = 'bar'
print(json.dumps(users)) # {"user1": {"username": "foo"}, "user2": {"username": "bar"}}
```
#### file.py
##### decompress
```
decompress(src_path, dst_path, size=65536)
Decompress the given compressed file in blocks based on its extension format.
Supports compression formats: gzip => (.gz), bzip2 => (.bz2), xz => (.xz)
:param str src_path: source file path
:param str dst_path: destination file(unzipped) path
:param int size: Read up to size bytes from src_path for each block.
:return: dst_path
Examples:
from pymince.file import decompress
decompress("/foo/src.txt.gz", "/baz/dst.txt") # --> "/baz/dst.txt"
decompress("/foo/src.txt.bz2", "/baz/dst.txt") # --> "/baz/dst.txt"
decompress("/foo/src.txt.xz", "/baz/dst.txt") # --> "/baz/dst.txt"
```
##### ensure_directory
```
ensure_directory(path, cleaning=False)
Make sure the given file path is an existing directory.
If it does not exist, a new directory will be created.
:param str path:
:param bool cleaning:
If "cleaning" is True and a directory already exists,
this directory and the files contained in it will be deleted.
If "cleaning" is True and a file already exists,
this file will be deleted.
```
##### get_valid_filename
```
get_valid_filename(s)
Returns a valid filename for the given string.
- Remove leading/trailing spaces
- Change spaces to underscores
- Remove anything that is not an alphanumeric, dash, underscore, or dot
```
##### is_empty_directory
```
is_empty_directory(path)
Check if the given path is an empty directory.
```
##### match_from_zip
```
match_from_zip(zip_file, pattern)
Make an iterator that returns file names in the zip file that
match the given pattern.
Uppercase/lowercase letters are ignored.
:param zip_file: ZipFile object or zip path.
:param pattern: "re.Pattern" to filter filename list
:return: Iterator with the filenames found
Examples:
import pymince.file
pymince.file.match_from_zip("archive.zip", "^file") # --> file1.log file2.txt
pymince.file.match_from_zip(zipfile.ZipFile("archive.zip"), "^file") # --> file1.log file2.txt
```
##### replace_extension
```
replace_extension(filename, old_ext=None, new_ext=None)
Replace filename "old_ext" with "new_ext".
:param str filename:
:param Optional[str] old_ext:
:param Optional[str] new_ext:
Examples:
from pymince.file import replace_extension
# remove extensions
replace_extension("/home/user/file.old") # --> "/home/user/file"
replace_extension("/home/user/file.old", old_ext=".old") # --> "/home/user/file"
replace_extension("/home/user/file.old", old_ext=".new") # --> "/home/user/file.old"
# replace extensions
replace_extension("/home/user/file.old", new_ext=".new") # --> "/home/user/file.new"
replace_extension("/home/user/file.old", old_ext=".old", new_ext=".new") # --> "/home/user/file.new"
replace_extension("/home/user/file.old", old_ext=".new", new_ext=".new") # --> "/home/user/file.old"
```
##### xopen
```
xopen(name, mode='rb', encoding=None)
Open compressed files in Python based on their file extension.
- Supports compression formats: gzip => (.gz), bzip2 => (.bz2), xz => (.xz)
- If the file extension is not recognized, the file will be opened without compression.
- When text mode is required, UTF-8 encoding is used by default.
```
#### functional.py
##### caller
```
caller(*args, **kwargs)
Return a callable that calls with given params.
Examples:
import pymince.functional
caller = pymince.functional.caller(range(5))
caller(len) # 5
caller(list) # [0, 1, 2, 3, 4]
```
##### classproperty
```
classproperty(method=None)
Decorator that converts a method with a single cls argument into a property
that can be accessed directly from the class.
Examples:
from pymince.functional import classproperty
class MyClass:
__foo = "var"
@classproperty
def foo(cls):
return cls.__foo
```
##### identity
```
identity(x)
Takes a single argument and returns it unchanged.
Identity function, as defined in https://en.wikipedia.org/wiki/Identity_function.
```
##### once
```
once(fn)
Decorator to execute a function only once.
Examples:
from pymince.functional import once
@once
def inc_once():
global n
n += 1
return 'anything'
n = 0
inc_once() # --> 'anything'
inc_once() # --> 'anything'
inc_once() # --> 'anything'
print(n) # --> 1
```
##### pipe
```
pipe(*fns)
Compose functions from left to right.
:param fns: Functions to compose.
:rtype: Callable[[Any], Any]
Examples:
from pymince.functional import pipe
addtwo = lambda n: n + 2
double = lambda n: n * 2
square = lambda n: n * n
fn = pipe(addtwo, double, square)
fn(1) # --> 36
```
##### retry_if_errors
```
retry_if_errors(*exceptions, delay=0, tries=1)
Decorator that retries to call the wrapped function
if any of given exceptions are thrown.
:param exceptions: Lists of exceptions that trigger a retry attempt.
:param int delay: seconds delay between attempts. default: 0.
:param int tries: number of attempts. default: 1
Examples:
@retry_if_errors(ValueError, TypeError, delay=0, tries=1)
def foo():
return 1
```
##### retry_if_none
```
retry_if_none(delay=0, tries=1)
Decorator that retries to call the wrapped function
if it returns None.
:param int delay: seconds delay between attempts. default: 0.
:param int tries: number of attempts. default: 1
Examples:
@retry_if_none(delay=0, tries=1)
def foo():
return 1
```
##### set_attributes
```
set_attributes(**kwargs)
Decorator to set attributes on functions and classes.
Examples:
from pymince.functional import set_attributes
@set_attributes(short_description="dummy function")
def foo():
pass
print(foo.short_description) # "dummy function"
Based on: https://github.com/wolph/python-utils/ (set_attributes)
```
##### suppress
```
suppress(*exceptions, default=None)
Decorator to suppress the specified exceptions and return the
default value instead.
Examples:
from pymince.functional import suppress
@suppress(FileNotFoundError, default=False)
def remove(somefile):
os.remove(somefile)
remove("no_found.txt") # False
```
#### iterator.py
Functions that use iterators for efficient loops.
##### all_distinct
```
all_distinct(iterable, key=None)
Check if all the elements of a key-based iterable are distinct.
:param iterable:
:param key: None or "Callable" to compare if iterable items.
:rtype: bool
Examples:
from pymince.iterator import all_distinct
all_distinct([1, 1]) # --> False
all_distinct([1, 2]) # --> True
```
##### all_equal
```
all_equal(iterable, key=None)
Check if all the elements of a key-based iterable are equals.
:param iterable:
:param key: None or "Callable" to compare if iterable items.
:rtype: bool
Examples:
from pymince.iterator import all_equal
all_equal([1, 1]) # --> True
all_equal([1, 2]) # --> False
```
##### all_equals
```
all_equals(*iterables, key=None)
Check if the iterables are equal.
If the "iterables" are empty, it returns True.
:param iterables:
:param key: None or "Callable" to compare if iterable items.
:rtype: bool
Examples:
from pymince.iterator import all_equals
all_equals() # --> True
all_equals(range(1, 4), (1, 2, 3), {1, 2, 3}) # --> True
all_equals((1, 2), (1, 2, 3)) # --> False
```
##### all_identical
```
all_identical(left, right)
Check that the items of `left` are the same objects
as those in `right`.
:param Iterable[Any] left:
:param Iterable[Any] right:
:rtype: bool
Examples:
from pymince.iterator import all_identical
a, b = object(), object()
all_identical([a, b, a], [a, b, a]) # --> True
all_identical([a, b, [a]], [a, b, [a]]) # --> False *new list object, while "equal" is not "identical"*
```
##### centroid
```
centroid(coordinates)
Calculate the centroid of a set of n-dimensional coordinates.
In Cartesian coordinates, the centroid is
just the mean of the components.
:param Iterable[Iterable[int]] coordinates: Iterable of n-dimensional coordinates.
:rtype: Generator[int]
Examples:
from pymince.iterator import centroid
coord = (((2, 2), (4, 4)))
tuple(centroid(coord)) # --> (3, 3)
```
##### consume
```
consume(iterator, n=None)
Advance *iterator* by *n* steps. If *n* is ``None``, consume it
entirely.
Examples:
from pymince.iterator import consume
it = iter([1, 2])
consume(it)
next(it) # --> StopIteration
```
##### grouper
```
grouper(iterable, size)
Make a generator that returns each element being iterable
with "size" as the maximum number of elements.
:param iterable:
:param int size: maximum size of element groups.
:rtype: Generator
Examples:
from pymince.iterator import grouper
groups = grouper([1, 2, 3, 4, 5], 2)
list(list(g) for g in groups) # --> [[1, 2], [3, 4], [5]]
```
##### ibool
```
ibool(iterable)
Iterator class supporting ´__bool__´.
Examples:
from pymince.iterator import ibool
it = ibool((1, 2, 3))
bool(it) # --> True
list(it) # --> [1, 2, 3]
```
##### in_all
```
in_all(obj, iterables)
Check if the object is contained in all the given iterables.
If the "iterables" are empty, return True.
:param Any obj:
:param iterables: iterable of iterables
:rtype: bool
Examples:
from pymince.iterator import in_all
in_all("a", (("a", "b"), "bcd")) # --> False
in_all("a", (("a", "b"), "abc")) # --> True
in_all("a", ()) # --> True
```
##### in_any
```
in_any(obj, iterables)
Check if the object is contained in any of the given iterables.
:param Any obj:
:param iterables: iterable of iterables
:rtype: bool
Examples:
from pymince.iterator import in_any
in_any("a", (("a", "b"), "bcd")) # --> True
in_any("a", (("b", "b"), "def")) # --> False
in_any("a", ()) # --> False
```
##### ipush
```
ipush(iterable)
Iterator class supporting ´append´ and ´prepend´.
Examples:
from pymince.iterator import ipush
it = ipush(iter([2, 3])
it.append(4)
it.append(5)
it.prepend(1)
it.prepend(0)
list(it) # --> [0, 1, 2, 3, 4, 5]
```
##### mul
```
mul(iterable, start=1)
Return the multiplication of a 'start' value (default: 1)
plus an iterable of numbers.
When the iterable is empty, return the start value.
```
##### only_one
```
only_one(iterable)
Check if given iterable has only one element.
:param iterable:
:rtype: bool
Examples:
from pymince.iterator import only_one
only_one([1]) # --> True
only_one([1, 2]) # --> False
only_one([]) # --> False
```
##### pad_end
```
pad_end(iterable, length, fill_value=None)
The function adds "fill_value" at the finishing of the iterable,
until it reaches the specified length.
If the value of the "length" param is less than the length of
the given "iterable", no filling is done.
:param iterable:
:param int length: A number specifying the desired length of the resulting iterable.
:param Any fill_value: Any value to fill the given iterable.
:rtype: Generator
Examples:
from pymince.iterator import pad_end
pad_end(("a", "b"), 3, fill_value="1") # --> "a" "b" "1"
pad_end(("a", "b"), 3) # --> "a" "b" None
pad_end(("a", "b", "c"), 3) # --> "a" "b" "c"
```
##### pad_start
```
pad_start(iterable, length, fill_value=None)
The function adds "fill_value" at the beginning of the iterable,
until it reaches the specified length.
If the value of the "length" param is less than the length of
the given "iterable", no filling is done.
:param iterable:
:param int length: A number specifying the desired length of the resulting iterable.
:param Any fill_value: Any value to fill the given iterable.
:rtype: Generator
Examples:
from pymince.iterator import pad_start
pad_start(("a", "b"), 3, fill_value="1") # --> "1" "a" "b"
pad_start(("a", "b"), 3) # --> None "a" "b"
pad_start(("a", "b", "c"), 3) # --> "a" "b" "c"
```
##### partition
```
partition(predicate, iterable)
Split the iterable into two lists, based on the boolean return-value
of the predicate.
- (1): items that have predicate(item) == False.
- (2): items that have predicate(item) == True.
Examples:
from pymince.iterator import partition
is_odd = lambda x: x % 2 != 0
even_items, odd_items = partition(is_odd, range(10)) # ([0, 2, 4, 6, 8], [1, 3, 5, 7, 9])
```
##### replacer
```
replacer(iterable, matcher, new_value, count=-1)
Make a generator that yields all occurrences of the old "iterable"
replaced by "new_value".
:param iterable:
:param matcher: Callable to find occurrences. It is an occurrence if the matcher returns True.
:param new_value: Any value to replace found occurrences.
:param int count:
Maximum number of occurrences to replace.
-1 (the default value) means replace all occurrences.
:rtype: Generator
Examples:
from pymince.iterator import replacer
is_one = lambda n: n == 1
replacer([1,2,3,1,2,3], is_one, None) # --> None 2 3 None 2 3
replacer([1,2,3,1,2,3], is_one, None, count=1) # --> None 2 3 1 2 3
```
##### splitter
```
splitter(iterable, sep, key=None, maxsplit=-1, container=None)
Splits an iterable based on a separator.
A separator will never appear in the output.
:param iterable:
:param sep: The delimiter to split the iterable.
:param key
A function to compare the equality of each element with the given delimiter.
If the key function is not specified or is None, the element itself is used for compare.
:param maxsplit:
Maximum number of splits to do.
-1 (the default value) means no limit.
:param container: Callable to save the splits. By default tuple is used.
:return: Generator with consecutive splits of "iterable" without the delimiter item.
Examples:
from pymince.iterator import splitter
data = ("a", "b", "c", "d", "b", "e")
split_n = splitter(data, "b") # --> ("a",) ("c", "d") ("e",)
split_1 = splitter(data, "b", maxsplit=1) # --> ("a",) ("c", "d", "b", "e")
```
##### sub
```
sub(iterable)
Return the subtraction of a non-empty iterable of numbers and sets.
```
##### truediv
```
truediv(iterable)
Return the division of an non-empty iterable of numbers.
```
##### uniquer
```
uniquer(iterable, key=None)
Make a generator that returns each element from iterable only once
respecting the input order.
Examples:
from pymince.iterator import uniquer
uniquer([1, 2, 3, 2]) # --> 1 2 3
```
##### uniques
```
uniques(iterable, key=None)
Check if all the elements of a key-based iterable are unique.
:param iterable:
:param key: None or "Callable" to compare if iterable items.
:rtype: bool
Examples:
from pymince.iterator import uniques
uniques([1,2]) # --> True
uniques([1,1]) # --> False
```
#### json.py
Useful functions for working with JSONs.
- Supports `orjson`, `ujson` libraries or standard `json`.
- Supports following compression formats: gzip => (.gz), bzip2 => (.bz2), xz => (.xz)
##### JSONEncoder
```
JSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)
JSON encoder that handles additional types compared
to `json.JSONEncoder`
- `datetime` and `date` are serialized to strings according to the isoformat.
- `decimal.Decimal` is serialized to a string.
- `uuid.UUID` is serialized to a string.
- `dataclasses.dataclass` is passed to `dataclasses.asdict`.
- `frozenset` and `set` are serialized by ordering their values.
```
##### dump_from_csv
```
dump_from_csv(csv_path, json_path, /, *, fieldnames=None, start=0, stop=None, strip=True, encoding='utf-8', **kwargs)
Dump CSV file to a JSON file.
- Use (`.gz`, `.xz`, `.bz2`) extensions to create a compressed file.
- Dumps falls back to the functions: (`orjson.dumps`, `ujson.dumps`, and `json.dumps`).
:param str csv_path:
:param str json_path:
:param fieldnames: list of keys for the JSON
:param int start:
If start is specified, will skip all preceding elements;
otherwise, start defaults to zero.
:param int stop:
:param bool strip:
Whether white space should be removed from the
beginning and end of field values.
:param str encoding: utf-8 is used by default.
```
##### dump_into
```
dump_into(filename, obj, encoding='utf-8', **kwargs)
Dump JSON to a file.
- Use (`.gz`, `.xz`, `.bz2`) extensions to create compressed files.
- Dumps falls back to the functions: (`orjson.dump`, `ujson.dump`, and `json.dump`).
Examples:
from pymince.json import dump_into
dump_into("foo.json", {"key": "value"}) # uncompressed
dump_into("foo.json.gz", {"key": "value"}) # gzip-compressed
dump_into("foo.json.xz", {"key": "value"}) # lzma-compressed
dump_into("foo.json.bz2", {"key": "value"}) # bz2-compressed
```
##### dump_into_zip
```
dump_into_zip(zip_path, arcname, payload, **kwargs)
Dump JSON into the zip archive under the name arcname.
Examples:
from pymince.json import dump_into_zip
dump_into_zip("archive.zip", "foo.json", {"key": "value"})
```
##### idump_fork
```
idump_fork(path_items, encoding='utf-8', dump_if_empty=True, **dumps_kwargs)
Incrementally dumps different groups of elements into
the indicated JSON file.
*** Useful to reduce memory consumption ***
- Use (`.gz`, `.xz`, `.bz2`) extensions to create compressed files.
- Dumps falls back to the functions: (`orjson.dumps`, `ujson.dumps`, and `json.dumps`).
:param Iterable[file_path, Iterable[dict]] path_items: group items by file path
:param encoding: 'utf-8' by default.
:param bool dump_if_empty: If false, don't create an empty file.
:param dumps_kwargs: json.dumps kwargs.
Examples:
from pymince.json import idump_fork
path_items = (
("num.json.gz", ({"value": 1}, {"value": 2})),
("num.json.gz", ({"value": 3},)),
("foo.json", ({"a": "1"}, {"b": 2})),
("baz.json", ()),
)
idump_fork(iter(path_items))
```
##### idump_into
```
idump_into(filename, iterable, encoding='utf-8', **kwargs)
Dump an iterable incrementally into a JSON file.
- Use (`.gz`, `.xz`, `.bz2`) extensions to create compressed files.
- Dumps falls back to the functions: (`orjson.dumps`, `ujson.dumps`, and `json.dumps`).
The result will always be an array with the elements of the iterable.
*** Useful to reduce memory consumption ***
Examples:
from pymince.json import idump_into
values = ([{"key": "foo"}, {"key": "bar"}])
idump_into("foo.json", values) # uncompressed
idump_into("foo.json.gz", values) # gzip-compressed
idump_into("foo.json.xz", values) # lzma-compressed
idump_into("foo.json.bz2", values) # bz2-compressed
```
##### idump_lines
```
idump_lines(iterable, **dumps_kwargs)
Generator yielding string lines that form a JSON array
with the serialized elements of given iterable.
*** Useful to reduce memory consumption ***
- Dumps falls back to the functions: (`orjson.dumps`, `ujson.dumps`, and `json.dumps`).
:param iterable: Iterable[dict]
:rtype: Iterable[str]
```
##### load
```
load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
a JSON document) to a Python object.
``object_hook`` is an optional function that will be called with the
result of any object literal decode (a ``dict``). The return value of
``object_hook`` will be used instead of the ``dict``. This feature
can be used to implement custom decoders (e.g. JSON-RPC class hinting).
``object_pairs_hook`` is an optional function that will be called with the
result of any object literal decoded with an ordered list of pairs. The
return value of ``object_pairs_hook`` will be used instead of the ``dict``.
This feature can be used to implement custom decoders. If ``object_hook``
is also defined, the ``object_pairs_hook`` takes priority.
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
kwarg; otherwise ``JSONDecoder`` is used.
```
##### load_from
```
load_from(filename, encoding='utf-8')
Load JSON from a file.
- Recognizes (`.gz`, `.xz`, `.bz2`) extensions to load compressed files.
- Loads falls back to the functions: (`orjson.load`, `ujson.load`, and `json.load`).
Examples:
from pymince.json import load_from
dictionary1 = load_from("foo.json") # uncompressed
dictionary2 = load_from("foo.json.gz") # gzip-compressed
dictionary3 = load_from("foo.json.xz") # lzma-compressed
dictionary4 = load_from("foo.json.bz2") # bz2-compressed
```
##### load_from_zip
```
load_from_zip(zip_path, arcname)
Load JSON from a file named "arcname" inside a zip archive.
Examples:
from pymince.json import load_from_zip
dictionary = load_from_zip("archive.zip", "foo.json")
```
#### logging.py
##### ColoredFormatter
```
ColoredFormatter(fmt=None, datefmt=None, style='%', validate=True)
A class for formatting colored logs.
Default colors:
- DEBUG: blue
- INFO: green
- WARNING: yellow
- ERROR: red
- CRITICAL: red
Examples:
import logging
from pymince.logging import ColoredFormatter
# Config
logger = logging.getLogger('mylog')
logger.setLevel('DEBUG')
stream_handler = logging.StreamHandler()
stream_handler.setFormatter(ColoredFormatter(logging.BASIC_FORMAT))
logger.addHandler(stream_handler)
# Use default colors
logger.debug("This is debug") # blue color
# Use custom colors
import colorama
logger.debug("This is debug", extra={"color": colorama.Fore.BLACK})
```
##### ColoredLogger
```
ColoredLogger(name=None, level=10, **fmt_kwargs)
Custom logger to generate color logs.
Examples:
from pymince.logging import ColoredLogger
logger = ColoredLogger()
# Use default colors
logger.debug("This is debug") # blue color
# Use custom colors
import colorama
logger.debug("This is debug", extra={"color": colorama.Fore.BLACK})
```
##### StructuredFormatter
```
StructuredFormatter(fmt=None, datefmt=None, style='%', validate=True)
Implementation of JSON structured logging that works
for most handlers.
Examples:
import logging
import sys
from pymince.logging import StructuredFormatter
# Config
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
formatter = StructuredFormatter('%(message)s')
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)
handler.setFormatter(formatter)
logger.addHandler(handler)
# Usage
logger.debug('', {"string": "value1", "number": 1})
logger.debug('', {"string": "value2", "number": 2})
>>Output<<
{"timestamp":"2022-06-17 18:37:48,789","level":"DEBUG","payload":{"string":"value1","number":1}}
{"timestamp":"2022-06-17 18:37:48,789","level":"DEBUG","payload":{"string":"value2","number":2}}
```
##### timed_block
```
timed_block(name, logger=None)
Log the duration of the handled context.
Examples:
import logging
from pymince.logging import timed_block
logging.basicConfig(level=logging.DEBUG)
with timed_block("sleeping"):
time.sleep(1)
>>Output<<
INFO:root:Generating [sleeping]
DEBUG:root:Finished [sleeping in 1.002 s]
```
#### std.py
##### bind_json_std
```
bind_json_std(encoding='utf-8')
Decorator to call "function" passing the json read from
"stdin" in the keyword parameter "data" and dump the json that the callback returns
to "stdout".
Examples:
from pymince.std import bind_json_std
@bind_json_std()
def foo(data=None):
print("Processing data from sys.stdin", data)
result = data and {**data, "new": "value"}
print("Result to write in sys.stdout", result)
return result
```
#### text.py
Useful functions for working with strings.
##### are_anagram
```
are_anagram(text1, text2)
Check if two strings are anagram.
Examples:
from pymince.text import are_anagram
are_anagram("listen", "silent") # --> True
are_anagram("they see", "the eyes") # --> True
```
##### get_random_secret
```
get_random_secret(length, alphabet='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
Generate a cryptographically secure random string.
Useful for creating temporary passwords.
```
##### get_random_string
```
get_random_string(length, alphabet='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
Generate random string.
```
##### is_binary
```
is_binary(text)
Check if the string is binary or not.
```
##### is_email_address
```
is_email_address(text)
Check if the string is an email address.
This solution does a very simple check. It only validates that the string contains an at sign (@)
that is preceded and followed by one or more non whitespace characters.
```
##### is_int
```
is_int(text)
Check if the string is the representation of
a integer number.
True: "10", "+10", "-10", "0"
```
##### is_negative_int
```
is_negative_int(text)
Check if the string is the representation of
negative integer number.
True: "-10"
```
##### is_palindrome
```
is_palindrome(text)
Check if the string is palindrome or not.
A string is said to be palindrome if the reverse of the string is the same as string
```
##### is_payment_card
```
is_payment_card(text)
Check if the string is a valid payment
card number.
https://en.wikipedia.org/wiki/Payment_card_number#Issuer_identification_number_(IIN)
```
##### is_percentage
```
is_percentage(text)
Check if the string is a valid percentage
True: "100%", "100 %", "100 %", 100.0 %",
```
##### is_positive_int
```
is_positive_int(text)
Check if the string is the representation of
positive integer number.
True: "10", "+10"
```
##### is_roman
```
is_roman(text)
Check if the string is a valid roman numeral.
```
##### is_url
```
is_url(text, schemes=None, hostnames=None)
Check if the string is a URL according to the
given schemes and host-names.
:param str text:
:param Optional[Container[str]] schemes: ("http", "https")
:param Optional[Container[str]] hostnames: ("www.python.org", "github.com", "localhost")
:rtype: bool
Examples:
from pymince.text import is_url
# True
is_url("https://github.com/")
is_url("https://github.com/", hostnames=("github.com",))
is_url("https://github.com/", hostnames=("github.com",), schemes=("https",))
# False
is_url("https://github.com/", schemes=("http",))
is_url("https://github.com/", hostnames=("www.python.org", "localhost"))
```
##### multireplace
```
multireplace(text, replacements)
Given a string and a replacement map, it returns the replaced string.
:param str text: string to execute replacements on.
:param Union[dict[str, str], tuple[tuple[str, str], ...] replacements:
2-dict or 2-tuples with value to find and value to replace
:rtype: str
Examples:
from pymince.text import multireplace
mapping = {",": "", "cry": "smile"}
multireplace("No, woman, no cry", mapping) # --> "No woman no smile"
```
##### multireplacer
```
multireplacer(replacements)
Given a replacement map, returns a function that can be reused to replace any string.
:param Union[dict[str, str], tuple[tuple[str, str], ...] replacements:
2-dict or 2-tuples with value to find and value to replace
:rtype: Callable[[str], str]
Examples:
from pymince.text import multireplacer
mapping = (("abc", "123"), ("def", "456"))
replace = multireplacer(mapping)
replace("...def...") # --> "...456..."
replace("...abc...") # --> "...123..."
replace("...abc...def...") # --> "...123...456..."
```
##### normalize_newlines
```
normalize_newlines(s)
Normalize CRLF and CR newlines to just LF.
```
##### remove_decimal_zeros
```
remove_decimal_zeros(value, decimal_sep='.', min_decimals=None)
Removes non-significant decimal zeros from a formatted text number.
Examples:
from pymince.text import remove_decimal_zeros
remove_decimal_zeros("2.000100", ".") # --> "2.0001"
remove_decimal_zeros("2.000000", ".") # --> "2"
remove_decimal_zeros("2.000000", ".", min_decimals=2) # --> "2.00"
```
##### remove_number_commas
```
remove_number_commas(s)
Removes commas from a formatted text number having commas
as group separator.
:param str s:
:rtype str
Examples:
from pymince.text import remove_number_commas
remove_number_commas('1,234,567.8') # --> '1234567.8'
```
##### replace
```
replace(value, old_values, new_value, count=-1)
Replace matching values in the given string with new_value.
:param str value:
:param old_values: iterable of values to replace.
:param str new_value: replacement value.
:param int count:
Maximum number of occurrences to replace.
-1 (the default value) means replace all occurrences.
:rtype: str
Examples:
from pymince.text import replace
replace("No, woman, no cry", [","], ";") # --> "No; woman; no cry"
replace("No, woman, no cry", [","], ";", count=1) # --> "No; woman, no cry"
```
##### slugify
```
slugify(value, allow_unicode=False)
Convert to ASCII if 'allow_unicode' is False. Convert spaces or repeated
dashes to single dashes. Remove characters that aren't alphanumerics,
underscores, or hyphens. Convert to lowercase. Also strip leading and
trailing whitespace, dashes, and underscores.
https://github.com/django/django/blob/main/django/utils/text.py
```
#### warnings.py
##### deprecated
```
deprecated(fn)
This is a decorator which can be used to mark functions
as deprecated. It will result in a warning being emitted
when the function is used.
http://code.activestate.com/recipes/391367-deprecated/?in=lang-python
Examples:
from pymince.warnings import deprecated
@deprecated
def check_function():
pass
class SomeClass:
@deprecated
def check_method(self):
pass
@deprecated
class CheckClass:
pass
>> check_function() # DeprecationWarning --> 'Deprecated "check_function".'
>> SomeClass().check_method() # DeprecationWarning --> 'Deprecated "check_method".'
>> CheckClass() # DeprecationWarning --> 'Deprecated "CheckClass".'
```
#### xml.py
##### iterparse
```
iterparse(filename)
Incrementally parse XML document into ElementTree.
This function is based on: https://github.com/python/cpython/issues/93618
'Fix misleading hint for original ElementTree.iterparse.'
'''
The code below deletes a root child once it is completed, then processes and removes
it from the memory (if nothing more references to it ofc).
This allows to process 7GB XML with with a memory usage up to 10MB (in case of great number of root children).
'''
:param str filename: XML filename
:rtype: Generator
Examples:
from pymince.xml import iterparse
for event, obj in iterparse("countries.xml")
if event == 'start'
print(obj, obj.tag, obj.attrib, obj.text)
>>Output<<
<Element 'country' at 0x0000018ADF9D0CC0> country {'code': 'as', 'iso': '16'} American Samoa
<Element 'country' at 0x0000018ADF9D0C70> country {'code': 'ad', 'iso': '20'} Andorra
```
### Upgrade README.md
Upgrade README.md `Usage` section according to current *pymince* code.
```
(env) python upgrade_readme_usage.py
```
Raw data
{
"_id": null,
"home_page": "https://github.com/rmoralespp/pymince",
"name": "pymince",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": null,
"author": "rmoralespp",
"author_email": "rmoralespp@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/12/5d/72df3850a3761e7e6b70736a279fb4f9ff6fa721bd5f9b1998778fdb992e/pymince-2.11.1.tar.gz",
"platform": null,
"description": "# pymince\n\n[![CI](https://github.com/rmoralespp/pymince/workflows/CI/badge.svg)](https://github.com/rmoralespp/pymince/actions?query=event%3Arelease+workflow%3ACI)\n[![pypi](https://img.shields.io/pypi/v/pymince.svg)](https://pypi.python.org/pypi/pymince)\n[![versions](https://img.shields.io/pypi/pyversions/pymince.svg)](https://github.com/rmoralespp/pymince)\n[![codecov](https://codecov.io/gh/rmoralespp/pymince/branch/main/graph/badge.svg)](https://app.codecov.io/gh/rmoralespp/pymince)\n[![license](https://img.shields.io/github/license/rmoralespp/pymince.svg)](https://github.com/rmoralespp/pymince/blob/main/LICENSE)\n[![Downloads](https://pepy.tech/badge/pymince)](https://pepy.tech/project/pymince)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Linter: ruff](https://img.shields.io/badge/linter-_ruff-orange)](https://github.com/charliermarsh/ruff)\n[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)\n\n### About\n\npymince is a collection of useful tools that are \"missing\" from the Python standard library.\n\n### Installation (via pip)\n\n```pip install pymince```\n\n### Tests\n\n```\n(env)$ pip install -r requirements.txt # Ignore this command if it has already been executed\n(env)$ pytest tests/\n(env)$ pytest --cov pymince # Tests with coverge\n```\n\n### Usage\n| PyModules | Tools |\n| :-------- | :----- |\n| **algorithm.py** |[*fibonacci*](#fibonacci), [*luhn*](#luhn), [*sieve_of_eratosthenes*](#sieve_of_eratosthenes)|\n| **boolean.py** |[*string2bool*](#string2bool)|\n| **dates.py** |[*IsoWeekDay*](#IsoWeekDay), [*WeekDay*](#WeekDay), [*irange*](#irange), [*string2year*](#string2year)|\n| **dictionary.py** |[*DigestGetter*](#DigestGetter), [*all_true_values*](#all_true_values), [*find_leaf_value*](#find_leaf_value), [*from_objects*](#from_objects), [*frozendict*](#frozendict), [*tree*](#tree)|\n| **file.py** |[*decompress*](#decompress), [*ensure_directory*](#ensure_directory), [*get_valid_filename*](#get_valid_filename), [*is_empty_directory*](#is_empty_directory), [*match_from_zip*](#match_from_zip), [*replace_extension*](#replace_extension), [*xopen*](#xopen)|\n| **functional.py** |[*caller*](#caller), [*classproperty*](#classproperty), [*identity*](#identity), [*once*](#once), [*pipe*](#pipe), [*retry_if_errors*](#retry_if_errors), [*retry_if_none*](#retry_if_none), [*set_attributes*](#set_attributes), [*suppress*](#suppress)|\n| **iterator.py** |[*all_distinct*](#all_distinct), [*all_equal*](#all_equal), [*all_equals*](#all_equals), [*all_identical*](#all_identical), [*centroid*](#centroid), [*consume*](#consume), [*grouper*](#grouper), [*ibool*](#ibool), [*in_all*](#in_all), [*in_any*](#in_any), [*ipush*](#ipush), [*mul*](#mul), [*only_one*](#only_one), [*pad_end*](#pad_end), [*pad_start*](#pad_start), [*partition*](#partition), [*replacer*](#replacer), [*splitter*](#splitter), [*sub*](#sub), [*truediv*](#truediv), [*uniquer*](#uniquer), [*uniques*](#uniques)|\n| **json.py** |[*JSONEncoder*](#JSONEncoder), [*dump_from_csv*](#dump_from_csv), [*dump_into*](#dump_into), [*dump_into_zip*](#dump_into_zip), [*idump_fork*](#idump_fork), [*idump_into*](#idump_into), [*idump_lines*](#idump_lines), [*load*](#load), [*load_from*](#load_from), [*load_from_zip*](#load_from_zip)|\n| **logging.py** |[*ColoredFormatter*](#ColoredFormatter), [*ColoredLogger*](#ColoredLogger), [*StructuredFormatter*](#StructuredFormatter), [*timed_block*](#timed_block)|\n| **std.py** |[*bind_json_std*](#bind_json_std)|\n| **text.py** |[*are_anagram*](#are_anagram), [*get_random_secret*](#get_random_secret), [*get_random_string*](#get_random_string), [*is_binary*](#is_binary), [*is_email_address*](#is_email_address), [*is_int*](#is_int), [*is_negative_int*](#is_negative_int), [*is_palindrome*](#is_palindrome), [*is_payment_card*](#is_payment_card), [*is_percentage*](#is_percentage), [*is_positive_int*](#is_positive_int), [*is_roman*](#is_roman), [*is_url*](#is_url), [*multireplace*](#multireplace), [*multireplacer*](#multireplacer), [*normalize_newlines*](#normalize_newlines), [*remove_decimal_zeros*](#remove_decimal_zeros), [*remove_number_commas*](#remove_number_commas), [*replace*](#replace), [*slugify*](#slugify)|\n| **warnings.py** |[*deprecated*](#deprecated)|\n| **xml.py** |[*iterparse*](#iterparse)|\n\n#### algorithm.py\n\n##### fibonacci\n```\nfibonacci(n=None)\n\nReturns a generator with fibonacci series up to n.\nRuns indefinitely if n is specified as None.\n\n:param Optional[int] n: Must be None or number.\n:rtype: Generator[int]\n```\n##### luhn\n```\nluhn(value: str) -> bool\n\nThe Luhn algorithm or Luhn formula, also known as the \"modulus 10\" or \"mod 10\" algorithm,\nnamed after its creator, IBM scientist Hans Peter Luhn,\nis a simple checksum formula used to validate a variety of\nidentification numbers, such as credit card numbers, IMEI numbers, National Provider Identifier numbers\n\nBased on: https://en.wikipedia.org/wiki/Luhn_algorithm\n```\n##### sieve_of_eratosthenes\n```\nsieve_of_eratosthenes(n)\n\nPrimes less than n.\nBased on: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes\n\n:param int n: n an integer n > 1\n:rtype: Generator[int]. All prime numbers from 2 through n.\n\nExamples:\n from pymince.algorithm import sieve_of_eratosthenes as primes\n primes(30) # --> 2, 3, 5, 7, 11, 13, 17, 19, 23, 29\n```\n#### boolean.py\n\n##### string2bool\n```\nstring2bool(value, ignorecase=False)\n\nFunction to convert a string representation of\ntruth to True or False.\n\n:param str value: value to convert.\n:param bool ignorecase: Uppercase/lowercase letters of given \"value\" are ignored.\n\n:raise: \"ValueError\" if \"value\" is anything else.\n:rtype: bool\n\nExamples:\n from pymince.boolean import string2bool\n\n string2bool(\"true\") # --> True\n string2bool(\"false\") # --> False\n\n string2bool(\"TRUE\") # --> ValueError\n string2bool(\"TRUE\", ignorecase=True) # --> True\n\n string2bool(\"FALSE\") # --> ValueError\n string2bool(\"FALSE\", ignorecase=True) # --> False\n```\n#### dates.py\n\n##### IsoWeekDay\n```\nIsoWeekDay(value, names=None, *, module=None, qualname=None, type=None, start=1)\n\nPython Enum containing Days of the Week, according to ISO,\nwhere Monday == 1 ... Sunday == 7.\n\nProvides a 'of' method can be used to verbalize a datetime.datetime.isoweekday\nreturn value.\n\nExample:\n from pymince.dates import IsoWeekDay\n\n friday = datetime.datetime(2023, 2, 17)\n IsoWeekDay.of(friday) # pymince.dates.IsoWeekDay.FRIDAY\n```\n##### WeekDay\n```\nWeekDay(value, names=None, *, module=None, qualname=None, type=None, start=1)\n\nPython Enum containing Days of the Week,\nwhere Monday == 0 ... Sunday == 6.\n\nProvides a 'of' method can be used to verbalize a datetime.datetime.weekday\nreturn value.\n\nExample:\n from pymince.dates import WeekDay\n\n friday = datetime.datetime(2023, 2, 17)\n WeekDay.of(friday) # pymince.dates.WeekDay.FRIDAY\n```\n##### irange\n```\nirange(start_date, stop_date=None, time_step=None)\n\nReturns a generator that produces a sequence of datetime's from \"start_date\" (inclusive)\nto \"stop_date\" (exclusive) by \"time_step\".\n\n:param datetime.datetime start_date: Inclusive.\n:param datetime.datetime stop_date: Exclusive. `utcnow` is used by default.\n:param datetime.delta time_step: one-day `timedelta` is used by default.\n\n Examples:\n import datetime\n\n from pymince.dates import irange\n\n ini = datetime.datetime.fromisoformat(\"2022-10-31\")\n end = datetime.datetime.fromisoformat(\"2022-11-02\")\n day = datetime.timedelta(days=1)\n\n it = irange(ini, stop_date=end, time_step=day)\n\n next(it) # --> datetime.datetime(2022, 10, 31, 0, 0)\n next(it) # --> datetime.datetime(2022, 11, 1, 0, 0)\n next(it) # --> raise StopIteration\n```\n##### string2year\n```\nstring2year(value, gte=None, lte=None, shift=None)\n\nFunction to convert a string year representation to integer year.\n\n:param str value: Value to convert.\n:param Optional[int] gte: if it is specified is required that: year >= gte\n:param Optional[int] lte: if it is specified is required that: year <= lte\n:param Optional[int] shift: use a two-digit year on shift\n\n:raise: \"ValueError\" if \"value\" cannot be converted.\n:rtype: int\n\nExamples:\n from pymince.dates import string2year\n\n string2year(\"53\", shift=None) # --> 2053\n string2year(\"53\", shift=1953) # --> 1953\n string2year(\"52\", shift=1953) # --> 2052\n string2year(\"54\", shift=1953) # --> 1954\n\n string2year(\"1954\") # --> 1954\n\n string2year(\"123\") # --> ValueError\n string2year(\"1955\", gte=1956) # --> ValueError\n string2year(\"1955\", lte=1954) # --> ValueError\n```\n#### dictionary.py\nUseful functions that use dictionaries.\n##### DigestGetter\n```\nDigestGetter(include_keys=None, exclude_keys=None)\n\nCalculate a digest of a \"jsonified\" python dictionary.\n\n:param include_keys: dictionary keys to exclude\n:param exclude_keys: dictionary keys to include\n:rtype: str\n\nExamples:\n from pymince.dictionary import DigestGetter\n\n getter = DigestGetter(include_keys=(\"a\",))\n getter({\"a\": 1, \"b\": 1}) # --> bb6cb5c68df4652941caf652a366f2d8\n getter({\"a\": 1}) # --> bb6cb5c68df4652941caf652a366f2d8\n```\n##### all_true_values\n```\nall_true_values(dictionary, keys)\n\nCheck if a dictionary has all the specified keys and if all its\nevaluated key-related values are True.\n\n:param dict dictionary:\n:param keys: keys sequence\n:rtype: bool\n\nExamples:\nfrom pymince.dictionary import all_true_values\n\nall_true_values({\"a\": 1, \"b\": 2}, (\"a\", \"b\")) # --> True\nall_true_values({\"a\": 1, \"b\": 0}, (\"a\", \"b\")) # --> False\nall_true_values({\"a\": 1, \"b\": 0}, (\"a\",)) # --> True\n```\n##### find_leaf_value\n```\nfind_leaf_value(key, dictionary)\n\nFind leaf value in mapping.\n\n:param Any key: key to find\n:param dict dictionary:\n\nExamples:\n from pymince.dictionary import find_leaf_value\n\n find_leaf_value('a', {}) # --> 'a'\n find_leaf_value('a', {'a': 'b', 'b': 'c'}) # --> 'c'\n find_leaf_value('a', {'a': 'a'}) # --> 'a'\n```\n##### from_objects\n```\nfrom_objects(iterable, key_getter, value_getter)\n\nCreate a new dictionary with elements generated from\nthe \"key_getter\" and \"value_getter\" callbacks applied to each element of the iterable.\n\n:param Iterable[any] iterable:\n:param Callable key_getter:\n Dictionary keys getter.\n It is called with each element of \"iterable\" passing it as an argument.\n:param Callable value_getter:\n Dictionary values getter.\n It is called with each element of \"iterable\" passing it as an argument.\n\n:raise: ValueError if any generated key is duplicate.\n:rtype: dict\n\nExamples:\n from pymince.dictionary import from_objects\n\n keygetter = operator.itemgetter(0)\n valgetter = operator.itemgetter(1, 2)\n\n values = iter([(1, \"a\", \"b\"), (2, \"a\", \"b\")])\n from_objects(values, keygetter, valgetter) # --> {1: ('a', 'b'), 2: ('a', 'b')}\n```\n##### frozendict\n```\nfrozendict(*args, **kwargs)\n\nReturns a \"MappingProxyType\" from a dictionary built according to given parameters.\nAdd immutability only on a first level.\n\nExamples:\n from pymince.dictionary import frozendict\n\n my_dict = frozendict(a=1, b=2)\n my_dict[\"a\"] # --> 1\n list(my_dict.items()) # --> [(\"a\", 1), (\"b\", 2)]\n my_dict[\"c\"] = 3 # --> TypeError\n```\n##### tree\n```\ntree()\n\nReturns a dict whose defaults are dicts.\nAs suggested here: https://gist.github.com/2012250\n\nExamples:\n import json\n\n from pymince.dictionary import tree\n\n users = tree()\n users['user1']['username'] = 'foo'\n users['user2']['username'] = 'bar'\n\n print(json.dumps(users)) # {\"user1\": {\"username\": \"foo\"}, \"user2\": {\"username\": \"bar\"}}\n```\n#### file.py\n\n##### decompress\n```\ndecompress(src_path, dst_path, size=65536)\n\nDecompress the given compressed file in blocks based on its extension format.\nSupports compression formats: gzip => (.gz), bzip2 => (.bz2), xz => (.xz)\n\n:param str src_path: source file path\n:param str dst_path: destination file(unzipped) path\n:param int size: Read up to size bytes from src_path for each block.\n:return: dst_path\n\n Examples:\n from pymince.file import decompress\n\n decompress(\"/foo/src.txt.gz\", \"/baz/dst.txt\") # --> \"/baz/dst.txt\"\n decompress(\"/foo/src.txt.bz2\", \"/baz/dst.txt\") # --> \"/baz/dst.txt\"\n decompress(\"/foo/src.txt.xz\", \"/baz/dst.txt\") # --> \"/baz/dst.txt\"\n```\n##### ensure_directory\n```\nensure_directory(path, cleaning=False)\n\nMake sure the given file path is an existing directory.\nIf it does not exist, a new directory will be created.\n\n:param str path:\n:param bool cleaning:\n If \"cleaning\" is True and a directory already exists,\n this directory and the files contained in it will be deleted.\n\n If \"cleaning\" is True and a file already exists,\n this file will be deleted.\n```\n##### get_valid_filename\n```\nget_valid_filename(s)\n\nReturns a valid filename for the given string.\n\n- Remove leading/trailing spaces\n- Change spaces to underscores\n- Remove anything that is not an alphanumeric, dash, underscore, or dot\n```\n##### is_empty_directory\n```\nis_empty_directory(path)\n\nCheck if the given path is an empty directory.\n```\n##### match_from_zip\n```\nmatch_from_zip(zip_file, pattern)\n\nMake an iterator that returns file names in the zip file that\nmatch the given pattern.\nUppercase/lowercase letters are ignored.\n\n:param zip_file: ZipFile object or zip path.\n:param pattern: \"re.Pattern\" to filter filename list\n:return: Iterator with the filenames found\n\nExamples:\n import pymince.file\n pymince.file.match_from_zip(\"archive.zip\", \"^file\") # --> file1.log file2.txt\n pymince.file.match_from_zip(zipfile.ZipFile(\"archive.zip\"), \"^file\") # --> file1.log file2.txt\n```\n##### replace_extension\n```\nreplace_extension(filename, old_ext=None, new_ext=None)\n\nReplace filename \"old_ext\" with \"new_ext\".\n\n:param str filename:\n:param Optional[str] old_ext:\n:param Optional[str] new_ext:\n\nExamples:\n from pymince.file import replace_extension\n\n # remove extensions\n replace_extension(\"/home/user/file.old\") # --> \"/home/user/file\"\n replace_extension(\"/home/user/file.old\", old_ext=\".old\") # --> \"/home/user/file\"\n replace_extension(\"/home/user/file.old\", old_ext=\".new\") # --> \"/home/user/file.old\"\n\n # replace extensions\n replace_extension(\"/home/user/file.old\", new_ext=\".new\") # --> \"/home/user/file.new\"\n replace_extension(\"/home/user/file.old\", old_ext=\".old\", new_ext=\".new\") # --> \"/home/user/file.new\"\n replace_extension(\"/home/user/file.old\", old_ext=\".new\", new_ext=\".new\") # --> \"/home/user/file.old\"\n```\n##### xopen\n```\nxopen(name, mode='rb', encoding=None)\n\nOpen compressed files in Python based on their file extension.\n\n- Supports compression formats: gzip => (.gz), bzip2 => (.bz2), xz => (.xz)\n- If the file extension is not recognized, the file will be opened without compression.\n- When text mode is required, UTF-8 encoding is used by default.\n```\n#### functional.py\n\n##### caller\n```\ncaller(*args, **kwargs)\n\nReturn a callable that calls with given params.\n\nExamples:\n import pymince.functional\n\n caller = pymince.functional.caller(range(5))\n caller(len) # 5\n caller(list) # [0, 1, 2, 3, 4]\n```\n##### classproperty\n```\nclassproperty(method=None)\n\nDecorator that converts a method with a single cls argument into a property\nthat can be accessed directly from the class.\n\nExamples:\n from pymince.functional import classproperty\n\n class MyClass:\n __foo = \"var\"\n\n @classproperty\n def foo(cls):\n return cls.__foo\n```\n##### identity\n```\nidentity(x)\n\nTakes a single argument and returns it unchanged.\nIdentity function, as defined in https://en.wikipedia.org/wiki/Identity_function.\n```\n##### once\n```\nonce(fn)\n\nDecorator to execute a function only once.\n\nExamples:\n from pymince.functional import once\n\n @once\n def inc_once():\n global n\n n += 1\n return 'anything'\n\n n = 0\n inc_once() # --> 'anything'\n inc_once() # --> 'anything'\n inc_once() # --> 'anything'\n print(n) # --> 1\n```\n##### pipe\n```\npipe(*fns)\n\nCompose functions from left to right.\n\n:param fns: Functions to compose.\n:rtype: Callable[[Any], Any]\n\nExamples:\n from pymince.functional import pipe\n\n addtwo = lambda n: n + 2\n double = lambda n: n * 2\n square = lambda n: n * n\n\n fn = pipe(addtwo, double, square)\n fn(1) # --> 36\n```\n##### retry_if_errors\n```\nretry_if_errors(*exceptions, delay=0, tries=1)\n\nDecorator that retries to call the wrapped function\nif any of given exceptions are thrown.\n\n:param exceptions: Lists of exceptions that trigger a retry attempt.\n:param int delay: seconds delay between attempts. default: 0.\n:param int tries: number of attempts. default: 1\n\nExamples:\n@retry_if_errors(ValueError, TypeError, delay=0, tries=1)\ndef foo():\n return 1\n```\n##### retry_if_none\n```\nretry_if_none(delay=0, tries=1)\n\nDecorator that retries to call the wrapped function\nif it returns None.\n\n:param int delay: seconds delay between attempts. default: 0.\n:param int tries: number of attempts. default: 1\n\nExamples:\n @retry_if_none(delay=0, tries=1)\n def foo():\n return 1\n```\n##### set_attributes\n```\nset_attributes(**kwargs)\n\nDecorator to set attributes on functions and classes.\n\nExamples:\n from pymince.functional import set_attributes\n\n @set_attributes(short_description=\"dummy function\")\n def foo():\n pass\n\n print(foo.short_description) # \"dummy function\"\n\nBased on: https://github.com/wolph/python-utils/ (set_attributes)\n```\n##### suppress\n```\nsuppress(*exceptions, default=None)\n\nDecorator to suppress the specified exceptions and return the\ndefault value instead.\n\nExamples:\n from pymince.functional import suppress\n\n @suppress(FileNotFoundError, default=False)\n def remove(somefile):\n os.remove(somefile)\n\n remove(\"no_found.txt\") # False\n```\n#### iterator.py\nFunctions that use iterators for efficient loops.\n##### all_distinct\n```\nall_distinct(iterable, key=None)\n\nCheck if all the elements of a key-based iterable are distinct.\n\n:param iterable:\n:param key: None or \"Callable\" to compare if iterable items.\n:rtype: bool\n\nExamples:\n from pymince.iterator import all_distinct\n\n all_distinct([1, 1]) # --> False\n all_distinct([1, 2]) # --> True\n```\n##### all_equal\n```\nall_equal(iterable, key=None)\n\nCheck if all the elements of a key-based iterable are equals.\n\n:param iterable:\n:param key: None or \"Callable\" to compare if iterable items.\n:rtype: bool\n\nExamples:\n from pymince.iterator import all_equal\n\n all_equal([1, 1]) # --> True\n all_equal([1, 2]) # --> False\n```\n##### all_equals\n```\nall_equals(*iterables, key=None)\n\nCheck if the iterables are equal.\nIf the \"iterables\" are empty, it returns True.\n\n:param iterables:\n:param key: None or \"Callable\" to compare if iterable items.\n:rtype: bool\n\nExamples:\n from pymince.iterator import all_equals\n\n all_equals() # --> True\n all_equals(range(1, 4), (1, 2, 3), {1, 2, 3}) # --> True\n all_equals((1, 2), (1, 2, 3)) # --> False\n```\n##### all_identical\n```\nall_identical(left, right)\n\nCheck that the items of `left` are the same objects\nas those in `right`.\n\n:param Iterable[Any] left:\n:param Iterable[Any] right:\n:rtype: bool\n\nExamples:\n from pymince.iterator import all_identical\n\n a, b = object(), object()\n all_identical([a, b, a], [a, b, a]) # --> True\n all_identical([a, b, [a]], [a, b, [a]]) # --> False *new list object, while \"equal\" is not \"identical\"*\n```\n##### centroid\n```\ncentroid(coordinates)\n\nCalculate the centroid of a set of n-dimensional coordinates.\nIn Cartesian coordinates, the centroid is\njust the mean of the components.\n\n:param Iterable[Iterable[int]] coordinates: Iterable of n-dimensional coordinates.\n:rtype: Generator[int]\n\n Examples:\n from pymince.iterator import centroid\n\n coord = (((2, 2), (4, 4)))\n tuple(centroid(coord)) # --> (3, 3)\n```\n##### consume\n```\nconsume(iterator, n=None)\n\nAdvance *iterator* by *n* steps. If *n* is ``None``, consume it\nentirely.\n\nExamples:\n from pymince.iterator import consume\n it = iter([1, 2])\n consume(it)\n next(it) # --> StopIteration\n```\n##### grouper\n```\ngrouper(iterable, size)\n\nMake a generator that returns each element being iterable\nwith \"size\" as the maximum number of elements.\n\n:param iterable:\n:param int size: maximum size of element groups.\n:rtype: Generator\n\nExamples:\n from pymince.iterator import grouper\n\n groups = grouper([1, 2, 3, 4, 5], 2)\n list(list(g) for g in groups) # --> [[1, 2], [3, 4], [5]]\n```\n##### ibool\n```\nibool(iterable)\n\nIterator class supporting \u00b4__bool__\u00b4.\n\nExamples:\n from pymince.iterator import ibool\n\n it = ibool((1, 2, 3))\n bool(it) # --> True\n list(it) # --> [1, 2, 3]\n```\n##### in_all\n```\nin_all(obj, iterables)\n\nCheck if the object is contained in all the given iterables.\nIf the \"iterables\" are empty, return True.\n\n:param Any obj:\n:param iterables: iterable of iterables\n:rtype: bool\n\nExamples:\n from pymince.iterator import in_all\n\n in_all(\"a\", ((\"a\", \"b\"), \"bcd\")) # --> False\n in_all(\"a\", ((\"a\", \"b\"), \"abc\")) # --> True\n in_all(\"a\", ()) # --> True\n```\n##### in_any\n```\nin_any(obj, iterables)\n\nCheck if the object is contained in any of the given iterables.\n\n:param Any obj:\n:param iterables: iterable of iterables\n:rtype: bool\n\nExamples:\n from pymince.iterator import in_any\n\n in_any(\"a\", ((\"a\", \"b\"), \"bcd\")) # --> True\n in_any(\"a\", ((\"b\", \"b\"), \"def\")) # --> False\n in_any(\"a\", ()) # --> False\n```\n##### ipush\n```\nipush(iterable)\n\nIterator class supporting \u00b4append\u00b4 and \u00b4prepend\u00b4.\n\nExamples:\n from pymince.iterator import ipush\n\n it = ipush(iter([2, 3])\n\n it.append(4)\n it.append(5)\n\n it.prepend(1)\n it.prepend(0)\n\n list(it) # --> [0, 1, 2, 3, 4, 5]\n```\n##### mul\n```\nmul(iterable, start=1)\n\nReturn the multiplication of a 'start' value (default: 1)\nplus an iterable of numbers.\n\nWhen the iterable is empty, return the start value.\n```\n##### only_one\n```\nonly_one(iterable)\n\nCheck if given iterable has only one element.\n\n:param iterable:\n:rtype: bool\n\nExamples:\n from pymince.iterator import only_one\n\n only_one([1]) # --> True\n only_one([1, 2]) # --> False\n only_one([]) # --> False\n```\n##### pad_end\n```\npad_end(iterable, length, fill_value=None)\n\nThe function adds \"fill_value\" at the finishing of the iterable,\nuntil it reaches the specified length.\nIf the value of the \"length\" param is less than the length of\nthe given \"iterable\", no filling is done.\n\n:param iterable:\n:param int length: A number specifying the desired length of the resulting iterable.\n:param Any fill_value: Any value to fill the given iterable.\n:rtype: Generator\n\n Examples:\n from pymince.iterator import pad_end\n\n pad_end((\"a\", \"b\"), 3, fill_value=\"1\") # --> \"a\" \"b\" \"1\"\n pad_end((\"a\", \"b\"), 3) # --> \"a\" \"b\" None\n pad_end((\"a\", \"b\", \"c\"), 3) # --> \"a\" \"b\" \"c\"\n```\n##### pad_start\n```\npad_start(iterable, length, fill_value=None)\n\nThe function adds \"fill_value\" at the beginning of the iterable,\nuntil it reaches the specified length.\nIf the value of the \"length\" param is less than the length of\nthe given \"iterable\", no filling is done.\n\n:param iterable:\n:param int length: A number specifying the desired length of the resulting iterable.\n:param Any fill_value: Any value to fill the given iterable.\n:rtype: Generator\n\n Examples:\n from pymince.iterator import pad_start\n\n pad_start((\"a\", \"b\"), 3, fill_value=\"1\") # --> \"1\" \"a\" \"b\"\n pad_start((\"a\", \"b\"), 3) # --> None \"a\" \"b\"\n pad_start((\"a\", \"b\", \"c\"), 3) # --> \"a\" \"b\" \"c\"\n```\n##### partition\n```\npartition(predicate, iterable)\n\nSplit the iterable into two lists, based on the boolean return-value\nof the predicate.\n- (1): items that have predicate(item) == False.\n- (2): items that have predicate(item) == True.\n\n\nExamples:\n from pymince.iterator import partition\n\n is_odd = lambda x: x % 2 != 0\n even_items, odd_items = partition(is_odd, range(10)) # ([0, 2, 4, 6, 8], [1, 3, 5, 7, 9])\n```\n##### replacer\n```\nreplacer(iterable, matcher, new_value, count=-1)\n\nMake a generator that yields all occurrences of the old \"iterable\"\nreplaced by \"new_value\".\n\n:param iterable:\n:param matcher: Callable to find occurrences. It is an occurrence if the matcher returns True.\n:param new_value: Any value to replace found occurrences.\n:param int count:\n Maximum number of occurrences to replace.\n -1 (the default value) means replace all occurrences.\n:rtype: Generator\n\nExamples:\n from pymince.iterator import replacer\n\n is_one = lambda n: n == 1\n replacer([1,2,3,1,2,3], is_one, None) # --> None 2 3 None 2 3\n replacer([1,2,3,1,2,3], is_one, None, count=1) # --> None 2 3 1 2 3\n```\n##### splitter\n```\nsplitter(iterable, sep, key=None, maxsplit=-1, container=None)\n\nSplits an iterable based on a separator.\nA separator will never appear in the output.\n\n:param iterable:\n:param sep: The delimiter to split the iterable.\n:param key\n A function to compare the equality of each element with the given delimiter.\n If the key function is not specified or is None, the element itself is used for compare.\n:param maxsplit:\n Maximum number of splits to do.\n -1 (the default value) means no limit.\n:param container: Callable to save the splits. By default tuple is used.\n\n:return: Generator with consecutive splits of \"iterable\" without the delimiter item.\n\nExamples:\n from pymince.iterator import splitter\n\n data = (\"a\", \"b\", \"c\", \"d\", \"b\", \"e\")\n split_n = splitter(data, \"b\") # --> (\"a\",) (\"c\", \"d\") (\"e\",)\n split_1 = splitter(data, \"b\", maxsplit=1) # --> (\"a\",) (\"c\", \"d\", \"b\", \"e\")\n```\n##### sub\n```\nsub(iterable)\n\nReturn the subtraction of a non-empty iterable of numbers and sets.\n```\n##### truediv\n```\ntruediv(iterable)\n\nReturn the division of an non-empty iterable of numbers.\n```\n##### uniquer\n```\nuniquer(iterable, key=None)\n\nMake a generator that returns each element from iterable only once\nrespecting the input order.\n\nExamples:\n from pymince.iterator import uniquer\n\n uniquer([1, 2, 3, 2]) # --> 1 2 3\n```\n##### uniques\n```\nuniques(iterable, key=None)\n\nCheck if all the elements of a key-based iterable are unique.\n\n:param iterable:\n:param key: None or \"Callable\" to compare if iterable items.\n:rtype: bool\n\nExamples:\n from pymince.iterator import uniques\n\n uniques([1,2]) # --> True\n uniques([1,1]) # --> False\n```\n#### json.py\nUseful functions for working with JSONs.\n- Supports `orjson`, `ujson` libraries or standard `json`.\n- Supports following compression formats: gzip => (.gz), bzip2 => (.bz2), xz => (.xz)\n##### JSONEncoder\n```\nJSONEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)\n\nJSON encoder that handles additional types compared\nto `json.JSONEncoder`\n\n- `datetime` and `date` are serialized to strings according to the isoformat.\n- `decimal.Decimal` is serialized to a string.\n- `uuid.UUID` is serialized to a string.\n- `dataclasses.dataclass` is passed to `dataclasses.asdict`.\n- `frozenset` and `set` are serialized by ordering their values.\n```\n##### dump_from_csv\n```\ndump_from_csv(csv_path, json_path, /, *, fieldnames=None, start=0, stop=None, strip=True, encoding='utf-8', **kwargs)\n\nDump CSV file to a JSON file.\n- Use (`.gz`, `.xz`, `.bz2`) extensions to create a compressed file.\n- Dumps falls back to the functions: (`orjson.dumps`, `ujson.dumps`, and `json.dumps`).\n\n:param str csv_path:\n:param str json_path:\n:param fieldnames: list of keys for the JSON\n:param int start:\n If start is specified, will skip all preceding elements;\n otherwise, start defaults to zero.\n:param int stop:\n:param bool strip:\n Whether white space should be removed from the\n beginning and end of field values.\n:param str encoding: utf-8 is used by default.\n```\n##### dump_into\n```\ndump_into(filename, obj, encoding='utf-8', **kwargs)\n\nDump JSON to a file.\n- Use (`.gz`, `.xz`, `.bz2`) extensions to create compressed files.\n- Dumps falls back to the functions: (`orjson.dump`, `ujson.dump`, and `json.dump`).\n\nExamples:\n from pymince.json import dump_into\n\n dump_into(\"foo.json\", {\"key\": \"value\"}) # uncompressed\n dump_into(\"foo.json.gz\", {\"key\": \"value\"}) # gzip-compressed\n dump_into(\"foo.json.xz\", {\"key\": \"value\"}) # lzma-compressed\n dump_into(\"foo.json.bz2\", {\"key\": \"value\"}) # bz2-compressed\n```\n##### dump_into_zip\n```\ndump_into_zip(zip_path, arcname, payload, **kwargs)\n\nDump JSON into the zip archive under the name arcname.\n\nExamples:\n from pymince.json import dump_into_zip\n\n dump_into_zip(\"archive.zip\", \"foo.json\", {\"key\": \"value\"})\n```\n##### idump_fork\n```\nidump_fork(path_items, encoding='utf-8', dump_if_empty=True, **dumps_kwargs)\n\nIncrementally dumps different groups of elements into\nthe indicated JSON file.\n*** Useful to reduce memory consumption ***\n\n- Use (`.gz`, `.xz`, `.bz2`) extensions to create compressed files.\n- Dumps falls back to the functions: (`orjson.dumps`, `ujson.dumps`, and `json.dumps`).\n\n:param Iterable[file_path, Iterable[dict]] path_items: group items by file path\n:param encoding: 'utf-8' by default.\n:param bool dump_if_empty: If false, don't create an empty file.\n:param dumps_kwargs: json.dumps kwargs.\n\nExamples:\n from pymince.json import idump_fork\n\n path_items = (\n (\"num.json.gz\", ({\"value\": 1}, {\"value\": 2})),\n (\"num.json.gz\", ({\"value\": 3},)),\n (\"foo.json\", ({\"a\": \"1\"}, {\"b\": 2})),\n (\"baz.json\", ()),\n )\n idump_fork(iter(path_items))\n```\n##### idump_into\n```\nidump_into(filename, iterable, encoding='utf-8', **kwargs)\n\nDump an iterable incrementally into a JSON file.\n- Use (`.gz`, `.xz`, `.bz2`) extensions to create compressed files.\n- Dumps falls back to the functions: (`orjson.dumps`, `ujson.dumps`, and `json.dumps`).\n\nThe result will always be an array with the elements of the iterable.\n*** Useful to reduce memory consumption ***\n\nExamples:\n from pymince.json import idump_into\n\n values = ([{\"key\": \"foo\"}, {\"key\": \"bar\"}])\n\n idump_into(\"foo.json\", values) # uncompressed\n idump_into(\"foo.json.gz\", values) # gzip-compressed\n idump_into(\"foo.json.xz\", values) # lzma-compressed\n idump_into(\"foo.json.bz2\", values) # bz2-compressed\n```\n##### idump_lines\n```\nidump_lines(iterable, **dumps_kwargs)\n\nGenerator yielding string lines that form a JSON array\nwith the serialized elements of given iterable.\n*** Useful to reduce memory consumption ***\n- Dumps falls back to the functions: (`orjson.dumps`, `ujson.dumps`, and `json.dumps`).\n\n:param iterable: Iterable[dict]\n:rtype: Iterable[str]\n```\n##### load\n```\nload(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)\n\nDeserialize ``fp`` (a ``.read()``-supporting file-like object containing\na JSON document) to a Python object.\n\n``object_hook`` is an optional function that will be called with the\nresult of any object literal decode (a ``dict``). The return value of\n``object_hook`` will be used instead of the ``dict``. This feature\ncan be used to implement custom decoders (e.g. JSON-RPC class hinting).\n\n``object_pairs_hook`` is an optional function that will be called with the\nresult of any object literal decoded with an ordered list of pairs. The\nreturn value of ``object_pairs_hook`` will be used instead of the ``dict``.\nThis feature can be used to implement custom decoders. If ``object_hook``\nis also defined, the ``object_pairs_hook`` takes priority.\n\nTo use a custom ``JSONDecoder`` subclass, specify it with the ``cls``\nkwarg; otherwise ``JSONDecoder`` is used.\n```\n##### load_from\n```\nload_from(filename, encoding='utf-8')\n\nLoad JSON from a file.\n- Recognizes (`.gz`, `.xz`, `.bz2`) extensions to load compressed files.\n- Loads falls back to the functions: (`orjson.load`, `ujson.load`, and `json.load`).\n\nExamples:\n from pymince.json import load_from\n\n dictionary1 = load_from(\"foo.json\") # uncompressed\n dictionary2 = load_from(\"foo.json.gz\") # gzip-compressed\n dictionary3 = load_from(\"foo.json.xz\") # lzma-compressed\n dictionary4 = load_from(\"foo.json.bz2\") # bz2-compressed\n```\n##### load_from_zip\n```\nload_from_zip(zip_path, arcname)\n\nLoad JSON from a file named \"arcname\" inside a zip archive.\n\nExamples:\n from pymince.json import load_from_zip\n\n dictionary = load_from_zip(\"archive.zip\", \"foo.json\")\n```\n#### logging.py\n\n##### ColoredFormatter\n```\nColoredFormatter(fmt=None, datefmt=None, style='%', validate=True)\n\nA class for formatting colored logs.\n\nDefault colors:\n- DEBUG: blue\n- INFO: green\n- WARNING: yellow\n- ERROR: red\n- CRITICAL: red\n\nExamples:\n import logging\n from pymince.logging import ColoredFormatter\n\n # Config\n logger = logging.getLogger('mylog')\n logger.setLevel('DEBUG')\n\n stream_handler = logging.StreamHandler()\n stream_handler.setFormatter(ColoredFormatter(logging.BASIC_FORMAT))\n logger.addHandler(stream_handler)\n\n # Use default colors\n logger.debug(\"This is debug\") # blue color\n\n # Use custom colors\n import colorama\n logger.debug(\"This is debug\", extra={\"color\": colorama.Fore.BLACK})\n```\n##### ColoredLogger\n```\nColoredLogger(name=None, level=10, **fmt_kwargs)\n\nCustom logger to generate color logs.\n\nExamples:\n from pymince.logging import ColoredLogger\n\n logger = ColoredLogger()\n\n # Use default colors\n logger.debug(\"This is debug\") # blue color\n\n # Use custom colors\n import colorama\n logger.debug(\"This is debug\", extra={\"color\": colorama.Fore.BLACK})\n```\n##### StructuredFormatter\n```\nStructuredFormatter(fmt=None, datefmt=None, style='%', validate=True)\n\nImplementation of JSON structured logging that works\nfor most handlers.\n\nExamples:\n import logging\n import sys\n from pymince.logging import StructuredFormatter\n\n # Config\n logger = logging.getLogger()\n logger.setLevel(logging.DEBUG)\n formatter = StructuredFormatter('%(message)s')\n handler = logging.StreamHandler(sys.stdout)\n handler.setLevel(logging.DEBUG)\n handler.setFormatter(formatter)\n logger.addHandler(handler)\n\n # Usage\n logger.debug('', {\"string\": \"value1\", \"number\": 1})\n logger.debug('', {\"string\": \"value2\", \"number\": 2})\n\n >>Output<<\n {\"timestamp\":\"2022-06-17 18:37:48,789\",\"level\":\"DEBUG\",\"payload\":{\"string\":\"value1\",\"number\":1}}\n {\"timestamp\":\"2022-06-17 18:37:48,789\",\"level\":\"DEBUG\",\"payload\":{\"string\":\"value2\",\"number\":2}}\n```\n##### timed_block\n```\ntimed_block(name, logger=None)\n\nLog the duration of the handled context.\n\nExamples:\n import logging\n from pymince.logging import timed_block\n\n logging.basicConfig(level=logging.DEBUG)\n with timed_block(\"sleeping\"):\n time.sleep(1)\n\n >>Output<<\n INFO:root:Generating [sleeping]\n DEBUG:root:Finished [sleeping in 1.002 s]\n```\n#### std.py\n\n##### bind_json_std\n```\nbind_json_std(encoding='utf-8')\n\nDecorator to call \"function\" passing the json read from\n\"stdin\" in the keyword parameter \"data\" and dump the json that the callback returns\nto \"stdout\".\n\nExamples:\nfrom pymince.std import bind_json_std\n\n@bind_json_std()\ndef foo(data=None):\n print(\"Processing data from sys.stdin\", data)\n\n result = data and {**data, \"new\": \"value\"}\n\n print(\"Result to write in sys.stdout\", result)\n return result\n```\n#### text.py\nUseful functions for working with strings.\n##### are_anagram\n```\nare_anagram(text1, text2)\n\nCheck if two strings are anagram.\n\nExamples:\n from pymince.text import are_anagram\n\n are_anagram(\"listen\", \"silent\") # --> True\n are_anagram(\"they see\", \"the eyes\") # --> True\n```\n##### get_random_secret\n```\nget_random_secret(length, alphabet='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')\n\nGenerate a cryptographically secure random string.\nUseful for creating temporary passwords.\n```\n##### get_random_string\n```\nget_random_string(length, alphabet='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')\n\nGenerate random string.\n```\n##### is_binary\n```\nis_binary(text)\n\nCheck if the string is binary or not.\n```\n##### is_email_address\n```\nis_email_address(text)\n\nCheck if the string is an email address.\n\nThis solution does a very simple check. It only validates that the string contains an at sign (@)\nthat is preceded and followed by one or more non whitespace characters.\n```\n##### is_int\n```\nis_int(text)\n\nCheck if the string is the representation of\na integer number.\n\nTrue: \"10\", \"+10\", \"-10\", \"0\"\n```\n##### is_negative_int\n```\nis_negative_int(text)\n\nCheck if the string is the representation of\nnegative integer number.\n\nTrue: \"-10\"\n```\n##### is_palindrome\n```\nis_palindrome(text)\n\nCheck if the string is palindrome or not.\nA string is said to be palindrome if the reverse of the string is the same as string\n```\n##### is_payment_card\n```\nis_payment_card(text)\n\nCheck if the string is a valid payment\ncard number.\n\nhttps://en.wikipedia.org/wiki/Payment_card_number#Issuer_identification_number_(IIN)\n```\n##### is_percentage\n```\nis_percentage(text)\n\nCheck if the string is a valid percentage\n\nTrue: \"100%\", \"100 %\", \"100 %\", 100.0 %\",\n```\n##### is_positive_int\n```\nis_positive_int(text)\n\nCheck if the string is the representation of\npositive integer number.\n\nTrue: \"10\", \"+10\"\n```\n##### is_roman\n```\nis_roman(text)\n\nCheck if the string is a valid roman numeral.\n```\n##### is_url\n```\nis_url(text, schemes=None, hostnames=None)\n\nCheck if the string is a URL according to the\ngiven schemes and host-names.\n\n:param str text:\n:param Optional[Container[str]] schemes: (\"http\", \"https\")\n:param Optional[Container[str]] hostnames: (\"www.python.org\", \"github.com\", \"localhost\")\n:rtype: bool\n\nExamples:\n from pymince.text import is_url\n\n # True\n is_url(\"https://github.com/\")\n is_url(\"https://github.com/\", hostnames=(\"github.com\",))\n is_url(\"https://github.com/\", hostnames=(\"github.com\",), schemes=(\"https\",))\n\n # False\n is_url(\"https://github.com/\", schemes=(\"http\",))\n is_url(\"https://github.com/\", hostnames=(\"www.python.org\", \"localhost\"))\n```\n##### multireplace\n```\nmultireplace(text, replacements)\n\nGiven a string and a replacement map, it returns the replaced string.\n\n:param str text: string to execute replacements on.\n:param Union[dict[str, str], tuple[tuple[str, str], ...] replacements:\n 2-dict or 2-tuples with value to find and value to replace\n:rtype: str\n\n Examples:\n from pymince.text import multireplace\n\n mapping = {\",\": \"\", \"cry\": \"smile\"}\n multireplace(\"No, woman, no cry\", mapping) # --> \"No woman no smile\"\n```\n##### multireplacer\n```\nmultireplacer(replacements)\n\nGiven a replacement map, returns a function that can be reused to replace any string.\n\n:param Union[dict[str, str], tuple[tuple[str, str], ...] replacements:\n 2-dict or 2-tuples with value to find and value to replace\n:rtype: Callable[[str], str]\n\n Examples:\n from pymince.text import multireplacer\n\n mapping = ((\"abc\", \"123\"), (\"def\", \"456\"))\n replace = multireplacer(mapping)\n\n replace(\"...def...\") # --> \"...456...\"\n replace(\"...abc...\") # --> \"...123...\"\n replace(\"...abc...def...\") # --> \"...123...456...\"\n```\n##### normalize_newlines\n```\nnormalize_newlines(s)\n\nNormalize CRLF and CR newlines to just LF.\n```\n##### remove_decimal_zeros\n```\nremove_decimal_zeros(value, decimal_sep='.', min_decimals=None)\n\nRemoves non-significant decimal zeros from a formatted text number.\n\nExamples:\n from pymince.text import remove_decimal_zeros\n\n remove_decimal_zeros(\"2.000100\", \".\") # --> \"2.0001\"\n remove_decimal_zeros(\"2.000000\", \".\") # --> \"2\"\n remove_decimal_zeros(\"2.000000\", \".\", min_decimals=2) # --> \"2.00\"\n```\n##### remove_number_commas\n```\nremove_number_commas(s)\n\nRemoves commas from a formatted text number having commas\nas group separator.\n\n:param str s:\n:rtype str\n\nExamples:\n from pymince.text import remove_number_commas\n remove_number_commas('1,234,567.8') # --> '1234567.8'\n```\n##### replace\n```\nreplace(value, old_values, new_value, count=-1)\n\nReplace matching values \u200b\u200bin the given string with new_value.\n\n:param str value:\n:param old_values: iterable of values \u200b\u200bto replace.\n:param str new_value: replacement value.\n:param int count:\n Maximum number of occurrences to replace.\n -1 (the default value) means replace all occurrences.\n:rtype: str\n\nExamples:\n from pymince.text import replace\n\n replace(\"No, woman, no cry\", [\",\"], \";\") # --> \"No; woman; no cry\"\n replace(\"No, woman, no cry\", [\",\"], \";\", count=1) # --> \"No; woman, no cry\"\n```\n##### slugify\n```\nslugify(value, allow_unicode=False)\n\nConvert to ASCII if 'allow_unicode' is False. Convert spaces or repeated\ndashes to single dashes. Remove characters that aren't alphanumerics,\nunderscores, or hyphens. Convert to lowercase. Also strip leading and\ntrailing whitespace, dashes, and underscores.\n\nhttps://github.com/django/django/blob/main/django/utils/text.py\n```\n#### warnings.py\n\n##### deprecated\n```\ndeprecated(fn)\n\nThis is a decorator which can be used to mark functions\nas deprecated. It will result in a warning being emitted\nwhen the function is used.\nhttp://code.activestate.com/recipes/391367-deprecated/?in=lang-python\n\nExamples:\n from pymince.warnings import deprecated\n\n @deprecated\n def check_function():\n pass\n\n class SomeClass:\n @deprecated\n def check_method(self):\n pass\n\n @deprecated\n class CheckClass:\n pass\n\n >> check_function() # DeprecationWarning --> 'Deprecated \"check_function\".'\n >> SomeClass().check_method() # DeprecationWarning --> 'Deprecated \"check_method\".'\n >> CheckClass() # DeprecationWarning --> 'Deprecated \"CheckClass\".'\n```\n#### xml.py\n\n##### iterparse\n```\niterparse(filename)\n\nIncrementally parse XML document into ElementTree.\n\nThis function is based on: https://github.com/python/cpython/issues/93618\n\n'Fix misleading hint for original ElementTree.iterparse.'\n'''\nThe code below deletes a root child once it is completed, then processes and removes\nit from the memory (if nothing more references to it ofc).\nThis allows to process 7GB XML with with a memory usage up to 10MB (in case of great number of root children).\n'''\n\n:param str filename: XML filename\n:rtype: Generator\n\n Examples:\n from pymince.xml import iterparse\n\n for event, obj in iterparse(\"countries.xml\")\n if event == 'start'\n print(obj, obj.tag, obj.attrib, obj.text)\n\n >>Output<<\n <Element 'country' at 0x0000018ADF9D0CC0> country {'code': 'as', 'iso': '16'} American Samoa\n <Element 'country' at 0x0000018ADF9D0C70> country {'code': 'ad', 'iso': '20'} Andorra\n```\n### Upgrade README.md\n\nUpgrade README.md `Usage` section according to current *pymince* code.\n\n```\n(env) python upgrade_readme_usage.py\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Python shredded utilities",
"version": "2.11.1",
"project_urls": {
"Homepage": "https://github.com/rmoralespp/pymince"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "24c08d38712d2f73d79a99788efd54c14202fc05971048ce77c5d0c90fc9a14d",
"md5": "12e409886f394cb419c7bc69817f1a81",
"sha256": "e9e760a45b149d786f695f4139cf3692cddc89bde30930831fce399f189fbdf3"
},
"downloads": -1,
"filename": "pymince-2.11.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "12e409886f394cb419c7bc69817f1a81",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 36662,
"upload_time": "2024-09-19T14:10:08",
"upload_time_iso_8601": "2024-09-19T14:10:08.486239Z",
"url": "https://files.pythonhosted.org/packages/24/c0/8d38712d2f73d79a99788efd54c14202fc05971048ce77c5d0c90fc9a14d/pymince-2.11.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "125d72df3850a3761e7e6b70736a279fb4f9ff6fa721bd5f9b1998778fdb992e",
"md5": "1ede5d79bbab4e6f5b22e125ac4ef37d",
"sha256": "7f2ef678dbf2493aa7f1f0fe5367555e55e00df25edb9f2f3b84497f8d3cdee4"
},
"downloads": -1,
"filename": "pymince-2.11.1.tar.gz",
"has_sig": false,
"md5_digest": "1ede5d79bbab4e6f5b22e125ac4ef37d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 57440,
"upload_time": "2024-09-19T14:10:09",
"upload_time_iso_8601": "2024-09-19T14:10:09.973214Z",
"url": "https://files.pythonhosted.org/packages/12/5d/72df3850a3761e7e6b70736a279fb4f9ff6fa721bd5f9b1998778fdb992e/pymince-2.11.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-19 14:10:09",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "rmoralespp",
"github_project": "pymince",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "pytest",
"specs": []
},
{
"name": "coverage",
"specs": []
},
{
"name": "pytest-cov",
"specs": []
},
{
"name": "ruff",
"specs": []
},
{
"name": "black",
"specs": []
},
{
"name": "pre-commit",
"specs": []
}
],
"lcname": "pymince"
}