============================================================================

PROJECT REVIEW SCHEDULER - JUPYTER NOTEBOOK TESTING SUITE

============================================================================

This notebook tests the Project Review Scheduler implementation directly in Jupyter. Run each cell in sequence to perform comprehensive testing.

# SETUP AND IMPORTS
import time
import sys
import os
import tempfile
import shutil
import statistics
from datetime import datetime, timedelta
from collections import defaultdict, Counter
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from faker import Faker
import json
import hashlib
from pathlib import Path

# Optional imports with fallbacks
try:
    import memory_profiler
    HAS_MEMORY_PROFILER = True
except ImportError:
    HAS_MEMORY_PROFILER = False

try:
    import psutil
    HAS_PSUTIL = True
except ImportError:
    HAS_PSUTIL = False
    print("⚠️  psutil not available - using fallback system info")

import time
import functools
import sys
import os
from pathlib import Path
import csv
import tempfile
import shutil
from datetime import datetime, timedelta
from collections import defaultdict, Counter
import statistics
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from unittest.mock import patch, MagicMock
import smtplib
from faker import Faker

# Initialize Faker for generating test data
fake = Faker()
Faker.seed(42)  # For reproducible results

print(" All packages imported successfully")
print(" Ready to test Project Review Scheduler")
 All packages imported successfully
 Ready to test Project Review Scheduler
import sys
import os

# Step 1: Fix the path conflict
wrong_file = "/Users/cynthiamcginnis/scheduler.py"
if os.path.exists(wrong_file):
    os.rename(wrong_file, "/Users/cynthiamcginnis/scheduler_OLD_BACKUP.py")
    print(" Moved conflicting file")

# Step 2: Add correct directory to path
correct_dir = "/Users/cynthiamcginnis/Documents/ProjectReviewScheduler/src"
sys.path.insert(0, correct_dir)

# Step 3: Clean jupyter artifacts
file_path = "/Users/cynthiamcginnis/Documents/ProjectReviewScheduler/src/scheduler.py"
with open(file_path, 'r') as f:
    content = f.read()

# Remove jupyter markers
lines = [line for line in content.split('\n') if not any(marker in line for marker in ['# In[', '# Out['])]
cleaned_content = '\n'.join(lines)

with open(file_path, 'w') as f:
    f.write(cleaned_content)

# Step 4: Clear cache and test
if 'scheduler' in sys.modules:
    del sys.modules['scheduler']

# Step 5: Test import
from scheduler import send_notifications
print(" SUCCESS! Everything should work now!")

# Test the performance suite
from scheduler import calculate_all_reviews, assign_reviewer, validate_csv_data, backup_file
print(" All functions imported successfully!")
 SUCCESS! Everything should work now!
 All functions imported successfully!
from scheduler import (
    calculate_all_reviews, calculate_due_date,
    assign_all_reviewers, assign_reviewer,
    send_notifications, validate_csv_data,
    read_csv, write_csv, backup_file,
    get_all_projects, get_all_users, get_all_reviews
)

# Set up matplotlib for better plots
plt.style.use('seaborn-v0_8' if 'seaborn-v0_8' in plt.style.available else 'default')
sns.set_palette("husl")
# ===============================================================================
# Performance Monitoring Infrastructure
# ===============================================================================

class AlgorithmProfiler:
    """Advanced profiler for algorithm performance and validation."""
    
    def __init__(self):
        self.metrics = defaultdict(list)
        self.validation_results = {}
        self.memory_usage = defaultdict(list)
        self.start_time = None
        
    def profile_algorithm(self, algorithm_name):
        """Decorator for profiling algorithm performance."""
        def decorator(func):
            def wrapper(*args, **kwargs):
                # Pre-execution metrics
                process = psutil.Process()
                memory_before = process.memory_info().rss / 1024 / 1024  # MB
                cpu_before = process.cpu_percent()
                start_time = time.perf_counter()
                
                # Execute algorithm
                result = func(*args, **kwargs)
                
                # Post-execution metrics
                end_time = time.perf_counter()
                memory_after = process.memory_info().rss / 1024 / 1024  # MB
                cpu_after = process.cpu_percent()
                
                # Record metrics
                execution_time = end_time - start_time
                memory_delta = memory_after - memory_before
                
                self.metrics[algorithm_name].append({
                    'execution_time': execution_time,
                    'memory_before': memory_before,
                    'memory_after': memory_after,
                    'memory_delta': memory_delta,
                    'cpu_usage': (cpu_before + cpu_after) / 2,
                    'timestamp': datetime.now()
                })
                
                return result
            return wrapper
        return decorator
    
    def get_algorithm_stats(self, algorithm_name):
        """Get comprehensive statistics for an algorithm."""
        if algorithm_name not in self.metrics:
            return None
            
        measurements = self.metrics[algorithm_name]
        execution_times = [m['execution_time'] for m in measurements]
        memory_deltas = [m['memory_delta'] for m in measurements]
        
        return {
            'algorithm': algorithm_name,
            'runs': len(measurements),
            'avg_execution_time': np.mean(execution_times),
            'min_execution_time': np.min(execution_times),
            'max_execution_time': np.max(execution_times),
            'std_execution_time': np.std(execution_times),
            'avg_memory_delta': np.mean(memory_deltas),
            'max_memory_usage': max(m['memory_after'] for m in measurements),
            'total_runtime': sum(execution_times)
        }
    
    def generate_performance_report(self):
        """Generate comprehensive performance report."""
        report = {
            'test_timestamp': datetime.now().isoformat(),
            'system_info': {
                'cpu_count': psutil.cpu_count(),
                'memory_total': psutil.virtual_memory().total / 1024 / 1024 / 1024,  # GB
                'python_version': sys.version
            },
            'algorithms': {}
        }
        
        for algo_name in self.metrics:
            report['algorithms'][algo_name] = self.get_algorithm_stats(algo_name)
            
        return report

# Global profiler instance
profiler = AlgorithmProfiler()
# ===============================================================================
# Synthetic Data Generation for Algorithm Testing
# ===============================================================================

