help@rskworld.in +91 93305 39277
RSK World
  • Home
  • Development
    • Web Development
    • Mobile Apps
    • Software
    • Games
    • Project
  • Technologies
    • Data Science
    • AI Development
    • Cloud Development
    • Blockchain
    • Cyber Security
    • Dev Tools
    • Testing Tools
  • About
  • Contact

Theme Settings

Color Scheme
Display Options
Font Size
100%
Back to Project
RSK World
python-pattern-generator
RSK World
python-pattern-generator
Python Number Pattern Generator - 22 Pattern Types + Fractals + Mathematical Algorithms + GUI & Web Interface + REST API + Educational Design
python-pattern-generator
  • __pycache__
  • static
  • templates
  • .gitignore1.6 KB
  • README.md9.7 KB
  • animation.py14.3 KB
  • api.py19.9 KB
  • config.py14 KB
  • demo.py9.3 KB
  • index.html10.1 KB
  • main.py30.9 KB
  • pattern_comparison.py15.4 KB
  • patterns.py23 KB
  • push_to_github.bat3.9 KB
  • requirements.txt1 KB
  • svg_export.py13.4 KB
  • test_gui.py2.2 KB
  • test_patterns.py13.7 KB
  • web_app.py13.6 KB
animation.py
animation.py
Raw Download
Find: Go to:
"""
Animation Module for Python Number Pattern Generator
Author: Molla Samser (Founder, RSK World)
Designer & Tester: Rima Khatun
Website: https://rskworld.in
Year: 2026
Description: Step-by-step pattern generation animations
"""

import time
from typing import List, Dict, Any, Optional, Callable, Iterator
from patterns import PatternAlgorithms


