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
  • Blog
  • About
  • Contact

Theme Settings

Color Scheme
Display Options
Font Size
100%
Back to Project
RSK World
python-pattern-generator
/
static
/
js
RSK World
python-pattern-generator
Python Number Pattern Generator - 22 Pattern Types + Fractals + Mathematical Algorithms + GUI & Web Interface + REST API + Educational Design
js
  • app.js16.8 KB
tabular.csv.gitkeep.gitignorecleanup.batpattern_comparison.py
.gitignore
Raw Download
Find: Go to:
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# IDE
.vscode/
.idea/
*.swp
*.swo
*~

# OS
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Temporary files
*.tmp
*.temp
*.bak

# Log files
logs/
*.log

# Screenshots and exports
exports/
screenshots/

# Virtual environments
venv/
env/

# Database files
*.db
*.sqlite
*.sqlite3

# Configuration files that may contain sensitive data
config.json
settings.json
146 lines•1.6 KB
text
pattern_comparison.py
Raw Download
Find: Go to:
"""
Pattern Comparison Module for Python Number Pattern Generator
Author: Molla Samser (Founder, RSK World)
Designer & Tester: Rima Khatun
Website: https://rskworld.in
Year: 2026
Description: Compare patterns and analyze differences
"""

import difflib
from typing import Dict, List, Any, Optional, Tuple
from patterns import PatternUtils
from api import PatternAPI


