Metadata-Version: 2.4
Name: cocobeans
Version: 0.1.1
Summary: A library for representing, transforming, and engineering numerical features.
Author: Shashwat
License: MIT License
        
        Copyright (c) 2026 Shashwat
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
Project-URL: Homepage, https://github.com/IIraycastII/cocobeans
Project-URL: Repository, https://github.com/IIraycastII/cocobeans
Project-URL: Issues, https://github.com/IIraycastII/cocobeans/issues
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# cocobeans

**A lightweight Python library for representing, transforming, and engineering numerical features.**

`cocobeans` provides a simple `Feature` abstraction for numerical data, recursive transformations for nested Python structures, composable transformation pipelines, transformation-history tracking, and automated feature-expression generation.

> **Status:** Early-stage / experimental  
> **Version:** `0.1.1`  
> **Python:** `>=3.10`

---

## Why cocobeans?

Feature engineering can become a collection of disconnected preprocessing functions, temporary variables, and transformations whose history is difficult to track.

`cocobeans` provides a small, composable abstraction around that workflow.

```python
from cocobeans import Feature, Pipeline, FillMissing, Scale, Standardize, Round

feature = Feature([1, None, 3, 4])

pipeline = Pipeline([
    FillMissing(0),
    Scale(2),
    Standardize(),
    Round(3),
])

result = pipeline.fit_transformation(feature)

print(result.data())
```

The original `Feature` remains separate from the transformed result, while transformation history is preserved across operations.

---

## Features

- **Feature abstraction** — represent numerical feature data together with names and metadata.
- **Nested-data support** — recursively process nested Python lists.
- **Non-destructive transformations** — transformations normally return new `Feature` objects.
- **Transformation history** — retain information about how a feature was created and transformed.
- **Composable pipelines** — combine multiple transformations into a sequential workflow.
- **Built-in transformations** — normalization, scaling, standardization, clipping, rounding, type conversion, missing-value handling, replacement, and mathematical transformations.
- **Automatic feature engineering** — generate candidate feature expressions from supplied functions and operators.
- **Zero runtime dependencies** — the current package declares no third-party runtime dependencies.

---

## Installation

### Install from PyPI

```bash
python -m pip install cocobeans
```

### Install from source

```bash
git clone https://github.com/IIraycastII/cocobeans.git
cd cocobeans
python -m pip install .
```

### Development installation

For development, clone the repository and install it in editable mode:

```bash
git clone https://github.com/IIraycastII/cocobeans.git
cd cocobeans
python -m pip install -e .
```

---

## Quick Start

### Create a Feature

```python
from cocobeans import Feature

feature = Feature([10, 20, 30])

print(feature.data())
```

```text
[10, 20, 30]
```

Features can also contain nested lists:

```python
feature = Feature([
    [1, 2],
    [3, 4],
    [5, 6],
])
```

---

## Naming Features

Feature names can be attached when creating a `Feature`:

```python
from cocobeans import Feature

feature = Feature(
    [10, 20, 30],
    names=["age", "height", "weight"],
)
```

The names are represented through the feature's internal marking structure.

For row-oriented nested data:

```python
data = [
    [20, 170],
    [25, 180],
    [30, 175],
]

feature = Feature(
    data,
    names=["age", "height"],
)
```

The feature can interpret these names as columns:

```text
age      -> [20, 25, 30]
height   -> [170, 180, 175]
```

Nested naming structures are also supported when the structure of the names matches the structure of the input data.

---

## Inspecting Features

`Feature` provides methods for inspecting the underlying data and its structure.

### Data

```python
feature.data()
```

### Names / marking

```python
feature.names()
```

### Data types

```python
feature.dtype()
```

For example:

```python
feature = Feature([
    [1, 2],
    [3, 4],
])

print(feature.dtype())
```

Conceptually:

```python
{"int": 4}
```

### Shape

```python
feature.shape()
```

`shape()` describes the structure of nested feature data and also reports whether the structure is distorted.

---

# Transformations

Transformations are represented as operation objects.

The built-in operations are:

| Operation | Purpose |
| --- | --- |
| `Normalize` | Normalize numerical values |
| `TypeCast` | Recursively convert values to a target type |
| `Scale` | Multiply values by a constant |
| `Standardize` | Standardize values using mean and population standard deviation |
| `Clip` | Restrict values to a specified range |
| `Round` | Round numerical values |
| `FillMissing` | Replace `None` values |
| `Replace` | Replace matching values |
| `Transform` | Apply functions from Python's `math` module |

All of these are available directly from `cocobeans`:

```python
from cocobeans import (
    Normalize,
    TypeCast,
    Scale,
    Standardize,
    Clip,
    Round,
    FillMissing,
    Replace,
    Transform,
)
```

---

## Normalize

Normalize numerical values to the `[0, 1]` range.

```python
from cocobeans import Feature, Normalize

feature = Feature([10, 20, 30])

result = Normalize(feature).apply()

print(result.data())
```

```text
[0.0, 0.5, 1.0]
```

The transformation uses:

```text
(value - minimum) / (maximum - minimum)
```

Constant-valued inputs are handled without division by zero.

---

## Scale

Multiply every numerical leaf value by a constant.

```python
from cocobeans import Feature, Scale

feature = Feature([1, 2, 3])

result = Scale(10, feature).apply()

print(result.data())
```

```text
[10, 20, 30]
```

---

## Standardize

Standardize numerical values using their mean and population standard deviation.

```python
from cocobeans import Feature, Standardize

feature = Feature([1, 2, 3])

result = Standardize(feature).apply()

print(result.data())
```

The transformation is:

```text
(value - mean) / standard_deviation
```

For constant-valued data, the result is represented as zeros.

---

## Clip

Restrict values to a specified interval.

```python
from cocobeans import Feature, Clip

feature = Feature([1, 5, 10, 20])

result = Clip(5, 10, feature).apply()

print(result.data())
```

```text
[5, 5, 10, 10]
```

`Clip` raises `ValueError` when the minimum value is greater than the maximum value.

---

## Round

Apply Python's `round()` recursively.

```python
from cocobeans import Feature, Round

feature = Feature([1.234, 5.678])

result = Round(2, feature).apply()

print(result.data())
```

```text
[1.23, 5.68]
```

---

## Fill Missing Values

Replace `None` values recursively.

```python
from cocobeans import Feature, FillMissing

feature = Feature([1, None, 3, None])

result = FillMissing(0, feature).apply()

print(result.data())
```

```text
[1, 0, 3, 0]
```

---

## Replace Values

Replace every matching leaf value.

```python
from cocobeans import Feature, Replace

feature = Feature([1, 2, 1, 3])

result = Replace(1, 99, feature).apply()

print(result.data())
```

```text
[99, 2, 99, 3]
```

---

## Type Conversion

Convert feature values recursively.

```python
from cocobeans import Feature, TypeCast

feature = Feature([1, 2, 3])

result = TypeCast(float, feature).apply()

print(result.data())
```

```text
[1.0, 2.0, 3.0]
```

`Feature.to()` provides the corresponding feature-level conversion API:

```python
feature = Feature([1, 2, 3])

converted = feature.to(float)

print(converted.data())
```

---

## Mathematical Transformations

`Transform` can apply named functions from Python's `math` module.

```python
from cocobeans import Feature, Transform

feature = Feature([1, 4, 9])

result = Transform(
    ["sqrt"],
    feature,
).apply()

print(result.data())
```

```text
[1.0, 2.0, 3.0]
```

Multiple mathematical operations can be applied sequentially:

```python
result = Transform(
    ["sqrt", "log"],
    feature,
).apply()
```

If a requested operation does not exist in `math`, `ValueError` is raised.

---

# Pipelines

`Pipeline` allows multiple transformations to be composed into a single workflow.

```python
from cocobeans import (
    Feature,
    Pipeline,
    FillMissing,
    Scale,
    Standardize,
    Round,
)

feature = Feature([
    1,
    None,
    3,
    4,
])

pipeline = Pipeline([
    FillMissing(0),
    Scale(2),
    Standardize(),
    Round(3),
])

result = pipeline.fit_transformation(feature)
```

Operations are executed sequentially:

```text
Feature
   │
   ▼
FillMissing
   │
   ▼
Scale
   │
   ▼
Standardize
   │
   ▼
Round
   │
   ▼
Result
```

Operations do not need to receive their `Feature` when they are constructed:

```python
pipeline = Pipeline([
    FillMissing(0),
    Scale(2),
    Round(2),
])

result = pipeline.fit_transformation(feature)
```

The pipeline supplies the current feature to each operation before applying it.

---

# Transformation History

`Feature` objects maintain transformation history.

```python
feature = Feature([1, 2, 3])

scaled = Scale(10, feature).apply()

print(scaled.history())
```

The original creation and subsequent transformations are recorded in the feature's history.

Transformations generally preserve the previous history and append information about the new operation.

This makes it possible to inspect how a feature was produced rather than only looking at its final values.

---

# Recursive Processing

`Recursive` exposes the recursive machinery used by the library.

```python
from cocobeans import Recursive

result = Recursive.apply(
    [1, [2, 3], [4, [5, 6]]],
    lambda x: x * 2,
)

print(result)
```

```text
[2, [4, 6], [8, [10, 12]]]
```

The function is applied to leaf values while preserving the nested list structure.

`Recursive.copy()` can also be used to create a separate `Feature` while preserving its data, names, and history.

---

# Automated Feature Engineering

`FeatureEngineer` provides an experimental mechanism for generating feature expressions automatically.

It can combine:

- feature values
- unary operators
- multi-argument functions
- generated expressions

For example:

```python
from cocobeans import Feature, FeatureEngineer

def add(x, y):
    return x + y

feature = Feature(
    [1, 2, 3],
    names=["x", "y", "z"],
)

engineer = FeatureEngineer(
    feature,
    functions=[add],
    horizontal_depth=1,
    vertical_depth=1,
)

result = engineer.generate()

print(result)
```

Generated results are represented as expression/value mappings, conceptually:

```python
[
    {"x": 1},
    {"y": 2},
    {"add(x, y)": 3},
]
```

The exact result depends on the supplied data, functions, operators, and depth configuration.

## FeatureEngineer Complexity

`FeatureEngineer` can become computationally expensive as the number of generated expressions increases.

Multi-argument functions generate combinations of available expressions, and increasing `horizontal_depth` or `vertical_depth` can significantly increase both computation time and memory usage.

For this reason, `FeatureEngineer` should be treated as an experimental, potentially expensive feature-generation mechanism.

---

# API Overview

## Core

```python
from cocobeans import Feature, Recursive
```

### `Feature`

```python
Feature(input_features, names=None)
```

Provides:

```python
feature.data()
feature.names()
feature.dtype()
feature.shape()
feature.to(...)
feature.history()
```

### `Recursive`

```python
Recursive.apply(data, func)
Recursive.copy(feature)
```

---

## Transformations

```python
from cocobeans import (
    Normalize,
    TypeCast,
    Scale,
    Standardize,
    Clip,
    Round,
    FillMissing,
    Replace,
    Transform,
)
```

---

## Composition

```python
from cocobeans import Pipeline
```

```python
Pipeline(actions)
```

Run a pipeline with:

```python
pipeline.fit_transformation(feature)
```

---

## Feature Engineering

```python
from cocobeans import FeatureEngineer
```

```python
FeatureEngineer(
    feature,
    functions=None,
    operators=None,
    horizontal_depth=1,
    vertical_depth=1,
)
```

Generate expressions with:

```python
engineer.generate()
```

---

# Supported Data Model

`cocobeans` is currently designed primarily around:

- Python lists
- nested Python lists
- scalar numerical values
- `None` values for missing data

The recursive processing model is based on Python lists.

`cocobeans` is **not currently a pandas-native or NumPy-native library**. NumPy arrays, pandas Series, DataFrames, tensors, and other array types should not be assumed to be first-class supported inputs unless explicitly added in a future release.

---

# Design Principles

`cocobeans` is built around a few core principles.

### Feature-centered

The `Feature` object is the central representation of feature data.

### Non-destructive transformations

Transformations generally create new `Feature` objects rather than modifying the original feature.

### Recursive data processing

Operations work recursively across nested Python lists.

### Transformation history

Feature transformations preserve information about how the current result was produced.

### Composable operations

Individual transformations can be combined into reusable pipelines.

### Separate automated feature generation

`FeatureEngineer` provides a distinct mechanism for generating candidate feature expressions.

---

# Requirements