class SyntheticDataGenerator:
    """Generate realistic synthetic datasets for algorithm validation."""
    
    def __init__(self, seed=42):
        self.fake = Faker()
        Faker.seed(seed)
        np.random.seed(seed)
        self.departments = ['Engineering', 'Marketing', 'Sales', 'HR', 'Finance', 'Operations', 'Legal', 'Research']
        
    def generate_project_dataset(self, size, complexity='medium'):
        """Generate synthetic project data with configurable complexity."""
        
        complexity_configs = {
            'simple': {'freq_variance': 0.2, 'date_range_years': 2},
            'medium': {'freq_variance': 0.5, 'date_range_years': 5},
            'complex': {'freq_variance': 1.0, 'date_range_years': 10}
        }
        
        config = complexity_configs.get(complexity, complexity_configs['medium'])
        
        projects = []
        base_date = datetime(2020, 1, 1)
        
        for i in range(size):
            # Generate realistic project timeline
            start_date = base_date + timedelta(days=np.random.randint(0, config['date_range_years'] * 365))
            days_since_start = (datetime.now() - start_date).days
            max_last_review_days = min(days_since_start, 365 * 3)  # Max 3 years ago
            
            if max_last_review_days > 0:
                last_review_days_ago = np.random.randint(0, max_last_review_days)
                last_review_date = datetime.now() - timedelta(days=last_review_days_ago)
            else:
                last_review_date = start_date
            
            # Generate review frequency with variance
            base_frequency = np.random.choice([0.5, 1.0, 1.5, 2.0, 3.0], p=[0.1, 0.4, 0.25, 0.2, 0.05])
            frequency_variance = np.random.normal(0, config['freq_variance'])
            review_frequency = max(0.25, base_frequency + frequency_variance)
            
            project = {
                'Project_ID': f'PRJ{i+1:06d}',
                'Project_Name': f"{self.fake.company()} {self.fake.catch_phrase()}",
                'Start_Date': start_date.strftime('%Y-%m-%d'),
                'Last_Review_Date': last_review_date.strftime('%Y-%m-%d'),
                'Review_Frequency_Years': round(review_frequency, 2),
                'Department': np.random.choice(self.departments),
                'Status': '',  # Will be calculated
                'Next_Review_Date': ''  # Will be calculated
            }
            projects.append(project)
            
        return projects
    
    def generate_user_dataset(self, size, workload_distribution='balanced'):
        """Generate synthetic user data with configurable workload distribution."""
        
        distribution_configs = {
            'balanced': {'load_mean': 3, 'load_std': 1},
            'unbalanced': {'load_mean': 3, 'load_std': 3},
            'heavy': {'load_mean': 8, 'load_std': 2}
        }
        
        config = distribution_configs.get(workload_distribution, distribution_configs['balanced'])
        
        users = []
        
        for i in range(size):
            # Generate workload following specified distribution
            current_load = max(0, int(np.random.normal(config['load_mean'], config['load_std'])))
            
            user = {
                'User_ID': f'USR{i+1:05d}',
                'Name': self.fake.name(),
                'Email': self.fake.email(),
                'Department': np.random.choice(self.departments),
                'Current_Load': current_load
            }
            users.append(user)
            
        return users
    
    def generate_corrupted_data(self, base_data, corruption_rate=0.1):
        """Generate corrupted data for validation algorithm testing."""
        
        corrupted_data = []
        corruption_types = [
            'invalid_date', 'missing_field', 'invalid_number', 
            'invalid_email', 'duplicate_id', 'future_date'
        ]
        
        for i, record in enumerate(base_data):
            record_copy = record.copy()
            
            # Randomly corrupt some records
            if np.random.random() < corruption_rate:
                corruption_type = np.random.choice(corruption_types)
                
                if corruption_type == 'invalid_date' and 'Start_Date' in record_copy:
                    record_copy['Start_Date'] = '2023-13-45'  # Invalid date
                elif corruption_type == 'missing_field' and 'Project_Name' in record_copy:
                    record_copy['Project_Name'] = ''  # Missing required field
                elif corruption_type == 'invalid_number' and 'Review_Frequency_Years' in record_copy:
                    record_copy['Review_Frequency_Years'] = 'not-a-number'
                elif corruption_type == 'invalid_email' and 'Email' in record_copy:
                    record_copy['Email'] = 'invalid-email-format'
                elif corruption_type == 'duplicate_id' and i > 0:
                    record_copy[list(record_copy.keys())[0]] = corrupted_data[0][list(record_copy.keys())[0]]  # Duplicate ID
                elif corruption_type == 'future_date' and 'Last_Review_Date' in record_copy:
                    future_date = datetime.now() + timedelta(days=365)
                    record_copy['Last_Review_Date'] = future_date.strftime('%Y-%m-%d')
                    
            corrupted_data.append(record_copy)
            
        return corrupted_data
# ===============================================================================
# Due Date Calculation Algorithm Validation
# ===============================================================================

