algomanim 0.1.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.
- algomanim/__init__.py +0 -0
- algomanim/algomanim.py +411 -0
- algomanim-0.1.0.dist-info/LICENSE +21 -0
- algomanim-0.1.0.dist-info/METADATA +21 -0
- algomanim-0.1.0.dist-info/RECORD +6 -0
- algomanim-0.1.0.dist-info/WHEEL +4 -0
algomanim/__init__.py
ADDED
|
File without changes
|
algomanim/algomanim.py
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import manim as mn
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Array(mn.VGroup):
|
|
5
|
+
def __init__(
|
|
6
|
+
self,
|
|
7
|
+
arr: list,
|
|
8
|
+
position: mn.Mobject,
|
|
9
|
+
bg_color=mn.DARK_GRAY
|
|
10
|
+
):
|
|
11
|
+
"""
|
|
12
|
+
Create a Manim array visualization as a VGroup.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
arr (list): The array of values to visualize.
|
|
16
|
+
position (mn.Mobject): The position to place the array
|
|
17
|
+
on the screen.
|
|
18
|
+
|
|
19
|
+
Attributes:
|
|
20
|
+
arr (list): The data array.
|
|
21
|
+
sq_mob (mn.VGroup): Group of square mobjects for array cells.
|
|
22
|
+
num_mob (mn.VGroup): Group of text mobjects for array values.
|
|
23
|
+
"""
|
|
24
|
+
# Call __init__ of the parent classes
|
|
25
|
+
super().__init__()
|
|
26
|
+
# Add class attributes
|
|
27
|
+
self.arr = arr
|
|
28
|
+
self.bg_color = bg_color
|
|
29
|
+
|
|
30
|
+
# Construction: Create square mobjects for each array element
|
|
31
|
+
# NB: if opacity is not specified, it will be set to None
|
|
32
|
+
# and some methods will break for unknown reasons
|
|
33
|
+
self.sq_mob = mn.VGroup(*[
|
|
34
|
+
mn.Square().set_fill(
|
|
35
|
+
self.bg_color, 1).set_width(0.7).set_height(0.7)
|
|
36
|
+
for _ in arr
|
|
37
|
+
])
|
|
38
|
+
# Construction: Arrange squares in a row
|
|
39
|
+
self.sq_mob.arrange(mn.RIGHT, buff=0.1)
|
|
40
|
+
# Construction: Move array to the specified position
|
|
41
|
+
self.sq_mob.move_to(position)
|
|
42
|
+
|
|
43
|
+
# Construction: Create text mobjects and center them in squares
|
|
44
|
+
self.num_mob = mn.VGroup(*[
|
|
45
|
+
mn.Text(str(num)).move_to(square)
|
|
46
|
+
for num, square in zip(arr, self.sq_mob)
|
|
47
|
+
])
|
|
48
|
+
|
|
49
|
+
# Create pointers as a list with top and bottom groups
|
|
50
|
+
self.pointers = [[], []] # [0] for top, [1] for bottom
|
|
51
|
+
|
|
52
|
+
for square in self.sq_mob:
|
|
53
|
+
# Create top triangles (3 per square)
|
|
54
|
+
top_tri_group = mn.VGroup(*[
|
|
55
|
+
mn.Triangle(
|
|
56
|
+
color=self.bg_color,
|
|
57
|
+
)
|
|
58
|
+
.scale([0.5, 1, 1])
|
|
59
|
+
.scale(0.1)
|
|
60
|
+
.rotate(mn.PI)
|
|
61
|
+
for _ in range(3)
|
|
62
|
+
])
|
|
63
|
+
# Arrange top triangles horizontally above the square
|
|
64
|
+
top_tri_group.arrange(mn.RIGHT, buff=0.08)
|
|
65
|
+
top_tri_group.next_to(square, mn.UP, buff=0.15)
|
|
66
|
+
self.pointers[0].append(top_tri_group)
|
|
67
|
+
|
|
68
|
+
# Create bottom triangles (3 per square)
|
|
69
|
+
bottom_tri_group = mn.VGroup(*[
|
|
70
|
+
mn.Triangle(
|
|
71
|
+
color=self.bg_color,
|
|
72
|
+
)
|
|
73
|
+
.scale([0.5, 1, 1])
|
|
74
|
+
.scale(0.1)
|
|
75
|
+
for _ in range(3)
|
|
76
|
+
])
|
|
77
|
+
# Arrange bottom triangles horizontally below the square
|
|
78
|
+
bottom_tri_group.arrange(mn.RIGHT, buff=0.08)
|
|
79
|
+
bottom_tri_group.next_to(square, mn.DOWN, buff=0.15)
|
|
80
|
+
self.pointers[1].append(bottom_tri_group)
|
|
81
|
+
|
|
82
|
+
# Adds local objects as instance attributes
|
|
83
|
+
self.add(self.sq_mob, self.num_mob)
|
|
84
|
+
self.add(*[ptr for group in self.pointers for ptr in group])
|
|
85
|
+
|
|
86
|
+
def first_appear(self, scene, time=0.5):
|
|
87
|
+
scene.play(mn.FadeIn(self), run_time=time)
|
|
88
|
+
|
|
89
|
+
def pointers_1(
|
|
90
|
+
self, i: int,
|
|
91
|
+
pos: int = 0,
|
|
92
|
+
i_color=mn.GREEN,
|
|
93
|
+
):
|
|
94
|
+
"""
|
|
95
|
+
Highlight a single pointer at one side (top | bottom) in the
|
|
96
|
+
array visualization.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
i (int): Index of the block whose pointer to highlight.
|
|
100
|
+
pos (int): 0 for top pointers, 1 for bottom. Defaults to 0.
|
|
101
|
+
i_color: Color for the highlighted pointer. Defaults to mn.GREEN.
|
|
102
|
+
"""
|
|
103
|
+
if pos not in (0, 1):
|
|
104
|
+
raise ValueError('pos must be 0 (top) or 1 (bottom)')
|
|
105
|
+
for idx, mob in enumerate(self.sq_mob):
|
|
106
|
+
self.pointers[pos][idx][1].set_color(
|
|
107
|
+
i_color if idx == i else self.bg_color)
|
|
108
|
+
|
|
109
|
+
# Highlight blocks for 1 index
|
|
110
|
+
def highlight_blocks_1(
|
|
111
|
+
self, i: int,
|
|
112
|
+
i_color=mn.GREEN,
|
|
113
|
+
):
|
|
114
|
+
"""
|
|
115
|
+
Highlight a single block in the array visualization.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
i (int): Index of the block to highlight.
|
|
119
|
+
i_color: Color for the highlighted block.
|
|
120
|
+
"""
|
|
121
|
+
for idx, mob in enumerate(self.sq_mob):
|
|
122
|
+
mob.set_fill(i_color if idx == i else self.bg_color)
|
|
123
|
+
|
|
124
|
+
def pointers_2(
|
|
125
|
+
self, i: int, j: int,
|
|
126
|
+
pos: int = 0,
|
|
127
|
+
i_color=mn.RED,
|
|
128
|
+
j_color=mn.BLUE,
|
|
129
|
+
):
|
|
130
|
+
"""
|
|
131
|
+
Highlight two pointers at one side (top | bottom) in the
|
|
132
|
+
array visualization.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
i (int), j (int): Indices of the block whose pointer to highlight.
|
|
136
|
+
pos (int): 0 for top pointers, 1 for bottom. Defaults to 0.
|
|
137
|
+
i_color: Color for the highlighted pointer. Defaults to mn.GREEN.
|
|
138
|
+
"""
|
|
139
|
+
if pos not in (0, 1):
|
|
140
|
+
raise ValueError('pos must be 0 (top) or 1 (bottom)')
|
|
141
|
+
for idx, mob in enumerate(self.sq_mob):
|
|
142
|
+
if idx == i == j:
|
|
143
|
+
self.pointers[pos][idx][0].set_color(i_color)
|
|
144
|
+
self.pointers[pos][idx][1].set_color(self.bg_color)
|
|
145
|
+
self.pointers[pos][idx][2].set_color(j_color)
|
|
146
|
+
elif idx == i:
|
|
147
|
+
self.pointers[pos][idx][0].set_color(self.bg_color)
|
|
148
|
+
self.pointers[pos][idx][1].set_color(i_color)
|
|
149
|
+
self.pointers[pos][idx][2].set_color(self.bg_color)
|
|
150
|
+
elif idx == j:
|
|
151
|
+
self.pointers[pos][idx][0].set_color(self.bg_color)
|
|
152
|
+
self.pointers[pos][idx][1].set_color(j_color)
|
|
153
|
+
self.pointers[pos][idx][2].set_color(self.bg_color)
|
|
154
|
+
else:
|
|
155
|
+
self.pointers[pos][idx][0].set_color(self.bg_color)
|
|
156
|
+
self.pointers[pos][idx][1].set_color(self.bg_color)
|
|
157
|
+
self.pointers[pos][idx][2].set_color(self.bg_color)
|
|
158
|
+
|
|
159
|
+
# Highlight blocks for 2 indices
|
|
160
|
+
def highlight_blocks_2(
|
|
161
|
+
self, i: int, j: int,
|
|
162
|
+
i_color=mn.RED,
|
|
163
|
+
j_color=mn.BLUE,
|
|
164
|
+
ij_color=mn.PURPLE,
|
|
165
|
+
):
|
|
166
|
+
"""
|
|
167
|
+
Highlight two blocks in the array visualization.
|
|
168
|
+
If indices coincide, use a special color.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
i (int): First index to highlight.
|
|
172
|
+
j (int): Second index to highlight.
|
|
173
|
+
i_color: Color for the first index.
|
|
174
|
+
j_color: Color for the second index.
|
|
175
|
+
ij_color: Color if both indices are the same.
|
|
176
|
+
"""
|
|
177
|
+
for idx, mob in enumerate(self.sq_mob):
|
|
178
|
+
if idx == i == j:
|
|
179
|
+
mob.set_fill(ij_color)
|
|
180
|
+
elif idx == i:
|
|
181
|
+
mob.set_fill(i_color)
|
|
182
|
+
elif idx == j:
|
|
183
|
+
mob.set_fill(j_color)
|
|
184
|
+
else:
|
|
185
|
+
mob.set_fill(self.bg_color)
|
|
186
|
+
|
|
187
|
+
def pointers_3(
|
|
188
|
+
self, i: int, j: int, k: int,
|
|
189
|
+
pos: int = 0,
|
|
190
|
+
i_color=mn.RED,
|
|
191
|
+
j_color=mn.GREEN,
|
|
192
|
+
k_color=mn.BLUE,
|
|
193
|
+
):
|
|
194
|
+
"""
|
|
195
|
+
Highlight two pointers at one side (top | bottom) in the
|
|
196
|
+
array visualization.
|
|
197
|
+
|
|
198
|
+
Args:
|
|
199
|
+
i (int), j (int), k (int): Indices of the block whose pointer
|
|
200
|
+
to highlight.
|
|
201
|
+
pos (int): 0 for top pointers, 1 for bottom. Defaults to 0.
|
|
202
|
+
i_color: Color for the highlighted pointer. Defaults to mn.GREEN.
|
|
203
|
+
"""
|
|
204
|
+
for idx, mob in enumerate(self.sq_mob):
|
|
205
|
+
if idx == i == j == k:
|
|
206
|
+
self.pointers[pos][idx][0].set_color(i_color)
|
|
207
|
+
self.pointers[pos][idx][1].set_color(j_color)
|
|
208
|
+
self.pointers[pos][idx][2].set_color(k_color)
|
|
209
|
+
elif idx == i == j:
|
|
210
|
+
self.pointers[pos][idx][0].set_color(i_color)
|
|
211
|
+
self.pointers[pos][idx][1].set_color(self.bg_color)
|
|
212
|
+
self.pointers[pos][idx][2].set_color(j_color)
|
|
213
|
+
elif idx == i == k:
|
|
214
|
+
self.pointers[pos][idx][0].set_color(i_color)
|
|
215
|
+
self.pointers[pos][idx][1].set_color(self.bg_color)
|
|
216
|
+
self.pointers[pos][idx][2].set_color(k_color)
|
|
217
|
+
elif idx == k == j:
|
|
218
|
+
self.pointers[pos][idx][0].set_color(j_color)
|
|
219
|
+
self.pointers[pos][idx][1].set_color(self.bg_color)
|
|
220
|
+
self.pointers[pos][idx][2].set_color(k_color)
|
|
221
|
+
elif idx == i:
|
|
222
|
+
self.pointers[pos][idx][0].set_color(self.bg_color)
|
|
223
|
+
self.pointers[pos][idx][1].set_color(i_color)
|
|
224
|
+
self.pointers[pos][idx][2].set_color(self.bg_color)
|
|
225
|
+
elif idx == j:
|
|
226
|
+
self.pointers[pos][idx][0].set_color(self.bg_color)
|
|
227
|
+
self.pointers[pos][idx][1].set_color(j_color)
|
|
228
|
+
self.pointers[pos][idx][2].set_color(self.bg_color)
|
|
229
|
+
elif idx == k:
|
|
230
|
+
self.pointers[pos][idx][0].set_color(self.bg_color)
|
|
231
|
+
self.pointers[pos][idx][1].set_color(k_color)
|
|
232
|
+
self.pointers[pos][idx][2].set_color(self.bg_color)
|
|
233
|
+
else:
|
|
234
|
+
self.pointers[pos][idx][0].set_color(self.bg_color)
|
|
235
|
+
self.pointers[pos][idx][1].set_color(self.bg_color)
|
|
236
|
+
self.pointers[pos][idx][2].set_color(self.bg_color)
|
|
237
|
+
|
|
238
|
+
# Highlight blocks for 3 indices
|
|
239
|
+
def highlight_blocks_3(
|
|
240
|
+
self, i: int, j: int, k: int,
|
|
241
|
+
i_color=mn.RED,
|
|
242
|
+
j_color=mn.GREEN,
|
|
243
|
+
k_color=mn.BLUE,
|
|
244
|
+
ijk_color=mn.BLACK,
|
|
245
|
+
ij_color=mn.YELLOW_E,
|
|
246
|
+
ik_color=mn.PURPLE,
|
|
247
|
+
jk_color=mn.TEAL,
|
|
248
|
+
):
|
|
249
|
+
"""
|
|
250
|
+
Highlight three blocks in the array visualization.
|
|
251
|
+
Use special colors for index coincidences.
|
|
252
|
+
|
|
253
|
+
Args:
|
|
254
|
+
i (int): First index to highlight.
|
|
255
|
+
j (int): Second index to highlight.
|
|
256
|
+
k (int): Third index to highlight.
|
|
257
|
+
i_color: Color for the first index.
|
|
258
|
+
j_color: Color for the second index.
|
|
259
|
+
k_color: Color for the third index.
|
|
260
|
+
ijk_color: Color if all three indices are the same.
|
|
261
|
+
ij_color: Color if i and j are the same.
|
|
262
|
+
ik_color: Color if i and k are the same.
|
|
263
|
+
jk_color: Color if j and k are the same.
|
|
264
|
+
"""
|
|
265
|
+
for idx, mob in enumerate(self.sq_mob):
|
|
266
|
+
if idx == i == j == k:
|
|
267
|
+
mob.set_fill(ijk_color)
|
|
268
|
+
elif idx == i == j:
|
|
269
|
+
mob.set_fill(ij_color)
|
|
270
|
+
elif idx == i == k:
|
|
271
|
+
mob.set_fill(ik_color)
|
|
272
|
+
elif idx == k == j:
|
|
273
|
+
mob.set_fill(jk_color)
|
|
274
|
+
elif idx == i:
|
|
275
|
+
mob.set_fill(i_color)
|
|
276
|
+
elif idx == j:
|
|
277
|
+
mob.set_fill(j_color)
|
|
278
|
+
elif idx == k:
|
|
279
|
+
mob.set_fill(k_color)
|
|
280
|
+
else:
|
|
281
|
+
mob.set_fill(self.bg_color)
|
|
282
|
+
|
|
283
|
+
# Animation of changing values in the array
|
|
284
|
+
def update_number_mobject(
|
|
285
|
+
self, scene, i: int,
|
|
286
|
+
add_arr: list, j: int):
|
|
287
|
+
"""
|
|
288
|
+
Animate the change of a number in the array visualization.
|
|
289
|
+
The number at index i in num_mob is replaced with a new value
|
|
290
|
+
from add_arr[j], and the new text is positioned at the center
|
|
291
|
+
of the corresponding square.
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
i (int): Index in the array to update.
|
|
295
|
+
add_arr (list): Source array for the new value.
|
|
296
|
+
j (int): Index in add_arr to get the new value from.
|
|
297
|
+
"""
|
|
298
|
+
# self.num_mob - group of text objects in the array
|
|
299
|
+
# .animate.become() - animation of transforming the receiver object
|
|
300
|
+
# into the argument
|
|
301
|
+
# mn.Text(str(arr[i])) - construction of a new text object
|
|
302
|
+
# self.arr_mob - group of graphical square objects
|
|
303
|
+
# .move_to(self.arr_mob[j]) - positioning the new text object
|
|
304
|
+
# in the same location, that self.arr_mob[k] has
|
|
305
|
+
# location in Manim is the center of mass
|
|
306
|
+
|
|
307
|
+
# Animate replacing the text at index i with new value from add_arr[j]
|
|
308
|
+
scene.play(
|
|
309
|
+
self.num_mob[i].animate.become(
|
|
310
|
+
mn.Text(
|
|
311
|
+
str(add_arr[j]),
|
|
312
|
+
).move_to(self.sq_mob[i])),
|
|
313
|
+
# animation duration
|
|
314
|
+
run_time=0.2
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
class TopText(mn.VGroup):
|
|
319
|
+
def __init__(
|
|
320
|
+
self,
|
|
321
|
+
mob_center: mn.Mobject,
|
|
322
|
+
*vars: tuple,
|
|
323
|
+
font_size=40,
|
|
324
|
+
buff=0.7,
|
|
325
|
+
vector=mn.UP * 1.2,
|
|
326
|
+
):
|
|
327
|
+
super().__init__()
|
|
328
|
+
self.mob_center = mob_center
|
|
329
|
+
self.vars = vars
|
|
330
|
+
self.font_size = font_size
|
|
331
|
+
self.buff = buff
|
|
332
|
+
self.vector = vector
|
|
333
|
+
self._refresh()
|
|
334
|
+
|
|
335
|
+
def _refresh(self):
|
|
336
|
+
self.submobjects = []
|
|
337
|
+
parts = [
|
|
338
|
+
mn.Text(f"{name} = {value()}",
|
|
339
|
+
font_size=self.font_size, color=color)
|
|
340
|
+
for name, value, color in self.vars
|
|
341
|
+
]
|
|
342
|
+
top_text = mn.VGroup(*parts).arrange(mn.RIGHT, buff=self.buff)
|
|
343
|
+
top_text.move_to(self.mob_center.get_center() + self.vector)
|
|
344
|
+
self.add(*top_text)
|
|
345
|
+
|
|
346
|
+
def first_appear(self, scene, time=0.5):
|
|
347
|
+
scene.play(mn.FadeIn(self), run_time=time)
|
|
348
|
+
|
|
349
|
+
def update_text(self, scene, time=0.1):
|
|
350
|
+
# Create a new object with the same parameters
|
|
351
|
+
# (vars may be updated)
|
|
352
|
+
new_group = TopText(
|
|
353
|
+
self.mob_center,
|
|
354
|
+
*self.vars,
|
|
355
|
+
font_size=self.font_size,
|
|
356
|
+
buff=self.buff,
|
|
357
|
+
vector=self.vector,
|
|
358
|
+
)
|
|
359
|
+
scene.play(mn.Transform(self, new_group), run_time=time)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
class CodeBlock(mn.VGroup):
|
|
363
|
+
def __init__(
|
|
364
|
+
self,
|
|
365
|
+
code_lines: list,
|
|
366
|
+
position: mn.Mobject,
|
|
367
|
+
font_size=25,
|
|
368
|
+
font="MesloLGS NF"
|
|
369
|
+
):
|
|
370
|
+
"""
|
|
371
|
+
Creates a code block visualization on the screen.
|
|
372
|
+
|
|
373
|
+
Args:
|
|
374
|
+
code_lines (list): List of code lines to display.
|
|
375
|
+
position (mn.Mobject): Position to place the code block.
|
|
376
|
+
font_size (int, optional): Font size for the code text.
|
|
377
|
+
font (str, optional): Font for the code text.
|
|
378
|
+
"""
|
|
379
|
+
super().__init__()
|
|
380
|
+
# Construction
|
|
381
|
+
code_mobs = [
|
|
382
|
+
mn.Text(line, font=font, font_size=font_size)
|
|
383
|
+
for line in code_lines
|
|
384
|
+
]
|
|
385
|
+
code_vgroup = mn.VGroup(
|
|
386
|
+
*code_mobs).arrange(mn.DOWN, aligned_edge=mn.LEFT)
|
|
387
|
+
code_vgroup.move_to(position)
|
|
388
|
+
self.code_vgroup = code_vgroup
|
|
389
|
+
# Construstion: add to scene
|
|
390
|
+
self.add(self.code_vgroup)
|
|
391
|
+
|
|
392
|
+
def first_appear(self, scene, time=0.5):
|
|
393
|
+
scene.play(mn.FadeIn(self), run_time=time)
|
|
394
|
+
|
|
395
|
+
def highlight_line(self, scene, i: int):
|
|
396
|
+
"""
|
|
397
|
+
Highlights a single line of code in the code block by fading it
|
|
398
|
+
to yellow, instead of white.
|
|
399
|
+
|
|
400
|
+
Args:
|
|
401
|
+
scene (mn.Scene): The scene to play the animation in.
|
|
402
|
+
i (int): Index of the line to highlight.
|
|
403
|
+
"""
|
|
404
|
+
scene.play(*[
|
|
405
|
+
mn.FadeToColor(
|
|
406
|
+
mob,
|
|
407
|
+
mn.YELLOW if k == i else mn.WHITE,
|
|
408
|
+
run_time=0.2
|
|
409
|
+
)
|
|
410
|
+
for k, mob in enumerate(self.code_vgroup)
|
|
411
|
+
])
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Benedict Abub
|
|
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, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: algomanim
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Manim-powered algorithm tasks visualizations for LeetCode and beyond
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: Benedict Abub
|
|
7
|
+
Author-email: fkhurkhd2123dfs@tutamail.com
|
|
8
|
+
Requires-Python: >=3.9,<4.0
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Requires-Dist: manim (>=0.19.0,<0.20.0)
|
|
17
|
+
Project-URL: Homepage, https://github.com/benabub/algomanim
|
|
18
|
+
Project-URL: Repository, https://github.com/benabub/algomanim
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
algomanim/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
algomanim/algomanim.py,sha256=wndPFCv-1cC0wVffPQ0W08xDhSxjTi4InR9RtXRX-2M,14838
|
|
3
|
+
algomanim-0.1.0.dist-info/LICENSE,sha256=Yz65_ZGsd5EX86yt5-oFHeMgWlfa6z5AMPMkVPz2-As,1070
|
|
4
|
+
algomanim-0.1.0.dist-info/METADATA,sha256=dqcWLbRLyLoSOe8jGqhi0Ew_mkmyhcLsbImL6zxgD_4,794
|
|
5
|
+
algomanim-0.1.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
6
|
+
algomanim-0.1.0.dist-info/RECORD,,
|