TurtleExtension 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- TurtleExtension/Foundations/CustomTurtleShapes.py +78 -0
- TurtleExtension/Foundations/CustomTurtleShapes.pyi +71 -0
- TurtleExtension/Foundations/GlobalFunctions.py +90 -0
- TurtleExtension/Foundations/GlobalFunctions.pyi +53 -0
- TurtleExtension/Foundations/GlobalVariables.py +14 -0
- TurtleExtension/Foundations/GlobalVariables.pyi +40 -0
- TurtleExtension/Foundations/TurtleFunctions.py +55 -0
- TurtleExtension/Foundations/TurtleFunctions.pyi +28 -0
- TurtleExtension/Foundations/__init__.py +41 -0
- TurtleExtension/TurtleHeart/TurtleSkeleton.py +100 -0
- TurtleExtension/TurtleHeart/TurtleSkeleton.pyi +200 -0
- TurtleExtension/TurtleHeart/__init__.py +6 -0
- TurtleExtension/__init__.py +58 -0
- turtleextension-1.0.0.dist-info/METADATA +67 -0
- turtleextension-1.0.0.dist-info/RECORD +18 -0
- turtleextension-1.0.0.dist-info/WHEEL +5 -0
- turtleextension-1.0.0.dist-info/licenses/LICENSE +20 -0
- turtleextension-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from ..TurtleHeart import tl
|
|
2
|
+
from numbers import Real
|
|
3
|
+
import UF as uf
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
helper = uf.helper
|
|
7
|
+
|
|
8
|
+
@uf.cls_deco_superposition(staticmethod)
|
|
9
|
+
class UserShape:
|
|
10
|
+
def custom_circle():
|
|
11
|
+
radius: Real = uf.get_num(float, "Enter the radius: ")
|
|
12
|
+
tl.begin_poly()
|
|
13
|
+
tl.circle(radius)
|
|
14
|
+
tl.end_poly()
|
|
15
|
+
return tl.get_poly()
|
|
16
|
+
|
|
17
|
+
def custom_square():
|
|
18
|
+
length: Real = helper.length_float()
|
|
19
|
+
tl.begin_poly()
|
|
20
|
+
|
|
21
|
+
for _ in range(4):
|
|
22
|
+
tl.fd(length)
|
|
23
|
+
tl.lt(90)
|
|
24
|
+
|
|
25
|
+
tl.end_poly()
|
|
26
|
+
return tl.get_poly()
|
|
27
|
+
|
|
28
|
+
def custom_triangle():
|
|
29
|
+
length: Real = helper.length_float()
|
|
30
|
+
tl.begin_poly()
|
|
31
|
+
|
|
32
|
+
for _ in range(3):
|
|
33
|
+
tl.fd(length)
|
|
34
|
+
tl.lt(120)
|
|
35
|
+
|
|
36
|
+
tl.end_poly()
|
|
37
|
+
return tl.get_poly()
|
|
38
|
+
|
|
39
|
+
def custom_poly():
|
|
40
|
+
length: Real = helper.length_float()
|
|
41
|
+
sides: int = helper.sides_num()
|
|
42
|
+
|
|
43
|
+
radius = length / (2 * uf.sine(180 / sides))
|
|
44
|
+
angle_to_right = (180 - (180 * (sides - 2)) / sides) / 2
|
|
45
|
+
tl.begin_poly()
|
|
46
|
+
|
|
47
|
+
tl.rt(angle_to_right)
|
|
48
|
+
tl.circle(radius, 360, sides)
|
|
49
|
+
tl.lt(angle_to_right)
|
|
50
|
+
|
|
51
|
+
tl.end_poly()
|
|
52
|
+
return tl.get_poly()
|
|
53
|
+
|
|
54
|
+
def custom_SOD():
|
|
55
|
+
side: Real = helper.length_float()
|
|
56
|
+
tl.begin_poly()
|
|
57
|
+
|
|
58
|
+
for _ in range(6):
|
|
59
|
+
tl.pu(); tl.fd(side); tl.pd(); tl.rt(60)
|
|
60
|
+
for _ in range(3):
|
|
61
|
+
tl.fd(side); tl.rt(120)
|
|
62
|
+
tl.lt(60); tl.pu(); tl.bk(side); tl.pd(); tl.lt(60)
|
|
63
|
+
|
|
64
|
+
tl.end_poly()
|
|
65
|
+
return tl.get_poly()
|
|
66
|
+
|
|
67
|
+
@classmethod
|
|
68
|
+
def _list_shapes(cls):
|
|
69
|
+
return uf.classes_to_dict(cls)
|
|
70
|
+
|
|
71
|
+
def get_UserShape_dict():
|
|
72
|
+
return {
|
|
73
|
+
f"cm {name.removeprefix('custom_')}": func
|
|
74
|
+
for name, func in UserShape._list_shapes().items()
|
|
75
|
+
if not name.startswith("_")
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
CUSTOM_SHAPES = get_UserShape_dict()
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains the class Usershape which contains functions to make a customized turtle shape.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from numbers import Real
|
|
6
|
+
from collections.abc import Callable, Sequence
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
type return_shape = Sequence[tuple[Real,Real]] | None
|
|
10
|
+
type user_shape_dict = dict[str, Callable[[], return_shape]]
|
|
11
|
+
|
|
12
|
+
class UserShape:
|
|
13
|
+
"""
|
|
14
|
+
This class contains different custom turtle shape maker functions
|
|
15
|
+
"""
|
|
16
|
+
@staticmethod
|
|
17
|
+
def custom_circle() -> return_shape:
|
|
18
|
+
"""
|
|
19
|
+
Creates a custom circle turtle shape.
|
|
20
|
+
:return: the custom shape
|
|
21
|
+
"""
|
|
22
|
+
...
|
|
23
|
+
|
|
24
|
+
@staticmethod
|
|
25
|
+
def custom_square() -> return_shape:
|
|
26
|
+
"""
|
|
27
|
+
Creates a custom square turtle shape.
|
|
28
|
+
:return: the custom shape
|
|
29
|
+
"""
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def custom_triangle() -> return_shape:
|
|
34
|
+
"""
|
|
35
|
+
Creates a custom equilateral triangle turtle shape.
|
|
36
|
+
:return: the custom shape
|
|
37
|
+
"""
|
|
38
|
+
...
|
|
39
|
+
|
|
40
|
+
@staticmethod
|
|
41
|
+
def custom_poly() -> return_shape:
|
|
42
|
+
"""
|
|
43
|
+
Creates a custom regular polygon turtle shape.
|
|
44
|
+
:return: the custom shape
|
|
45
|
+
"""
|
|
46
|
+
...
|
|
47
|
+
|
|
48
|
+
@staticmethod
|
|
49
|
+
def custom_SOD() -> return_shape:
|
|
50
|
+
"""
|
|
51
|
+
Creates a custom star of David turtle shape.
|
|
52
|
+
:return: the custom shape
|
|
53
|
+
"""
|
|
54
|
+
...
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
def _list_shapes(cls) -> user_shape_dict:
|
|
58
|
+
"""
|
|
59
|
+
Creates a dictionary with the functions in UserShape and returns it
|
|
60
|
+
:return: dictionary containing function names -> function
|
|
61
|
+
"""
|
|
62
|
+
...
|
|
63
|
+
|
|
64
|
+
def get_UserShape_dict() -> user_shape_dict:
|
|
65
|
+
"""
|
|
66
|
+
Takes all custom turtle functions in UserShape and returns a dictionary with them
|
|
67
|
+
:return: dictionary mapping function names to functions
|
|
68
|
+
"""
|
|
69
|
+
...
|
|
70
|
+
|
|
71
|
+
CUSTOM_SHAPES: user_shape_dict
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from ..TurtleHeart import tl, ChainTurtle
|
|
2
|
+
from .GlobalVariables import t_shape, UV
|
|
3
|
+
from turtle import TurtleGraphicsError
|
|
4
|
+
from time import sleep as rest
|
|
5
|
+
import UF as uf
|
|
6
|
+
from typing import Final, Literal
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
_screen = None
|
|
10
|
+
|
|
11
|
+
def get_screen():
|
|
12
|
+
global _screen
|
|
13
|
+
|
|
14
|
+
if _screen is None:
|
|
15
|
+
_screen = tl.Screen()
|
|
16
|
+
_screen.getcanvas().winfo_toplevel().state("zoomed")
|
|
17
|
+
_screen.tracer(0)
|
|
18
|
+
|
|
19
|
+
return _screen
|
|
20
|
+
|
|
21
|
+
def SU():
|
|
22
|
+
get_screen().update()
|
|
23
|
+
|
|
24
|
+
def mainloop():
|
|
25
|
+
get_screen().mainloop()
|
|
26
|
+
|
|
27
|
+
type turtle_list = list[ChainTurtle]
|
|
28
|
+
|
|
29
|
+
def tls_color(**options):
|
|
30
|
+
|
|
31
|
+
tl_num_name: Final[Literal["tl_num"]] = "tl_num"
|
|
32
|
+
entry_name: Final[Literal["entry"]] = "entry"
|
|
33
|
+
index_name: Final[Literal["index"]] = "index"
|
|
34
|
+
|
|
35
|
+
if tl_num_name in options:
|
|
36
|
+
tl_num = options[tl_num_name]
|
|
37
|
+
uf.int_validate()(tl_num, tl_num_name)
|
|
38
|
+
uf.Positive()(tl_num, tl_num_name)
|
|
39
|
+
turtles_num_count = tl_num
|
|
40
|
+
|
|
41
|
+
elif entry_name in options:
|
|
42
|
+
entry = options[entry_name]
|
|
43
|
+
uf.str_validate()(entry, entry_name)
|
|
44
|
+
turtles_num_count = uf.get_num(int, entry, MIN=1)
|
|
45
|
+
|
|
46
|
+
elif index_name in options:
|
|
47
|
+
index = options[index_name]
|
|
48
|
+
uf.int_validate()(index, index_name)
|
|
49
|
+
uf.Positive()(index, index_name)
|
|
50
|
+
turtles_num_count = index
|
|
51
|
+
else:
|
|
52
|
+
print("NONE of the entered options exist!")
|
|
53
|
+
return None
|
|
54
|
+
tls: turtle_list = []
|
|
55
|
+
|
|
56
|
+
for color_num in range(turtles_num_count):
|
|
57
|
+
while True:
|
|
58
|
+
color_iteration: str = input(f"Enter turtle color {color_num + 1}: ")
|
|
59
|
+
try:
|
|
60
|
+
turtle: ChainTurtle = ChainTurtle().color(color_iteration).shape(t_shape())
|
|
61
|
+
if index_name in options:
|
|
62
|
+
UV["tls"].append(turtle)
|
|
63
|
+
else:
|
|
64
|
+
tls.append(turtle)
|
|
65
|
+
break
|
|
66
|
+
|
|
67
|
+
except TurtleGraphicsError:
|
|
68
|
+
print("Enter a VALID color!"); rest(2)
|
|
69
|
+
|
|
70
|
+
if index_name in options:
|
|
71
|
+
return len(UV["tls"]) - 1
|
|
72
|
+
|
|
73
|
+
elif entry_name in options:
|
|
74
|
+
return tls, turtles_num_count
|
|
75
|
+
|
|
76
|
+
elif tl_num_name in options:
|
|
77
|
+
return tls
|
|
78
|
+
return None
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def reset_tls(tls_list):
|
|
82
|
+
|
|
83
|
+
tls_list_name: Final[Literal["tls_list"]] = "tls_list"
|
|
84
|
+
uf.TypeValidate(list)(tls_list, name=tls_list_name)
|
|
85
|
+
uf.SequenceValidate(ChainTurtle, ...)(tls_list, name=tls_list_name)
|
|
86
|
+
|
|
87
|
+
for t in tls_list:
|
|
88
|
+
t.clear().ht()
|
|
89
|
+
tls_list.clear()
|
|
90
|
+
return tls_list
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains a very useful function: tls_color, which lets the user create any number of turtles with
|
|
3
|
+
colors and get a list with them.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from ..TurtleHeart import tl, ChainTurtle
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def get_screen() -> tl.Screen:
|
|
10
|
+
"""
|
|
11
|
+
Initiates the turtle screen when the function is called.
|
|
12
|
+
:return: turtle screen object
|
|
13
|
+
"""
|
|
14
|
+
...
|
|
15
|
+
|
|
16
|
+
def SU() -> None:
|
|
17
|
+
"""
|
|
18
|
+
This function updates the turtle screen.
|
|
19
|
+
:return: None
|
|
20
|
+
"""
|
|
21
|
+
...
|
|
22
|
+
|
|
23
|
+
def mainloop() -> None:
|
|
24
|
+
"""
|
|
25
|
+
This function keeps the turtle screen open.
|
|
26
|
+
:return: None
|
|
27
|
+
"""
|
|
28
|
+
...
|
|
29
|
+
|
|
30
|
+
type turtle_list = list[ChainTurtle]
|
|
31
|
+
|
|
32
|
+
def tls_color(**options) -> int | tuple[turtle_list, int] | turtle_list | None:
|
|
33
|
+
"""This function creates a turtle list with their colors or adds newly creates turtles to the UV["tls"] list
|
|
34
|
+
to be used for the user_drawing_ft()
|
|
35
|
+
|
|
36
|
+
USERS NOTICE: it is HIGHLY recommended to NOT enter a turtles count of MORE than a few hundred (max. 200) unless required!!!
|
|
37
|
+
|
|
38
|
+
:param options: tl_num -> number of turtles to create, entry -> input string, index -> number of turtles to be created for user_drawing_ft()
|
|
39
|
+
& it returns the index of the last turtle
|
|
40
|
+
:return: tls_num: turtle list with colored turtles, entry: list with colored turtles + number of turtles ,otherwise: index of last turtle
|
|
41
|
+
"""
|
|
42
|
+
...
|
|
43
|
+
|
|
44
|
+
def reset_tls(tls_list: turtle_list) -> list:
|
|
45
|
+
"""
|
|
46
|
+
This function deletes the drawings of given turtle list + turtles
|
|
47
|
+
|
|
48
|
+
>>> tls = [ChainTurtle(), ChainTurtle()]
|
|
49
|
+
>>> reset_tls(tls)
|
|
50
|
+
[]
|
|
51
|
+
|
|
52
|
+
:return: empty tls_list
|
|
53
|
+
"""
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# UV = UNIVERSAL VARIABLES
|
|
2
|
+
UV = {
|
|
3
|
+
"delay": None, # Delay for user_drawing_ft()
|
|
4
|
+
"t": 0, # user_drawing_ft's current turtle
|
|
5
|
+
"tls": [], # user_drawing_ft's turtle list
|
|
6
|
+
"tls_shape": "arrow", # user_drawing_ft's turtle's current shape
|
|
7
|
+
"shape_library": [], # user_drawing_ft's turtle shapes list
|
|
8
|
+
}
|
|
9
|
+
def t_now():
|
|
10
|
+
return UV["tls"][UV["t"]]
|
|
11
|
+
|
|
12
|
+
def t_shape():
|
|
13
|
+
return UV["tls_shape"]
|
|
14
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains a dictionary (UV) which contains important info about turtles and user_drawing_ft().
|
|
3
|
+
|
|
4
|
+
Other functions:
|
|
5
|
+
|
|
6
|
+
t_now() -> lets users take the current UV turtle
|
|
7
|
+
|
|
8
|
+
t_shape() -> lets users take the current turtle shape
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from typing import Any
|
|
12
|
+
from ..TurtleHeart import ChainTurtle
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
UV: dict[str, Any]
|
|
16
|
+
|
|
17
|
+
def t_now() -> ChainTurtle:
|
|
18
|
+
"""
|
|
19
|
+
This function returns the current UV turtle
|
|
20
|
+
|
|
21
|
+
>>> turtle = ChainTurtle()
|
|
22
|
+
>>> UV["tls"].append(turtle)
|
|
23
|
+
>>> t_now()
|
|
24
|
+
ChainTurtle()
|
|
25
|
+
|
|
26
|
+
:return: ChainTurtle
|
|
27
|
+
"""
|
|
28
|
+
...
|
|
29
|
+
|
|
30
|
+
def t_shape() -> str:
|
|
31
|
+
"""
|
|
32
|
+
This function returns the current UV turtle shape
|
|
33
|
+
|
|
34
|
+
>>> UV['tls_shape'] = 'turtle'
|
|
35
|
+
>>> t_shape()
|
|
36
|
+
'turtle'
|
|
37
|
+
|
|
38
|
+
:return: string
|
|
39
|
+
"""
|
|
40
|
+
...
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from ..TurtleHeart import tl, ChainTurtle
|
|
2
|
+
from .GlobalVariables import UV
|
|
3
|
+
from .CustomTurtleShapes import CUSTOM_SHAPES
|
|
4
|
+
import UF as uf
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TurtleFct:
|
|
8
|
+
@classmethod
|
|
9
|
+
def change_shape(cls, tls_num = None):
|
|
10
|
+
if tls_num is not None:
|
|
11
|
+
uf.TypeValidate(ChainTurtle)(tls_num, name="tls_num")
|
|
12
|
+
|
|
13
|
+
turtle_shapes_list: list[str] = tl.getshapes()
|
|
14
|
+
|
|
15
|
+
user_shape: str = uf.get_str(f'''
|
|
16
|
+
Here are the options for the turtle shape:
|
|
17
|
+
{turtle_shapes_list}
|
|
18
|
+
custom -> custom turtle shapes
|
|
19
|
+
Enter choice: ''', turtle_shapes_list, "custom")
|
|
20
|
+
|
|
21
|
+
if user_shape in turtle_shapes_list:
|
|
22
|
+
if tls_num is not None:
|
|
23
|
+
tls_num.shape(user_shape)
|
|
24
|
+
return tls_num
|
|
25
|
+
else:
|
|
26
|
+
UV["tls_shape"] = user_shape
|
|
27
|
+
return user_shape
|
|
28
|
+
else:
|
|
29
|
+
if tls_num is not None:
|
|
30
|
+
return cls.user_tls_shape_ft(tls_num)
|
|
31
|
+
else:
|
|
32
|
+
return cls.user_tls_shape_ft()
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def user_tls_shape_ft(tls_num = None):
|
|
36
|
+
if tls_num is not None:
|
|
37
|
+
uf.TypeValidate(ChainTurtle)(tls_num, name="tls_num")
|
|
38
|
+
|
|
39
|
+
user_shape: str = uf.get_str(f'''
|
|
40
|
+
Here are some custom options:
|
|
41
|
+
{CUSTOM_SHAPES.keys()}
|
|
42
|
+
Enter choice:
|
|
43
|
+
''', CUSTOM_SHAPES)
|
|
44
|
+
tl.home()
|
|
45
|
+
shape_made = CUSTOM_SHAPES[user_shape]()
|
|
46
|
+
tl.addshape(user_shape, shape_made)
|
|
47
|
+
tl.clear()
|
|
48
|
+
tl.ht()
|
|
49
|
+
|
|
50
|
+
if tls_num is not None:
|
|
51
|
+
tls_num.shape(user_shape)
|
|
52
|
+
return tls_num
|
|
53
|
+
else:
|
|
54
|
+
UV["tls_shape"] = user_shape
|
|
55
|
+
return user_shape
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains the class TurtleFct which lets the user change the turtle shape to a customized one.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from ..TurtleHeart import ChainTurtle
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TurtleFct:
|
|
9
|
+
"""
|
|
10
|
+
This class contains a function that lets users change the shape of the turtles that will be created in the future with tls_color.
|
|
11
|
+
"""
|
|
12
|
+
@classmethod
|
|
13
|
+
def change_shape(cls, tls_num: ChainTurtle|None = None) -> ChainTurtle | str:
|
|
14
|
+
"""
|
|
15
|
+
This function lets the user choose different turtles shapes, including a custom option.
|
|
16
|
+
:param tls_num: ChainTurtle() or None
|
|
17
|
+
:return: ChainTurtle() if tls_num is a ChainTurtle(), otherwise None
|
|
18
|
+
"""
|
|
19
|
+
...
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def user_tls_shape_ft(tls_num: ChainTurtle | None = None) -> ChainTurtle | str:
|
|
23
|
+
"""
|
|
24
|
+
This function lets the user create custom turtle shapes.
|
|
25
|
+
:param tls_num: ChainTurtle() or None
|
|
26
|
+
:return: ChainTurtle() if tls_num is a ChainTurtle(), otherwise None
|
|
27
|
+
"""
|
|
28
|
+
...
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from .GlobalVariables import (
|
|
2
|
+
UV,
|
|
3
|
+
t_now,
|
|
4
|
+
t_shape,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
from .GlobalFunctions import (
|
|
8
|
+
get_screen,
|
|
9
|
+
SU,
|
|
10
|
+
mainloop,
|
|
11
|
+
tls_color,
|
|
12
|
+
reset_tls,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from .CustomTurtleShapes import (
|
|
16
|
+
UserShape,
|
|
17
|
+
get_UserShape_dict,
|
|
18
|
+
CUSTOM_SHAPES,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
from .TurtleFunctions import (
|
|
22
|
+
TurtleFct,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"UV",
|
|
27
|
+
"t_now",
|
|
28
|
+
"t_shape",
|
|
29
|
+
|
|
30
|
+
"get_screen",
|
|
31
|
+
"SU",
|
|
32
|
+
"mainloop",
|
|
33
|
+
"tls_color",
|
|
34
|
+
"reset_tls",
|
|
35
|
+
|
|
36
|
+
"UserShape",
|
|
37
|
+
"get_UserShape_dict",
|
|
38
|
+
"CUSTOM_SHAPES",
|
|
39
|
+
|
|
40
|
+
"TurtleFct",
|
|
41
|
+
]
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import turtle as tl
|
|
2
|
+
import UF as uf
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ChainTurtle(tl.Turtle):
|
|
6
|
+
def fd(self, distance):
|
|
7
|
+
super().fd(distance)
|
|
8
|
+
return self
|
|
9
|
+
|
|
10
|
+
def fd_inv(self,distance):
|
|
11
|
+
self.pu().fd(distance).pd()
|
|
12
|
+
return self
|
|
13
|
+
|
|
14
|
+
def bk(self, distance):
|
|
15
|
+
super().bk(distance)
|
|
16
|
+
return self
|
|
17
|
+
|
|
18
|
+
def bk_inv(self,distance):
|
|
19
|
+
self.pu().bk(distance).pd()
|
|
20
|
+
return self
|
|
21
|
+
|
|
22
|
+
def rt(self, angle):
|
|
23
|
+
super().rt(angle)
|
|
24
|
+
return self
|
|
25
|
+
|
|
26
|
+
def lt(self, angle):
|
|
27
|
+
super().lt(angle)
|
|
28
|
+
return self
|
|
29
|
+
|
|
30
|
+
def setpos(self, x_val, y_val):
|
|
31
|
+
super().setpos(x_val, y_val)
|
|
32
|
+
return self
|
|
33
|
+
|
|
34
|
+
def pu(self):
|
|
35
|
+
super().pu()
|
|
36
|
+
return self
|
|
37
|
+
|
|
38
|
+
def pd(self):
|
|
39
|
+
super().pd()
|
|
40
|
+
return self
|
|
41
|
+
|
|
42
|
+
def seth(self, direction):
|
|
43
|
+
super().seth(direction)
|
|
44
|
+
return self
|
|
45
|
+
|
|
46
|
+
def home(self):
|
|
47
|
+
super().home()
|
|
48
|
+
return self
|
|
49
|
+
|
|
50
|
+
def home_inv(self):
|
|
51
|
+
self.pu().home().pd()
|
|
52
|
+
return self
|
|
53
|
+
|
|
54
|
+
def begin_fill(self):
|
|
55
|
+
super().begin_fill()
|
|
56
|
+
return self
|
|
57
|
+
|
|
58
|
+
def end_fill(self):
|
|
59
|
+
super().end_fill()
|
|
60
|
+
return self
|
|
61
|
+
|
|
62
|
+
def circle(self, radius, extent=None, steps=None):
|
|
63
|
+
super().circle(radius, extent, steps)
|
|
64
|
+
return self
|
|
65
|
+
|
|
66
|
+
def circle_fill(self,radius,angle=None,sides=None):
|
|
67
|
+
self.begin_fill().circle(radius,angle,sides).end_fill()
|
|
68
|
+
return self
|
|
69
|
+
|
|
70
|
+
def dot(self, radius):
|
|
71
|
+
self.begin_fill().circle(radius).end_fill()
|
|
72
|
+
return self
|
|
73
|
+
|
|
74
|
+
def color(self, turtle_color):
|
|
75
|
+
super().color(turtle_color)
|
|
76
|
+
return self
|
|
77
|
+
|
|
78
|
+
def teleport(self, x, y, *, fill_gap: bool=False):
|
|
79
|
+
super().teleport(x,y)
|
|
80
|
+
return self
|
|
81
|
+
|
|
82
|
+
def shape(self, shape_name):
|
|
83
|
+
super().shape(shape_name)
|
|
84
|
+
return self
|
|
85
|
+
|
|
86
|
+
def undo(self):
|
|
87
|
+
super().undo()
|
|
88
|
+
return self
|
|
89
|
+
|
|
90
|
+
def clear(self):
|
|
91
|
+
super().clear()
|
|
92
|
+
return self
|
|
93
|
+
|
|
94
|
+
def ht(self):
|
|
95
|
+
super().ht()
|
|
96
|
+
return self
|
|
97
|
+
|
|
98
|
+
@classmethod
|
|
99
|
+
def list_methods(cls):
|
|
100
|
+
return uf.classes_to_dict(cls)
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains the class ChainTurtle() which is the foundational object around which this entire software has been made.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from numbers import Real
|
|
6
|
+
from collections.abc import Callable
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
tl = tl
|
|
10
|
+
|
|
11
|
+
class ChainTurtle:
|
|
12
|
+
"""This class adds chaining functionality to turtle.Turtle"""
|
|
13
|
+
def fd(self, distance: Real) -> ChainTurtle:
|
|
14
|
+
"""
|
|
15
|
+
Makes the turtle go forward with trace.
|
|
16
|
+
:param distance: distance in pixels
|
|
17
|
+
:return: ChainTurtle()
|
|
18
|
+
"""
|
|
19
|
+
...
|
|
20
|
+
|
|
21
|
+
def fd_inv(self, distance: Real) -> ChainTurtle:
|
|
22
|
+
"""
|
|
23
|
+
Makes the turtle go forward with no trace.
|
|
24
|
+
:param distance: distance in pixels
|
|
25
|
+
:return: ChainTurtle()
|
|
26
|
+
"""
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
def bk(self, distance: Real) -> ChainTurtle:
|
|
30
|
+
"""
|
|
31
|
+
Makes the turtle go backwards with trace.
|
|
32
|
+
:param distance: distance in pixels
|
|
33
|
+
:return: ChainTurtle()
|
|
34
|
+
"""
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
def bk_inv(self, distance: Real) -> ChainTurtle:
|
|
38
|
+
"""
|
|
39
|
+
Makes the turtle go backward with no trace.
|
|
40
|
+
:param distance: distance in pixels
|
|
41
|
+
:return: ChainTurtle()
|
|
42
|
+
"""
|
|
43
|
+
...
|
|
44
|
+
|
|
45
|
+
def rt(self, angle: Real) -> ChainTurtle:
|
|
46
|
+
"""
|
|
47
|
+
Makes the turtle turn right.
|
|
48
|
+
:param angle: angle in degrees
|
|
49
|
+
:return: ChainTurtle()
|
|
50
|
+
"""
|
|
51
|
+
...
|
|
52
|
+
|
|
53
|
+
def lt(self, angle: Real) -> ChainTurtle:
|
|
54
|
+
"""
|
|
55
|
+
Makes the turtle turn left.
|
|
56
|
+
:param angle: angle in degrees
|
|
57
|
+
:return: ChainTurtle()
|
|
58
|
+
"""
|
|
59
|
+
...
|
|
60
|
+
|
|
61
|
+
def setpos(self, x_val: Real, y_val: Real) -> ChainTurtle:
|
|
62
|
+
"""
|
|
63
|
+
Makes the turtle go to a specific position with a trace.
|
|
64
|
+
:param x_val: x position in pixels
|
|
65
|
+
:param y_val: y position in pixels
|
|
66
|
+
:return: ChainTurtle()
|
|
67
|
+
"""
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
def pu(self) -> ChainTurtle:
|
|
71
|
+
"""
|
|
72
|
+
Puts the pen down to leave a trace.
|
|
73
|
+
:return: ChainTurtle()
|
|
74
|
+
"""
|
|
75
|
+
...
|
|
76
|
+
|
|
77
|
+
def pd(self) -> ChainTurtle:
|
|
78
|
+
"""
|
|
79
|
+
Puts the pen up to not leave a trace.
|
|
80
|
+
:return: ChainTurtle()
|
|
81
|
+
"""
|
|
82
|
+
...
|
|
83
|
+
|
|
84
|
+
def seth(self, direction: Real) -> ChainTurtle:
|
|
85
|
+
"""
|
|
86
|
+
Sets the direction of the turtle starting East, going counterclockwise.
|
|
87
|
+
:param direction: direction in degrees
|
|
88
|
+
"""
|
|
89
|
+
...
|
|
90
|
+
|
|
91
|
+
def home(self) -> ChainTurtle:
|
|
92
|
+
"""
|
|
93
|
+
Sets the position of the turtle to home (0, 0) with trace, heading = 0 .
|
|
94
|
+
:return: ChainTurtle()
|
|
95
|
+
"""
|
|
96
|
+
...
|
|
97
|
+
|
|
98
|
+
def home_inv(self) -> ChainTurtle:
|
|
99
|
+
"""
|
|
100
|
+
Sets the position of the turtle to home (0, 0) without trace, heading = 0 .
|
|
101
|
+
:return: ChainTurtle()
|
|
102
|
+
"""
|
|
103
|
+
...
|
|
104
|
+
|
|
105
|
+
def begin_fill(self) -> ChainTurtle:
|
|
106
|
+
"""
|
|
107
|
+
Makes the turtle begin fill for a closed shape.
|
|
108
|
+
:return: ChainTurtle()
|
|
109
|
+
"""
|
|
110
|
+
...
|
|
111
|
+
|
|
112
|
+
def end_fill(self) -> ChainTurtle:
|
|
113
|
+
"""
|
|
114
|
+
Ends the turtle fill for a closed shape, therefore fills the shapes.
|
|
115
|
+
:return: ChainTurtle()
|
|
116
|
+
"""
|
|
117
|
+
...
|
|
118
|
+
|
|
119
|
+
def circle(self,
|
|
120
|
+
radius: Real,
|
|
121
|
+
extent: Real | None = None,
|
|
122
|
+
steps: int = None) -> ChainTurtle:
|
|
123
|
+
"""
|
|
124
|
+
Makes the turtle draw a circle
|
|
125
|
+
:param radius: radius in pixels
|
|
126
|
+
:param extent: extent in degrees
|
|
127
|
+
:param steps: number of sides
|
|
128
|
+
:return: ChainTurtle()
|
|
129
|
+
"""
|
|
130
|
+
...
|
|
131
|
+
|
|
132
|
+
def circle_fill(self,
|
|
133
|
+
radius: Real,
|
|
134
|
+
angle: Real | None = None,
|
|
135
|
+
sides: int = None) -> ChainTurtle:
|
|
136
|
+
"""
|
|
137
|
+
Makes the turtle draw a circle and fills it
|
|
138
|
+
:param radius: radius in degrees
|
|
139
|
+
:param angle: angle in degrees
|
|
140
|
+
:param sides: number of sides
|
|
141
|
+
"""
|
|
142
|
+
...
|
|
143
|
+
|
|
144
|
+
def dot(self, radius: Real) -> ChainTurtle:
|
|
145
|
+
"""
|
|
146
|
+
Makes the turtle draw a colored dot
|
|
147
|
+
:param radius: radius in pixels
|
|
148
|
+
"""
|
|
149
|
+
...
|
|
150
|
+
|
|
151
|
+
def color(self, turtle_color: str) -> ChainTurtle:
|
|
152
|
+
"""
|
|
153
|
+
Lets the user change the color of the turtle trace and turtle color itself
|
|
154
|
+
:param turtle_color: valid turtle color
|
|
155
|
+
"""
|
|
156
|
+
...
|
|
157
|
+
|
|
158
|
+
def teleport(self, x: Real, y: Real, *, fill_gap: bool = False) -> ChainTurtle:
|
|
159
|
+
"""
|
|
160
|
+
Makes the turtle to go a specific coordinate with no trace
|
|
161
|
+
:param x: x position in pixels
|
|
162
|
+
:param y: y position in pixels
|
|
163
|
+
"""
|
|
164
|
+
...
|
|
165
|
+
|
|
166
|
+
def shape(self, shape_name: str) -> ChainTurtle:
|
|
167
|
+
"""
|
|
168
|
+
Changes the shape of the turtle shape
|
|
169
|
+
:param shape_name: name of the shape
|
|
170
|
+
"""
|
|
171
|
+
...
|
|
172
|
+
|
|
173
|
+
def undo(self) -> ChainTurtle:
|
|
174
|
+
"""
|
|
175
|
+
Undoes the last turtle command.
|
|
176
|
+
:return: ChainTurtle()
|
|
177
|
+
"""
|
|
178
|
+
...
|
|
179
|
+
|
|
180
|
+
def clear(self) -> ChainTurtle:
|
|
181
|
+
"""
|
|
182
|
+
Deletes the turtles drawings.
|
|
183
|
+
:return: ChainTurtle()
|
|
184
|
+
"""
|
|
185
|
+
...
|
|
186
|
+
|
|
187
|
+
def ht(self) -> ChainTurtle:
|
|
188
|
+
"""
|
|
189
|
+
Hides the turtle.
|
|
190
|
+
:return: ChainTurtle()
|
|
191
|
+
"""
|
|
192
|
+
...
|
|
193
|
+
|
|
194
|
+
@classmethod
|
|
195
|
+
def list_methods(cls) -> dict[str, Callable]:
|
|
196
|
+
"""
|
|
197
|
+
Creates a dictionary with all ChainTurtle methods and returns it
|
|
198
|
+
:return: dictionary
|
|
199
|
+
"""
|
|
200
|
+
...
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This package is part of the GeometricalDomination project ecosystem.
|
|
3
|
+
|
|
4
|
+
It contains a chainable turtle class called ChainTurtle and a collection of extra provided features along with it:
|
|
5
|
+
|
|
6
|
+
1. tls_color -> this function make a list of colored turtles and returns it
|
|
7
|
+
2. get_screen -> turtle screen initializer function
|
|
8
|
+
3. SU -> screen update function
|
|
9
|
+
|
|
10
|
+
And a lot more.
|
|
11
|
+
|
|
12
|
+
Author: Miah M. Sabiq
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from .Foundations import (
|
|
16
|
+
UV,
|
|
17
|
+
t_now,
|
|
18
|
+
t_shape,
|
|
19
|
+
|
|
20
|
+
get_screen,
|
|
21
|
+
SU,
|
|
22
|
+
mainloop,
|
|
23
|
+
tls_color,
|
|
24
|
+
reset_tls,
|
|
25
|
+
|
|
26
|
+
UserShape,
|
|
27
|
+
get_UserShape_dict,
|
|
28
|
+
CUSTOM_SHAPES,
|
|
29
|
+
|
|
30
|
+
TurtleFct,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
from .TurtleHeart import (
|
|
34
|
+
ChainTurtle,
|
|
35
|
+
tl,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
__all__ = [
|
|
39
|
+
"UV",
|
|
40
|
+
"t_now",
|
|
41
|
+
"t_shape",
|
|
42
|
+
|
|
43
|
+
"get_screen",
|
|
44
|
+
"SU",
|
|
45
|
+
"mainloop",
|
|
46
|
+
"tls_color",
|
|
47
|
+
"reset_tls",
|
|
48
|
+
|
|
49
|
+
"UserShape",
|
|
50
|
+
"get_UserShape_dict",
|
|
51
|
+
"CUSTOM_SHAPES",
|
|
52
|
+
|
|
53
|
+
"TurtleFct",
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
"ChainTurtle",
|
|
57
|
+
"tl",
|
|
58
|
+
]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: TurtleExtension
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A Python utility library providing turtle extensions on top of Python's original turtle feature.
|
|
5
|
+
Author-email: "Miah M. Sabiq" <miah.sabiq@gibs.at>
|
|
6
|
+
Requires-Python: >=3.14
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: UniversalFunctions>=2.7.0
|
|
10
|
+
Dynamic: license-file
|
|
11
|
+
|
|
12
|
+
# TurtleExtension
|
|
13
|
+
|
|
14
|
+
**Extend Python's turtle graphics with your own tools and functionality.**
|
|
15
|
+
|
|
16
|
+
TurtleExtension is a Python project dedicated to extending and experimenting with turtle graphics.
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
- Built around Python's `turtle` graphics module.
|
|
21
|
+
- Designed for reusable extensions and custom drawing functionality.
|
|
22
|
+
- A foundation for experimenting with geometric designs and turtle-based programming.
|
|
23
|
+
|
|
24
|
+
## Requirements
|
|
25
|
+
|
|
26
|
+
- Python 3.14 or later
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
Once published to PyPI, install with:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
python -m pip install TurtleExtension
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
import turtle
|
|
40
|
+
|
|
41
|
+
# Your TurtleExtension functionality goes here.
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The public API and usage examples will be documented as the project develops.
|
|
45
|
+
|
|
46
|
+
## Development
|
|
47
|
+
|
|
48
|
+
Clone the repository:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
git clone https://github.com/YOUR-USERNAME/TurtleExtension.git
|
|
52
|
+
cd TurtleExtension
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Install the package locally if your project contains a `pyproject.toml`:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
python -m pip install .
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
|
|
63
|
+
See the repository for licensing information.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
*More turtle-powered functionality coming soon.* 🐢
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
TurtleExtension/__init__.py,sha256=eLRjpUEmKLkAB2E_Zt9s0UfbNrPQFs0PS7eTx6r_9HY,878
|
|
2
|
+
TurtleExtension/Foundations/CustomTurtleShapes.py,sha256=F5oNQ9rZFEhCxkBbXvwAM8IKhcpOiaUzXVICPpByFUI,1862
|
|
3
|
+
TurtleExtension/Foundations/CustomTurtleShapes.pyi,sha256=2OkqPMRFqX4ee_NKa-t-FmiNtlCJCfE1XkloGJMlanQ,1798
|
|
4
|
+
TurtleExtension/Foundations/GlobalFunctions.py,sha256=hbN9dJQoclIUPhf1jnNp9vIP0r6Bse4hxNSVy_QoO6A,2417
|
|
5
|
+
TurtleExtension/Foundations/GlobalFunctions.pyi,sha256=U63zbldoUmB_o2plIdmtUMb7QTJQVNfy4skXyQ4jkA0,1557
|
|
6
|
+
TurtleExtension/Foundations/GlobalVariables.py,sha256=E26iNVG7yZNIfOzGW8vfq99qtSADLP4e19gjEcOTgJs,460
|
|
7
|
+
TurtleExtension/Foundations/GlobalVariables.pyi,sha256=5pnPbyHLTlxGBmTTwvkFdGREOOZOjuD_7Mg8IhawHZs,734
|
|
8
|
+
TurtleExtension/Foundations/TurtleFunctions.py,sha256=7dVe8Ob21eJkTL2FllnJ13zMRe-wU_f1iFIbBIV6hyk,1692
|
|
9
|
+
TurtleExtension/Foundations/TurtleFunctions.pyi,sha256=BP6f-cbupmoVnxRJvvC9kM6NOT1UZ7VfR5F4PkQLm_o,1002
|
|
10
|
+
TurtleExtension/Foundations/__init__.py,sha256=EIz2E3vKukvLxE4ino_6qIqZ_z0PJFiiu0Ha52zVFi0,521
|
|
11
|
+
TurtleExtension/TurtleHeart/TurtleSkeleton.py,sha256=2ZlZOW5LSSAdpPFRgcJDY5mG7dpNxoVE-RBMWldCt5w,2050
|
|
12
|
+
TurtleExtension/TurtleHeart/TurtleSkeleton.pyi,sha256=WdaY346PB8p3K2-k8MhgTXMKdg-T9Ckk0_qwr34ynu0,5232
|
|
13
|
+
TurtleExtension/TurtleHeart/__init__.py,sha256=apY_ehzohDfvPOpT9jbzfeNsLjURik_rVVwqTTmow6g,87
|
|
14
|
+
turtleextension-1.0.0.dist-info/licenses/LICENSE,sha256=nrw6zlyCnuR0x3l8MDzKxHPec415l9XTDAM3XYuvn3o,1026
|
|
15
|
+
turtleextension-1.0.0.dist-info/METADATA,sha256=Bn-qI9ASvG-d59NTPCMOM4Iv7LIm7kpo9HjeBdP_7qA,1458
|
|
16
|
+
turtleextension-1.0.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
17
|
+
turtleextension-1.0.0.dist-info/top_level.txt,sha256=s79HVl0CvAGBuW2VeUSaqF1k8ObR9IKRGm6Fqm89aNM,16
|
|
18
|
+
turtleextension-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Miah M. Sabiq
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, merge, publish, distribute, sublicense, and to permit persons to whom the Software is
|
|
9
|
+
furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all
|
|
12
|
+
copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
TurtleExtension
|