Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/code-checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
python-version: ["3.12", "3.13", "3.14"]

steps:

Expand Down
9 changes: 9 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Complexitty ChangeLog

## Unreleased

**Released: WiP**

- Dropped support for Python 3.10 and Python 3.11. ([#36](https://github.com/davep/complexitty/pull/36))
- Added optional support for using [Numba](https://numba.pydata.org) to
speed up the calculations.
([#36](https://github.com/davep/complexitty/pull/36))

## v1.0.0

**Released: 2025-10-03**
Expand Down
26 changes: 22 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,33 @@ The package can be installed using [`pipx`](https://pypa.github.io/pipx/):
$ pipx install complexitty
```

### Homebrew
### uv

The package is available via Homebrew. Use the following commands to install:
The application can be installed using [`uv`](https://docs.astral.sh/uv/getting-started/installation/):

```sh
$ brew tap davep/homebrew
$ brew install complexitty
uv tool install complexitty
```

If you don't have `uv` installed you can use [uvx.sh](https://uvx.sh) to
perform the installation. For GNU/Linux or macOS or similar:

```sh
curl -LsSf uvx.sh/complexitty/install.sh | sh
```

or on Windows:

```sh
powershell -ExecutionPolicy ByPass -c "irm https://uvx.sh/complexitty/install.ps1 | iex"
```

### Going faster

Complexitty has a (currently experimental) installation option to make it go
faster using [Numba](http://numba.pydata.org). If you want to try this out,
install it as `complexitty[faster]` rather than `complexitty`.

## Using Complexitty

Once you've installed Complexitty using one of the above methods, you can
Expand Down
19 changes: 14 additions & 5 deletions docs/source/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,25 @@ uvx complexitty

to run `complexitty`.

### Homebrew
If you don't have `uv` installed you can use [uvx.sh](https://uvx.sh) to
perform the installation. For GNU/Linux or macOS or similar:

The package is available via [Homebrew](https://brew.sh). Use the following
commands to install:
```sh
curl -LsSf uvx.sh/complexitty/install.sh | sh
```

or on Windows:

```sh
brew tap davep/homebrew
brew install complexitty
powershell -ExecutionPolicy ByPass -c "irm https://uvx.sh/complexitty/install.ps1 | iex"
```

### Going faster

Complexitty has a (currently experimental) installation option to make it go
faster using [Numba](http://numba.pydata.org). If you want to try this out,
install it as `complexitty[faster]` rather than `complexitty`.

## Running Complexitty

Once you've installed Complexitty using one of the [above
Expand Down
11 changes: 7 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ dependencies = [
"xdg-base-dirs>=6.0.2",
]
readme = "README.md"
requires-python = ">= 3.10"
requires-python = ">= 3.12"
license = "GPL-3.0-or-later"
keywords = [
"terminal",
Expand All @@ -29,8 +29,6 @@ classifiers = [
"Intended Audience :: End Users/Desktop",
"Intended Audience :: Science/Research",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
Expand All @@ -50,11 +48,16 @@ Source = "https://github.com/davep/complexitty"
Issues = "https://github.com/davep/complexitty/issues"
Discussions = "https://github.com/davep/complexitty/discussions"

[project.optional-dependencies]
faster = [
"numba>=0.59.0",
]

[project.scripts]
complexitty = "complexitty.__main__:main"

[build-system]
requires = ["uv_build>=0.8.11,<0.9.0"]
requires = ["uv_build>=0.9.4"]
build-backend = "uv_build"

[tool.uv]
Expand Down
23 changes: 23 additions & 0 deletions src/complexitty/mandelbrot/calculator.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
"""The code for calculating the Mandelbrot set."""

##############################################################################
# Python imports.
from collections.abc import Callable
from typing import cast

##############################################################################
# Set up for [faster] support.

type MandelbrotCalculator = Callable[[float, float, float, int], int]
"""Type of the Mandelbrot calculator function."""

try:
from numba import jit # type: ignore[import-not-found]

def _maybe_faster(calculator: MandelbrotCalculator) -> MandelbrotCalculator:
return cast(MandelbrotCalculator, jit(nopython=True)(calculator))

except ImportError:

def _maybe_faster(calculator: MandelbrotCalculator) -> MandelbrotCalculator:
return calculator


##############################################################################
@_maybe_faster
def mandelbrot(x: float, y: float, multibrot: float, max_iteration: int) -> int:
"""Return the Mandelbrot calculation for the given point.

Expand Down
4 changes: 2 additions & 2 deletions src/complexitty/mandelbrot/colouring.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
# Python imports.
from collections.abc import Callable
from functools import lru_cache
from typing import Final, TypeAlias
from typing import Final

##############################################################################
# Textual imports.
from textual.color import Color, Gradient

##############################################################################
ColourMap: TypeAlias = Callable[[int, int], Color]
type ColourMap = Callable[[int, int], Color]
"""Type for a colour map."""


Expand Down
8 changes: 4 additions & 4 deletions src/complexitty/mandelbrot/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
from dataclasses import dataclass
from time import monotonic

##############################################################################
# Typing extension imports.
from typing import Self

##############################################################################
# Textual imports.
from textual import on
Expand All @@ -20,10 +24,6 @@
# Textual-canvas imports.
from textual_canvas import Canvas

##############################################################################
# Typing extension imports.
from typing_extensions import Self

##############################################################################
# Local imports.
from .calculator import mandelbrot
Expand Down
19 changes: 16 additions & 3 deletions src/complexitty/screens/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
# Python imports.
from argparse import Namespace
from collections import deque
from functools import cache
from importlib.util import find_spec
from math import floor, log10
from re import Pattern, compile
from typing import Final, NamedTuple, TypeAlias
from typing import Final, NamedTuple

##############################################################################
# Textual imports.
Expand Down Expand Up @@ -78,7 +80,18 @@ class Situation(NamedTuple):


##############################################################################
PlotHistory: TypeAlias = deque[Situation]
@cache
def _faster_label() -> str:
"""Get the label that gives our faster status.

Returns:
The labelto show the faster status.
"""
return " | [b]Faster[/]" if find_spec("numba") else ""


##############################################################################
PlotHistory = deque[Situation]
"""Type of the plot history."""


Expand Down Expand Up @@ -217,7 +230,7 @@ def _update_situation(self, message: Mandelbrot.Plotted) -> None:
message.mandelbrot.border_subtitle = (
f"{message.mandelbrot.multibrot:0.2f} multibrot | "
f"{message.mandelbrot.max_iteration:0.2f} iterations | "
f"{message.elapsed:0.4f} seconds"
f"{message.elapsed:0.4f} seconds{_faster_label()}"
)

def _remember(self) -> None:
Expand Down
Loading