X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=src%2Fdunshire%2Ferrors.py;h=020186475b2a920f8425ffe0be76b3a27625de85;hb=23a5893ede3a22653128d3e7a66fb3f6b80616b8;hp=3a5b601cec9ca0a2753e16ede6460a2ac6ca101a;hpb=4849db71b289f77851cc9bd98fc1fb7d1e41a811;p=dunshire.git diff --git a/src/dunshire/errors.py b/src/dunshire/errors.py index 3a5b601..0201864 100644 --- a/src/dunshire/errors.py +++ b/src/dunshire/errors.py @@ -10,7 +10,10 @@ def _pretty_format_dict(dictionary): Return a pretty-formatted string representation of a dictionary containing CVXOPT matrices. - EXAMPLES: + The dictionary is also sorted so that it can be tested repeatably. + + Examples + -------- >>> d = {'foo': 1.234, 'bar': matrix([1,2,3])} >>> print(_pretty_format_dict(d)) @@ -22,7 +25,7 @@ def _pretty_format_dict(dictionary): """ result = '' - for (key, value) in dictionary.items(): + for (key, value) in sorted(dictionary.items()): if isinstance(value, matrix): # Display matrices on their own lines, indented. result += '{:s}:'.format(key) @@ -37,20 +40,67 @@ def _pretty_format_dict(dictionary): class GameUnsolvableException(Exception): """ - Every linear game has a solution (this follows from a general - min-max theorem). If we can't solve the conic program associated - with a linear game, then something is wrong with either the model of - the input. + An exception raised when a game cannot be solved. + + Every linear game has a solution. If we can't solve the conic + program associated with a linear game, then something is wrong with + either the model or the input, and this exception should be raised. + + Parameters + ---------- + + solution_dict : dict + The solution dictionary returned from the failed cone program. + + Examples + -------- + + >>> d = {'residual as dual infeasibility certificate': None, + ... 'y': matrix([1,1]), + ... 'dual slack': 8.779496368228267e-10, + ... 'z': matrix([1,1,0,0]), + ... 's': None, + ... 'primal infeasibility': None, + ... 'status': 'primal infeasible', + ... 'dual infeasibility': None, + ... 'relative gap': None, + ... 'iterations': 5, + ... 'primal slack': None, + ... 'x': None, + ... 'dual objective': 1.0, + ... 'primal objective': None, + ... 'gap': None, + ... 'residual as primal infeasibility certificate': + ... 3.986246886102996e-09} + >>> print(GameUnsolvableException(d)) + Solution failed with result "primal infeasible." + CVXOPT returned: + dual infeasibility: None + dual objective: 1.0 + dual slack: 8.779496368228267e-10 + gap: None + iterations: 5 + primal infeasibility: None + primal objective: None + primal slack: None + relative gap: None + residual as dual infeasibility certificate: None + residual as primal infeasibility certificate: 3.986246886102996e-09 + s: None + status: primal infeasible + x: None + y: + [ 1] + [ 1] + z: + [ 1] + [ 1] + [ 0] + [ 0] """ def __init__(self, solution_dict): """ Create a new GameUnsolvableException object. - - INPUT: - - - ``solution_dict`` -- the solution dictionary returned from the - cone program. - """ super().__init__() self._solution_dict = solution_dict @@ -68,5 +118,8 @@ class GameUnsolvableException(Exception): tpl = 'Solution failed with result "{:s}."\n' \ 'CVXOPT returned:\n {!s}' cvx_lines = _pretty_format_dict(self._solution_dict).splitlines() - cvx_str = '\n '.join(cvx_lines) # Indent the whole dict by two spaces. + + # Indent the whole dict by two spaces. + cvx_str = '\n '.join(cvx_lines) + return tpl.format(self._solution_dict['status'], cvx_str)