#!/usr/bin/env python3 """ Test script for normalization calculations. This script tests the normalization functions to ensure they work correctly without requiring database connections. """ import sys import os # Add the project root to the path sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) from app.services.normalization import apply_normalization def test_apply_normalization(): """Test the apply_normalization function.""" print("Testing apply_normalization function...") print("=" * 60) # Test case 1: Normal normalization (NM=500, rataan=500, sb=100) nm1 = 500 rataan1 = 500 sb1 = 100 nn1 = apply_normalization(nm1, rataan1, sb1) expected1 = 500 print(f"Test 1: NM={nm1}, rataan={rataan1}, sb={sb1}") print(f" Expected NN: {expected1}") print(f" Actual NN: {nn1}") print(f" Status: {'PASS' if nn1 == expected1 else 'FAIL'}") print() # Test case 2: High score (NM=600, rataan=500, sb=100) nm2 = 600 rataan2 = 500 sb2 = 100 nn2 = apply_normalization(nm2, rataan2, sb2) expected2 = 600 print(f"Test 2: NM={nm2}, rataan={rataan2}, sb={sb2}") print(f" Expected NN: {expected2}") print(f" Actual NN: {nn2}") print(f" Status: {'PASS' if nn2 == expected2 else 'FAIL'}") print() # Test case 3: Low score (NM=400, rataan=500, sb=100) nm3 = 400 rataan3 = 500 sb3 = 100 nn3 = apply_normalization(nm3, rataan3, sb3) expected3 = 400 print(f"Test 3: NM={nm3}, rataan={rataan3}, sb={sb3}") print(f" Expected NN: {expected3}") print(f" Actual NN: {nn3}") print(f" Status: {'PASS' if nn3 == expected3 else 'FAIL'}") print() # Test case 4: Edge case - maximum NM nm4 = 1000 rataan4 = 500 sb4 = 100 nn4 = apply_normalization(nm4, rataan4, sb4) expected4 = 1000 print(f"Test 4: NM={nm4}, rataan={rataan4}, sb={sb4}") print(f" Expected NN: {expected4}") print(f" Actual NN: {nn4}") print(f" Status: {'PASS' if nn4 == expected4 else 'FAIL'}") print() # Test case 5: Edge case - minimum NM nm5 = 0 rataan5 = 500 sb5 = 100 nn5 = apply_normalization(nm5, rataan5, sb5) expected5 = 0 print(f"Test 5: NM={nm5}, rataan={rataan5}, sb={sb5}") print(f" Expected NN: {expected5}") print(f" Actual NN: {nn5}") print(f" Status: {'PASS' if nn5 == expected5 else 'FAIL'}") print() # Test case 6: Error case - invalid NM (above max) try: nm6 = 1200 # Above valid range rataan6 = 500 sb6 = 100 nn6 = apply_normalization(nm6, rataan6, sb6) print(f"Test 6: NM={nm6}, rataan={rataan6}, sb={sb6} (should raise ValueError)") print(f" Status: FAIL - Should have raised ValueError") except ValueError as e: print(f"Test 6: NM={nm6}, rataan={rataan6}, sb={sb6} (should raise ValueError)") print(f" Error: {e}") print(f" Status: PASS - Correctly raised ValueError") print() # Test case 7: Error case - invalid NM (below min) try: nm7 = -100 # Below valid range rataan7 = 500 sb7 = 100 nn7 = apply_normalization(nm7, rataan7, sb7) print(f"Test 7: NM={nm7}, rataan={rataan7}, sb={sb7} (should raise ValueError)") print(f" Status: FAIL - Should have raised ValueError") except ValueError as e: print(f"Test 7: NM={nm7}, rataan={rataan7}, sb={sb7} (should raise ValueError)") print(f" Error: {e}") print(f" Status: PASS - Correctly raised ValueError") print() # Test case 8: Different rataan/sb (NM=500, rataan=600, sb=80) nm8 = 500 rataan8 = 600 sb8 = 80 nn8 = apply_normalization(nm8, rataan8, sb8) # z_score = (500 - 600) / 80 = -1.25 # nn = 500 + 100 * (-1.25) = 500 - 125 = 375 expected8 = 375 print(f"Test 8: NM={nm8}, rataan={rataan8}, sb={sb8}") print(f" Expected NN: {expected8}") print(f" Actual NN: {nn8}") print(f" Status: {'PASS' if nn8 == expected8 else 'FAIL'}") print() # Test case 9: Error case - invalid NM try: nm9 = 1500 # Above valid range rataan9 = 500 sb9 = 100 nn9 = apply_normalization(nm9, rataan9, sb9) print(f"Test 9: NM={nm9}, rataan={rataan9}, sb={sb9} (should raise ValueError)") print(f" Status: FAIL - Should have raised ValueError") except ValueError as e: print(f"Test 9: NM=1500, rataan=500, sb=100 (should raise ValueError)") print(f" Error: {e}") print(f" Status: PASS - Correctly raised ValueError") print() # Test case 10: Error case - invalid sb try: nm10 = 500 rataan10 = 500 sb10 = 0 # Invalid SD nn10 = apply_normalization(nm10, rataan10, sb10) expected10 = 500 # Should return default when sb <= 0 print(f"Test 10: NM={nm10}, rataan={rataan10}, sb={sb10} (should return default)") print(f" Expected NN: {expected10}") print(f" Actual NN: {nn10}") print(f" Status: {'PASS' if nn10 == expected10 else 'FAIL'}") except Exception as e: print(f"Test 10: NM=500, rataan=500, sb=0 (should return default)") print(f" Error: {e}") print(f" Status: FAIL - Should have returned default value") print() print("=" * 60) print("All tests completed!") print("=" * 60) def calculate_dynamic_mean_and_std(nm_values): """ Calculate mean and standard deviation from a list of NM values. This simulates what update_dynamic_normalization does. """ n = len(nm_values) if n == 0: return None, None # Calculate mean mean = sum(nm_values) / n # Calculate variance (population variance) if n > 1: variance = sum((x - mean) ** 2 for x in nm_values) / n std = variance ** 0.5 else: std = 0.0 return mean, std def test_dynamic_normalization_simulation(): """Test dynamic normalization with simulated participant scores.""" print("\nTesting dynamic normalization simulation...") print("=" * 60) # Simulate 10 participant NM scores nm_scores = [450, 480, 500, 520, 550, 480, 510, 490, 530, 470] print(f"Simulated NM scores: {nm_scores}") print() # Calculate mean and SD mean, std = calculate_dynamic_mean_and_std(nm_scores) print(f"Calculated mean (rataan): {mean:.2f}") print(f"Calculated SD (sb): {std:.2f}") print() # Normalize each score print("Normalized scores:") for i, nm in enumerate(nm_scores): nn = apply_normalization(nm, mean, std) print(f" Participant {i+1}: NM={nm:3d} -> NN={nn:3d}") print() # Check if normalized distribution is close to mean=500, SD=100 nn_scores = [apply_normalization(nm, mean, std) for nm in nm_scores] nn_mean, nn_std = calculate_dynamic_mean_and_std(nn_scores) print(f"Normalized distribution:") print(f" Mean: {nn_mean:.2f} (target: 500 ± 5)") print(f" SD: {nn_std:.2f} (target: 100 ± 5)") print(f" Status: {'PASS' if abs(nn_mean - 500) <= 5 and abs(nn_std - 100) <= 5 else 'NEAR PASS'}") print() print("=" * 60) def test_incremental_update(): """Test incremental update of dynamic normalization.""" print("\nTesting incremental update simulation...") print("=" * 60) # Simulate adding scores incrementally nm_scores = [] participant_count = 0 total_nm_sum = 0.0 total_nm_sq_sum = 0.0 new_scores = [500, 550, 450, 600, 400] for i, nm in enumerate(new_scores): # Update running statistics participant_count += 1 total_nm_sum += nm total_nm_sq_sum += nm * nm # Calculate mean and SD mean = total_nm_sum / participant_count if participant_count > 1: variance = (total_nm_sq_sum / participant_count) - (mean ** 2) std = variance ** 0.5 else: std = 0.0 nm_scores.append(nm) print(f"After adding participant {i+1}:") print(f" NM: {nm}") print(f" Participant count: {participant_count}") print(f" Mean (rataan): {mean:.2f}") print(f" SD (sb): {std:.2f}") print() # Final calculation final_mean, final_std = calculate_dynamic_mean_and_std(nm_scores) print(f"Final statistics:") print(f" All scores: {nm_scores}") print(f" Mean: {final_mean:.2f}") print(f" SD: {final_std:.2f}") print() print("=" * 60) if __name__ == "__main__": print("Normalization Calculation Tests") print("=" * 60) print() test_apply_normalization() test_dynamic_normalization_simulation() test_incremental_update() print("\nAll test simulations completed successfully!")