class PatternComparator:
    """Compare and analyze patterns"""

    def __init__(self):
        """Initialize pattern comparator"""
        self.api = PatternAPI()

    def compare_patterns(self, pattern1: Dict[str, Any], pattern2: Dict[str, Any],
                        include_visual_diff: bool = True) -> Dict[str, Any]:
        """Compare two patterns comprehensively

        Args:
            pattern1: First pattern data
            pattern2: Second pattern data
            include_visual_diff: Whether to include visual diff

        Returns:
            Comparison results dictionary
        """
        comparison = {
            'patterns': {
                'pattern1': {
                    'type': pattern1.get('pattern_type'),
                    'display_name': pattern1.get('display_name'),
                    'size': pattern1.get('size'),
                    'start_num': pattern1.get('start_num'),
                    'generation_time': pattern1.get('generation_time')
                },
                'pattern2': {
                    'type': pattern2.get('pattern_type'),
                    'display_name': pattern2.get('display_name'),
                    'size': pattern2.get('size'),
                    'start_num': pattern2.get('start_num'),
                    'generation_time': pattern2.get('generation_time')
                }
            },
            'statistics_comparison': self._compare_statistics(
                pattern1.get('statistics', {}),
                pattern2.get('statistics', {})
            ),
            'similarity_score': self._calculate_similarity_score(pattern1, pattern2)
        }

        if include_visual_diff:
            comparison['visual_diff'] = self._create_visual_diff(
                pattern1.get('pattern', ''),
                pattern2.get('pattern', '')
            )

        return comparison

    def _compare_statistics(self, stats1: Dict[str, Any], stats2: Dict[str, Any]) -> Dict[str, Any]:
        """Compare pattern statistics"""
        comparison = {}

        for key in ['lines', 'characters', 'numbers', 'max_num', 'min_num', 'sum_nums', 'avg_per_line']:
            val1 = stats1.get(key, 0)
            val2 = stats2.get(key, 0)

            comparison[key] = {
                'pattern1': val1,
                'pattern2': val2,
                'difference': val2 - val1,
                'percentage_change': ((val2 - val1) / val1 * 100) if val1 != 0 else 0
            }

        return comparison

    def _calculate_similarity_score(self, pattern1: Dict[str, Any], pattern2: Dict[str, Any]) -> float:
        """Calculate similarity score between patterns (0-100)"""
        score = 0.0

        # Same pattern type
        if pattern1.get('pattern_type') == pattern2.get('pattern_type'):
            score += 20

        # Similar sizes
        size_diff = abs(pattern1.get('size', 0) - pattern2.get('size', 0))
        if size_diff == 0:
            score += 20
        elif size_diff <= 2:
            score += 10

        # Statistical similarity
        stats1 = pattern1.get('statistics', {})
        stats2 = pattern2.get('statistics', {})

        for key in ['lines', 'characters', 'numbers']:
            val1 = stats1.get(key, 0)
            val2 = stats2.get(key, 0)
            if val1 > 0 and val2 > 0:
                ratio = min(val1, val2) / max(val1, val2)
                score += ratio * 5  # Up to 5 points per statistic

        # Text similarity
        text1 = pattern1.get('pattern', '')
        text2 = pattern2.get('pattern', '')

        if text1 and text2:
            # Simple character-based similarity
            chars1 = set(text1.replace('\n', '').replace(' ', ''))
            chars2 = set(text2.replace('\n', '').replace(' ', ''))
            char_similarity = len(chars1.intersection(chars2)) / len(chars1.union(chars2))
            score += char_similarity * 30  # Up to 30 points

        return min(100.0, score)

    def _create_visual_diff(self, pattern1: str, pattern2: str) -> Dict[str, Any]:
        """Create visual diff between two patterns"""
        lines1 = pattern1.split('\n') if pattern1 else []
        lines2 = pattern2.split('\n') if pattern2 else []

        # Create unified diff
        diff = list(difflib.unified_diff(
            lines1, lines2,
            fromfile='Pattern 1',
            tofile='Pattern 2',
            lineterm='',
            n=3
        ))

        # Create side-by-side diff
        side_by_side = self._create_side_by_side_diff(lines1, lines2)

        return {
            'unified_diff': diff,
            'side_by_side': side_by_side,
            'total_changes': len([line for line in diff if line.startswith(('+', '-'))])
        }

    def _create_side_by_side_diff(self, lines1: List[str], lines2: List[str]) -> List[Dict[str, str]]:
        """Create side-by-side diff view"""
        max_lines = max(len(lines1), len(lines2))
        side_by_side = []

        for i in range(max_lines):
            line1 = lines1[i] if i < len(lines1) else ""
            line2 = lines2[i] if i < len(lines2) else ""

            # Determine change type
            if line1 == line2:
                change_type = "equal"
            elif i >= len(lines1):
                change_type = "addition"
            elif i >= len(lines2):
                change_type = "deletion"
            else:
                change_type = "modification"

            side_by_side.append({
                'line_number': i + 1,
                'pattern1': line1,
                'pattern2': line2,
                'change_type': change_type
            })

        return side_by_side

    def find_similar_patterns(self, target_pattern: Dict[str, Any],
                             pattern_library: List[Dict[str, Any]],
                             threshold: float = 50.0) -> List[Dict[str, Any]]:
        """Find patterns similar to target pattern

        Args:
            target_pattern: Pattern to compare against
            pattern_library: List of patterns to search
            threshold: Minimum similarity score (0-100)

        Returns:
            List of similar patterns with scores
        """
        similar_patterns = []

        for pattern in pattern_library:
            similarity = self._calculate_similarity_score(target_pattern, pattern)
            if similarity >= threshold:
                result = pattern.copy()
                result['similarity_score'] = similarity
                similar_patterns.append(result)

        # Sort by similarity score (highest first)
        similar_patterns.sort(key=lambda x: x['similarity_score'], reverse=True)

        return similar_patterns

    def generate_pattern_report(self, pattern: Dict[str, Any]) -> str:
        """Generate a comprehensive report for a single pattern

        Args:
            pattern: Pattern data

        Returns:
            Formatted report string
        """
        report_lines = [
            "=" * 60,
            "PATTERN ANALYSIS REPORT",
            "=" * 60,
            "",
            f"Pattern Type: {pattern.get('display_name', 'Unknown')}",
            f"Technical Name: {pattern.get('pattern_type', 'unknown')}",
            f"Size Parameter: {pattern.get('size', 'N/A')}",
            f"Start Number: {pattern.get('start_num', 'N/A')}",
            f"Generation Time: {pattern.get('generation_time', 'N/A')} seconds",
            "",
            "STATISTICS:",
            "-" * 20
        ]

        stats = pattern.get('statistics', {})
        if stats:
            report_lines.extend([
                f"Lines: {stats.get('lines', 'N/A')}",
                f"Characters: {stats.get('characters', 'N/A')}",
                f"Numbers: {stats.get('numbers', 'N/A')}",
                f"Maximum Number: {stats.get('max_num', 'N/A')}",
                f"Minimum Number: {stats.get('min_num', 'N/A')}",
                f"Sum of Numbers: {stats.get('sum_nums', 'N/A')}",
                f"Average Numbers per Line: {stats.get('avg_per_line', 'N/A'):.2f}",
            ])
        else:
            report_lines.append("No statistics available")

        report_lines.extend([
            "",
            "PATTERN PREVIEW:",
            "-" * 20,
            pattern.get('pattern', 'No pattern data'),
            "",
            "=" * 60,
            f"Report Generated: {pattern.get('metadata', {}).get('generated_at', 'Unknown')}",
            f"Generator: {pattern.get('metadata', {}).get('generator', 'Pattern Generator')}",
            "=" * 60
        ])

        return "\n".join(report_lines)

    def benchmark_patterns(self, pattern_types: List[str], sizes: List[int],
                          iterations: int = 3) -> Dict[str, Any]:
        """Benchmark multiple pattern types

        Args:
            pattern_types: List of pattern types to benchmark
            sizes: List of sizes to test
            iterations: Number of iterations per test

        Returns:
            Benchmark results dictionary
        """
        results = {
            'benchmark_info': {
                'pattern_types': pattern_types,
                'sizes': sizes,
                'iterations': iterations,
                'timestamp': str(datetime.now())
            },
            'results': {}
        }

        import time

        for pattern_type in pattern_types:
            results['results'][pattern_type] = {}

            for size in sizes:
                times = []

                for _ in range(iterations):
                    try:
                        start_time = time.time()
                        self.api.generate(pattern_type, size, include_stats=False, include_metadata=False)
                        end_time = time.time()
                        times.append(end_time - start_time)
                    except Exception as e:
                        times.append(float('inf'))
                        print(f"Error benchmarking {pattern_type} size {size}: {e}")

                if times and times[0] != float('inf'):
                    avg_time = sum(times) / len(times)
                    min_time = min(times)
                    max_time = max(times)

                    results['results'][pattern_type][size] = {
                        'average_time': round(avg_time, 4),
                        'min_time': round(min_time, 4),
                        'max_time': round(max_time, 4),
                        'iterations': iterations
                    }
                else:
                    results['results'][pattern_type][size] = {
                        'error': 'Failed to generate pattern'
                    }

        return results

    def analyze_pattern_complexity(self, pattern: Dict[str, Any]) -> Dict[str, Any]:
        """Analyze pattern complexity metrics

        Args:
            pattern: Pattern data

        Returns:
            Complexity analysis dictionary
        """
        pattern_text = pattern.get('pattern', '')
        stats = pattern.get('statistics', {})

        if not pattern_text:
            return {'error': 'No pattern data available'}

        lines = pattern_text.split('\n')
        total_chars = len(pattern_text)
        total_lines = len(lines)

        # Calculate various complexity metrics
        analysis = {
            'basic_metrics': {
                'total_characters': total_chars,
                'total_lines': total_lines,
                'average_line_length': total_chars / total_lines if total_lines > 0 else 0,
                'max_line_length': max(len(line) for line in lines) if lines else 0,
                'min_line_length': min(len(line) for line in lines) if lines else 0
            },
            'pattern_density': {
                'number_density': stats.get('numbers', 0) / total_chars if total_chars > 0 else 0,
                'space_density': pattern_text.count(' ') / total_chars if total_chars > 0 else 0,
                'symbol_density': sum(1 for c in pattern_text if not c.isalnum() and c not in [' ', '\n']) / total_chars if total_chars > 0 else 0
            },
            'complexity_scores': {
                'size_complexity': min(pattern.get('size', 1) / 10, 1.0),
                'pattern_complexity': len(set(pattern_text.replace('\n', '').replace(' ', ''))) / 10,  # Unique characters
                'structural_complexity': total_lines / 10  # Based on height
            }
        }

        # Overall complexity score (0-100)
        analysis['overall_complexity'] = min(100, (
            analysis['complexity_scores']['size_complexity'] * 30 +
            analysis['complexity_scores']['pattern_complexity'] * 40 +
            analysis['complexity_scores']['structural_complexity'] * 30
        ))

        return analysis