class DueDateAlgorithmValidator:
    """Validate the due date calculation algorithm accuracy and performance."""
    
    @staticmethod
    def test_calculation_accuracy():
        """Test due date calculation accuracy with known scenarios."""
        print("\n DUE DATE CALCULATION ACCURACY TEST")
        print("=" * 60)
        
        test_cases = [
            {
                'name': 'Basic Annual Review',
                'project': {
                    'Project_ID': 'TEST001',
                    'Last_Review_Date': '2023-01-01',
                    'Review_Frequency_Years': 1.0
                },
                'current_date': '2024-01-01',
                'expected_next_date': '2024-01-01',
                'expected_status': 'Due Soon'
            },
            {
                'name': 'Overdue Project',
                'project': {
                    'Project_ID': 'TEST002',
                    'Last_Review_Date': '2022-01-01',
                    'Review_Frequency_Years': 1.0
                },
                'current_date': '2024-01-01',
                'expected_next_date': '2023-01-01',
                'expected_status': 'Overdue'
            },
            {
                'name': 'Semi-Annual Review',
                'project': {
                    'Project_ID': 'TEST003',
                    'Last_Review_Date': '2023-06-01',
                    'Review_Frequency_Years': 0.5
                },
                'current_date': '2024-01-01',
                'expected_next_date': '2023-12-01',
                'expected_status': 'Overdue'
            },
            {
                'name': 'Biennial Review',
                'project': {
                    'Project_ID': 'TEST004',
                    'Last_Review_Date': '2022-03-15',
                    'Review_Frequency_Years': 2.0
                },
                'current_date': '2024-01-01',
                'expected_next_date': '2024-03-15',
                'expected_status': 'Up to Date'
            }
        ]
        
        accuracy_results = []
        
        for test_case in test_cases:
            print(f"\n Testing: {test_case['name']}")
            
            # Run calculation with profiling
            @profiler.profile_algorithm('due_date_calculation')
            def run_calculation():
                return calculate_due_date(test_case['project'], test_case['current_date'])
            
            result = run_calculation()
            
            # Validate results
            next_date_correct = result['Next_Review_Date'] == test_case['expected_next_date']
            status_correct = result['Status'] == test_case['expected_status']
            
            accuracy = {
                'test_name': test_case['name'],
                'next_date_correct': next_date_correct,
                'status_correct': status_correct,
                'overall_correct': next_date_correct and status_correct,
                'expected_next_date': test_case['expected_next_date'],
                'actual_next_date': result['Next_Review_Date'],
                'expected_status': test_case['expected_status'],
                'actual_status': result['Status']
            }
            
            accuracy_results.append(accuracy)
            
            print(f"    Next Date: {result['Next_Review_Date']} {'✔️' if next_date_correct else '❌'}")
            print(f"    Status: {result['Status']} {'✔️' if status_correct else '❌'}")
            print(f"    Overall: {'✔️ PASS' if accuracy['overall_correct'] else ' FAIL'}")
        
        # Calculate overall accuracy
        total_tests = len(accuracy_results)
        passed_tests = sum(1 for r in accuracy_results if r['overall_correct'])
        accuracy_rate = (passed_tests / total_tests) * 100
        
        print(f"\n ACCURACY SUMMARY:")
        print(f"   Tests Passed: {passed_tests}/{total_tests}")
        print(f"   Accuracy Rate: {accuracy_rate:.1f}%")
        
        return accuracy_results
    
    @staticmethod
    def test_calculation_performance_scaling():
        """Test due date calculation performance with increasing dataset sizes."""
        print("\n⚡ DUE DATE CALCULATION PERFORMANCE SCALING")
        print("=" * 60)
        
        dataset_sizes = [100, 500, 1000, 2500, 5000, 10000]
        scaling_results = []
        
        for size in dataset_sizes:
            print(f"\n Testing with {size:,} projects...")
            
            # Generate synthetic dataset
            generator = SyntheticDataGenerator()
            projects = generator.generate_project_dataset(size, complexity='medium')
            
            # Write to temporary file
            with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as f:
                import csv
                writer = csv.DictWriter(f, fieldnames=projects[0].keys())
                writer.writeheader()
                writer.writerows(projects)
                temp_file = f.name
            
            try:
                # Profile the calculation
                @profiler.profile_algorithm(f'calculate_all_reviews_{size}')
                def run_calculation():
                    return calculate_all_reviews(temp_file)
                
                start_time = time.perf_counter()
                result = run_calculation()
                end_time = time.perf_counter()
                
                execution_time = end_time - start_time
                throughput = size / execution_time
                
                scaling_results.append({
                    'dataset_size': size,
                    'execution_time': execution_time,
                    'throughput': throughput,
                    'overdue_count': result['overdue'],
                    'due_soon_count': result['due_soon'],
                    'up_to_date_count': result['up_to_date']
                })
                
                print(f"     Execution Time: {execution_time:.4f}s")
                print(f"    Throughput: {throughput:.1f} projects/sec")
                print(f"    Status Distribution: {result['overdue']} overdue, {result['due_soon']} due soon")
                
            finally:
                # Cleanup
                os.unlink(temp_file)
        
        # Analyze scaling characteristics
        DueDateAlgorithmValidator._analyze_scaling_performance(scaling_results)
        
        return scaling_results
    
    @staticmethod
    def _analyze_scaling_performance(results):
        """Analyze and visualize performance scaling characteristics."""
        
        fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(16, 12))
        
        sizes = [r['dataset_size'] for r in results]
        times = [r['execution_time'] for r in results]
        throughputs = [r['throughput'] for r in results]
        
        # Execution time vs dataset size
        ax1.loglog(sizes, times, 'bo-', linewidth=2, markersize=8)
        ax1.set_xlabel('Dataset Size')
        ax1.set_ylabel('Execution Time (seconds)')
        ax1.set_title('Execution Time Scaling (Log-Log)')
        ax1.grid(True, alpha=0.3)
        
        # Add trend line
        log_sizes = np.log10(sizes)
        log_times = np.log10(times)
        slope, intercept = np.polyfit(log_sizes, log_times, 1)
        ax1.plot(sizes, [10**(intercept + slope * np.log10(s)) for s in sizes], 
                'r--', alpha=0.7, label=f'Slope: {slope:.2f}')
        ax1.legend()
        
        # Throughput vs dataset size
        ax2.semilogx(sizes, throughputs, 'go-', linewidth=2, markersize=8)
        ax2.set_xlabel('Dataset Size')
        ax2.set_ylabel('Throughput (projects/sec)')
        ax2.set_title('Throughput Scaling')
        ax2.grid(True, alpha=0.3)
        
        # Performance efficiency (time per project)
        efficiency = [t/s for t, s in zip(times, sizes)]
        ax3.semilogx(sizes, efficiency, 'mo-', linewidth=2, markersize=8)
        ax3.set_xlabel('Dataset Size')
        ax3.set_ylabel('Time per Project (seconds)')
        ax3.set_title('Algorithm Efficiency')
        ax3.grid(True, alpha=0.3)
        
        # Status distribution
        overdue_pcts = [r['overdue_count']/r['dataset_size']*100 for r in results]
        due_soon_pcts = [r['due_soon_count']/r['dataset_size']*100 for r in results]
        up_to_date_pcts = [r['up_to_date_count']/r['dataset_size']*100 for r in results]
        
        ax4.plot(sizes, overdue_pcts, 'r-o', label='Overdue %', linewidth=2)
        ax4.plot(sizes, due_soon_pcts, 'orange', marker='o', label='Due Soon %', linewidth=2)
        ax4.plot(sizes, up_to_date_pcts, 'g-o', label='Up to Date %', linewidth=2)
        ax4.set_xlabel('Dataset Size')
        ax4.set_ylabel('Percentage')
        ax4.set_title('Status Distribution Consistency')
        ax4.legend()
        ax4.grid(True, alpha=0.3)
        
        plt.tight_layout()
        plt.show()
        
        # Calculate complexity analysis
        if len(results) >= 3:
            # Estimate algorithmic complexity
            log_sizes = np.log10(sizes)
            log_times = np.log10(times)
            slope, _ = np.polyfit(log_sizes, log_times, 1)
            
            if slope < 1.1:
                complexity = "O(n) - Linear"
            elif slope < 1.5:
                complexity = "O(n log n) - Linearithmic"
            elif slope < 2.1:
                complexity = "O(n²) - Quadratic"
            else:
                complexity = f"O(n^{slope:.1f}) - Polynomial"
            
            print(f"\n ALGORITHMIC COMPLEXITY ANALYSIS:")
            print(f"   Estimated Complexity: {complexity}")
            print(f"   Scaling Slope: {slope:.3f}")
            print(f"   Peak Throughput: {max(throughputs):.1f} projects/sec")
            print(f"   Performance Consistency: {' Good' if max(efficiency)/min(efficiency) < 2 else '⚠️  Variable'}")
