first commit
This commit is contained in:
275
tests/test_normalization.py
Normal file
275
tests/test_normalization.py
Normal file
@@ -0,0 +1,275 @@
|
||||
#!/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!")
|
||||
Reference in New Issue
Block a user