Skip to content

Commit 1b39071

Browse files
authored
🔀 Merge pull request #7 from davep/cli
Add support for passing plot parameters on the command line
2 parents 9f4086e + 3344f42 commit 1b39071

File tree

9 files changed

+210
-19
lines changed

9 files changed

+210
-19
lines changed

ChangeLog.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
# Complexitty ChangeLog
22

3+
## Unreleased
4+
5+
**Released: WiP**
6+
7+
- Added `--colour-map` as a command line switch.
8+
([#7](https://github.com/davep/complexitty/pull/7))
9+
- Added `--max-iteration` as a command line switch.
10+
([#7](https://github.com/davep/complexitty/pull/7))
11+
- Added `--multibrot` as a command line switch.
12+
([#7](https://github.com/davep/complexitty/pull/7))
13+
- Added `--x-position` as a command line switch.
14+
([#7](https://github.com/davep/complexitty/pull/7))
15+
- Added `--y-position` as a command line switch.
16+
([#7](https://github.com/davep/complexitty/pull/7))
17+
- Added `--zoom` as a command line switch.
18+
([#7](https://github.com/davep/complexitty/pull/7))
19+
320
## v0.1.1
421

522
**Released: 2025-04-19**

docs/screenshots/basic_app.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
from complexitty.complexitty import Complexitty
44

5-
app = Complexitty(Namespace(theme="textual-dark"))
5+
app = Complexitty(
6+
Namespace(
7+
colour_map=None,
8+
max_iteration=None,
9+
multibrot=None,
10+
theme="textual-dark",
11+
x_position=None,
12+
y_position=None,
13+
zoom=None,
14+
)
15+
)
616
if __name__ == "__main__":
717
app.run()

docs/source/index.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ command.
5151

5252
### Command line options
5353

54-
Complexity has a number of command line options; they include:
54+
Complexitty has a number of command line options; they include:
5555

5656
#### `-b`, `--bindings`
5757

@@ -65,6 +65,10 @@ complexitty --bindings
6565
complexitty --bindings
6666
```
6767

68+
#### `-c`, `--colour-map`, `--color-map`
69+
70+
Set the colour map to use in the plot.
71+
6872
#### `-h`, `--help`
6973

7074
Prints the help for the `complexitty` command.
@@ -76,6 +80,10 @@ complexitty --help
7680
complexitty --help
7781
```
7882

83+
#### `-i`, `--max-iteration`
84+
85+
Set the maximum number of iterations for the plot's calculation.
86+
7987
#### `--license`, `--licence`
8088

8189
Prints a summary of [Complexitty's license](license.md).
@@ -87,6 +95,10 @@ complexitty --license
8795
complexitty --license
8896
```
8997

98+
#### `-m`, `--multibrot`
99+
100+
Set the 'multibrot' parameter for the plot.
101+
90102
#### `-t`, `--theme`
91103

92104
Sets Complexitty's theme; this overrides and changes any previous theme choice made
@@ -112,6 +124,18 @@ complexitty --version
112124
complexitty --version
113125
```
114126

127+
#### `-x`, `--x-position`
128+
129+
Set the X position of the centre of the plot.
130+
131+
#### `-y`, `--y-position`
132+
133+
Set the Y position of the centre of the plot.
134+
135+
#### `-z`, `--zoom`
136+
137+
Set the amount of zoom to use for the plot.
138+
115139
## Getting help
116140

117141
A great way to get to know Complexitty is to read the help screen. Once in

src/complexitty/__main__.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# Local imports.
1111
from . import __doc__, __version__
1212
from .complexitty import Complexitty
13+
from .mandelbrot import colour_maps
1314

1415

1516
##############################################################################
@@ -52,6 +53,56 @@ def get_args() -> Namespace:
5253
action="store_true",
5354
)
5455

56+
# Add --colour-map
57+
parser.add_argument(
58+
"-c",
59+
"--colour-map",
60+
"--color-map",
61+
help="Set the colour map",
62+
type=str,
63+
choices=colour_maps(),
64+
)
65+
66+
# Add --max-iteration
67+
parser.add_argument(
68+
"-i",
69+
"--max-iteration",
70+
help="Set maximum iterations",
71+
type=int,
72+
)
73+
74+
# Add --multibrot
75+
parser.add_argument(
76+
"-m",
77+
"--multibrot",
78+
help="Set the 'multibrot' value",
79+
type=int,
80+
)
81+
82+
# Add --x-position
83+
parser.add_argument(
84+
"-x",
85+
"--x-position",
86+
help="Set the X position",
87+
type=float,
88+
)
89+
90+
# Add --x-position
91+
parser.add_argument(
92+
"-y",
93+
"--y-position",
94+
help="Set the Y position",
95+
type=float,
96+
)
97+
98+
# Add --zoom
99+
parser.add_argument(
100+
"-z",
101+
"--zoom",
102+
help="Set the zoom level",
103+
type=int,
104+
)
105+
55106
# Add --theme
56107
parser.add_argument(
57108
"-t",

src/complexitty/complexitty.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def get_default_screen(self) -> Main:
8484
Returns:
8585
The default screen.
8686
"""
87-
return Main()
87+
return Main(self._arguments)
8888

8989

9090
### complexitty.py ends here

src/complexitty/mandelbrot/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
##############################################################################
44
# Local imports.
5+
from .colouring import colour_maps, get_colour_map
56
from .widget import Mandelbrot
67

78
##############################################################################
89
# Exports.
9-
__all__ = ["Mandelbrot"]
10+
__all__ = ["Mandelbrot", "colour_maps", "get_colour_map"]
1011

1112
### __init__.py ends here

src/complexitty/mandelbrot/colouring.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
##############################################################################
44
# Python imports.
55
from functools import lru_cache
6-
from typing import Callable, TypeAlias
6+
from typing import Callable, Final, TypeAlias
77

88
##############################################################################
99
# Textual imports.
@@ -118,4 +118,35 @@ def shades_of_blue(value: int, _: int) -> Color:
118118
return BLUES[value % 16]
119119

120120

121+
##############################################################################
122+
COLOUR_MAPS: Final[dict[str, ColourMap]] = {
123+
"blue_brown_map": blue_brown_map,
124+
"default_map": default_map,
125+
"shades_of_blue": shades_of_blue,
126+
"shades_of_green": shades_of_green,
127+
"shades_of_red": shades_of_red,
128+
}
129+
"""Name to colour map function map."""
130+
131+
132+
##############################################################################
133+
def colour_maps() -> tuple[str, ...]:
134+
"""Get the names of the available colour maps."""
135+
return tuple(COLOUR_MAPS.keys())
136+
137+
138+
##############################################################################
139+
def get_colour_map(map_name: str) -> ColourMap:
140+
"""Get a colour mapping function by its name.
141+
142+
Args:
143+
map_name: The name of the map to get.
144+
145+
Returns:
146+
The requested colour mapping function, or the default map if the
147+
name isn't known.
148+
"""
149+
return COLOUR_MAPS.get(map_name, default_map)
150+
151+
121152
### colouring.py ends here

src/complexitty/mandelbrot/widget.py

Lines changed: 45 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,42 @@ def plot(self) -> Self:
109109
self.post_message(self.Plotted(self, monotonic() - start))
110110
return self
111111

112+
def set(
113+
self,
114+
max_iteration: int | None = None,
115+
multibrot: float | None = None,
116+
x_position: float | None = None,
117+
y_position: float | None = None,
118+
zoom: float | None = None,
119+
colour_map: ColourMap | None = None,
120+
) -> Self:
121+
"""Set one or more properties in one go.
122+
123+
Args:
124+
max_iteration: The maximum iteration.
125+
multibrot: The 'multibrot' value.
126+
x_position: The X position of the middle of the plot.
127+
y_position: The Y position of the middle of the plot.
128+
zoom: The zoom value for the plot.
129+
colour_map: The colour map to use for the plot.
130+
131+
Returns:
132+
Self.
133+
"""
134+
if max_iteration is not None:
135+
self.set_reactive(Mandelbrot.max_iteration, max_iteration)
136+
if multibrot is not None:
137+
self.set_reactive(Mandelbrot.multibrot, multibrot)
138+
if x_position is not None:
139+
self.set_reactive(Mandelbrot.x_position, x_position)
140+
if y_position is not None:
141+
self.set_reactive(Mandelbrot.y_position, y_position)
142+
if zoom is not None:
143+
self.set_reactive(Mandelbrot.zoom, zoom)
144+
if colour_map is not None:
145+
self.set_reactive(Mandelbrot.colour_map, colour_map)
146+
return self
147+
112148
def goto(self, x: float, y: float) -> Self:
113149
"""Move the centre of the plot to the given location.
114150
@@ -119,25 +155,22 @@ def goto(self, x: float, y: float) -> Self:
119155
Returns:
120156
Self.
121157
"""
122-
self.set_reactive(Mandelbrot.x_position, x)
123-
self.set_reactive(Mandelbrot.y_position, y)
124-
return self.plot()
158+
return self.set(x_position=x, y_position=y).plot()
125159

126160
def reset(self) -> Self:
127161
"""Reset the plot to its default state.
128162
129163
Returns:
130164
Self.
131165
"""
132-
self.set_reactive(Mandelbrot.max_iteration, 80)
133-
self.set_reactive(Mandelbrot.multibrot, 2)
134-
self.set_reactive(Mandelbrot.x_position, -0.5)
135-
self.set_reactive(Mandelbrot.y_position, 0)
136-
self.set_reactive(Mandelbrot.zoom, 50)
137-
# Setting an ignore in the following line. For some reason mypy
138-
# can't deal with this; pyright is fine though.
139-
self.set_reactive(Mandelbrot.colour_map, default_map) # type:ignore
140-
return self.plot()
166+
return self.set(
167+
max_iteration=80,
168+
multibrot=2,
169+
x_position=-0.5,
170+
y_position=0,
171+
zoom=50,
172+
colour_map=default_map,
173+
).plot()
141174

142175
def _validate_zoom(self, zoom: int) -> int:
143176
"""Ensure the zoom doesn't fall to 0.

src/complexitty/screens/main.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
##############################################################################
44
# Python imports.
5+
from argparse import Namespace
56
from re import Pattern, compile
67
from typing import Final
78

@@ -49,7 +50,7 @@
4950
ZoomOut,
5051
ZoomOutFaster,
5152
)
52-
from ..mandelbrot import Mandelbrot, colouring
53+
from ..mandelbrot import Mandelbrot, get_colour_map
5354
from ..providers import MainCommands
5455

5556

@@ -104,12 +105,35 @@ class Main(EnhancedScreen[None]):
104105
COMMANDS = {MainCommands}
105106
HELP = "## Commands and keys"
106107

108+
def __init__(self, arguments: Namespace) -> None:
109+
"""Initialise the screen object.
110+
111+
Args:
112+
arguments: The command line arguments.
113+
"""
114+
self._arguments = arguments
115+
"""The command line arguments passed to the application."""
116+
super().__init__()
117+
107118
def compose(self) -> ComposeResult:
108119
"""Compose the content of the main screen."""
109120
yield Header()
110121
yield Mandelbrot()
111122
yield Footer()
112123

124+
def on_mount(self) -> None:
125+
"""Configure the Mandelbrot once the DOM is ready."""
126+
self.query_one(Mandelbrot).set(
127+
max_iteration=self._arguments.max_iteration,
128+
multibrot=self._arguments.multibrot,
129+
zoom=self._arguments.zoom,
130+
x_position=self._arguments.x_position,
131+
y_position=self._arguments.y_position,
132+
colour_map=None
133+
if self._arguments.colour_map is None
134+
else get_colour_map(self._arguments.colour_map),
135+
)
136+
113137
@on(Mandelbrot.Plotted)
114138
def _update_situation(self, message: Mandelbrot.Plotted) -> None:
115139
"""Update the current situation after the latest plot.
@@ -167,7 +191,7 @@ def action_set_colour(self, colour_map: str) -> None:
167191
Args:
168192
colour_map: The name of the colour map to use.
169193
"""
170-
self.query_one(Mandelbrot).colour_map = getattr(colouring, colour_map)
194+
self.query_one(Mandelbrot).colour_map = get_colour_map(colour_map)
171195

172196
def action_multibrot(self, change: int) -> None:
173197
"""Change the 'multibrot' value.

0 commit comments

Comments
 (0)