# ===============================================================================
# Reviewer Assignment Algorithm Validation
# ===============================================================================

class ReviewerAssignmentValidator:
    """Validate reviewer assignment algorithm fairness and efficiency."""
    
    @staticmethod
    def test_workload_balancing_effectiveness():
        """Test how effectively the assignment algorithm balances workload."""
        print("\n⚖️ REVIEWER ASSIGNMENT WORKLOAD BALANCING TEST")
        print("=" * 60)
        
        test_scenarios = [
            {'projects': 50, 'reviewers': 10, 'scenario': 'Balanced Load'},
            {'projects': 100, 'reviewers': 5, 'scenario': 'High Load'},
            {'projects': 200, 'reviewers': 20, 'scenario': 'Many Reviewers'},
            {'projects': 75, 'reviewers': 15, 'scenario': 'Excess Capacity'}
        ]
        
        balancing_results = []
        
        for scenario in test_scenarios:
            print(f"\n Testing Scenario: {scenario['scenario']}")
            print(f"    {scenario['projects']} projects, {scenario['reviewers']} reviewers")
            
            # Generate test data
            generator = SyntheticDataGenerator()
            projects = generator.generate_project_dataset(scenario['projects'])
            users = generator.generate_user_dataset(scenario['reviewers'], workload_distribution='balanced')
            
            # Create temporary files
            with tempfile.TemporaryDirectory() as temp_dir:
                projects_file = os.path.join(temp_dir, 'projects.csv')
                users_file = os.path.join(temp_dir, 'users.csv')
                reviews_file = os.path.join(temp_dir, 'reviews.csv')
                
                # Write test data
                with open(projects_file, 'w', newline='') as f:
                    import csv
                    writer = csv.DictWriter(f, fieldnames=projects[0].keys())
                    writer.writeheader()
                    writer.writerows(projects)
                
                with open(users_file, 'w', newline='') as f:
                    writer = csv.DictWriter(f, fieldnames=users[0].keys())
                    writer.writeheader()
                    writer.writerows(users)
                
                # Create empty reviews file
                with open(reviews_file, 'w', newline='') as f:
                    writer = csv.writer(f)
                    writer.writerow(['Review_ID', 'Project_ID', 'Reviewer_ID', 'Scheduled_Date', 'Status', 'Completion_Date'])
                
                # Calculate due dates first
                calculate_all_reviews(projects_file)
                
                # Profile assignment algorithm
                @profiler.profile_algorithm(f'assign_reviewers_{scenario["scenario"]}')
                def run_assignment():
                    return assign_all_reviewers(projects_file, users_file, reviews_file)
                
                assignment_result = run_assignment()
                
                # Analyze workload distribution
                final_users = read_csv(users_file)
                final_reviews = read_csv(reviews_file)
                
                workload_analysis = ReviewerAssignmentValidator._analyze_workload_fairness(
                    final_users, final_reviews, scenario
                )
                
                balancing_results.append(workload_analysis)
                
                print(f"    Assignments Created: {assignment_result['total_assigned']}")
                print(f"    Workload Std Dev: {workload_analysis['workload_std_dev']:.2f}")
                print(f"    Cross-Dept Ratio: {workload_analysis['cross_dept_ratio']:.2f}")
                print(f"    Fairness Score: {workload_analysis['fairness_score']:.2f}")
        
        # Generate comprehensive workload analysis
        ReviewerAssignmentValidator._generate_workload_report(balancing_results)
        
        return balancing_results
    
    @staticmethod
    def _analyze_workload_fairness(users, reviews, scenario):
        """Analyze the fairness and effectiveness of workload distribution."""
        
        # Calculate workload per user
        user_workloads = {}
        for user in users:
            user_id = user['User_ID']
            active_reviews = [r for r in reviews if r['Reviewer_ID'] == user_id and r['Status'] in ['Scheduled', 'In Progress']]
            user_workloads[user_id] = {
                'load': len(active_reviews),
                'department': user['Department'],
                'name': user['Name']
            }
        
        # Calculate fairness metrics
        loads = [w['load'] for w in user_workloads.values()]
        
        if len(loads) > 1:
            workload_std_dev = np.std(loads)
            workload_cv = workload_std_dev / np.mean(loads) if np.mean(loads) > 0 else 0
        else:
            workload_std_dev = 0
            workload_cv = 0
        
        # Calculate cross-department assignment ratio
        cross_dept_count = 0
        total_assignments = 0
        
        for review in reviews:
            if review['Status'] in ['Scheduled', 'In Progress']:
                total_assignments += 1
                reviewer_dept = next((u['Department'] for u in users if u['User_ID'] == review['Reviewer_ID']), None)
                # For this analysis, assume we have project data (in real scenario we'd read it)
                # This is a simplification for the demo
                if reviewer_dept:  # In real scenario, compare with project department
                    cross_dept_count += 1
        
        cross_dept_ratio = cross_dept_count / total_assignments if total_assignments > 0 else 0
        
        # Calculate overall fairness score (lower is better)
        fairness_score = workload_cv + (1 - cross_dept_ratio) * 0.5
        
        return {
            'scenario': scenario['scenario'],
            'total_reviewers': len(users),
            'total_assignments': total_assignments,
            'workload_mean': np.mean(loads),
            'workload_std_dev': workload_std_dev,
            'workload_cv': workload_cv,
            'workload_min': min(loads) if loads else 0,
            'workload_max': max(loads) if loads else 0,
            'cross_dept_ratio': cross_dept_ratio,
            'fairness_score': fairness_score,
            'user_workloads': user_workloads
        }
    
    @staticmethod
    def _generate_workload_report(results):
        """Generate comprehensive workload balancing report."""
        
        fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(16, 12))
        
        scenarios = [r['scenario'] for r in results]
        std_devs = [r['workload_std_dev'] for r in results]
        fairness_scores = [r['fairness_score'] for r in results]
        cross_dept_ratios = [r['cross_dept_ratio'] for r in results]
        
        # Workload standard deviation by scenario
        bars1 = ax1.bar(scenarios, std_devs, color='skyblue', alpha=0.7)
        ax1.set_xlabel('Test Scenario')
        ax1.set_ylabel('Workload Standard Deviation')
        ax1.set_title('Workload Distribution Fairness')
        ax1.tick_params(axis='x', rotation=45)
        
        # Add value labels on bars
        for bar, std_dev in zip(bars1, std_devs):
            ax1.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.01,
                    f'{std_dev:.2f}', ha='center', va='bottom')
        
        # Fairness scores
        bars2 = ax2.bar(scenarios, fairness_scores, color='lightgreen', alpha=0.7)
        ax2.set_xlabel('Test Scenario')
        ax2.set_ylabel('Fairness Score (Lower = Better)')
        ax2.set_title('Overall Assignment Fairness')
        ax2.tick_params(axis='x', rotation=45)
        
        for bar, score in zip(bars2, fairness_scores):
            ax2.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.01,
                    f'{score:.2f}', ha='center', va='bottom')
        
        # Cross-department assignment ratios
        bars3 = ax3.bar(scenarios, cross_dept_ratios, color='orange', alpha=0.7)
        ax3.set_xlabel('Test Scenario')
        ax3.set_ylabel('Cross-Department Assignment Ratio')
        ax3.set_title('Department Distribution')
        ax3.tick_params(axis='x', rotation=45)
        
        for bar, ratio in zip(bars3, cross_dept_ratios):
            ax3.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.01,
                    f'{ratio:.2f}', ha='center', va='bottom')
        
        # Workload range (max - min) by scenario
        workload_ranges = [r['workload_max'] - r['workload_min'] for r in results]
        bars4 = ax4.bar(scenarios, workload_ranges, color='salmon', alpha=0.7)
        ax4.set_xlabel('Test Scenario')
        ax4.set_ylabel('Workload Range (Max - Min)')
        ax4.set_title('Workload Inequality')
        ax4.tick_params(axis='x', rotation=45)
        
        for bar, range_val in zip(bars4, workload_ranges):
            ax4.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.1,
                    f'{range_val}', ha='center', va='bottom')
        
        plt.tight_layout()
        plt.show()
        
        # Print summary statistics
        print(f"\n WORKLOAD BALANCING SUMMARY:")
        print(f"   Average Fairness Score: {np.mean(fairness_scores):.3f}")
        print(f"   Average Std Deviation: {np.mean(std_devs):.3f}")
        print(f"   Average Cross-Dept Ratio: {np.mean(cross_dept_ratios):.3f}")
        print(f"   Best Performing Scenario: {scenarios[np.argmin(fairness_scores)]}")
