Library for advanced continuous handling of anything
Project description
Pyhandling
Library for advanced continuous handling of anything
Provides tools to extend single call logic on a nearly unlimited scale
You can even integrate the entire program logic into one call
Installation
pip install pyhandling
Usage examples
Composition
Merge your functions into one
from pyhandling import *
complemented_number = str |then>> (lambda line: line + '6') |then>> int
complemented_number(25)
to later get
256
or you can do the same but call the function immediately
25 >= str |then>> (lambda line: line + '6') |then>> int
and get the same result
256
Currying
Add additional arguments to function input arguments
formattly_sum = "{} {}{}".format
post_partial(formattly_sum, "world", '!')("Hello")
not necessarily now
container = close(formattly_sum)
opened_container = container("Hello")
opened_container("world", '!')
using all possible ways
post_container = close(formattly_sum, closer=post_partial)
post_container('!')("Hello", "world")
Eventually, they all return
Hello world!
Interface control
Abstract the output value
print(returnly(print)("Some input argument"))
Some input argument
Some input argument
or input values
from functools import partial
eventually(partial(print, 42))(2, 4, 8, 16, 32)
42
Atomic functions
Use any python atomic operations as functions
(lambda reource: (raise_ if isinstance(reource, Exception) else return_)(reource))("no error") # "no error"
execute_operation(60, '+', 4) # 64
transform_by('not', str()) # True
call(range, 16) # range(16)
getitem_of({"some-key": "some-value"}, "some-key") # "some-value"
take(42) # lambda *_, **__: 42
Annotating
Use standart annotation templates from annotations
package for routine cases
from pyhandling.annotations import checker_of, reformer_of, merger_of
from pyannotating import number
is_number_even: checker_of[number] = lambda number: number % 2 == 0
add_hundert_to: reformer_of[number] = lambda number: number + 100
format_lines: merger_of[str] = "{first} {second}{end_symbol}".format
or annotations themselves
from pyannotating import many_or_one
from pyhandling.annotations import handler, decorator
executing_of: Callable[[many_or_one[handler]], decorator] = ...
Function building
Create functions by describing them
total_sum: Callable[[Iterable[many_or_one[number]]], number] = documenting_by(
"""
Function of summing numbers from the input collection or the sum of its
subcollection.
"""
)(
close(map |then>> tuple)(
on_condition(post_partial(isinstance, Iterable), sum, else_=return_)
)
|then>> sum
)
in several processing processes
ratio_of_square_to_full: reformer_of[number] = documenting_by(
"""
Function of getting the ratio of the square of the input number to the
input number to the power of its value.
"""
)(
mergely(
take(execute_operation),
mergely(
take(execute_operation),
return_,
take('*'),
return_
),
take('/'),
mergely(
take(execute_operation),
return_,
take('**'),
return_
)
)
)
or in an indefinite number of iterative executions
from pyhandling.annotations import dirty
increase_up_to_ten: dirty[reformer_of[number]] = documenting_by(
"""
Function that prints numbers between the input number and 10 inclusive and
returns 10.
"""
)(
recursively(
returnly(print) |then>> post_partial(execute_operation, '+', 1),
post_partial(execute_operation, '<', 10)
)
|then>> returnly(print)
)
increase_up_to_ten(8)
8
9
10
Chain breaking
Forcibly break the chain of actions
optionally_exponentiate: Callable[[number], number | BadResourceWrapper] = documenting_by(
"""Function of exponentiation of the input number if it is > 0."""
)(
maybe(
on_condition(
post_partial(execute_operation, '<', 0),
BadResourceWrapper,
else_=return_
)
|then>> post_partial(execute_operation, '**', 2)
)
)
-16 >= optionally_exponentiate |then>> print
<Wrapper of bad -16>
with the possibility of returning a "bad" resource
main: dirty[reformer_of[number]] = optionally_exponentiate |then>> optionally_get_bad_resource_from
8 >= optionally_exponentiate |then>> print
-16 >= optionally_exponentiate |then>> print
64
-16
You can also interrupt by returning an error proxy that stores the error
that occurred while processing this resource and the resource itself
from pyhandling.annotations import reformer_of
div_by_zero: reformer_of[number] = documenting_by(
"""Function for dividing an input number by zero."""
)(
post_partial(execute_operation, '/', 0)
)
main: Callable[[number], number | BadResourceError] = (
returnly_rollbackable(div_by_zero, take(True))
)
256 >= main |then>> print
BadResourceError('Resource "256" could not be handled due to ZeroDivisionError: division by zero')
with corresponding possibilities
main: reformer_of[number] = (
partial(map |then>> maybe, post_partial(returnly_rollbackable, take(True)))(
post_partial(execute_operation, '*', 2)
|then>> div_by_zero
)
|then>> optionally_get_bad_resource_from
)
16 >= main |then>> print
32
Debugging
Display intermediate results
showly(total_sum)([128, [100, 28]])
[128, [100, 28]]
(128, 128)
256
by different ways
logger = Logger(is_date_logging=True)
showly(total_sum, writer=logger)([[2, 10], [15, 15]])
print(*logger.logs, sep='\n')
[2023-01-24 21:38:28.791516] [[2, 10], [15, 15]]
[2023-01-24 21:38:28.791516] (12, 30)
[2023-01-24 21:38:28.791516] 42
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.