- Python `3.10` or newer
- No third-party runtime dependencies in the current release

The project currently uses `setuptools` as its build backend and PEP 621 project metadata.

---

# Development

Clone the repository and create a virtual environment:

```bash
git clone https://github.com/IIraycastII/cocobeans.git
cd cocobeans

python -m venv .venv
```

Activate the environment and install the package in editable mode:

```bash
python -m pip install -e .
```

Run the test suite:

```bash
python -m pytest
```

The current test suite contains **156 passing tests**.

---

# Building the Package

Build the source distribution and wheel with:

```bash
python -m build
```

The `dist/` directory will contain the source distribution and wheel for the current release.

Before publishing a release, validate the generated distributions with:

```bash
python -m twine check dist/*
```

Package installation should also be validated from outside the source tree to ensure testing uses the installed distribution rather than the local source package.

---

# Project Structure

The core source layout is intentionally small:

```text
cocobeans/
├── cocobeans/
│   ├── __init__.py
│   ├── Feature.py
│   ├── FeatureEngineer.py
│   ├── Operations.py
│   ├── Pipeline.py
│   └── Recursive.py
│
├── tests/
│   ├── test_feature.py
│   ├── test_feature_engineer.py
│   ├── test_operations.py
│   ├── test_pipeline.py
│   └── test_recursive.py
│
├── .github/
│   └── workflows/
│
├── pyproject.toml
├── README.md
└── LICENSE
```

Build artifacts and local development environments are not part of the library's public API.

---

# Current Limitations

`cocobeans` is currently an early-stage library. The following limitations should be understood before using it in production systems:

- The implementation is primarily Python-list oriented.
- Numerical operations assume compatible numerical leaf values.
- NumPy and pandas are not runtime dependencies.
- Pipeline operation objects are stateful because the pipeline assigns `feature_instance` before execution.
- `FeatureEngineer` can have significant computational and memory costs as expression depth grows.
- `Transform` resolves operations through Python's `math` module.
- The public API is still subject to stabilization before a `1.0` release.

---

# Roadmap

Areas being considered for future development include:

- API stabilization
- expanded edge-case and integration testing
- supported-version testing
- improved package metadata
- API documentation
- tutorials and examples
- stronger type hints
- improved docstrings
- more consistent error handling
- clearer transformation-history semantics
- performance testing and controls for `FeatureEngineer`
- clearer data-shape semantics
- optional integrations with numerical and data-science ecosystems

The roadmap is intentionally non-binding and may change as the library evolves.

---

# Contributing

Contributions are welcome.

Before submitting a change:

1. Preserve the existing public API unless the change is intentional.
2. Add or update tests for behavioral changes.
3. Avoid introducing dependencies without a clear reason.
4. Consider nested-list behavior when modifying recursive operations.
5. Preserve transformation-history semantics unless intentionally redesigning them.
6. Consider the computational cost of changes to `FeatureEngineer`.
7. Clearly distinguish bug fixes from API or design changes.

Run the complete test suite before submitting a change:

```bash
python -m pytest
```

For breaking API changes, document:

- what is changing
- why it is changing
- what existing code will be affected
- whether the change should be deferred to a major release

---

# Versioning

The current version is:

```text
0.1.1
```

The project is not yet at a stable `1.0` API.

Future releases should follow a deliberate versioning policy so that users can distinguish between bug fixes, backward-compatible features, and breaking changes.

---

# License

`cocobeans` is released under the MIT License.

See the [LICENSE](https://github.com/IIraycastII/cocobeans/blob/main/LICENSE) file for the complete license text.

---

# Project Status

`cocobeans` currently has:

- a public Python API
- a test suite with 156 passing tests
- a `pyproject.toml`
- editable installation support
- source distribution support
- wheel distribution support
- no declared third-party runtime dependencies
- continuous integration through GitHub Actions
- a public PyPI release

The project is currently best described as an **early-stage functional development package**. The public API may change before the project reaches a stable `1.0` release.

---

## Links

- **PyPI:** https://pypi.org/project/cocobeans/
- **Repository:** https://github.com/IIraycastII/cocobeans
- **Issue tracker:** https://github.com/IIraycastII/cocobeans/issues

---

## Acknowledgements

Built with Python and the standard Python packaging ecosystem.