# ===============================================================================
# CSV Validation Algorithm Testing
# ===============================================================================

class ValidationAlgorithmTester:
    """Test CSV validation algorithm accuracy and performance."""
    
    @staticmethod
    def test_validation_accuracy():
        """Test validation algorithm with known error scenarios."""
        print("\n CSV VALIDATION ALGORITHM ACCURACY TEST")
        print("=" * 60)
        
        test_scenarios = [
            {
                'name': 'Clean Data',
                'corruption_rate': 0.0,
                'expected_valid': True,
                'expected_errors': 0
            },
            {
                'name': 'Low Corruption',
                'corruption_rate': 0.05,
                'expected_valid': False,
                'expected_errors': 'variable'
            },
            {
                'name': 'Medium Corruption',
                'corruption_rate': 0.15,
                'expected_valid': False,
                'expected_errors': 'variable'
            },
            {
                'name': 'High Corruption',
                'corruption_rate': 0.3,
                'expected_valid': False,
                'expected_errors': 'variable'
            }
        ]
        
        validation_results = []
        
        for scenario in test_scenarios:
            print(f"\n Testing: {scenario['name']} (corruption rate: {scenario['corruption_rate']*100:.1f}%)")
            
            # Generate test data
            generator = SyntheticDataGenerator()
            clean_projects = generator.generate_project_dataset(100, complexity='medium')
            
            if scenario['corruption_rate'] > 0:
                corrupted_projects = generator.generate_corrupted_data(clean_projects, scenario['corruption_rate'])
            else:
                corrupted_projects = clean_projects
            
            # Write to temporary file
            with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as f:
                import csv
                writer = csv.DictWriter(f, fieldnames=corrupted_projects[0].keys())
                writer.writeheader()
                writer.writerows(corrupted_projects)
                temp_file = f.name
            
            try:
                # Profile validation algorithm
                @profiler.profile_algorithm(f'validation_{scenario["name"]}')
                def run_validation():
                    return validate_csv_data(temp_file)
                
                validation_result = run_validation()
                
                # Analyze results
                detected_errors = len(validation_result['errors'])
                is_valid = validation_result['valid']
                
                # Calculate accuracy metrics
                accuracy_metrics = {
                    'scenario': scenario['name'],
                    'corruption_rate': scenario['corruption_rate'],
                    'is_valid': is_valid,
                    'detected_errors': detected_errors,
                    'expected_valid': scenario['expected_valid'],
                    'validity_correct': is_valid == scenario['expected_valid'],
                    'errors_per_record': detected_errors / len(corrupted_projects)
                }
                
                validation_results.append(accuracy_metrics)
                
                print(f"    Valid: {is_valid} {'✔️' if accuracy_metrics['validity_correct'] else '❌'}")
                print(f"    Errors Detected: {detected_errors}")
                print(f"    Error Rate: {accuracy_metrics['errors_per_record']*100:.1f}%")
                
                # Show sample errors
                if validation_result['errors']:
                    print(f"    Sample Errors:")
                    for error in validation_result['errors'][:3]:
                        print(f"      - Row {error['row']}: {error['message']}")
                
            finally:
                os.unlink(temp_file)
        
        # Generate validation performance analysis
        ValidationAlgorithmTester._analyze_validation_performance(validation_results)
        
        return validation_results
    
    @staticmethod
    def test_validation_performance_scaling():
        """Test validation performance with increasing dataset sizes."""
        print("\n⚡ VALIDATION ALGORITHM PERFORMANCE SCALING")
        print("=" * 60)
        
        dataset_sizes = [100, 500, 1000, 2500, 5000]
        performance_results = []
        
        for size in dataset_sizes:
            print(f"\n Testing validation with {size:,} records...")
            
            # Generate test data with some corruption
            generator = SyntheticDataGenerator()
            projects = generator.generate_project_dataset(size, complexity='medium')
            corrupted_projects = generator.generate_corrupted_data(projects, corruption_rate=0.1)
            
            # Write to temporary file
            with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as f:
                import csv
                writer = csv.DictWriter(f, fieldnames=corrupted_projects[0].keys())
                writer.writeheader()
                writer.writerows(corrupted_projects)
                temp_file = f.name
            
            try:
                # Profile validation
                @profiler.profile_algorithm(f'validation_scaling_{size}')
                def run_validation():
                    return validate_csv_data(temp_file)
                
                start_time = time.perf_counter()
                result = run_validation()
                end_time = time.perf_counter()
                
                execution_time = end_time - start_time
                throughput = size / execution_time
                
                performance_results.append({
                    'dataset_size': size,
                    'execution_time': execution_time,
                    'throughput': throughput,
                    'errors_detected': len(result['errors']),
                    'is_valid': result['valid']
                })
                
                print(f"     Execution Time: {execution_time:.4f}s")
                print(f"    Throughput: {throughput:.1f} records/sec")
                print(f"    Errors Detected: {len(result['errors'])}")
                
            finally:
                os.unlink(temp_file)
        
        # Analyze scaling characteristics
        ValidationAlgorithmTester._plot_validation_scaling(performance_results)
        
        return performance_results
    
    @staticmethod
    def _analyze_validation_performance(results):
        """Analyze validation algorithm performance."""
        
        fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
        
        scenarios = [r['scenario'] for r in results]
        corruption_rates = [r['corruption_rate'] * 100 for r in results]
        detected_errors = [r['detected_errors'] for r in results]
        validity_correct = [r['validity_correct'] for r in results]
        
        # Error detection by corruption rate
        ax1.scatter(corruption_rates, detected_errors, s=100, alpha=0.7, color='red')
        ax1.set_xlabel('Corruption Rate (%)')
        ax1.set_ylabel('Errors Detected')
        ax1.set_title('Error Detection Effectiveness')
        ax1.grid(True, alpha=0.3)
        
        # Add trend line
        if len(corruption_rates) > 2:
            z = np.polyfit(corruption_rates, detected_errors, 1)
            p = np.poly1d(z)
            ax1.plot(corruption_rates, p(corruption_rates), "b--", alpha=0.7, label=f'Trend: y={z[0]:.2f}x+{z[1]:.2f}')
            ax1.legend()
        
        # Validation accuracy
        colors = ['green' if correct else 'red' for correct in validity_correct]
        bars = ax2.bar(scenarios, [1 if correct else 0 for correct in validity_correct], color=colors, alpha=0.7)
        ax2.set_xlabel('Test Scenario')
        ax2.set_ylabel('Validation Correctness (1=Correct, 0=Incorrect)')
        ax2.set_title('Validation Algorithm Accuracy')
        ax2.tick_params(axis='x', rotation=45)
        
        plt.tight_layout()
        plt.show()
        
        # Calculate overall accuracy
        accuracy_rate = sum(validity_correct) / len(validity_correct) * 100
        print(f"\n VALIDATION ALGORITHM SUMMARY:")
        print(f"   Overall Accuracy: {accuracy_rate:.1f}%")
        print(f"   Error Detection Sensitivity: {' Good' if len([r for r in results if r['detected_errors'] > 0 and r['corruption_rate'] > 0]) > 0 else '⚠️ Low'}")
    
    @staticmethod
    def _plot_validation_scaling(results):
        """Plot validation performance scaling."""
        
        fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(16, 12))
        
        sizes = [r['dataset_size'] for r in results]
        times = [r['execution_time'] for r in results]
        throughputs = [r['throughput'] for r in results]
        errors_detected = [r['errors_detected'] for r in results]
        
        # Execution time scaling
        ax1.loglog(sizes, times, 'bo-', linewidth=2, markersize=8)
        ax1.set_xlabel('Dataset Size')
        ax1.set_ylabel('Execution Time (seconds)')
        ax1.set_title('Validation Time Scaling')
        ax1.grid(True, alpha=0.3)
        
        # Throughput
        ax2.semilogx(sizes, throughputs, 'go-', linewidth=2, markersize=8)
        ax2.set_xlabel('Dataset Size')
        ax2.set_ylabel('Throughput (records/sec)')
        ax2.set_title('Validation Throughput')
        ax2.grid(True, alpha=0.3)
        
        # Error detection scaling
        ax3.plot(sizes, errors_detected, 'ro-', linewidth=2, markersize=8)
        ax3.set_xlabel('Dataset Size')
        ax3.set_ylabel('Errors Detected')
        ax3.set_title('Error Detection Consistency')
        ax3.grid(True, alpha=0.3)
        
        # Performance efficiency
        efficiency = [t/s*1000 for t, s in zip(times, sizes)]  # milliseconds per record
        ax4.semilogx(sizes, efficiency, 'mo-', linewidth=2, markersize=8)
        ax4.set_xlabel('Dataset Size')
        ax4.set_ylabel('Time per Record (ms)')
        ax4.set_title('Validation Efficiency')
        ax4.grid(True, alpha=0.3)
        
        plt.tight_layout()
        plt.show()
