Skip to content

Tutorial: conditions

Paul Alexander Bilokon edited this page Dec 15, 2024 · 1 revision

Tutorial: Using Precondition and Postcondition Decorators in thalesians.adiutor.conditions

This tutorial explains how to use the @precondition and @postcondition decorators from the thalesians.adiutor.conditions library to validate function arguments and return values, ensuring robust and reliable code.

Precondition Decorator

The @precondition decorator validates input arguments before a function is executed. It takes a validation function and an error message as arguments.

Example: Unary Function Precondition

from thalesians.adiutor.conditions import precondition

@precondition(lambda arg: arg >= 0, 'arg must be greater than or equal to 0')
def plus_one(arg):
    return arg + 1

print(plus_one(1))  # Output: 2
plus_one(-1)  # Raises AssertionError: arg must be greater than or equal to 0

Postcondition Decorator

The @postcondition decorator validates the return value of a function after it is executed. It takes a validation function and an error message as arguments.

Example: Unary Function Postcondition

from thalesians.adiutor.conditions import postcondition

@postcondition(lambda result: result >= 0, 'result must be greater than or equal to 0')
def plus_one(arg):
    return arg + 1

print(plus_one(1))  # Output: 2
plus_one(-2)  # Raises AssertionError: result must be greater than or equal to 0

Using Preconditions and Postconditions in Methods

Example: Method with Precondition

class Adder:
    @precondition(lambda self, arg: arg >= 0, 'arg must be greater than or equal to 0')
    def plus_one(self, arg):
        return arg + 1

adder = Adder()
print(adder.plus_one(1))  # Output: 2
adder.plus_one(-1)  # Raises AssertionError: arg must be greater than or equal to 0

Example: Method with Precondition and Postcondition

class Subtractor:
    @precondition(lambda self, arg1, arg2: arg1 >= 0, 'arg1 must be greater than or equal to 0')
    @precondition(lambda self, arg1, arg2: arg2 >= 0, 'arg2 must be greater than or equal to 0')
    @postcondition(lambda result: result >= 0, 'result must be greater than or equal to 0')
    def subtract(self, arg1, arg2):
        return arg1 - arg2

subtractor = Subtractor()
print(subtractor.subtract(300, 200))  # Output: 100
subtractor.subtract(200, 300)  # Raises AssertionError: result must be greater than or equal to 0

Advanced Usage

Precondition Composition

You can compose multiple preconditions for more complex validation.

@precondition(lambda arg1, arg2: arg1 >= 0, 'arg1 must be greater than or equal to 0')
@precondition(lambda arg1, arg2: arg2 >= 0, 'arg2 must be greater than or equal to 0')
def add(arg1, arg2):
    return arg1 + arg2

print(add(100, 200))  # Output: 300
add(100, -200)  # Raises AssertionError: arg2 must be greater than or equal to 0

Conclusion

Using @precondition and @postcondition decorators can help enforce data validation and simplify debugging by clearly defining the expected behavior of your functions and methods.

For more details, refer to the official documentation.