276 lines
8.6 KiB
Python
276 lines
8.6 KiB
Python
#!/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!")
|