# ===============================================================================
# Comprehensive Algorithm Validation Suite
# ===============================================================================

def run_comprehensive_algorithm_validation():
    """Run complete algorithm validation and performance testing suite."""
    
    print(" COMPREHENSIVE ALGORITHM VALIDATION & PERFORMANCE SUITE")
    print("=" * 80)
    print("Testing core scheduler algorithms for accuracy, performance, and scalability...")
    print("=" * 80)
    
    # Initialize test environment
    test_results = {
        'test_timestamp': datetime.now().isoformat(),
        'system_info': {
            'cpu_count': psutil.cpu_count(),
            'memory_total_gb': psutil.virtual_memory().total / 1024 / 1024 / 1024,
            'python_version': sys.version
        }
    }
    
    try:
        # 1. Due Date Calculation Algorithm Tests
        print("\n PHASE 1: DUE DATE CALCULATION ALGORITHM")
        due_date_accuracy = DueDateAlgorithmValidator.test_calculation_accuracy()
        due_date_performance = DueDateAlgorithmValidator.test_calculation_performance_scaling()
        test_results['due_date_calculation'] = {
            'accuracy_tests': due_date_accuracy,
            'performance_tests': due_date_performance
        }
        
        # 2. Reviewer Assignment Algorithm Tests
        print("\n⚖️ PHASE 2: REVIEWER ASSIGNMENT ALGORITHM")
        assignment_results = ReviewerAssignmentValidator.test_workload_balancing_effectiveness()
        test_results['reviewer_assignment'] = {
            'workload_balancing': assignment_results
        }
        
        # 3. CSV Validation Algorithm Tests
        print("\n PHASE 3: CSV VALIDATION ALGORITHM")
        validation_accuracy = ValidationAlgorithmTester.test_validation_accuracy()
        validation_performance = ValidationAlgorithmTester.test_validation_performance_scaling()
        test_results['csv_validation'] = {
            'accuracy_tests': validation_accuracy,
            'performance_tests': validation_performance
        }
        
        # 4. Generate comprehensive performance report
        print("\n PHASE 4: PERFORMANCE ANALYSIS")
        performance_report = profiler.generate_performance_report()
        test_results['performance_profile'] = performance_report
        
        # 5. Generate final validation summary
        print("\n FINAL VALIDATION SUMMARY")
        print("=" * 60)
        
        # Due date calculation summary
        due_date_accuracy_rate = sum(1 for r in due_date_accuracy if r['overall_correct']) / len(due_date_accuracy) * 100
        max_due_date_throughput = max(r['throughput'] for r in due_date_performance)
        
        print(f" Due Date Calculation:")
        print(f"    Accuracy Rate: {due_date_accuracy_rate:.1f}%")
        print(f"    Peak Throughput: {max_due_date_throughput:.1f} projects/sec")
        
        # Assignment algorithm summary
        avg_fairness_score = np.mean([r['fairness_score'] for r in assignment_results])
        avg_std_dev = np.mean([r['workload_std_dev'] for r in assignment_results])
        
        print(f"⚖️ Reviewer Assignment:")
        print(f"    Average Fairness Score: {avg_fairness_score:.3f}")
        print(f"    Average Workload Std Dev: {avg_std_dev:.3f}")
        
        # Validation algorithm summary
        validation_accuracy_rate = sum(1 for r in validation_accuracy if r['validity_correct']) / len(validation_accuracy) * 100
        max_validation_throughput = max(r['throughput'] for r in validation_performance)
        
        print(f" CSV Validation:")
        print(f"    Accuracy Rate: {validation_accuracy_rate:.1f}%")
        print(f"   ⚡ Peak Throughput: {max_validation_throughput:.1f} records/sec")
        
        # Overall system assessment
        print(f"\n OVERALL SYSTEM ASSESSMENT:")
        overall_accuracy = (due_date_accuracy_rate + validation_accuracy_rate) / 2
        
        if overall_accuracy >= 95 and avg_fairness_score < 0.5:
            assessment = " EXCELLENT - Production Ready"
        elif overall_accuracy >= 90 and avg_fairness_score < 0.7:
            assessment = " GOOD - Ready with Minor Optimizations"
        elif overall_accuracy >= 80:
            assessment = "⚠️ ACCEPTABLE - Needs Improvement"
        else:
            assessment = " NEEDS WORK - Not Production Ready"
        
        print(f"   {assessment}")
        print(f"    Combined Accuracy: {overall_accuracy:.1f}%")
        print(f"   ⚖️ Assignment Fairness: {' Good' if avg_fairness_score < 0.5 else '⚠️ Needs Improvement'}")
        print(f"    Performance: {' Scalable' if max_due_date_throughput > 1000 else '⚠️ Limited'}")
        
        # Save detailed report
        report_filename = f"algorithm_validation_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
        with open(report_filename, 'w') as f:
            json.dump(test_results, f, indent=2, default=str)
        
        print(f"\n Detailed report saved to: {report_filename}")
        print(f" Algorithm validation complete!")
        
        return test_results
        
    except Exception as e:
        print(f"\n Error during algorithm validation: {e}")
        import traceback
        traceback.print_exc()
        return test_results

