Metadata-Version: 2.4
Name: eule
Version: 1.4.0
Summary: Euler diagrams in python
Project-URL: homepage, https://pypi.org/project/eule/
Project-URL: repository, https://github.com/trouchet/eule
Author-email: Bruno Peixoto <brunolnetto@gmail.com>
Maintainer-email: Bruno Peixoto <brunolnetto@gmail.com>
License: MIT License
License-File: LICENSE
Keywords: euler-diagram,sets
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Programming Language :: Python
Requires-Python: >=3.9
Requires-Dist: numpy>1.20.0
Provides-Extra: build
Requires-Dist: mypy>=0.991; extra == 'build'
Requires-Dist: wheel>=0.38.4; extra == 'build'
Provides-Extra: docs
Requires-Dist: docutils>=0.18.1; extra == 'docs'
Requires-Dist: sphinx-rtd-theme>=1.2.0; extra == 'docs'
Requires-Dist: sphinx>=6.0.0; extra == 'docs'
Requires-Dist: sphinxcontrib-serializinghtml>=1.1.5; extra == 'docs'
Requires-Dist: sphinxcontrib-websupport>=1.2.4; extra == 'docs'
Requires-Dist: toml>=0.10.2; extra == 'docs'
Requires-Dist: types-toml>=0.10.8.5; extra == 'docs'
Provides-Extra: geometry
Requires-Dist: matplotlib>=3.5.0; extra == 'geometry'
Requires-Dist: shapely>=2.0.0; extra == 'geometry'
Provides-Extra: interval
Requires-Dist: interval-sets>=0.1.0; extra == 'interval'
Provides-Extra: lint
Requires-Dist: black<25.0,>=22.12; extra == 'lint'
Requires-Dist: isort>=5.11.4; extra == 'lint'
Requires-Dist: pre-commit>=2.20.0; extra == 'lint'
Requires-Dist: pylint>=2.15.9; extra == 'lint'
Requires-Dist: ruff>=0.0.217; extra == 'lint'
Provides-Extra: test
Requires-Dist: coverage>=7.0; extra == 'test'
Requires-Dist: pytest-cov>=4.0.0; extra == 'test'
Requires-Dist: pytest-timer>=1.0.0; extra == 'test'
Requires-Dist: pytest-watch>=4.2.0; extra == 'test'
Requires-Dist: pytest>=7.2.0; extra == 'test'
Requires-Dist: types-mock>=4.0.15.2; extra == 'test'
Requires-Dist: watchdog>=3.0.0; extra == 'test'
Description-Content-Type: text/markdown

![a night owl](https://github.com/trouchet/eule/blob/main/images/eule_small.png?raw=true)

[![Version](https://img.shields.io/pypi/v/eule.svg)](https://pypi.python.org/pypi/eule)
[![downloads](https://img.shields.io/pypi/dm/eule)](https://pypi.org/project/eule/)
[![codecov](https://codecov.io/gh/trouchet/eule/branch/main/graph/badge.svg?token=PJMBaLIqar)](https://codecov.io/gh/trouchet/eule)
[![Documentation Status](https://readthedocs.org/projects/eule/badge/?version=latest)](https://eule.readthedocs.io/en/latest/?version=latest)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/trouchet/eule/HEAD)

**Eule** is a universal logic engine for generating Euler diagrams and analyzing set relationships. 

It generates **non-empty Euler diagrams** (disjoint partitions) for **ANY** type of overlapping data:
- **Discrete Sets**: Strings, integers, custom objects.
- **Continuous Intervals**: Time ranges, numerical values (via `interval-sets`).
- **Geometric Shapes**: 2D Polygons, 3D Boxes (via `shapely` and `box-sets`).

Motivation
================

<img src="https://github.com/trouchet/eule/blob/main/images/euler_venn.png?raw=true" width="400" height="364"/>

Installation
================

```bash
# Standard install (Discrete sets)
pip install eule

# With Interval support
pip install "eule[interval]"

# With Geometry support
pip install "eule[geometry]"
```

Universal Logic Engine 🚀
=========================

Eule is no longer just for Python sets. It now supports the **SetLike Protocol**, allowing it to compute disjoint regions for advanced mathematical objects.

### 1. Discrete Sets (Standard)
```python
from eule import euler

sets = {
    'A': {1, 2, 3},
    'B': {2, 3, 4},
    'C': {3, 4, 5}
}
diagram = euler(sets)
# Returns disjoint decomposition: 
# {'A': {1}, 'B': {5}, 'C': {6}, 'A,B': {2}, ...}
```

### 2. Continuous Intervals (Time/Numbers)
*Requires `interval-sets`*

```python
from interval_sets import IntervalSet, Interval
from eule import euler

schedules = {
    'Alice': IntervalSet([Interval(9, 12), Interval(13, 17)]),
    'Bob':   IntervalSet([Interval(11, 14)])
}

# Find exact overlap: 11:00-12:00 and 13:00-14:00
diagram = euler(schedules) 
```

### 3. Geometric Shapes (2D/3D)
*Requires `shapely`*

```python
from shapely.geometry import Polygon
from eule import euler

territories = {
    'Wolves': Polygon([(0,0), (0,10), (10,10), (10,0)]),
    'Bears':  Polygon([(5,5), (5,15), (15,15), (15,5)])
}

# Automatically computes the exact Intersection Polygon!
diagram = euler(territories)
```

Examples
========

Check the `examples/` directory for advanced real-world use cases:

- **[case_scatter_hulls.py](examples/case_scatter_hulls.py)**: 🐾 **Ecology / Spatial** - Convex Hull analysis of scatter points (e.g., animal territories).
- **[case_3d_clash_detection.py](examples/case_3d_clash_detection.py)**: 🏗️ **Engineering / BIM** - 3D Box collision detection (Beams vs HVAC).
- **[case_scheduling.py](examples/case_scheduling.py)**: 🗓️ **Productivity** - Finding common free time across multiple calendars.
- **[case_nlp_stylometry.py](examples/case_nlp_stylometry.py)**: 📜 **NLP** - Vocabulary overlap analysis.

How to Contribute
=================

We welcome implementations of the `SetLike` protocol for new domains!
See [Protocol Specification](docs/design/PROTOCOL_SPECIFICATION.md).
