Добавить в корзинуПозвонить
Найти в Дзене
khasan

from __future__ import annotations

from __future__ import annotations import turtle from dataclasses import dataclass, field from itertools import cycle from typing import Iterable, Sequence, Callable @dataclass(frozen=True) class PatternConfig: steps: int = 122 step_angle: float = 3.0 hop: float = 130.0 circle_radius: float = 40.0 colors: Sequence[str] = field(default_factory=lambda: ("orange", "white")) bgcolor: str = "black" speed: int = 0 pen_size: int = 1 center: tuple[float, float] = (0.0, 0.0) class PatternDrawer: def __init__(self, config: PatternConfig | None = None) -> None: self.config = config or PatternConfig() self._screen: turtle.Screen | None = None self._t: turtle.Turtle | None = None self._color_cycle: Iterable[str] = cycle(self.config.colors) def init(self) -> "PatternDrawer": screen = turtle.Screen() screen.bgcolor(self.config.bgcolor) t = turtle.Turtle(visible=False) t.speed(self.config.speed) t.pensize(self.config.pen_size) self._screen = screen self._t = t return self def run(self) -> None:

from __future__ import annotations

import turtle

from dataclasses import dataclass, field

from itertools import cycle

from typing import Iterable, Sequence, Callable

@dataclass(frozen=True)

class PatternConfig:

steps: int = 122

step_angle: float = 3.0

hop: float = 130.0

circle_radius: float = 40.0

colors: Sequence[str] = field(default_factory=lambda: ("orange", "white"))

bgcolor: str = "black"

speed: int = 0

pen_size: int = 1

center: tuple[float, float] = (0.0, 0.0)

class PatternDrawer:

def __init__(self, config: PatternConfig | None = None) -> None:

self.config = config or PatternConfig()

self._screen: turtle.Screen | None = None

self._t: turtle.Turtle | None = None

self._color_cycle: Iterable[str] = cycle(self.config.colors)

def init(self) -> "PatternDrawer":

screen = turtle.Screen()

screen.bgcolor(self.config.bgcolor)

t = turtle.Turtle(visible=False)

t.speed(self.config.speed)

t.pensize(self.config.pen_size)

self._screen = screen

self._t = t

return self

def run(self) -> None:

turtle.done()

def draw(self) -> "PatternDrawer":

self._require_ready()

t = self._t # type: ignore[assignment]

for _ in range(self.config.steps):

self._move_to_center(t)

t.color(next(self._color_cycle))

t.forward(self.config.hop)

t.left(self.config.step_angle)

t.circle(self.config.circle_radius)

t.forward(self.config.hop)

t.right(180)

return self

def draw_with_strategy(self, step_fn: Callable[[turtle.Turtle, PatternConfig], None]) -> "PatternDrawer":

self._require_ready()

t = self._t

for _ in range(self.config.steps):

self._move_to_center(t)

t.color(next(self._color_cycle))

step_fn(t, self.config)

return self

def set_colors(self, colors: Sequence[str]) -> "PatternDrawer":

self._color_cycle = cycle(colors)

return self

def _require_ready(self) -> None:

if self._t is None or self._screen is None:

raise RuntimeError("PatternDrawer не инициализирован. Вызовите .init() перед .draw().")

def _move_to_center(self, t: turtle.Turtle) -> None:

t.penup()

t.goto(*self.config.center)

t.pendown()

def main() -> None:

cfg = PatternConfig(

steps=122,

step_angle=3.0,

hop=130.0,

circle_radius=40.0,

colors=("orange", "white"),

bgcolor="black",

speed=0,

pen_size=1,

)

drawer = PatternDrawer(cfg).init()

drawer.draw().run()

def starry_step(t: turtle.Turtle, c: PatternConfig) -> None:

t.forward(c.hop)

t.left(c.step_angle)

for _ in range(5):

t.forward(c.circle_radius)

t.right(144)

t.forward(c.hop)

t.right(180)

if __name__ == "__main__":

main()