1212 python scripts/estimate_complexity.py my_script my_sorting_function
1313"""
1414
15- import sys
16- import time
1715import importlib
16+ import inspect
1817import math
1918import statistics
20- import inspect
19+ import sys
20+ import time
2121import typing
2222from pathlib import Path
2323
@@ -31,44 +31,45 @@ def measure_execution_time(func, input_size, iterations=5):
3131 Uses type hints to determine whether to pass 'n' (int) or data of size 'n'.
3232 """
3333 input_data = None
34-
34+
3535 # 1. Check type hints
3636 try :
3737 sig = inspect .signature (func )
3838 params = list (sig .parameters .values ())
3939 if params :
4040 first_param = params [0 ]
4141 hint = first_param .annotation
42-
42+
4343 if hint is int :
4444 input_data = input_size
45- elif hint in (list , typing .List , typing . Sequence ):
45+ elif hint in (list , typing .Sequence ):
4646 # Simple list generation
4747 input_data = list (range (input_size ))
4848 # Handle generic aliases like list[int] in newer Python
49- elif hasattr (hint , "__origin__" ) and hint .__origin__ in (list , typing .List , typing . Sequence ):
50- input_data = list (range (input_size ))
49+ elif hasattr (hint , "__origin__" ) and hint .__origin__ in (list , typing .Sequence ):
50+ input_data = list (range (input_size ))
5151 except (ValueError , TypeError ):
5252 # Signature inspection failed or function is weird
5353 pass
5454
5555 # 2. Heuristic fallback logic
5656 if input_data is None :
5757 return _measure_heuristic (func , input_size , iterations )
58-
58+
5959 # 3. Execution with determined input
6060 try :
6161 start_time = time .perf_counter ()
6262 for _ in range (iterations ):
6363 func (input_data )
6464 end_time = time .perf_counter ()
6565 return (end_time - start_time ) / iterations
66- except Exception as e :
67- # If specific input failed, maybe try heuristic as last resort?
66+ except Exception :
67+ # If specific input failed, maybe try heuristic as last resort?
6868 # But for now, just report error to avoid infinite fallback loops.
6969 # print(f"Error with generated input: {e}")
7070 return None
7171
72+
7273def _measure_heuristic (func , input_size , iterations ):
7374 """Fallback: Try int first, then list."""
7475 try :
@@ -89,6 +90,7 @@ def _measure_heuristic(func, input_size, iterations):
8990 except Exception :
9091 return None
9192
93+
9294def detect_complexity (n_values , times ):
9395 """
9496 Estimate complexity by comparing RSquared values for different models.
@@ -99,40 +101,42 @@ def detect_complexity(n_values, times):
99101
100102 # Normalize times
101103 min_time = min (times )
102- if min_time == 0 : min_time = 1e-9
104+ if min_time == 0 :
105+ min_time = 1e-9
103106 normalized_times = [t / min_time for t in times ]
104-
107+
105108 models = {
106109 "O(1) (Constant)" : [1 for _ in n_values ],
107110 "O(log n) (Logarithmic)" : [math .log (n ) if n > 0 else 0 for n in n_values ],
108- "O(n) (Linear)" : [ n for n in n_values ] ,
111+ "O(n) (Linear)" : list ( n_values ) ,
109112 "O(n log n) (Linearithmic)" : [n * math .log (n ) if n > 0 else 0 for n in n_values ],
110113 "O(n^2) (Quadratic)" : [n ** 2 for n in n_values ],
111114 }
112115
113116 best_fit = None
114- best_score = - float (' inf' )
117+ best_score = - float (" inf" )
115118
116119 for name , theoretical in models .items ():
117120 # Calculate correlation coefficient (Pearson)
118121 try :
119- if len (set (theoretical )) == 1 : # Handle constant case
122+ if len (set (theoretical )) == 1 : # Handle constant case
120123 # For constant time, we check variance of times
121- score = 1.0 / (statistics .stdev (normalized_times ) + 1.0 )
124+ score = 1.0 / (statistics .stdev (normalized_times ) + 1.0 )
122125 else :
123- # Correlation between theoretical and actual
124- # Using covariance / (std_dev_x * std_dev_y)
125- correlation = statistics .correlation (theoretical , times )
126- score = correlation
127-
126+ # Correlation between theoretical and actual
127+ # Using covariance / (std_dev_x * std_dev_y)
128+ correlation = statistics .correlation (theoretical , times )
129+ score = correlation
130+
128131 if score > best_score :
129132 best_score = score
130133 best_fit = name
131134 except statistics .StatisticsError :
132135 continue
133-
136+
134137 return best_fit , best_score
135138
139+
136140def main ():
137141 if len (sys .argv ) < 3 :
138142 print (__doc__ )
@@ -149,7 +153,7 @@ def main():
149153 sys .exit (1 )
150154
151155 print (f"Estimating complexity for { module_name } .{ func_name } ..." )
152-
156+
153157 # Input sizes to test
154158 n_values = [100 , 500 , 1000 , 2000 , 5000 ]
155159 times = []
@@ -170,6 +174,7 @@ def main():
170174 print ("-" * 35 )
171175 print (f"Estimated Complexity: { complexity } " )
172176 print (f"Fit Score: { score :.3f} " )
173-
177+
178+
174179if __name__ == "__main__" :
175180 main ()
0 commit comments