From 2e35061e57ce85e4a7a086d0189c72d13a0ee58a Mon Sep 17 00:00:00 2001 From: Ronan Lamy Date: Sun, 11 Nov 2012 20:49:59 +0000 Subject: [PATCH 1/9] don't evaluate bool(Relational) --- sympy/core/relational.py | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/sympy/core/relational.py b/sympy/core/relational.py index 4f8baf4fb5d7..8cb37880c0a7 100644 --- a/sympy/core/relational.py +++ b/sympy/core/relational.py @@ -201,6 +201,9 @@ def _eval_simplify(self, ratio, measure): return self.__class__(self.lhs.simplify(ratio=ratio), self.rhs.simplify(ratio=ratio)) + def __nonzero__(self): + raise TypeError("symbolic boolean expression has no truth value.") + class Equality(Relational): @@ -218,10 +221,6 @@ def _eval_relation(cls, lhs, rhs): def _eval_relation_doit(cls, lhs, rhs): return Eq(lhs, rhs) - def __nonzero__(self): - return self.lhs.compare(self.rhs) == 0 - - class Unequality(Relational): rel_op = '!=' @@ -236,10 +235,6 @@ def _eval_relation(cls, lhs, rhs): def _eval_relation_doit(cls, lhs, rhs): return Ne(lhs, rhs) - def __nonzero__(self): - return self.lhs.compare(self.rhs) != 0 - - class _Greater(Relational): """Not intended for general use @@ -525,9 +520,6 @@ class GreaterThan(_Greater): def _eval_relation(cls, lhs, rhs): return lhs >= rhs - def __nonzero__(self): - return self.lhs.compare( self.rhs ) >= 0 - class LessThan(_Less): __doc__ = GreaterThan.__doc__ @@ -539,9 +531,6 @@ class LessThan(_Less): def _eval_relation(cls, lhs, rhs): return lhs <= rhs - def __nonzero__(self): - return self.lhs.compare( self.rhs ) <= 0 - class StrictGreaterThan(_Greater): __doc__ = GreaterThan.__doc__ @@ -553,9 +542,6 @@ class StrictGreaterThan(_Greater): def _eval_relation(cls, lhs, rhs): return lhs > rhs - def __nonzero__(self): - return self.lhs.compare( self.rhs ) > 0 - class StrictLessThan(_Less): __doc__ = GreaterThan.__doc__ @@ -567,9 +553,6 @@ class StrictLessThan(_Less): def _eval_relation(cls, lhs, rhs): return lhs < rhs - def __nonzero__(self): - return self.lhs.compare( self.rhs ) < 0 - # A class-specific (not object-specific) data item used for a minor speedup. It # is defined here, rather than directly in the class, because the classes that # it references have not been defined until now (e.g. StrictLessThan). From 54c1c9630d214e307c8d8073d6286c9cc517dd79 Mon Sep 17 00:00:00 2001 From: Julien Rioux Date: Fri, 10 May 2013 18:09:28 +0200 Subject: [PATCH 2/9] Update the docstring of Relational. --- sympy/core/relational.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sympy/core/relational.py b/sympy/core/relational.py index d4c6b8de40e4..42220bf50856 100644 --- a/sympy/core/relational.py +++ b/sympy/core/relational.py @@ -465,9 +465,10 @@ class GreaterThan(_Greater): The other gotcha is with chained inequalities. Occasionally, one may be tempted to write statements like: - >>> e = x < y < z # silent error! Where did ``x`` go? - >>> e #doctest: +SKIP - y < z + >>> e = x < y < z + Traceback (most recent call last): + ... + TypeError: symbolic boolean expression has no truth value. Due to an implementation detail or decision of Python [1]_, there is no way for SymPy to reliably create that as a chained inequality. To create a From ee9b1f33976f23594fdb73678cf2ef5cbc933dee Mon Sep 17 00:00:00 2001 From: Julien Rioux Date: Fri, 10 May 2013 18:17:50 +0200 Subject: [PATCH 3/9] Remove extra sorting step from tests whenever possible. --- sympy/core/tests/test_expr.py | 37 +++++++++++------------ sympy/physics/quantum/tests/test_qubit.py | 30 +++++++++--------- sympy/polys/tests/test_monomials.py | 32 +++++++++++--------- sympy/polys/tests/test_polyroots.py | 14 ++++----- 4 files changed, 58 insertions(+), 55 deletions(-) diff --git a/sympy/core/tests/test_expr.py b/sympy/core/tests/test_expr.py index 7d03e1821dc9..76f8237e400d 100644 --- a/sympy/core/tests/test_expr.py +++ b/sympy/core/tests/test_expr.py @@ -290,32 +290,31 @@ class foo(Function): def test_atoms(): - assert sorted(list(x.atoms())) == [x] - assert sorted(list((1 + x).atoms())) == sorted([1, x]) + assert x.atoms() == set([x]) + assert (1 + x).atoms() == set([x, S(1)]) - assert sorted(list((1 + 2*cos(x)).atoms(Symbol))) == [x] - assert sorted( - list((1 + 2*cos(x)).atoms(Symbol, Number))) == sorted([1, 2, x]) + assert (1 + 2*cos(x)).atoms(Symbol) == set([x]) + assert (1 + 2*cos(x)).atoms(Symbol, Number) == set([S(1), S(2), x]) - assert sorted(list((2*(x**(y**x))).atoms())) == sorted([2, x, y]) + assert (2*(x**(y**x))).atoms() == set([S(2), x, y]) - assert sorted(list(Rational(1, 2).atoms())) == [S.Half] - assert sorted(list(Rational(1, 2).atoms(Symbol))) == [] + assert Rational(1, 2).atoms() == set([S.Half]) + assert Rational(1, 2).atoms(Symbol) == set([]) - assert sorted(list(sin(oo).atoms(oo))) == [oo] + assert sin(oo).atoms(oo) == set([oo]) - assert sorted(list(Poly(0, x).atoms())) == [S.Zero] - assert sorted(list(Poly(1, x).atoms())) == [S.One] + assert Poly(0, x).atoms() == set([S.Zero]) + assert Poly(1, x).atoms() == set([S.One]) - assert sorted(list(Poly(x, x).atoms())) == [x] - assert sorted(list(Poly(x, x, y).atoms())) == [x] - assert sorted(list(Poly(x + y, x, y).atoms())) == sorted([x, y]) - assert sorted(list(Poly(x + y, x, y, z).atoms())) == sorted([x, y]) - assert sorted(list(Poly(x + y*t, x, y, z).atoms())) == sorted([t, x, y]) + assert Poly(x, x).atoms() == set([x]) + assert Poly(x, x, y).atoms() == set([x]) + assert Poly(x + y, x, y).atoms() == set([x, y]) + assert Poly(x + y, x, y, z).atoms() == set([x, y]) + assert Poly(x + y*t, x, y, z).atoms() == set([t, x, y]) - assert list((I*pi).atoms(NumberSymbol)) == [pi] - assert sorted((I*pi).atoms(NumberSymbol, I)) == \ - sorted((I*pi).atoms(I, NumberSymbol)) == [pi, I] + assert (I*pi).atoms(NumberSymbol) == set([pi]) + assert (I*pi).atoms(NumberSymbol, I) == \ + (I*pi).atoms(I, NumberSymbol) == set([pi, I]) assert exp(exp(x)).atoms(exp) == set([exp(exp(x)), exp(x)]) assert (1 + x*(2 + y) + exp(3 + z)).atoms(Add) == \ diff --git a/sympy/physics/quantum/tests/test_qubit.py b/sympy/physics/quantum/tests/test_qubit.py index 87b3362852a0..6cf716f511f9 100644 --- a/sympy/physics/quantum/tests/test_qubit.py +++ b/sympy/physics/quantum/tests/test_qubit.py @@ -116,10 +116,10 @@ def test_measure_normalize(): def test_measure_partial(): #Basic test of collapse of entangled two qubits (Bell States) state = Qubit('01') + Qubit('10') - assert sorted(measure_partial(state, (0,))) == \ - [(Qubit('01'), Rational(1, 2)), (Qubit('10'), Rational(1, 2))] - assert sorted(measure_partial(state, (0,))) == \ - sorted(measure_partial(state, (1,))) + assert measure_partial(state, (0,)) == \ + [(Qubit('10'), Rational(1, 2)), (Qubit('01'), Rational(1, 2))] + assert measure_partial(state, (0,)) == \ + measure_partial(state, (1,))[::-1] #Test of more complex collapse and probability calculation state1 = sqrt(2)/sqrt(3)*Qubit('00001') + 1/sqrt(3)*Qubit('11111') @@ -131,23 +131,23 @@ def test_measure_partial(): #test of measuring multiple bits at once state2 = Qubit('1111') + Qubit('1101') + Qubit('1011') + Qubit('1000') - assert sorted(measure_partial(state2, (0, 1, 3))) == sorted( - [(Qubit('1011')/sqrt(2) + Qubit('1111')/sqrt(2), Rational(1, 2)), - (Qubit('1101'), Rational(1, 4)), (Qubit('1000'), Rational(1, 4))]) - assert sorted(measure_partial(state2, (0,))) == sorted( - [(Qubit('1111')/sqrt(3) + Qubit('1101')/sqrt(3) + - Qubit('1011')/sqrt(3), Rational(3, 4)), - (Qubit('1000'), Rational(1, 4))]) + assert measure_partial(state2, (0, 1, 3)) == \ + [(Qubit('1000'), Rational(1, 4)), (Qubit('1101'), Rational(1, 4)), + (Qubit('1011')/sqrt(2) + Qubit('1111')/sqrt(2), Rational(1, 2))] + assert measure_partial(state2, (0,)) == \ + [(Qubit('1000'), Rational(1, 4)), + (Qubit('1111')/sqrt(3) + Qubit('1101')/sqrt(3) + + Qubit('1011')/sqrt(3), Rational(3, 4))] def test_measure_all(): assert measure_all(Qubit('11')) == [(Qubit('11'), 1)] state = Qubit('11') + Qubit('10') - assert sorted(measure_all(state)) == sorted([(Qubit('11'), Rational(1, 2)), - (Qubit('10'), Rational(1, 2))]) + assert measure_all(state) == [(Qubit('10'), Rational(1, 2)), + (Qubit('11'), Rational(1, 2))] state2 = Qubit('11')/sqrt(5) + 2*Qubit('00')/sqrt(5) - assert sorted(measure_all(state2)) == sorted( - [(Qubit('11'), Rational(1, 5)), (Qubit('00'), Rational(4, 5))]) + assert measure_all(state2) == \ + [(Qubit('00'), Rational(4, 5)), (Qubit('11'), Rational(1, 5))] def test_eval_trace(): diff --git a/sympy/polys/tests/test_monomials.py b/sympy/polys/tests/test_monomials.py index 52b1a49abc16..09dda0a1487d 100644 --- a/sympy/polys/tests/test_monomials.py +++ b/sympy/polys/tests/test_monomials.py @@ -12,23 +12,27 @@ from sympy.polys.polyerrors import ExactQuotientFailed from sympy.abc import a, b, c, x, y, z +from sympy.core import S from sympy.utilities.pytest import raises + def test_monomials(): - assert sorted(itermonomials([], 0)) == [1] - assert sorted(itermonomials([], 1)) == [1] - assert sorted(itermonomials([], 2)) == [1] - assert sorted(itermonomials([], 3)) == [1] - - assert sorted(itermonomials([x], 0)) == [1] - assert sorted(itermonomials([x], 1)) == [1, x] - assert sorted(itermonomials([x], 2)) == [1, x, x**2] - assert sorted(itermonomials([x], 3)) == [1, x, x**2, x**3] - - assert sorted(itermonomials([x, y], 0)) == [1] - assert sorted(itermonomials([x, y], 1)) == [1, x, y] - assert sorted(itermonomials([x, y], 2)) == [1, x, y, x**2, y**2, x*y] - assert sorted(itermonomials([x, y], 3)) == [1, x, y, x**2, x**3, y**2, y**3, x*y, x*y**2, y*x**2] + assert itermonomials([], 0) == set([S(1)]) + assert itermonomials([], 1) == set([S(1)]) + assert itermonomials([], 2) == set([S(1)]) + assert itermonomials([], 3) == set([S(1)]) + + assert itermonomials([x], 0) == set([S(1)]) + assert itermonomials([x], 1) == set([S(1), x]) + assert itermonomials([x], 2) == set([S(1), x, x**2]) + assert itermonomials([x], 3) == set([S(1), x, x**2, x**3]) + + assert itermonomials([x, y], 0) == set([S(1)]) + assert itermonomials([x, y], 1) == set([S(1), x, y]) + assert itermonomials([x, y], 2) == set([S(1), x, y, x**2, y**2, x*y]) + assert itermonomials([x, y], 3) == \ + set([S(1), x, y, x**2, x**3, y**2, y**3, x*y, x*y**2, y*x**2]) + def test_monomial_count(): assert monomial_count(2, 2) == 6 diff --git a/sympy/polys/tests/test_polyroots.py b/sympy/polys/tests/test_polyroots.py index 903bb8795b6c..8b50902f29e2 100644 --- a/sympy/polys/tests/test_polyroots.py +++ b/sympy/polys/tests/test_polyroots.py @@ -403,18 +403,18 @@ def test_roots_slow(): def test_roots_inexact(): - R1 = sorted([ r.evalf() for r in roots(x**2 + x + 1, x) ]) - R2 = sorted([ r for r in roots(x**2 + x + 1.0, x) ]) + R1 = roots(x**2 + x + 1, x, multiple=True) + R2 = roots(x**2 + x + 1.0, x, multiple=True) for r1, r2 in zip(R1, R2): assert abs(r1 - r2) < 1e-12 - f = x**4 + 3.0*sqrt( - 2.0)*x**3 - (78.0 + 24.0*sqrt(3.0))*x**2 + 144.0*(2*sqrt(3.0) + 9.0) + f = x**4 + 3.0*sqrt(2.0)*x**3 - (78.0 + 24.0*sqrt(3.0))*x**2 \ + + 144.0*(2*sqrt(3.0) + 9.0) - R1 = sorted(roots(f, multiple=True)) - R2 = sorted([-12.7530479110482, -3.85012393732929, - 4.89897948556636, 7.46155167569183]) + R1 = roots(f, multiple=True) + R2 = (-12.7530479110482, -3.85012393732929, + 4.89897948556636, 7.46155167569183) for r1, r2 in zip(R1, R2): assert abs(r1 - r2) < 1e-10 From 102f322bf505c07d9195a9a3d829b8a02528efd8 Mon Sep 17 00:00:00 2001 From: Julien Rioux Date: Fri, 10 May 2013 18:20:41 +0200 Subject: [PATCH 4/9] Test chebyshevt_root and chebyshevu_root with valid arguments. --- sympy/core/tests/test_args.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sympy/core/tests/test_args.py b/sympy/core/tests/test_args.py index 0a8e3f45674c..b95e1eb124aa 100644 --- a/sympy/core/tests/test_args.py +++ b/sympy/core/tests/test_args.py @@ -1488,7 +1488,7 @@ def test_sympy__functions__special__polynomials__chebyshevt(): def test_sympy__functions__special__polynomials__chebyshevt_root(): from sympy.functions.special.polynomials import chebyshevt_root - assert _test_args(chebyshevt_root(x, 2)) + assert _test_args(chebyshevt_root(3, 2)) def test_sympy__functions__special__polynomials__chebyshevu(): @@ -1498,7 +1498,7 @@ def test_sympy__functions__special__polynomials__chebyshevu(): def test_sympy__functions__special__polynomials__chebyshevu_root(): from sympy.functions.special.polynomials import chebyshevu_root - assert _test_args(chebyshevu_root(x, 2)) + assert _test_args(chebyshevu_root(3, 2)) def test_sympy__functions__special__polynomials__hermite(): From 388a7ed02705e46c5418799e81ea7a24015eb466 Mon Sep 17 00:00:00 2001 From: Julien Rioux Date: Fri, 10 May 2013 18:24:29 +0200 Subject: [PATCH 5/9] Always specify the sort key when sorting. --- doc/src/modules/polys/basics.rst | 6 ++-- sympy/combinatorics/partitions.py | 8 +++-- sympy/core/trace.py | 3 +- sympy/geometry/polygon.py | 18 ++++++----- sympy/integrals/tests/test_meijerint.py | 3 +- sympy/integrals/transforms.py | 20 +++++++------ sympy/physics/quantum/gate.py | 40 +++++++++++++++++-------- sympy/physics/secondquant.py | 12 ++------ sympy/polys/domains/domain.py | 4 +-- sympy/polys/polyroots.py | 2 +- sympy/simplify/hyperexpand.py | 8 ++--- sympy/simplify/sqrtdenest.py | 4 +-- sympy/solvers/diophantine.py | 3 +- sympy/solvers/ode.py | 2 +- sympy/solvers/polysys.py | 10 +++---- sympy/solvers/tests/test_polysys.py | 21 ++++++------- sympy/statistics/distributions.py | 6 ++-- sympy/unify/rewrite.py | 3 +- sympy/utilities/iterables.py | 4 +-- 19 files changed, 100 insertions(+), 77 deletions(-) diff --git a/doc/src/modules/polys/basics.rst b/doc/src/modules/polys/basics.rst index 5c87e9a615b0..c0c04610c128 100644 --- a/doc/src/modules/polys/basics.rst +++ b/doc/src/modules/polys/basics.rst @@ -209,11 +209,11 @@ polynomials and to solve some systems of polynomial equations:: >>> p = Symbol('p') >>> q = Symbol('q') - >>> sorted(solve(x**2 + p*x + q, x)) + >>> solve(x**2 + p*x + q, x) __________ __________ / 2 / 2 p \/ p - 4*q p \/ p - 4*q - [- - + -------------, - - - -------------] + [- - - -------------, - - + -------------] 2 2 2 2 >>> solve_poly_system([y - x, x - 5], x, y) @@ -222,5 +222,5 @@ polynomials and to solve some systems of polynomial equations:: >>> solve_poly_system([y**2 - x**3 + 1, y*x], x, y) ___ ___ 1 \/ 3 *I 1 \/ 3 *I - [(0, I), (0, -I), (1, 0), (- - + -------, 0), (- - - -------, 0)] + [(0, -I), (0, I), (1, 0), (- - - -------, 0), (- - + -------, 0)] 2 2 2 2 diff --git a/sympy/combinatorics/partitions.py b/sympy/combinatorics/partitions.py index c9448cf0087d..8de0ca091914 100644 --- a/sympy/combinatorics/partitions.py +++ b/sympy/combinatorics/partitions.py @@ -86,7 +86,7 @@ def sort_key(self, order=None): else: members = tuple(sorted(self.members, key=lambda w: default_sort_key(w, order))) - return self.size, members, self.rank + return map(default_sort_key, (self.size, members, self.rank)) @property def partition(self): @@ -100,7 +100,8 @@ def partition(self): [[1], [2, 3]] """ if self._partition is None: - self._partition = sorted(sorted(p) for p in self.args) + self._partition = sorted([sorted(p, key=default_sort_key) + for p in self.args]) return self._partition def __add__(self, other): @@ -230,7 +231,8 @@ def RGS(self): for i, part in enumerate(partition): for j in part: rgs[j] = i - return tuple([rgs[i] for i in sorted(i for p in partition for i in p)]) + return tuple([rgs[i] for i in sorted( + [i for p in partition for i in p], key=default_sort_key)]) @classmethod def from_rgs(self, rgs, elements): diff --git a/sympy/core/trace.py b/sympy/core/trace.py index e3bbc9ef1019..95b601f36d7b 100644 --- a/sympy/core/trace.py +++ b/sympy/core/trace.py @@ -2,6 +2,7 @@ from sympy import Expr, Add, Mul, Matrix, Pow, sympify, Matrix, Tuple from sympy.core.compatibility import xrange +from sympy.utilities import default_sort_key def _is_scalar(e): @@ -32,7 +33,7 @@ def _cycle_permute(l): if len(l) == 1: return l - min_item = min(l) + min_item = min(l, key=default_sort_key) indices = [i for i, x in enumerate(l) if x == min_item] le = list(l) diff --git a/sympy/geometry/polygon.py b/sympy/geometry/polygon.py index c4f4d373a575..fe7ca8a8d1b2 100644 --- a/sympy/geometry/polygon.py +++ b/sympy/geometry/polygon.py @@ -2,13 +2,15 @@ from sympy.core import Expr, S, sympify, oo, pi, Symbol, zoo from sympy.core.compatibility import as_int, xrange -from sympy.functions.elementary.piecewise import Piecewise from sympy.functions.elementary.complexes import sign +from sympy.functions.elementary.piecewise import Piecewise from sympy.functions.elementary.trigonometric import cos, sin, tan, sqrt, atan -from sympy.simplify import simplify from sympy.geometry.exceptions import GeometryError +from sympy.logic import And from sympy.matrices import Matrix +from sympy.simplify import simplify from sympy.solvers import solve +from sympy.utilities import default_sort_key from sympy.utilities.iterables import has_variety, has_dups from .entity import GeometryEntity @@ -143,7 +145,8 @@ def __new__(cls, *args, **kwargs): got.add(p) i = -3 while i < len(nodup) - 3 and len(nodup) > 2: - a, b, c = sorted([nodup[i], nodup[i + 1], nodup[i + 2]]) + a, b, c = sorted( + [nodup[i], nodup[i + 1], nodup[i + 2]], key=default_sort_key) if b not in shared and Point.is_collinear(a, b, c): nodup[i] = a nodup[i + 1] = None @@ -1659,7 +1662,8 @@ def __new__(cls, *args, **kwargs): # remove collinear points i = -3 while i < len(nodup) - 3 and len(nodup) > 2: - a, b, c = sorted([nodup[i], nodup[i + 1], nodup[i + 2]]) + a, b, c = sorted( + [nodup[i], nodup[i + 1], nodup[i + 2]], key=default_sort_key) if Point.is_collinear(a, b, c): nodup[i] = a nodup[i + 1] = None @@ -2168,9 +2172,9 @@ def medians(self): """ s = self.sides v = self.vertices - return {v[0]: Segment(s[1].midpoint, v[0]), - v[1]: Segment(s[2].midpoint, v[1]), - v[2]: Segment(s[0].midpoint, v[2])} + return {v[0]: Segment(v[0], s[1].midpoint), + v[1]: Segment(v[1], s[2].midpoint), + v[2]: Segment(v[2], s[0].midpoint)} @property def medial(self): diff --git a/sympy/integrals/tests/test_meijerint.py b/sympy/integrals/tests/test_meijerint.py index dc5461499778..62e5da03fecb 100644 --- a/sympy/integrals/tests/test_meijerint.py +++ b/sympy/integrals/tests/test_meijerint.py @@ -4,6 +4,7 @@ from sympy.integrals.meijerint import (_rewrite_single, _rewrite1, meijerint_indefinite, _inflate_g, _create_lookup_table, meijerint_definite, meijerint_inversion) +from sympy.utilities import default_sort_key from sympy.utilities.randtest import (test_numerically, random_complex_number as randcplx) from sympy.abc import x, y, a, b, c, d, s, t, z @@ -280,7 +281,7 @@ def test_lookup_table(): table = {} _create_lookup_table(table) for _, l in sorted(table.items()): - for formula, terms, cond, hint in sorted(l): + for formula, terms, cond, hint in sorted(l, key=default_sort_key): subs = {} for a in list(formula.free_symbols) + [z_dummy]: if hasattr(a, 'properties') and a.properties: diff --git a/sympy/integrals/transforms.py b/sympy/integrals/transforms.py index 7b3bcbd04f19..e3f2dbd6eb29 100644 --- a/sympy/integrals/transforms.py +++ b/sympy/integrals/transforms.py @@ -1,16 +1,18 @@ """ Integral Transforms """ + from __future__ import print_function, division -from sympy.integrals import integrate, Integral +from sympy.core import S +from sympy.core.compatibility import reduce +from sympy.core.function import Function from sympy.core.numbers import oo from sympy.core.symbol import Dummy -from sympy.core.function import Function +from sympy.integrals import integrate, Integral +from sympy.integrals.meijerint import _dummy from sympy.logic.boolalg import to_cnf, conjuncts, disjuncts, Or, And from sympy.simplify import simplify -from sympy.core import S -from sympy.core.compatibility import reduce +from sympy.utilities import default_sort_key -from sympy.integrals.meijerint import _dummy ########################################################################## # Helpers / Utilities @@ -688,10 +690,10 @@ def linear_arg(arg): arg = Mul(*exponentials) # for testability, sort the arguments - an.sort() - ap.sort() - bm.sort() - bq.sort() + an.sort(key=default_sort_key) + ap.sort(key=default_sort_key) + bm.sort(key=default_sort_key) + bq.sort(key=default_sort_key) return (an, ap), (bm, bq), arg, exponent, fac diff --git a/sympy/physics/quantum/gate.py b/sympy/physics/quantum/gate.py index 0aaa7e903819..5df2d775e107 100644 --- a/sympy/physics/quantum/gate.py +++ b/sympy/physics/quantum/gate.py @@ -35,6 +35,8 @@ from sympy.matrices.matrices import MatrixBase +from sympy.utilities import default_sort_key + __all__ = [ 'Gate', 'CGate', @@ -75,6 +77,18 @@ _normalized = True +def _max(*args, **kwargs): + if "key" not in kwargs: + kwargs["key"] = default_sort_key + return max(*args, **kwargs) + + +def _min(*args, **kwargs): + if "key" not in kwargs: + kwargs["key"] = default_sort_key + return min(*args, **kwargs) + + def normalized(normalize): """Set flag controlling normalization of Hadamard gates by 1/sqrt(2). @@ -140,7 +154,7 @@ def _eval_args(cls, args): @classmethod def _eval_hilbert_space(cls, args): """This returns the smallest possible Hilbert space.""" - return ComplexSpace(2)**(max(args) + 1) + return ComplexSpace(2)**(_max(args) + 1) #------------------------------------------------------------------------- # Properties @@ -158,7 +172,7 @@ def nqubits(self): @property def min_qubits(self): """The minimum number of qubits this gate needs to act on.""" - return max(self.targets) + 1 + return _max(self.targets) + 1 @property def targets(self): @@ -332,7 +346,7 @@ def _eval_args(cls, args): @classmethod def _eval_hilbert_space(cls, args): """This returns the smallest possible Hilbert space.""" - return ComplexSpace(2)**max(max(args[0]) + 1, args[1].min_qubits) + return ComplexSpace(2)**_max(_max(args[0]) + 1, args[1].min_qubits) #------------------------------------------------------------------------- # Properties @@ -350,7 +364,7 @@ def nqubits(self): @property def min_qubits(self): """The minimum number of qubits this gate needs to act on.""" - return max(max(self.controls), max(self.targets)) + 1 + return _max(_max(self.controls), _max(self.targets)) + 1 @property def targets(self): @@ -427,8 +441,8 @@ def plot_gate(self, circ_plot, gate_idx): Plot the controlled gate. If *simplify_cgate* is true, simplify C-X and C-Z gates into their more familiar forms. """ - min_wire = int(min(chain(self.controls, self.targets))) - max_wire = int(max(chain(self.controls, self.targets))) + min_wire = int(_min(chain(self.controls, self.targets))) + max_wire = int(_max(chain(self.controls, self.targets))) circ_plot.control_line(gate_idx, min_wire, max_wire) for c in self.controls: circ_plot.control_point(gate_idx, int(c)) @@ -514,7 +528,7 @@ def _eval_args(cls, args): @classmethod def _eval_hilbert_space(cls, args): """This returns the smallest possible Hilbert space.""" - return ComplexSpace(2)**(max(args[0]) + 1) + return ComplexSpace(2)**(_max(args[0]) + 1) #------------------------------------------------------------------------- # Properties @@ -869,7 +883,7 @@ def _eval_args(cls, args): @classmethod def _eval_hilbert_space(cls, args): """This returns the smallest possible Hilbert space.""" - return ComplexSpace(2)**(max(args) + 1) + return ComplexSpace(2)**(_max(args) + 1) #------------------------------------------------------------------------- # Properties @@ -878,7 +892,7 @@ def _eval_hilbert_space(cls, args): @property def min_qubits(self): """The minimum number of qubits this gate needs to act on.""" - return max(self.label) + 1 + return _max(self.label) + 1 @property def targets(self): @@ -973,8 +987,8 @@ def decompose(self, **options): return g1*g2*g1 def plot_gate(self, circ_plot, gate_idx): - min_wire = int(min(self.targets)) - max_wire = int(max(self.targets)) + min_wire = int(_min(self.targets)) + max_wire = int(_max(self.targets)) circ_plot.control_line(gate_idx, min_wire, max_wire) circ_plot.swap_point(gate_idx, min_wire) circ_plot.swap_point(gate_idx, max_wire) @@ -988,8 +1002,8 @@ def _represent_ZGate(self, basis, **options): """ format = options.get('format', 'sympy') targets = [int(t) for t in self.targets] - min_target = min(targets) - max_target = max(targets) + min_target = _min(targets) + max_target = _max(targets) nqubits = options.get('nqubits', self.min_qubits) op01 = matrix_cache.get_matrix('op01', format) diff --git a/sympy/physics/secondquant.py b/sympy/physics/secondquant.py index a6ef02ae6635..f002108679d2 100644 --- a/sympy/physics/secondquant.py +++ b/sympy/physics/secondquant.py @@ -2937,11 +2937,8 @@ class PermutationOperator(Expr): is_commutative = True def __new__(cls, i, j): - i, j = list(map(sympify, (i, j))) - if (i > j): - obj = Basic.__new__(cls, j, i) - else: - obj = Basic.__new__(cls, i, j) + i, j = sorted(map(sympify, (i, j)), key=default_sort_key) + obj = Basic.__new__(cls, i, j) return obj def get_permuted(self, expr): @@ -3018,10 +3015,7 @@ def _get_indices(expr, ind): def _choose_one_to_keep(a, b, ind): # we keep the one where indices in ind are in order ind[0] < ind[1] - if _get_indices(a, ind) < _get_indices(b, ind): - return a - else: - return b + return min(a, b, key=lambda x: default_sort_key(_get_indices(x, ind))) expr = expr.expand() if isinstance(expr, Add): diff --git a/sympy/polys/domains/domain.py b/sympy/polys/domains/domain.py index 4eab3db945dc..9d97d2ffbfa6 100644 --- a/sympy/polys/domains/domain.py +++ b/sympy/polys/domains/domain.py @@ -11,7 +11,7 @@ from sympy.polys.orderings import lex from sympy.polys.polyutils import _unify_gens -from sympy.utilities import public +from sympy.utilities import default_sort_key, public @public class Domain(object): @@ -316,7 +316,7 @@ def mkinexact(cls, K0, K1): return K1 if K0.is_FiniteField and K1.is_FiniteField: - return K0.__class__(max(K0.mod, K1.mod)) + return K0.__class__(max(K0.mod, K1.mod, key=default_sort_key)) from sympy.polys.domains import EX return EX diff --git a/sympy/polys/polyroots.py b/sympy/polys/polyroots.py index ba6ddd0a35a6..ba36dd1bae7e 100644 --- a/sympy/polys/polyroots.py +++ b/sympy/polys/polyroots.py @@ -543,7 +543,7 @@ def roots_quintic(f): result_n = [] for root in result: result_n.append(root.n(5)) - result_n = sorted(result_n) + result_n = sorted(result_n, key=default_sort_key) prev_entry = None for r in result_n: diff --git a/sympy/simplify/hyperexpand.py b/sympy/simplify/hyperexpand.py index 5b921ae2b8b0..8958c491c536 100644 --- a/sympy/simplify/hyperexpand.py +++ b/sympy/simplify/hyperexpand.py @@ -527,7 +527,7 @@ def build_invariants(self): def tr(bucket): bucket = list(bucket.items()) if not any(isinstance(x[0], Mod) for x in bucket): - bucket.sort(key=lambda x: x[0]) + bucket.sort(key=lambda x: default_sort_key(x[0])) bucket = tuple([(mod, len(values)) for mod, values in bucket if values]) return bucket @@ -1448,7 +1448,7 @@ def reduce_order(func): (Hyper_Function((2,), (3,)), []) """ - nap, nbq, operators = _reduce_order(func.ap, func.bq, ReduceOrder, lambda x: x) + nap, nbq, operators = _reduce_order(func.ap, func.bq, ReduceOrder, default_sort_key) return Hyper_Function(Tuple(*nap), Tuple(*nbq)), operators @@ -1476,9 +1476,9 @@ def reduce_order_meijer(func): """ nan, nbq, ops1 = _reduce_order(func.an, func.bq, ReduceOrder.meijer_plus, - lambda x: -x) + lambda x: default_sort_key(-x)) nbm, nap, ops2 = _reduce_order(func.bm, func.ap, ReduceOrder.meijer_minus, - lambda x: x) + default_sort_key) return G_Function(nan, nap, nbm, nbq), ops1 + ops2 diff --git a/sympy/simplify/sqrtdenest.py b/sympy/simplify/sqrtdenest.py index 610b9032a0cc..be84863f41e3 100644 --- a/sympy/simplify/sqrtdenest.py +++ b/sympy/simplify/sqrtdenest.py @@ -41,7 +41,7 @@ def sqrt_depth(p): if p.is_Atom: return 0 elif p.is_Add or p.is_Mul: - return max([sqrt_depth(x) for x in p.args]) + return max([sqrt_depth(x) for x in p.args], key=default_sort_key) elif is_sqrt(p): return sqrt_depth(p.base) + 1 else: @@ -164,7 +164,7 @@ def _sqrt_match(p): # so when the max is selected, it will be the largest arg having a # given depth v = [(sqrt_depth(x), x, i) for i, x in enumerate(pargs)] - nmax = max(v) + nmax = max(v, key=default_sort_key) if nmax[0] == 0: res = [] else: diff --git a/sympy/solvers/diophantine.py b/sympy/solvers/diophantine.py index a18332316303..9cc10452b977 100644 --- a/sympy/solvers/diophantine.py +++ b/sympy/solvers/diophantine.py @@ -5,6 +5,7 @@ from sympy.simplify.simplify import rad_rationalize from sympy.ntheory.modular import solve_congruence +from sympy.utilities import default_sort_key def diop_solve(eq, param=symbols("t", Integer=True)): @@ -75,7 +76,7 @@ def classify_diop(eq): """ eq = eq.expand(force=True) var = list(eq.free_symbols) - var.sort() + var.sort(key=default_sort_key) coeff = {} diop_type = None diff --git a/sympy/solvers/ode.py b/sympy/solvers/ode.py index 7e87cb095398..cdcc79d78381 100644 --- a/sympy/solvers/ode.py +++ b/sympy/solvers/ode.py @@ -1634,7 +1634,7 @@ def _take(i): # else return ``i`` c = i.free_symbols & con_set if c: - return min(c) + return min(c, key=str) return i if not (expr.has(x) and x in expr.free_symbols): diff --git a/sympy/solvers/polysys.py b/sympy/solvers/polysys.py index 380edbd86026..14d5bfb2a56d 100644 --- a/sympy/solvers/polysys.py +++ b/sympy/solvers/polysys.py @@ -2,13 +2,13 @@ from __future__ import print_function, division +from sympy.core import S from sympy.polys import Poly, groebner, roots from sympy.polys.polytools import parallel_poly_from_expr from sympy.polys.polyerrors import (ComputationFailed, PolificationFailed, CoercionFailed) -from sympy.utilities import postfixes from sympy.simplify import rcollect -from sympy.core import S +from sympy.utilities import default_sort_key, postfixes class SolveFailed(Exception): @@ -95,7 +95,7 @@ def solve_biquadratic(f, g, opt): solution = (p_root.subs(y, q_root), q_root) solutions.append(solution) - return sorted(solutions) + return sorted(solutions, key=default_sort_key) def solve_generic(polys, opt): @@ -230,7 +230,7 @@ def _solve_reduced_system(system, gens, entry=False): raise NotImplementedError if result is not None: - return sorted(result) + return sorted(result, key=default_sort_key) else: return None @@ -316,4 +316,4 @@ def solve_triangulated(polys, *gens, **args): for i, (solution, _) in enumerate(solutions): solutions[i] = solution - return sorted(solutions) + return sorted(solutions, key=default_sort_key) diff --git a/sympy/solvers/tests/test_polysys.py b/sympy/solvers/tests/test_polysys.py index eef1e5234da6..4417b1a1e5ea 100644 --- a/sympy/solvers/tests/test_polysys.py +++ b/sympy/solvers/tests/test_polysys.py @@ -21,16 +21,16 @@ def test_solve_poly_system(): [(0, 0), (2, -sqrt(2)), (2, sqrt(2))] assert solve_poly_system([y - x**2, y + x**2 + 1], x, y) == \ - [(I*sqrt(S.Half), -S.Half), (-I*sqrt(S.Half), -S.Half)] + [(-I*sqrt(S.Half), -S.Half), (I*sqrt(S.Half), -S.Half)] f_1 = x**2 + y + z - 1 f_2 = x + y**2 + z - 1 f_3 = x + y + z**2 - 1 - a, b = -sqrt(2) - 1, sqrt(2) - 1 + a, b = sqrt(2) - 1, -sqrt(2) - 1 assert solve_poly_system([f_1, f_2, f_3], x, y, z) == \ - [(a, a, a), (0, 0, 1), (0, 1, 0), (b, b, b), (1, 0, 0)] + [(0, 0, 1), (0, 1, 0), (1, 0, 0), (a, a, a), (b, b, b)] solution = [(1, -1), (1, 1)] @@ -52,15 +52,15 @@ def test_solve_biquadratic(): f_2 = (x - 2)**2 + (y - 2)**2 - r**2 assert solve_poly_system([f_1, f_2], x, y) == \ - [(S(3)/2 + sqrt(-1 + 2*r**2)/2, S(3)/2 - sqrt(-1 + 2*r**2)/2), - (S(3)/2 - sqrt(-1 + 2*r**2)/2, S(3)/2 + sqrt(-1 + 2*r**2)/2)] + [(S(3)/2 - sqrt(-1 + 2*r**2)/2, S(3)/2 + sqrt(-1 + 2*r**2)/2), + (S(3)/2 + sqrt(-1 + 2*r**2)/2, S(3)/2 - sqrt(-1 + 2*r**2)/2)] f_1 = (x - 1)**2 + (y - 2)**2 - r**2 f_2 = (x - 1)**2 + (y - 1)**2 - r**2 assert solve_poly_system([f_1, f_2], x, y) == \ - [(1 + sqrt(((2*r - 1)*(2*r + 1)))/2, S(3)/2), - (1 - sqrt(((2*r - 1)*(2*r + 1)))/2, S(3)/2)] + [(1 - sqrt(((2*r - 1)*(2*r + 1)))/2, S(3)/2), + (1 + sqrt(((2*r - 1)*(2*r + 1)))/2, S(3)/2)] query = lambda expr: expr.is_Pow and expr.exp is S.Half @@ -86,7 +86,7 @@ def test_solve_triangualted(): f_2 = x + y**2 + z - 1 f_3 = x + y + z**2 - 1 - a, b = -sqrt(2) - 1, sqrt(2) - 1 + a, b = sqrt(2) - 1, -sqrt(2) - 1 assert solve_triangulated([f_1, f_2, f_3], x, y, z) == \ [(0, 0, 1), (0, 1, 0), (1, 0, 0)] @@ -94,11 +94,12 @@ def test_solve_triangualted(): dom = QQ.algebraic_field(sqrt(2)) assert solve_triangulated([f_1, f_2, f_3], x, y, z, domain=dom) == \ - [(a, a, a), (0, 0, 1), (0, 1, 0), (b, b, b), (1, 0, 0)] + [(0, 0, 1), (0, 1, 0), (1, 0, 0), (a, a, a), (b, b, b)] + def test_solve_issue_3686(): roots = solve_poly_system([((x - 5)**2/250000 + (y - S(5)/10)**2/250000) - 1, x], x, y) - assert roots == [(0, -15*sqrt(1111) + S(1)/2), (0, S(1)/2 + 15*sqrt(1111))] + assert roots == [(0, S(1)/2 + 15*sqrt(1111)), (0, S(1)/2 - 15*sqrt(1111))] roots = solve_poly_system([((x - 5)**2/250000 + (y - 5.0/10)**2/250000) - 1, x], x, y) # TODO: does this really have to be so complicated?! diff --git a/sympy/statistics/distributions.py b/sympy/statistics/distributions.py index 871835ccd9f8..44a4f2028c0c 100644 --- a/sympy/statistics/distributions.py +++ b/sympy/statistics/distributions.py @@ -1,9 +1,11 @@ from __future__ import print_function, division from sympy.core import sympify, Lambda, Dummy, Integer, Rational, oo, Float, pi +from sympy.core.compatibility import xrange from sympy.functions import sqrt, exp, erf from sympy.printing import sstr -from sympy.core.compatibility import xrange +from sympy.utilities import default_sort_key + import random @@ -34,7 +36,7 @@ class Sample(tuple): """ def __new__(cls, sample): - s = tuple.__new__(cls, sorted(sample)) + s = tuple.__new__(cls, sorted(sample, key=default_sort_key)) s.mean = mean = sum(s) / Integer(len(s)) s.variance = sum([(x - mean)**2 for x in s]) / Integer(len(s)) s.stddev = sqrt(s.variance) diff --git a/sympy/unify/rewrite.py b/sympy/unify/rewrite.py index 74600db74cc9..d44eb82c3f1e 100644 --- a/sympy/unify/rewrite.py +++ b/sympy/unify/rewrite.py @@ -16,8 +16,9 @@ def rewriterule(source, target, variables=(), condition=None, assume=None): >>> from sympy.abc import w, x, y, z >>> from sympy.unify.rewrite import rewriterule + >>> from sympy.utilities import default_sort_key >>> rl = rewriterule(x + y, x**y, [x, y]) - >>> sorted(rl(z + 3)) + >>> sorted(rl(z + 3), key=default_sort_key) [3**z, z**3] Use ``condition`` to specify additional requirements. Inputs are taken in diff --git a/sympy/utilities/iterables.py b/sympy/utilities/iterables.py index d7bc58830941..a6055ebffa8e 100644 --- a/sympy/utilities/iterables.py +++ b/sympy/utilities/iterables.py @@ -1809,14 +1809,14 @@ def minlex(seq, directed=True, is_set=False, small=None): is_str = isinstance(seq, str) seq = list(seq) if small is None: - small = min(seq) + small = min(seq, key=default_sort_key) if is_set: i = seq.index(small) if not directed: n = len(seq) p = (i + 1) % n m = (i - 1) % n - if seq[p] > seq[m]: + if default_sort_key(seq[p]) > default_sort_key(seq[m]): seq = list(reversed(seq)) i = n - i - 1 if i: From b6ea43b3317464ad40d01bb6da55ae9276302b86 Mon Sep 17 00:00:00 2001 From: Julien Rioux Date: Fri, 10 May 2013 18:25:46 +0200 Subject: [PATCH 6/9] Don't rely on the truth value of Rational. --- sympy/concrete/summations.py | 4 ++-- sympy/core/mod.py | 2 +- sympy/core/mul.py | 2 +- sympy/core/power.py | 6 +++--- sympy/functions/elementary/exponential.py | 2 +- sympy/functions/elementary/piecewise.py | 3 ++- sympy/functions/special/gamma_functions.py | 8 ++++---- sympy/functions/special/hyper.py | 6 +++--- sympy/functions/special/polynomials.py | 14 ++++++++------ .../special/tests/test_spec_polynomials.py | 2 +- sympy/geometry/line.py | 4 ++-- sympy/geometry/polygon.py | 6 +++--- sympy/integrals/meijerint.py | 8 ++++---- sympy/integrals/rationaltools.py | 2 +- sympy/integrals/rde.py | 2 +- sympy/matrices/expressions/blockmatrix.py | 4 ++-- sympy/matrices/expressions/matexpr.py | 3 ++- sympy/matrices/expressions/slice.py | 6 +++--- sympy/physics/quantum/state.py | 2 +- sympy/polys/polyroots.py | 2 +- sympy/simplify/fu.py | 6 +++--- sympy/simplify/hyperexpand.py | 4 ++-- sympy/solvers/solvers.py | 2 +- 23 files changed, 52 insertions(+), 48 deletions(-) diff --git a/sympy/concrete/summations.py b/sympy/concrete/summations.py index 297465252350..9b7914dd5b17 100644 --- a/sympy/concrete/summations.py +++ b/sympy/concrete/summations.py @@ -243,7 +243,7 @@ def doit(self, **hints): for n, limit in enumerate(self.limits): i, a, b = limit dif = b - a - if dif.is_integer and dif < 0: + if dif.is_integer and (dif < 0) is True: a, b = b + 1, a - 1 f = -f @@ -361,7 +361,7 @@ def euler_maclaurin(self, m=0, n=0, eps=0, eval_integral=True): f = self.function assert len(self.limits) == 1 i, a, b = self.limits[0] - if a > b: + if (a > b) is True: a, b = b + 1, a - 1 f = -f s = S.Zero diff --git a/sympy/core/mod.py b/sympy/core/mod.py index 83116fda34c8..d258e99b1d0b 100644 --- a/sympy/core/mod.py +++ b/sympy/core/mod.py @@ -51,7 +51,7 @@ def doit(p, q): else: if type(d) is int: rv = p - d*q - if rv*q < 0: + if (rv*q < 0) is True: rv += q return rv diff --git a/sympy/core/mul.py b/sympy/core/mul.py index 1a634f134515..f4c79ee2189c 100644 --- a/sympy/core/mul.py +++ b/sympy/core/mul.py @@ -177,7 +177,7 @@ def flatten(cls, seq): if b.is_Rational: a, b = b, a assert not a is S.One - if a and a.is_Rational: + if not a.is_zero and a.is_Rational: r, b = b.as_coeff_Mul() if b.is_Add: if r is not S.One: # 2-arg hack diff --git a/sympy/core/power.py b/sympy/core/power.py index a12dbad94c6b..1ee12cd6aeca 100644 --- a/sympy/core/power.py +++ b/sympy/core/power.py @@ -153,7 +153,7 @@ def _eval_power(self, other): e.is_real is False and smallarg is False): return -self.func(b, e*other) if (other.is_integer or - e.is_real and (b_nneg or abs(e) < 1) or + e.is_real and (b_nneg or (abs(e) < 1) is True) or e.is_real is False and smallarg is True or b.is_polar): return self.func(b, e*other) @@ -689,7 +689,7 @@ def _eval_evalf(self, prec): base = base._evalf(prec) if not exp.is_Integer: exp = exp._evalf(prec) - if exp < 0 and base.is_number and base.is_real is False: + if (exp < 0) is True and base.is_number and base.is_real is False: base = base.conjugate() / (base * base.conjugate())._evalf(prec) exp = -exp return self.func(base, exp).expand() @@ -702,7 +702,7 @@ def _eval_is_polynomial(self, syms): if self.base.has(*syms): return self.base._eval_is_polynomial(syms) and \ self.exp.is_Integer and \ - self.exp >= 0 + (self.exp >= 0) is True else: return True diff --git a/sympy/functions/elementary/exponential.py b/sympy/functions/elementary/exponential.py index af4902ca671b..6ae6dd57affb 100644 --- a/sympy/functions/elementary/exponential.py +++ b/sympy/functions/elementary/exponential.py @@ -114,7 +114,7 @@ def _eval_power(b, e): if be.is_polar: return rv besmall = abs(be) <= S.Pi - if besmall: + if besmall is True: return rv elif besmall is False and e.is_Rational and e.q == 2: return -rv diff --git a/sympy/functions/elementary/piecewise.py b/sympy/functions/elementary/piecewise.py index adc8e7ed04a3..32d6a48786b4 100644 --- a/sympy/functions/elementary/piecewise.py +++ b/sympy/functions/elementary/piecewise.py @@ -357,7 +357,8 @@ def _sort_expr_cond(self, sym, a, b, targetcond=None): else: int_expr[n][1] = Min(lower, int_expr[n][1]) elif len(int_expr[n][1].free_symbols) and \ - lower < int_expr[n][0] is not True: + (lower >= int_expr[n][0]) is not True and \ + (int_expr[n][1] == Min(lower, upper)) is not True: upper = Min(upper, int_expr[n][0]) elif self.__eval_cond(upper > int_expr[n][0]) and \ self.__eval_cond(upper <= int_expr[n][1]): diff --git a/sympy/functions/special/gamma_functions.py b/sympy/functions/special/gamma_functions.py index 619924325893..1d77a0cc03d5 100644 --- a/sympy/functions/special/gamma_functions.py +++ b/sympy/functions/special/gamma_functions.py @@ -343,11 +343,11 @@ def eval(cls, a, z): # We extract branching information here. C/f lowergamma. nx, n = z.extract_branch_factor() - if a.is_integer and a > 0: + if a.is_integer and (a > 0) is True: nx = unpolarify(z) if z != nx: return uppergamma(a, nx) - elif a.is_integer and a <= 0: + elif a.is_integer and (a <= 0) is True: if n != 0: return -2*pi*I*n*(-1)**(-a)/factorial(-a) + uppergamma(a, nx) elif n != 0: @@ -428,11 +428,11 @@ def fdiff(self, argindex=2): raise ArgumentIndexError(self, argindex) def _eval_is_positive(self): - if self.args[1].is_positive and self.args[0] > 0: + if self.args[1].is_positive and (self.args[0] > 0) is True: return self.args[0].is_odd def _eval_is_negative(self): - if self.args[1].is_positive and self.args[0] > 0: + if self.args[1].is_positive and (self.args[0] > 0) is True: return self.args[0].is_even def _eval_is_real(self): diff --git a/sympy/functions/special/hyper.py b/sympy/functions/special/hyper.py index bbb0f90ded0a..bd989bab723f 100644 --- a/sympy/functions/special/hyper.py +++ b/sympy/functions/special/hyper.py @@ -254,9 +254,9 @@ def radius_of_convergence(self): >>> hyper((1, 2), (3, 4), z).radius_of_convergence oo """ - if any(a.is_integer and a <= 0 for a in self.ap + self.bq): - aints = [a for a in self.ap if a.is_Integer and a <= 0] - bints = [a for a in self.bq if a.is_Integer and a <= 0] + if any(a.is_integer and (a <= 0) is True for a in self.ap + self.bq): + aints = [a for a in self.ap if a.is_Integer and (a <= 0) is True] + bints = [a for a in self.bq if a.is_Integer and (a <= 0) is True] if len(aints) < len(bints): return S(0) popped = False diff --git a/sympy/functions/special/polynomials.py b/sympy/functions/special/polynomials.py index 9cd73f55093d..de6de2fd9e74 100644 --- a/sympy/functions/special/polynomials.py +++ b/sympy/functions/special/polynomials.py @@ -352,13 +352,13 @@ def eval(cls, n, a, x): if not n.is_Number: # Handle this before the general sign extraction rule if x == S.NegativeOne: - if C.re(a) > S.Half: + if (C.re(a) > S.Half) is True: return S.ComplexInfinity else: # No sec function available yet #return (C.cos(S.Pi*(a+n)) * C.sec(S.Pi*a) * C.gamma(2*a+n) / # (C.gamma(2*a) * C.gamma(n+1))) - return cls + return None # Symbolic result C^a_n(x) # C^a_n(-x) ---> (-1)**n * C^a_n(x) @@ -670,8 +670,9 @@ class chebyshevt_root(Function): @classmethod def eval(cls, n, k): - if not 0 <= k < n: - raise ValueError("must have 0 <= k < n") + if not ((0 <= k) is (k < n) is True): + raise ValueError("must have 0 <= k < n, " + "got k = %s and n = %s" % (k, n)) return C.cos(S.Pi*(2*k + 1)/(2*n)) @@ -710,8 +711,9 @@ class chebyshevu_root(Function): @classmethod def eval(cls, n, k): - if not 0 <= k < n: - raise ValueError("must have 0 <= k < n") + if not ((0 <= k) is (k < n) is True): + raise ValueError("must have 0 <= k < n, " + "got k = %s and n = %s" % (k, n)) return C.cos(S.Pi*(k + 1)/(n + 1)) #---------------------------------------------------------------------------- diff --git a/sympy/functions/special/tests/test_spec_polynomials.py b/sympy/functions/special/tests/test_spec_polynomials.py index a3c009ca7dd9..e81ccb4453e2 100644 --- a/sympy/functions/special/tests/test_spec_polynomials.py +++ b/sympy/functions/special/tests/test_spec_polynomials.py @@ -75,7 +75,7 @@ def test_gegenbauer(): gamma(a + n/2)/(gamma(a)*gamma(-n/2 + S(1)/2)*gamma(n + 1)) assert gegenbauer(n, a, 1) == gamma(2*a + n)/(gamma(2*a)*gamma(n + 1)) - assert gegenbauer(n, a, -1) == zoo + assert gegenbauer(n, Rational(3, 4), -1) == zoo m = Symbol("m", positive=True) assert gegenbauer(m, a, oo) == oo*RisingFactorial(a, m) diff --git a/sympy/geometry/line.py b/sympy/geometry/line.py index 333195ae5405..9ead67d015fe 100644 --- a/sympy/geometry/line.py +++ b/sympy/geometry/line.py @@ -1419,9 +1419,9 @@ def __new__(cls, p1, p2, **kwargs): p2 = Point(p2) if p1 == p2: return Point(p1) - if p1.x > p2.x: + if (p1.x > p2.x) is True: p1, p2 = p2, p1 - elif p1.x == p2.x and p1.y > p2.y: + elif (p1.x == p2.x) is (p1.y > p2.y) is True: p1, p2 = p2, p1 return LinearEntity.__new__(cls, p1, p2, **kwargs) diff --git a/sympy/geometry/polygon.py b/sympy/geometry/polygon.py index fe7ca8a8d1b2..99c5db791c78 100644 --- a/sympy/geometry/polygon.py +++ b/sympy/geometry/polygon.py @@ -599,7 +599,7 @@ def arbitrary_point(self, parameter='t'): pt = s.arbitrary_point(parameter).subs( t, (t - perim_fraction_start)/side_perim_fraction) sides.append( - (pt, (perim_fraction_start <= t < perim_fraction_end))) + (pt, (And(perim_fraction_start <= t, t < perim_fraction_end)))) perim_fraction_start = perim_fraction_end return Piecewise(*sides) @@ -843,7 +843,7 @@ def _do_poly_distance(self, e2): e2_angle = pi - support_line.angle_between(Line( e2_current, e2_next)) - if e1_angle < e2_angle: + if (e1_angle < e2_angle) is True: support_line = Line(e1_current, e1_next) e1_segment = Segment(e1_current, e1_next) min_dist_current = e1_segment.distance(e2_current) @@ -857,7 +857,7 @@ def _do_poly_distance(self, e2): else: e1_current = e1_next e1_next = e1_connections[e1_next][1] - elif e1_angle > e2_angle: + elif (e1_angle > e2_angle) is True: support_line = Line(e2_next, e2_current) e2_segment = Segment(e2_current, e2_next) min_dist_current = e2_segment.distance(e1_current) diff --git a/sympy/integrals/meijerint.py b/sympy/integrals/meijerint.py index 989ca2d0a990..b14bdeb50729 100644 --- a/sympy/integrals/meijerint.py +++ b/sympy/integrals/meijerint.py @@ -879,10 +879,10 @@ def pb(g): _, s = _get_coeff_exp(po, x) _, b1 = _get_coeff_exp(g1.argument, x) _, b2 = _get_coeff_exp(g2.argument, x) - if b1 < 0: + if (b1 < 0) is True: b1 = -b1 g1 = _flip_g(g1) - if b2 < 0: + if (b2 < 0) is True: b2 = -b2 g2 = _flip_g(g2) if not b1.is_Rational or not b2.is_Rational: @@ -970,7 +970,7 @@ def lambda_s0(c1, c2): for a in g1.an: for b in g1.bm: diff = a - b - if diff > 0 and diff.is_integer: + if (diff > 0) is True and diff.is_integer: c1 = False tmp = [] @@ -1638,7 +1638,7 @@ def _meijerint_indefinite_1(f, x): def tr(p): return [a + rho + 1 for a in p] - if any(b.is_integer and b <= 0 for b in tr(g.bm)): + if any(b.is_integer and (b <= 0) is True for b in tr(g.bm)): r = -meijerg( tr(g.an), tr(g.aother) + [1], tr(g.bm) + [0], tr(g.bother), t) else: diff --git a/sympy/integrals/rationaltools.py b/sympy/integrals/rationaltools.py index 7206bbb56fda..1dff1f869552 100644 --- a/sympy/integrals/rationaltools.py +++ b/sympy/integrals/rationaltools.py @@ -216,7 +216,7 @@ def ratint_logpart(f, g, x, t=None): R_map[r.degree()] = r def _include_sign(c, sqf): - if c < 0: + if (c < 0) is True: h, k = sqf[0] sqf[0] = h*c, k diff --git a/sympy/integrals/rde.py b/sympy/integrals/rde.py index 941c599e40d3..37b4909efe93 100644 --- a/sympy/integrals/rde.py +++ b/sympy/integrals/rde.py @@ -374,7 +374,7 @@ def spde(a, b, c, n, DE): pow_a = 0 while True: - if n < 0: + if (n < 0) is True: if c.is_zero: return (zero, zero, 0, zero, beta) raise NonElementaryIntegralException diff --git a/sympy/matrices/expressions/blockmatrix.py b/sympy/matrices/expressions/blockmatrix.py index 842bfe902d1e..474a939dc08c 100644 --- a/sympy/matrices/expressions/blockmatrix.py +++ b/sympy/matrices/expressions/blockmatrix.py @@ -150,12 +150,12 @@ def transpose(self): def _entry(self, i, j): # Find row entry for row_block, numrows in enumerate(self.rowblocksizes): - if i < numrows: + if (i < numrows) is not False: break else: i -= numrows for col_block, numcols in enumerate(self.colblocksizes): - if j < numcols: + if (j < numcols) is not False: break else: j -= numcols diff --git a/sympy/matrices/expressions/matexpr.py b/sympy/matrices/expressions/matexpr.py index a463cc1aa2af..2c7317e7eb14 100644 --- a/sympy/matrices/expressions/matexpr.py +++ b/sympy/matrices/expressions/matexpr.py @@ -186,7 +186,8 @@ def valid_index(self, i, j): def is_valid(idx): return isinstance(idx, (int, Integer, Symbol, Expr)) return (is_valid(i) and is_valid(j) and - 0 <= i < self.rows and 0 <= j < self.cols) + (0 <= i) is not False and (i < self.rows) is not False and + (0 <= j) is not False and (j < self.cols) is not False) def __getitem__(self, key): if not isinstance(key, tuple) and isinstance(key, slice): diff --git a/sympy/matrices/expressions/slice.py b/sympy/matrices/expressions/slice.py index efac44896a39..3d026c65e9e9 100644 --- a/sympy/matrices/expressions/slice.py +++ b/sympy/matrices/expressions/slice.py @@ -19,13 +19,13 @@ def normalize(i, parentsize): start = start or 0 if stop == None: stop = parentsize - if start < 0: + if (start < 0) is True: start += parentsize - if stop < 0: + if (stop < 0) is True: stop += parentsize step = step or 1 - if (stop - start) * step < 1: + if ((stop - start) * step < 1) is True: raise IndexError() return (start, stop, step) diff --git a/sympy/physics/quantum/state.py b/sympy/physics/quantum/state.py index 3c31fafe9a8f..78984f737c68 100644 --- a/sympy/physics/quantum/state.py +++ b/sympy/physics/quantum/state.py @@ -735,7 +735,7 @@ def __call__(self, *args, **options): or upper in args[ct].free_symbols): continue - if args[ct] < lower or args[ct] > upper: + if (args[ct] < lower) is True or (args[ct] > upper) is True: return 0 ct += 1 diff --git a/sympy/polys/polyroots.py b/sympy/polys/polyroots.py index ba36dd1bae7e..973d76e25b8d 100644 --- a/sympy/polys/polyroots.py +++ b/sympy/polys/polyroots.py @@ -105,7 +105,7 @@ def roots_cubic(f): return [-aon3]*3 else: if q.is_real: - if q > 0: + if (q > 0) is True: u1 = -q**Rational(1, 3) else: u1 = (-q)**Rational(1, 3) diff --git a/sympy/simplify/fu.py b/sympy/simplify/fu.py index 21570f68d09d..c98202dc9635 100644 --- a/sympy/simplify/fu.py +++ b/sympy/simplify/fu.py @@ -426,7 +426,7 @@ def f(rv): if not isinstance(rv, C.TrigonometricFunction): return rv rv = rv.func(signsimp(rv.args[0])) - if S.Pi/4 < rv.args[0] < S.Pi/2: + if (S.Pi/4 < rv.args[0]) is (rv.args[0] < S.Pi/2) is True: fmap = {cos: sin, sin: cos, tan: cot, cot: tan, sec: csc, csc: sec} rv = fmap[rv.func](S.Pi/2 - rv.args[0]) return rv @@ -496,9 +496,9 @@ def _f(rv): if not (rv.is_Pow and rv.base.func == f): return rv - if rv.exp < 0: + if (rv.exp < 0) is True: return rv - if rv.exp > max: + if (rv.exp > max) is True: return rv if rv.exp == 2: return h(g(rv.base.args[0])**2) diff --git a/sympy/simplify/hyperexpand.py b/sympy/simplify/hyperexpand.py index 8958c491c536..206535f856d1 100644 --- a/sympy/simplify/hyperexpand.py +++ b/sympy/simplify/hyperexpand.py @@ -572,7 +572,7 @@ def _is_suitable_origin(self): """ for a in self.ap: for b in self.bq: - if (a - b).is_integer and not a < b: + if (a - b).is_integer and (a < b) is False: return False for a in self.ap: if a == 0: @@ -1370,7 +1370,7 @@ def _meijer(cls, b, a, sign): b = sympify(b) a = sympify(a) n = b - a - if n < 0 or not n.is_Integer: + if (n < 0) is True or not n.is_Integer: return None self = Operator.__new__(cls) diff --git a/sympy/solvers/solvers.py b/sympy/solvers/solvers.py index 9c553b43bc93..814ac08ad704 100644 --- a/sympy/solvers/solvers.py +++ b/sympy/solvers/solvers.py @@ -2581,7 +2581,7 @@ def _canonical(eq): # make sign canonical free = eq.free_symbols if len(free) == 1: - if eq.coeff(free.pop()**degree(eq)) < 0: + if (eq.coeff(free.pop()**degree(eq)) < 0) is True: eq = -eq elif eq.could_extract_minus_sign(): eq = -eq From abf77e567e0f7eb8afb886a1b522159212aa36d1 Mon Sep 17 00:00:00 2001 From: Julien Rioux Date: Mon, 5 Aug 2013 10:08:19 +0200 Subject: [PATCH 7/9] Fix for python 3. --- sympy/combinatorics/partitions.py | 2 +- sympy/core/relational.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sympy/combinatorics/partitions.py b/sympy/combinatorics/partitions.py index 8de0ca091914..12f27cd74bdb 100644 --- a/sympy/combinatorics/partitions.py +++ b/sympy/combinatorics/partitions.py @@ -86,7 +86,7 @@ def sort_key(self, order=None): else: members = tuple(sorted(self.members, key=lambda w: default_sort_key(w, order))) - return map(default_sort_key, (self.size, members, self.rank)) + return list(map(default_sort_key, (self.size, members, self.rank))) @property def partition(self): diff --git a/sympy/core/relational.py b/sympy/core/relational.py index 42220bf50856..0056f3410615 100644 --- a/sympy/core/relational.py +++ b/sympy/core/relational.py @@ -225,6 +225,8 @@ def _eval_simplify(self, ratio, measure): def __nonzero__(self): raise TypeError("symbolic boolean expression has no truth value.") + __bool__ = __nonzero__ + class Equality(Relational): From 4c85b3f4100b338811d70f694a842b5f6eb28c38 Mon Sep 17 00:00:00 2001 From: Julien Rioux Date: Tue, 6 Aug 2013 10:18:21 +0200 Subject: [PATCH 8/9] Test for issue 2832. --- sympy/core/tests/test_relational.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sympy/core/tests/test_relational.py b/sympy/core/tests/test_relational.py index f7fba047e07b..5b6f17e9615a 100644 --- a/sympy/core/tests/test_relational.py +++ b/sympy/core/tests/test_relational.py @@ -261,11 +261,14 @@ def test_new_relational(): raises(ValueError, lambda: Relational(x, 1, relation_type)) -@XFAIL def test_relational_bool_output(): - # XFail test for issue: # http://code.google.com/p/sympy/issues/detail?id=2832 - raises(ValueError, lambda: bool(x > 3)) + raises(TypeError, lambda: bool(x > 3)) + raises(TypeError, lambda: bool(x >= 3)) + raises(TypeError, lambda: bool(x < 3)) + raises(TypeError, lambda: bool(x <= 3)) + raises(TypeError, lambda: bool(Eq(x, 3))) + raises(TypeError, lambda: bool(Ne(x, 3))) def test_relational_logic_symbols(): From 9138eb744ccce11f1ff1c626ccae805dd374861c Mon Sep 17 00:00:00 2001 From: Julien Rioux Date: Wed, 7 Aug 2013 14:58:55 -0400 Subject: [PATCH 9/9] Edit docstring of GreaterThan. --- sympy/core/relational.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/sympy/core/relational.py b/sympy/core/relational.py index 0056f3410615..4a755e805eae 100644 --- a/sympy/core/relational.py +++ b/sympy/core/relational.py @@ -505,8 +505,9 @@ class GreaterThan(_Greater): evaluated once and the comparison can short-circuit. For example, ``1 > 2 > 3`` is evaluated by Python as ``(1 > 2) and (2 > 3)``. The ``and`` operator coerces each side into a bool, returning the object - itself when it short-circuits. Currently, the bool of the --Than - operators will give True or False arbitrarily. Thus, if we were to + itself when it short-circuits. The bool of the --Than operators + will raise TypeError on purpose, because SymPy cannot determine the + mathematical ordering of symbolic expressions. Thus, if we were to compute ``x > y > z``, with ``x``, ``y``, and ``z`` being Symbols, Python converts the statement (roughly) into these steps: @@ -514,14 +515,11 @@ class GreaterThan(_Greater): (2) (x > y) and (y > z) (3) (GreaterThanObject) and (y > z) (4) (GreaterThanObject.__nonzero__()) and (y > z) - (5) (True) and (y > z) - (6) (y > z) - (7) LessThanObject + (5) TypeError Because of the "and" added at step 2, the statement gets turned into a - weak ternary statement. If the first object evalutes __nonzero__ as - True, then the second object, (y > z) is returned. If the first object - evaluates __nonzero__ as False (step 5), then (x > y) is returned. + weak ternary statement, and the first object's __nonzero__ method will + raise TypeError. Thus, creating a chained inequality is not possible. In Python, there is no way to override the ``and`` operator, or to control how it short circuits, so it is impossible to make something