@@ -1392,10 +1392,7 @@ def risk_adjusted_return(return_val, weight):
13921392 candidate_helper_code = {}
13931393 for file_path in file_path_to_helper_class :
13941394 candidate_helper_code [file_path ] = Path (file_path ).read_text ("utf-8" )
1395- file_path_to_helper_classes = {
1396- # Path(helper_path_1): {"HelperClass1"},
1397- # Path(helper_path_2): {"HelperClass2", "AnotherHelperClass"},
1398- }
1395+ file_path_to_helper_classes = {}
13991396 instrument_codeflash_capture (fto , file_path_to_helper_classes , tests_root )
14001397 modified_test_results , coverage_data = func_optimizer .run_and_parse_tests (
14011398 testing_type = TestingMode .BEHAVIOR ,
@@ -1413,6 +1410,70 @@ def risk_adjusted_return(return_val, weight):
14131410
14141411 assert not matched
14151412
1413+ new_fixed_code = """import math
1414+ from typing import List, Tuple, Optional
1415+
1416+ def calculate_portfolio_metrics(
1417+ investments: List[Tuple[str, float, float]],
1418+ risk_free_rate: float = 0.02
1419+ ) -> dict:
1420+ if not investments:
1421+ raise ValueError("Investments list cannot be empty")
1422+
1423+ # Tolerant weight check (matches original)
1424+ total_weight = sum(weight for _, weight, _ in investments)
1425+ if abs(total_weight - 1.0) > 1e-10:
1426+ raise ValueError("Portfolio weights must sum to 1.0")
1427+
1428+ # Same weighted return as original
1429+ weighted_return = sum(weight * ret for _, weight, ret in investments)
1430+
1431+ # Same volatility formula as original
1432+ volatility = math.sqrt(sum((weight * ret) ** 2 for _, weight, ret in investments))
1433+
1434+ # Same Sharpe ratio logic
1435+ if volatility == 0:
1436+ sharpe_ratio = 0.0
1437+ else:
1438+ sharpe_ratio = (weighted_return - risk_free_rate) / volatility
1439+
1440+ # Same best/worst logic (based on return only)
1441+ best_asset = max(investments, key=lambda x: x[2])
1442+ worst_asset = min(investments, key=lambda x: x[2])
1443+
1444+ return {
1445+ "weighted_return": round(weighted_return, 6),
1446+ "volatility": round(volatility, 6),
1447+ "sharpe_ratio": round(sharpe_ratio, 6),
1448+ "best_performing": (best_asset[0], round(best_asset[2], 6)),
1449+ "worst_performing": (worst_asset[0], round(worst_asset[2], 6)),
1450+ "total_assets": len(investments),
1451+ }
1452+ """
1453+ with fto_file_path .open ("w" ) as f :
1454+ f .write (new_fixed_code )
1455+ candidate_fto_code = Path (fto .file_path ).read_text ("utf-8" )
1456+ candidate_helper_code = {}
1457+ for file_path in file_path_to_helper_class :
1458+ candidate_helper_code [file_path ] = Path (file_path ).read_text ("utf-8" )
1459+ file_path_to_helper_classes = {}
1460+ instrument_codeflash_capture (fto , file_path_to_helper_classes , tests_root )
1461+ modified_test_results_2 , coverage_data = func_optimizer .run_and_parse_tests (
1462+ testing_type = TestingMode .BEHAVIOR ,
1463+ test_env = test_env ,
1464+ test_files = func_optimizer .test_files ,
1465+ optimization_iteration = 0 ,
1466+ pytest_min_loops = 1 ,
1467+ pytest_max_loops = 1 ,
1468+ testing_time = 0.1 ,
1469+ )
1470+ # Remove instrumentation
1471+ FunctionOptimizer .write_code_and_helpers (candidate_fto_code , candidate_helper_code , fto .file_path )
1472+ matched , diffs = compare_test_results (test_results , modified_test_results_2 )
1473+ # now the test should match and no diffs should be found
1474+ assert len (diffs ) == 0
1475+ assert matched
1476+
14161477 finally :
14171478 test_path .unlink (missing_ok = True )
14181479 fto_file_path .unlink (missing_ok = True )
0 commit comments