# Global comparator instance
comparator = PatternComparator()


def compare_patterns(pattern1: Dict[str, Any], pattern2: Dict[str, Any]) -> Dict[str, Any]:
    """Convenience function to compare two patterns"""
    return comparator.compare_patterns(pattern1, pattern2)


def generate_pattern_report(pattern: Dict[str, Any]) -> str:
    """Convenience function to generate pattern report"""
    return comparator.generate_pattern_report(pattern)


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

    # Example usage
    from api import PatternAPI

    api = PatternAPI()

    # Generate two patterns to compare
    pattern1 = api.generate('pyramid', 4, 1, include_stats=True)
    pattern2 = api.generate('reverse_pyramid', 4, 1, include_stats=True)

    print("\nšŸ” Pattern Comparison:")
    print("-" * 30)

    comparison = compare_patterns(pattern1, pattern2)
    print(f"Pattern 1: {comparison['patterns']['pattern1']['display_name']}")
    print(f"Pattern 2: {comparison['patterns']['pattern2']['display_name']}")
    print(f"Similarity Score: {comparison['similarity_score']:.1f}%")

    # Statistics comparison
    stats_comp = comparison['statistics_comparison']
    print(f"\nLines - P1: {stats_comp['lines']['pattern1']}, P2: {stats_comp['lines']['pattern2']}, Diff: {stats_comp['lines']['difference']}")

    # Generate report for one pattern
    print("\nšŸ“Š Pattern Report:")
    print("-" * 20)
    report = generate_pattern_report(pattern1)
    print(report[:500] + "..." if len(report) > 500 else report)

    # Complexity analysis
    print("\n🧠 Complexity Analysis:")
    print("-" * 25)
    complexity = comparator.analyze_pattern_complexity(pattern1)
    print(f"Overall Complexity: {complexity['overall_complexity']:.1f}%")
    print(f"Pattern Density: {complexity['pattern_density']['number_density']:.3f}")

    print("\nāœ… Pattern comparison demonstrations completed!")
    print("šŸ’” Use these tools to analyze and compare different patterns")
419 lines•15.4 KB
python
šŸš€ Support RSK World

Subscribe to our YouTube channel for latest tutorials & updates!



Click subscribe & support our work ā¤ļø

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