Skip to main content

A simple pythonic implementation of the Specification Pattern for Python 3.7 or higher.

Project description

Build Status Code Coverage https://badge.fury.io/py/simple-specification.svg

A simple pythonic implementation of the Specification Pattern for Python 3.7 or higher.

Installation

pip install simple-specification

Examples

Creating specification classes to check integer numbers

from simple_specification import Specification


# hardcoded specification
class Odd(Specification):
    def is_satisfied_by(self, candidate: int) -> bool:
        return candidate % 2 != 0


# parametrized specification
class DivisibleBy(Specification):
    def __init__(self, number: int):
        self.number = number

    def is_satisfied_by(self, candidate: int) -> bool:
        return candidate % self.number == 0

Instantiating the specifications

>>> odd = Odd()
>>> even = ~odd
>>> div3 = DivisibleBy(3)
>>> div5 = DivisibleBy(5)

Using specifications - method is_satisfied_by(candidate)

>>> odd.is_satisfied_by(1)
True
>>> odd.is_satisfied_by(2)
False
>>> even.is_satisfied_by(3)
False
>>> even.is_satisfied_by(4)
True
>>> div3.is_satisfied_by(9)
True
>>> div5.is_satisfied_by(12)
False

Composing specifications - operators & and |

>>> # AND
>>> (even & div3).is_satisfied_by(6)
True
>>> (even & div3).is_satisfied_by(9)
False
>>> (even & div3 & div5).is_satisfied_by(30)
True
>>> (even & div3 & div5).is_satisfied_by(36)
False
>>>
>>> # OR
>>> (even | div3).is_satisfied_by(10)
True
>>> (even | div3).is_satisfied_by(15)
True
>>> (even | div3).is_satisfied_by(5)
False

Negating specifications - operator ~

Warning

Always surround the negation with parenthesis

>>> (~odd).is_satisfied_by(2)
True
>>> (~div5).is_satisfied_by(25)
False
>>> (~div5).is_satisfied_by(11)
True
>>> (~(odd | div5)).is_satisfied_by(6)
True
>>> (~(odd | div5)).is_satisfied_by(7)
False

Composing a list of specifications with & - class method Specification.all(specs)

>>> all_spec = Specification.all([~even, div3, div5])
>>> all_spec.is_satisfied_by(15)
True
>>> all_spec.is_satisfied_by(30)
False
>>> all_spec.is_satisfied_by(25)
False
>>> all_spec.is_satisfied_by(6)
False

Composing a list of specifications with | - class method Specification.any(specs)

>>> div15 = DivisibleBy(3) & DivisibleBy(5)
>>> any_spec = Specification.any([div15, even])
>>> any_spec.is_satisfied_by(2)
True
>>> any_spec.is_satisfied_by(15)
True
>>> any_spec.is_satisfied_by(30)
True
>>> any_spec.is_satisfied_by(3)
False
>>> any_spec.is_satisfied_by(5)
False

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for simple-specification, version 0.3
Filename, size File type Python version Upload date Hashes
Filename, size simple_specification-0.3-py3-none-any.whl (3.6 kB) File type Wheel Python version py3 Upload date Hashes View
Filename, size simple-specification-0.3.tar.gz (2.6 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page