Skip to content

Commit 00a1d17

Browse files
committed
refactor(python): move Python examples, src, tests to nested directories
1 parent fe59ea0 commit 00a1d17

29 files changed

+3889
-1100
lines changed

README.md

Lines changed: 120 additions & 160 deletions
Large diffs are not rendered by default.

python/examples/algorithms_example.py

Lines changed: 474 additions & 0 deletions
Large diffs are not rendered by default.

python/examples/containers_example.py

Lines changed: 349 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,349 @@
1+
#!/usr/bin/env python3
2+
"""Containers module example demonstrating type-safe container operations.
3+
4+
This example shows how to use the container wrapper for type-safe operations
5+
including filtering, transformation, and collection management.
6+
"""
7+
8+
import sys
9+
from pathlib import Path
10+
from typing import Any, Callable, List
11+
12+
# Add the python module to the path
13+
sys.path.insert(0, str(Path(__file__).parent.parent / 'src'))
14+
15+
from containers import Container, create_container
16+
17+
18+
def basic_container_demo() -> None:
19+
"""Demonstrate basic container creation and operations.
20+
21+
Shows fundamental container operations including creation, addition,
22+
removal, and basic iteration.
23+
"""
24+
print('=== Basic Container Demo ===')
25+
26+
# Create containers with different types
27+
int_container = create_container([1, 3, 2, 5, 4])
28+
str_container = Container(str, ['apple', 'banana', 'cherry'])
29+
30+
print(f'Integer container: {list(int_container)}')
31+
print(f'String container: {list(str_container)}')
32+
33+
# Add and remove items
34+
int_container.add(6)
35+
removed = int_container.remove(3)
36+
print(f'After adding 6 and removing 3 (removed {removed}): {list(int_container)}')
37+
38+
# Container properties
39+
print(f'Integer container size: {len(int_container)}')
40+
print(f'Is empty: {int_container.is_empty()}')
41+
print(f'Contains 5: {int_container.contains(5)}')
42+
43+
print()
44+
45+
46+
def filtering_demo() -> None:
47+
"""Demonstrate container filtering capabilities.
48+
49+
Shows various filtering patterns and how to chain filter operations
50+
for complex data selection.
51+
"""
52+
print('=== Filtering Demo ===')
53+
54+
# Create test data
55+
numbers = create_container(list(range(1, 21))) # 1 to 20
56+
words = Container(str, ['apple', 'banana', 'cherry', 'date', 'elderberry', 'fig'])
57+
58+
# Numeric filtering
59+
even_numbers = numbers.filter(lambda x: x % 2 == 0)
60+
large_numbers = numbers.filter(lambda x: x > 15)
61+
divisible_by_three = numbers.filter(lambda x: x % 3 == 0)
62+
63+
print(f'Original numbers: {list(numbers)}')
64+
print(f'Even numbers: {even_numbers}')
65+
print(f'Large numbers (>15): {large_numbers}')
66+
print(f'Divisible by 3: {divisible_by_three}')
67+
68+
# String filtering
69+
long_words = words.filter(lambda s: len(s) > 5)
70+
words_with_e = words.filter(lambda s: 'e' in s)
71+
words_starting_with_c = words.filter(lambda s: s.startswith('c'))
72+
73+
print(f'\nOriginal words: {list(words)}')
74+
print(f'Long words (>5 chars): {long_words}')
75+
print(f'Words containing "e": {words_with_e}')
76+
print(f'Words starting with "c": {words_starting_with_c}')
77+
78+
# Complex filtering with multiple conditions
79+
complex_filter = numbers.filter(lambda x: x % 2 == 0 and x > 10)
80+
print(f'Even numbers > 10: {complex_filter}')
81+
82+
print()
83+
84+
85+
def transformation_demo() -> None:
86+
"""Demonstrate container transformation capabilities.
87+
88+
Shows how to transform container elements using mapping functions
89+
and create new containers with modified data.
90+
"""
91+
print('=== Transformation Demo ===')
92+
93+
# Numeric transformations
94+
numbers = create_container([1, 2, 3, 4, 5])
95+
96+
squared = numbers.transform(lambda x: x * x)
97+
doubled = numbers.transform(lambda x: x * 2)
98+
negated = numbers.transform(lambda x: -x)
99+
100+
print(f'Original: {list(numbers)}')
101+
print(f'Squared: {squared}')
102+
print(f'Doubled: {doubled}')
103+
print(f'Negated: {negated}')
104+
105+
# String transformations
106+
words = Container(str, ['hello', 'world', 'python', 'container'])
107+
108+
lengths = words.transform(len)
109+
uppercase = words.transform(str.upper)
110+
reversed_words = words.transform(lambda s: s[::-1])
111+
first_chars = words.transform(lambda s: s[0] if s else '')
112+
113+
print(f'\nOriginal words: {list(words)}')
114+
print(f'Word lengths: {lengths}')
115+
print(f'Uppercase: {uppercase}')
116+
print(f'Reversed: {reversed_words}')
117+
print(f'First characters: {first_chars}')
118+
119+
# Complex transformations
120+
numbers_to_strings = numbers.transform(lambda x: f'Number: {x}')
121+
print(f'Complex transformation: {numbers_to_strings}')
122+
123+
print()
124+
125+
126+
def chained_operations_demo() -> None:
127+
"""Demonstrate chaining of container operations.
128+
129+
Shows how to combine filtering and transformation operations
130+
to create complex data processing pipelines.
131+
"""
132+
print('=== Chained Operations Demo ===')
133+
134+
# Create sample data
135+
data = create_container(list(range(1, 11)))
136+
print(f'Original data: {list(data)}')
137+
138+
# Chain operations step by step
139+
step1 = data.filter(lambda x: x % 2 == 1) # Keep odd numbers
140+
step2 = step1.transform(lambda x: x * x) # Square them
141+
step3 = Container(int, step2).filter(lambda x: x < 50) # Keep those < 50
142+
143+
print(f'Step 1 - Odd numbers: {step1}')
144+
print(f'Step 2 - Squared: {step2}')
145+
print(f'Step 3 - Squares < 50: {step3}')
146+
147+
# Working with strings - pipeline processing
148+
text_data = Container(
149+
str, ['The', 'quick', 'brown', 'fox', 'jumps', 'over', 'lazy', 'dog']
150+
)
151+
152+
# Process: keep words > 3 chars, convert to uppercase, get lengths
153+
processed_text = text_data.filter(lambda w: len(w) > 3)
154+
upper_text = Container(str, processed_text).transform(str.upper)
155+
final_lengths = Container(str, upper_text).transform(len)
156+
157+
print(f'\nText processing pipeline:')
158+
print(f'Original: {list(text_data)}')
159+
print(f'Words > 3 chars: {processed_text}')
160+
print(f'Uppercase: {upper_text}')
161+
print(f'Final lengths: {final_lengths}')
162+
163+
print()
164+
165+
166+
def type_safety_demo() -> None:
167+
"""Demonstrate type safety features of containers.
168+
169+
Shows how containers maintain type safety and provide
170+
compile-time and runtime type checking capabilities.
171+
"""
172+
print('=== Type Safety Demo ===')
173+
174+
# Homogeneous containers
175+
int_container = Container(int, [1, 2, 3])
176+
str_container = Container(str, ['a', 'b', 'c'])
177+
float_container = Container(float, [1.1, 2.2, 3.3])
178+
179+
print(f'Integer container: {list(int_container)}')
180+
print(f'String container: {list(str_container)}')
181+
print(f'Float container: {list(float_container)}')
182+
183+
# Type-specific operations
184+
print(f'\nType-specific operations:')
185+
186+
# Integer operations
187+
int_sum = sum(int_container)
188+
int_max = max(int_container)
189+
print(f'Integer sum: {int_sum}, max: {int_max}')
190+
191+
# String operations
192+
str_joined = ' '.join(str_container)
193+
str_total_length = sum(len(s) for s in str_container)
194+
print(f'Joined strings: "{str_joined}", total length: {str_total_length}')
195+
196+
# Float operations with precision
197+
float_avg = sum(float_container) / len(float_container)
198+
print(f'Float average: {float_avg:.3f}')
199+
200+
# Demonstrate type preservation in transformations
201+
int_squared = int_container.transform(lambda x: x * x)
202+
str_lengths = str_container.transform(len)
203+
float_rounded = float_container.transform(lambda x: round(x, 1))
204+
205+
print(f'\nType-preserving transformations:')
206+
print(f'Integer squared: {int_squared}')
207+
print(f'String lengths: {str_lengths}')
208+
print(f'Float rounded: {float_rounded}')
209+
210+
print()
211+
212+
213+
def advanced_operations_demo() -> None:
214+
"""Demonstrate advanced container operations.
215+
216+
Shows complex use cases including batch processing, conditional
217+
operations, and advanced filtering patterns.
218+
"""
219+
print('=== Advanced Operations Demo ===')
220+
221+
# Batch processing with multiple containers
222+
datasets = [
223+
create_container([1, 2, 3, 4, 5]),
224+
create_container([6, 7, 8, 9, 10]),
225+
create_container([11, 12, 13, 14, 15]),
226+
]
227+
228+
print('Batch processing multiple containers:')
229+
for i, dataset in enumerate(datasets, 1):
230+
processed = dataset.filter(lambda x: x % 2 == 0).transform(lambda x: x * 2)
231+
print(f' Dataset {i}: {list(dataset)} -> {processed}')
232+
233+
# Conditional operations
234+
mixed_data = create_container([-3, -1, 0, 2, 5, 8, 12])
235+
236+
# Separate positive and negative numbers
237+
positive = mixed_data.filter(lambda x: x > 0)
238+
negative = mixed_data.filter(lambda x: x < 0)
239+
zero_or_positive = mixed_data.filter(lambda x: x >= 0)
240+
241+
print(f'\nConditional separation:')
242+
print(f'Original: {list(mixed_data)}')
243+
print(f'Positive: {positive}')
244+
print(f'Negative: {negative}')
245+
print(f'Zero or positive: {zero_or_positive}')
246+
247+
# Statistical operations
248+
stats_data = create_container([1, 2, 2, 3, 4, 4, 4, 5, 6])
249+
250+
unique_values = list(set(stats_data))
251+
value_counts = {val: list(stats_data).count(val) for val in unique_values}
252+
253+
print(f'\nStatistical analysis:')
254+
print(f'Data: {list(stats_data)}')
255+
print(f'Unique values: {sorted(unique_values)}')
256+
print(f'Value counts: {value_counts}')
257+
258+
# Find most frequent value
259+
most_frequent = max(value_counts.items(), key=lambda x: x[1])
260+
print(f'Most frequent value: {most_frequent[0]} (appears {most_frequent[1]} times)')
261+
262+
print()
263+
264+
265+
def performance_demo() -> None:
266+
"""Demonstrate performance characteristics of container operations.
267+
268+
Shows how different operations scale and provides insights into
269+
performance considerations for large datasets.
270+
"""
271+
print('=== Performance Demo ===')
272+
273+
# Create larger datasets for performance testing
274+
small_data = create_container(list(range(100)))
275+
medium_data = create_container(list(range(1000)))
276+
large_data = create_container(list(range(10000)))
277+
278+
datasets = [
279+
('Small (100 elements)', small_data),
280+
('Medium (1000 elements)', medium_data),
281+
('Large (10000 elements)', large_data),
282+
]
283+
284+
print('Performance comparison across dataset sizes:')
285+
286+
for name, dataset in datasets:
287+
# Time filtering operation
288+
import time
289+
290+
start_time = time.perf_counter()
291+
filtered = dataset.filter(lambda x: x % 10 == 0)
292+
filter_time = time.perf_counter() - start_time
293+
294+
start_time = time.perf_counter()
295+
transformed = dataset.transform(lambda x: x * 2)
296+
transform_time = time.perf_counter() - start_time
297+
298+
print(f' {name}:')
299+
print(f' Filter time: {filter_time:.6f}s, result size: {len(filtered)}')
300+
print(
301+
f' Transform time: {transform_time:.6f}s, result size: {len(transformed)}'
302+
)
303+
304+
# Memory efficiency demonstration
305+
print(f'\nMemory efficiency:')
306+
efficient_chain = large_data.filter(lambda x: x % 100 == 0).transform(
307+
lambda x: x // 100
308+
)
309+
print(
310+
f'Chained operations on large dataset: {len(efficient_chain)} elements processed'
311+
)
312+
313+
print()
314+
315+
316+
def main() -> int:
317+
"""Run all container examples.
318+
319+
Returns
320+
-------
321+
int
322+
Exit code (0 for success, 1 for error)
323+
"""
324+
print('Containers Module Example')
325+
print('========================')
326+
print()
327+
328+
try:
329+
basic_container_demo()
330+
filtering_demo()
331+
transformation_demo()
332+
chained_operations_demo()
333+
type_safety_demo()
334+
advanced_operations_demo()
335+
performance_demo()
336+
337+
print('All container examples completed successfully!')
338+
return 0
339+
340+
except Exception as e:
341+
print(f'Error running container examples: {e}')
342+
import traceback
343+
344+
traceback.print_exc()
345+
return 1
346+
347+
348+
if __name__ == '__main__':
349+
sys.exit(main())

0 commit comments

Comments
 (0)