class PatternAnimator:
    """Animation controller for pattern generation"""

    def __init__(self):
        """Initialize the pattern animator"""
        self.algorithms = PatternAlgorithms()
        self.animation_speed = 0.5  # seconds between steps

    def animate_pyramid(self, size: int, start_num: int = 1, callback: Optional[Callable] = None) -> Iterator[str]:
        """Animate pyramid pattern generation step by step"""
        pattern_lines = []

        for i in range(1, size + 1):
            spaces = " " * (size - i)
            numbers = ""
            for j in range(1, i + 1):
                numbers += f"{start_num + j - 1} "
            numbers = numbers.rstrip()

            pattern_lines.append(spaces + numbers)

            current_pattern = "\n".join(pattern_lines)
            if callback:
                callback(current_pattern, f"Adding row {i}")
            else:
                print(current_pattern)
                print(f"Step {i}: Added row {i}")
                time.sleep(self.animation_speed)

            yield current_pattern

    def animate_sierpinski(self, levels: int, callback: Optional[Callable] = None) -> Iterator[str]:
        """Animate Sierpinski triangle generation"""
        if levels <= 0:
            return

        # Start with base triangle
        height = 2 ** levels
        grid = [[" " for _ in range(height * 2)] for _ in range(height)]

        def draw_triangle_step(x: int, y: int, size: int, step: int):
            """Draw one triangle in the fractal"""
            if size == 1:
                grid[y][x] = "1"
                return

            half = size // 2

            # Draw sub-triangles
            draw_triangle_step(x, y, half, step)
            draw_triangle_step(x + half, y, half, step)
            draw_triangle_step(x + half // 2, y + half, half, step)

        # Animate level by level
        current_size = 1
        for level in range(levels):
            # Clear grid for this level
            grid = [[" " for _ in range(height * 2)] for _ in range(height)]

            # Draw triangles up to current level
            for l in range(level + 1):
                size_for_level = 2 ** (levels - l)
                draw_triangle_step(0, 0, size_for_level, l)

            # Convert to string
            pattern = "\n".join("".join(row).rstrip() for row in grid)

            if callback:
                callback(pattern, f"Level {level + 1}: Added fractal detail")
            else:
                print(pattern)
                print(f"Level {level + 1}: Added fractal detail")
                time.sleep(self.animation_speed)

            yield pattern

    def animate_spiral(self, size: int, callback: Optional[Callable] = None) -> Iterator[str]:
        """Animate spiral pattern generation"""
        matrix = [[0] * size for _ in range(size)]
        num = 1
        top, bottom = 0, size - 1
        left, right = 0, size - 1

        steps = []

        while top <= bottom and left <= right:
            # Top row
            for i in range(left, right + 1):
                matrix[top][i] = num
                num += 1
                steps.append((top, i, matrix[top][i]))

            top += 1

            # Right column
            for i in range(top, bottom + 1):
                matrix[i][right] = num
                num += 1
                steps.append((i, right, matrix[i][right]))

            right -= 1

            # Bottom row
            if top <= bottom:
                for i in range(right, left - 1, -1):
                    matrix[bottom][i] = num
                    num += 1
                    steps.append((bottom, i, matrix[bottom][i]))

                bottom -= 1

            # Left column
            if left <= right:
                for i in range(bottom, top - 1, -1):
                    matrix[i][left] = num
                    num += 1
                    steps.append((i, left, matrix[i][left]))

                left += 1

        # Animate step by step
        for step_num, (row, col, value) in enumerate(steps, 1):
            pattern = "\n".join(" ".join(f"{num:3d}" for num in row_data) for row_data in matrix)

            if callback:
                callback(pattern, f"Step {step_num}: Added number {value} at position ({row}, {col})")
            else:
                print(pattern)
                print(f"Step {step_num}: Added number {value} at position ({row}, {col})")
                time.sleep(self.animation_speed * 0.5)  # Faster for spiral

            yield pattern

    def animate_cellular_automaton(self, generations: int, rule: int = 30, callback: Optional[Callable] = None) -> Iterator[str]:
        """Animate cellular automaton evolution"""
        width = generations * 2 + 1
        grid = [[0] * width for _ in range(generations)]
        grid[0][width // 2] = 1  # Single 1 in center

        # Convert rule to binary
        rule_bits = [(rule >> i) & 1 for i in range(8)]

        # Animate generation by generation
        for gen in range(1, generations):
            new_row = []
            for col in range(1, width - 1):
                # Get neighborhood (3 bits)
                left = grid[gen-1][col-1]
                center = grid[gen-1][col]
                right = grid[gen-1][col+1]

                # Convert to rule index
                neighborhood = (left << 2) | (center << 1) | right
                new_cell = rule_bits[neighborhood]
                new_row.append(new_cell)

            # Pad with zeros
            grid[gen] = [0] + new_row + [0]

            # Convert to visual representation
            pattern = "\n".join("".join("ā–ˆ" if cell else " " for cell in row) for row in grid[:gen+1])

            if callback:
                callback(pattern, f"Generation {gen}: Applied rule {rule}")
            else:
                print(pattern)
                print(f"Generation {gen}: Applied rule {rule}")
                time.sleep(self.animation_speed)

            yield pattern

    def animate_dragon_curve(self, iterations: int, callback: Optional[Callable] = None) -> Iterator[str]:
        """Animate dragon curve generation"""
        sequence = "FX"

        # Generate sequence step by step
        for iteration in range(iterations):
            new_sequence = ""
            for char in sequence:
                if char == "X":
                    new_sequence += "X+YF+"
                elif char == "Y":
                    new_sequence += "-FX-Y"
                else:
                    new_sequence += char
            sequence = new_sequence

            # Convert to grid (simplified visualization)
            x, y = 0, 0
            direction = 0
            grid_size = 3 ** (iteration + 2)
            grid = [[" " for _ in range(grid_size)] for _ in range(grid_size)]

            for char in sequence:
                if char == "F":
                    grid[y][x] = "ā–ˆ"
                    # Move forward
                    if direction == 0:
                        x += 1
                    elif direction == 1:
                        y -= 1
                    elif direction == 2:
                        x -= 1
                    elif direction == 3:
                        y += 1
                elif char == "+":
                    direction = (direction + 1) % 4
                elif char == "-":
                    direction = (direction - 1) % 4

            # Find bounds and extract pattern
            min_x = min(x for row in grid for x, cell in enumerate(row) if cell != " ")
            max_x = max(x for row in grid for x, cell in enumerate(row) if cell != " ")
            min_y = min(y for y, row in enumerate(grid) for x, cell in enumerate(row) if cell != " ")
            max_y = max(y for y, row in enumerate(grid) for x, cell in enumerate(row) if cell != " ")

            result = []
            for y in range(min_y, max_y + 1):
                row = ""
                for x in range(min_x, max_x + 1):
                    row += grid[y][x]
                result.append(row.rstrip())

            pattern = "\n".join(result)

            if callback:
                callback(pattern, f"Iteration {iteration + 1}: Extended dragon curve")
            else:
                print(pattern)
                print(f"Iteration {iteration + 1}: Extended dragon curve")
                time.sleep(self.animation_speed)

            yield pattern

    def set_animation_speed(self, speed: float):
        """Set animation speed in seconds"""
        self.animation_speed = max(0.1, min(5.0, speed))

    def animate_pattern(self, pattern_type: str, size: int, start_num: int = 1,
                       callback: Optional[Callable] = None) -> Iterator[str]:
        """Animate any supported pattern type"""
        if pattern_type == "pyramid":
            yield from self.animate_pyramid(size, start_num, callback)
        elif pattern_type == "sierpinski":
            yield from self.animate_sierpinski(min(size, 5), callback)
        elif pattern_type == "spiral":
            yield from self.animate_spiral(size, callback)
        elif pattern_type == "cellular":
            yield from self.animate_cellular_automaton(size, start_num, callback)
        elif pattern_type == "dragon":
            yield from self.animate_dragon_curve(min(size, 6), callback)
        else:
            # For non-animated patterns, just return final result
            if pattern_type == "reverse_pyramid":
                pattern = self.algorithms.reverse_pyramid(size, start_num)
            elif pattern_type == "triangle":
                pattern = self.algorithms.triangle(size, start_num)
            elif pattern_type == "pascal":
                pattern = self.algorithms.pascal_triangle(size)
            elif pattern_type == "floyd":
                pattern = self.algorithms.floyd_triangle(size)
            elif pattern_type == "square":
                pattern = self.algorithms.square(size, start_num)
            elif pattern_type == "diamond":
                pattern = self.algorithms.diamond(size, start_num)
            elif pattern_type == "hourglass":
                pattern = self.algorithms.hourglass(size, start_num)
            elif pattern_type == "prime":
                pattern = self.algorithms.prime_numbers(size)
            elif pattern_type == "fibonacci":
                pattern = self.algorithms.fibonacci_triangle(size)
            elif pattern_type == "multiplication":
                pattern = self.algorithms.multiplication_table(size)
            elif pattern_type == "magic":
                pattern = self.algorithms.magic_square(size)
            elif pattern_type == "mandelbrot":
                pattern = self.algorithms.mandelbrot_set(min(size, 15))
            elif pattern_type == "hilbert":
                pattern = self.algorithms.hilbert_curve(min(size, 4))
            elif pattern_type == "koch":
                pattern = self.algorithms.koch_snowflake(min(size, 3))
            elif pattern_type == "binary_tree":
                pattern = self.algorithms.binary_tree(min(size, 5))
            else:
                pattern = "Pattern type not supported for animation"

            yield pattern


class AnimationController:
    """Controller for managing pattern animations"""

    def __init__(self):
        """Initialize animation controller"""
        self.animator = PatternAnimator()
        self.current_animation = None
        self.is_playing = False

    def start_animation(self, pattern_type: str, size: int, start_num: int = 1,
                       speed: float = 0.5, callback: Optional[Callable] = None):
        """Start a pattern animation"""
        self.animator.set_animation_speed(speed)
        self.current_animation = self.animator.animate_pattern(
            pattern_type, size, start_num, callback
        )
        self.is_playing = True

    def get_next_frame(self) -> Optional[str]:
        """Get next frame of animation"""
        if self.current_animation and self.is_playing:
            try:
                return next(self.current_animation)
            except StopIteration:
                self.is_playing = False
                return None
        return None

    def stop_animation(self):
        """Stop current animation"""
        self.is_playing = False
        self.current_animation = None

    def is_animation_active(self) -> bool:
        """Check if animation is currently active"""
        return self.is_playing


# Global animation controller instance
animation_controller = AnimationController()


def animate_pattern(pattern_type: str, size: int, start_num: int = 1,
                   speed: float = 0.5, callback: Optional[Callable] = None):
    """Convenience function to animate a pattern"""
    animation_controller.start_animation(pattern_type, size, start_num, speed, callback)
    return animation_controller


if __name__ == '__main__':
    print("Python Number Pattern Generator - Animation Module")
    print("=" * 60)
    print("Developed by Molla Samser (RSK World)")
    print("Designed by Rima Khatun")
    print("Website: https://rskworld.in")
    print("Year: 2026")
    print("=" * 60)

    # Example animations
    animator = PatternAnimator()

    print("\nšŸŽÆ Animating Pyramid Pattern:")
    print("-" * 30)
    for frame in animator.animate_pyramid(4, 1):
        pass  # Already printed in the iterator

    print("\nšŸŒ€ Animating Spiral Pattern:")
    print("-" * 30)
    animator.set_animation_speed(0.3)  # Faster for spiral
    for frame in animator.animate_spiral(3):
        pass

    print("\nšŸ”ŗ Animating Sierpinski Triangle:")
    print("-" * 30)
    for frame in animator.animate_sierpinski(3):
        pass

    print("\nāœ… Animation demonstrations completed!")
    print("šŸ’” Use these animations in GUI or web interface for interactive visualization")
382 lines•14.3 KB
python

About RSK World

Founded by Molla Samser, with Designer & Tester Rima Khatun, RSK World is your one-stop destination for free programming resources, source code, and development tools.

Founder: Molla Samser
Designer & Tester: Rima Khatun

Development

  • Game Development
  • Web Development
  • Mobile Development
  • AI Development
  • Development Tools

Legal

  • Terms & Conditions
  • Privacy Policy
  • Disclaimer

Contact Info

Nutanhat, Mongolkote
Purba Burdwan, West Bengal
India, 713147

+91 93305 39277

hello@rskworld.in
support@rskworld.in

© 2026 RSK World. All rights reserved.

Content used for educational purposes only. View Disclaimer