def quick_algorithm_test():
    """Run a quick algorithm validation test for Jupyter notebooks."""
    
    print(" QUICK ALGORITHM VALIDATION TEST")
    print("=" * 50)
    
    # Quick due date test
    print("\n Testing Due Date Calculation...")
    test_project = {
        'Project_ID': 'QUICK001',
        'Last_Review_Date': '2023-01-01',
        'Review_Frequency_Years': 1.0
    }
    
    result = calculate_due_date(test_project, '2024-01-15')
    print(f"   Next Review Date: {result['Next_Review_Date']}")
    print(f"   Status: {result['Status']}")
    
    # Quick assignment test
    print("\n⚖️ Testing Reviewer Assignment...")
    generator = SyntheticDataGenerator()
    
    with tempfile.TemporaryDirectory() as temp_dir:
        projects_file = os.path.join(temp_dir, 'test_projects.csv')
        users_file = os.path.join(temp_dir, 'test_users.csv')
        reviews_file = os.path.join(temp_dir, 'test_reviews.csv')
        
        # Generate small test dataset
        projects = generator.generate_project_dataset(10)
        users = generator.generate_user_dataset(3)
        
        # Write test files
        with open(projects_file, 'w', newline='') as f:
            import csv
            writer = csv.DictWriter(f, fieldnames=projects[0].keys())
            writer.writeheader()
            writer.writerows(projects)
        
        with open(users_file, 'w', newline='') as f:
            writer = csv.DictWriter(f, fieldnames=users[0].keys())
            writer.writeheader()
            writer.writerows(users)
        
        with open(reviews_file, 'w', newline='') as f:
            writer = csv.writer(f)
            writer.writerow(['Review_ID', 'Project_ID', 'Reviewer_ID', 'Scheduled_Date', 'Status', 'Completion_Date'])
        
        # Test assignment
        calculate_all_reviews(projects_file)
        assignment_result = assign_all_reviewers(projects_file, users_file, reviews_file)
        
        print(f"   Assignments Created: {assignment_result['total_assigned']}")
        print(f"   Projects Needing Review: {assignment_result['total_needing_review']}")
    
    # Quick validation test
    print("\n Testing CSV Validation...")
    valid_result = validate_csv_data(projects_file)
    print(f"   Validation Result: {' Valid' if valid_result['valid'] else ' Invalid'}")
    print(f"   Errors Found: {len(valid_result['errors'])}")
    
    print(f"\n Quick test complete! All core algorithms functional.")
