| 349 | } |
| 350 | |
| 351 | auto register_par_bindings(py::module_& module) -> void |
| 352 | { |
| 353 | module.def( |
| 354 | "par", |
| 355 | [](const py::dict& table_results, const int vulnerable) { |
| 356 | if (vulnerable < 0 || vulnerable > 3) { |
| 357 | throw py::value_error( |
| 358 | "vulnerable has invalid value " + std::to_string(vulnerable) + |
| 359 | " (expected 0=none, 1=both, 2=NS, 3=EW)"); |
| 360 | } |
| 361 | |
| 362 | const DdTableResults native_table = dds3_python::dict_to_dd_table_results(table_results); |
| 363 | ParResults par_results{}; |
| 364 | int code = RETURN_NO_FAULT; |
| 365 | { |
| 366 | py::gil_scoped_release release; |
| 367 | code = Par(&native_table, &par_results, vulnerable); |
| 368 | } |
| 369 | throw_on_dds_error(code); |
| 370 | return dds3_python::par_results_to_dict(par_results); |
| 371 | }, |
| 372 | py::arg("table_results"), |
| 373 | py::arg("vulnerable") = 0, |
| 374 | "Calculate par contracts and scores for a given double-dummy table.\n\n" |
| 375 | "Args:\n" |
| 376 | " table_results (dict): DD table results dict with key 'res_table' (5x4 nested list).\n" |
| 377 | " vulnerable (int): Vulnerability (0=none, 1=both, 2=NS, 3=EW).\n\n" |
| 378 | "Returns:\n" |
| 379 | " dict: Par results with keys 'par_score' and 'par_contracts_string'.\n" |
| 380 | " par_contracts_string[ns] = contract string (e.g., '6NT+1', '7C=').\n\n" |
| 381 | "Raises:\n" |
| 382 | " ValueError: If input validation fails (invalid table or vulnerability).\n" |
| 383 | " RuntimeError: If DDS solver returns error code."); |
| 384 | } |
| 385 | |
| 386 | auto register_calc_par_bindings(py::module_& module) -> void |
| 387 | { |
no test coverage detected