# Example usage
if __name__ == "__main__":
    # For comprehensive testing:
    
    # Execute comprehensive algorithm validation
    results = run_comprehensive_algorithm_validation()
    
    # Print final summary
    print(f"\nAlgorithm validation complete!")
    print(f"Results saved to JSON file with timestamp")
    print(f"All performance charts displayed above")
   
    
    # For quick testing in Jupyter:
    # quick_algorithm_test()
    pass
 COMPREHENSIVE ALGORITHM VALIDATION & PERFORMANCE SUITE
================================================================================
Testing core scheduler algorithms for accuracy, performance, and scalability...
================================================================================

 PHASE 1: DUE DATE CALCULATION ALGORITHM

 DUE DATE CALCULATION ACCURACY TEST
============================================================

 Testing: Basic Annual Review
    Next Date: 2024-01-01 ✔️
    Status: Due Soon ✔️
    Overall: ✔️ PASS

 Testing: Overdue Project
    Next Date: 2023-01-01 ✔️
    Status: Overdue ✔️
    Overall: ✔️ PASS

 Testing: Semi-Annual Review
    Next Date: 2023-12-01 ✔️
    Status: Overdue ✔️
    Overall: ✔️ PASS

 Testing: Biennial Review
    Next Date: 2024-03-15 ✔️
    Status: Up to Date ✔️
    Overall: ✔️ PASS

 ACCURACY SUMMARY:
   Tests Passed: 4/4
   Accuracy Rate: 100.0%

⚡ DUE DATE CALCULATION PERFORMANCE SCALING
============================================================

 Testing with 100 projects...
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp9we4gw48.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp9we4gw48.csv.20250524_120837.bak
     Execution Time: 0.0039s
    Throughput: 25639.1 projects/sec
    Status Distribution: 37 overdue, 5 due soon

 Testing with 500 projects...
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpflb9s_2t.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpflb9s_2t.csv.20250524_120837.bak
     Execution Time: 0.0089s
    Throughput: 56281.7 projects/sec
    Status Distribution: 221 overdue, 12 due soon

 Testing with 1,000 projects...
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpz1lwfcyg.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpz1lwfcyg.csv.20250524_120838.bak
     Execution Time: 0.0141s
    Throughput: 71152.0 projects/sec
    Status Distribution: 435 overdue, 28 due soon

 Testing with 2,500 projects...
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp07tnfzr0.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp07tnfzr0.csv.20250524_120838.bak
     Execution Time: 0.0395s
    Throughput: 63358.7 projects/sec
    Status Distribution: 1052 overdue, 73 due soon

 Testing with 5,000 projects...
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpmpzoflpq.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpmpzoflpq.csv.20250524_120838.bak
     Execution Time: 0.0590s
    Throughput: 84698.8 projects/sec
    Status Distribution: 2145 overdue, 153 due soon

 Testing with 10,000 projects...
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpp62bbg1c.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpp62bbg1c.csv.20250524_120840.bak
     Execution Time: 0.1250s
    Throughput: 79990.9 projects/sec
    Status Distribution: 4229 overdue, 300 due soon

png

 ALGORITHMIC COMPLEXITY ANALYSIS:
   Estimated Complexity: O(n) - Linear
   Scaling Slope: 0.764
   Peak Throughput: 84698.8 projects/sec
   Performance Consistency: ⚠️  Variable

⚖️ PHASE 2: REVIEWER ASSIGNMENT ALGORITHM

⚖️ REVIEWER ASSIGNMENT WORKLOAD BALANCING TEST
============================================================

 Testing Scenario: Balanced Load
    50 projects, 10 reviewers
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/projects.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/projects.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpnz9n8apl/reviews.csv.20250524_120840.bak
    Assignments Created: 22
    Workload Std Dev: 1.17
    Cross-Dept Ratio: 1.00
    Fairness Score: 0.53

 Testing Scenario: High Load
    100 projects, 5 reviewers
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/projects.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/projects.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpd0ua8n0q/reviews.csv.20250524_120840.bak
    Assignments Created: 42
    Workload Std Dev: 0.80
    Cross-Dept Ratio: 1.00
    Fairness Score: 0.10

 Testing Scenario: Many Reviewers
    200 projects, 20 reviewers
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/projects.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/projects.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmp1f9qmr09/reviews.csv.20250524_120840.bak
    Assignments Created: 97
    Workload Std Dev: 1.11
    Cross-Dept Ratio: 1.00
    Fairness Score: 0.23

 Testing Scenario: Excess Capacity
    75 projects, 15 reviewers
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/projects.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/projects.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/users.csv.20250524_120840.bak
 Backed up /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv → /var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/tmpryw9cbju/reviews.csv.20250524_120840.bak
    Assignments Created: 34
    Workload Std Dev: 0.85
    Cross-Dept Ratio: 1.00
    Fairness Score: 0.38

png

 WORKLOAD BALANCING SUMMARY:
   Average Fairness Score: 0.308
   Average Std Deviation: 0.982
   Average Cross-Dept Ratio: 1.000
   Best Performing Scenario: High Load

 PHASE 3: CSV VALIDATION ALGORITHM

 CSV VALIDATION ALGORITHM ACCURACY TEST
============================================================

 Testing: Clean Data (corruption rate: 0.0%)

 Error during algorithm validation: 'NoneType' object has no attribute 'items'

Algorithm validation complete!
Results saved to JSON file with timestamp
All performance charts displayed above


Traceback (most recent call last):
  File "/var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/ipykernel_85838/165793326.py", line 42, in run_comprehensive_algorithm_validation
    validation_accuracy = ValidationAlgorithmTester.test_validation_accuracy()
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/ipykernel_85838/2179377468.py", line 69, in test_validation_accuracy
    validation_result = run_validation()
                        ^^^^^^^^^^^^^^^^
  File "/var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/ipykernel_85838/3892952202.py", line 25, in wrapper
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/var/folders/nn/n0gdyyhj48db7mys4xblzvyc0000gn/T/ipykernel_85838/2179377468.py", line 67, in run_validation
    return validate_csv_data(temp_file)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/cynthiamcginnis/Documents/ProjectReviewScheduler/src/scheduler.py", line 277, in validate_csv_data
    for field, rules in schema.items():
                        ^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'items'