Repository: sympy/sympy

Issue:
lambdify inserts numpy after math
If you call `lambdify` without setting the `modules` argument, it defaults to `['math', 'mpmath', 'sympy']`. If numpy is available, it inserts it after `['math']`. Why does it do this? It seems that numpy is the most common usage of lambdify, so it should come first. 

Discussion:

Patch:
diff --git a/sympy/__init__.py b/sympy/__init__.py
index 01936a0045..85f6f7837b 100644
--- a/sympy/__init__.py
+++ b/sympy/__init__.py
@@ -20,8 +20,6 @@
     raise ImportError("SymPy now depends on mpmath as an external library. "
     "See http://docs.sympy.org/latest/install.html#mpmath for more information.")
 
-del mpmath
-
 from sympy.release import __version__
 
 if 'dev' in __version__:
diff --git a/sympy/concrete/summations.py b/sympy/concrete/summations.py
index 580682ce32..b1582eafb9 100644
--- a/sympy/concrete/summations.py
+++ b/sympy/concrete/summations.py
@@ -254,6 +254,8 @@ def _eval_derivative(self, x):
                 return None
             df = Derivative(f, x, evaluate=True)
             rv = self.func(df, limit)
+            if limit[0] not in df.free_symbols:
+                rv = rv.doit()
             return rv
         else:
             return NotImplementedError('Lower and upper bound expected.')
diff --git a/sympy/utilities/lambdify.py b/sympy/utilities/lambdify.py
index 2cc6034a1d..3b8bb39777 100644
--- a/sympy/utilities/lambdify.py
+++ b/sympy/utilities/lambdify.py
@@ -167,10 +167,12 @@ def lambdify(args, expr, modules=None, printer=None, use_imps=True,
     """
     Returns a lambda function for fast calculation of numerical values.
 
-    If not specified differently by the user, SymPy functions are replaced as
-    far as possible by either python-math, numpy (if available) or mpmath
-    functions - exactly in this order. To change this behavior, the "modules"
-    argument can be used. It accepts:
+    If not specified differently by the user, ``modules`` defaults to
+    ``["numpy"]`` if NumPy is installed, and ``["math", "mpmath", "sympy"]``
+    if it isn't, that is, SymPy functions are replaced as far as possible by
+    either ``numpy`` functions if available, and Python's standard library
+    ``math``, or ``mpmath`` functions otherwise. To change this behavior, the
+    "modules" argument can be used. It accepts:
 
      - the strings "math", "mpmath", "numpy", "numexpr", "sympy"
      - any modules (e.g. math)
@@ -301,6 +303,7 @@ def lambdify(args, expr, modules=None, printer=None, use_imps=True,
 
     ``lambdify`` always prefers ``_imp_`` implementations to implementations
     in other namespaces, unless the ``use_imps`` input parameter is False.
+
     """
     from sympy.core.symbol import Symbol
     from sympy.utilities.iterables import flatten
@@ -309,18 +312,16 @@ def lambdify(args, expr, modules=None, printer=None, use_imps=True,
     module_provided = True
     if modules is None:
         module_provided = False
-        # Use either numpy (if available) or python.math where possible.
-        # XXX: This leads to different behaviour on different systems and
-        #      might be the reason for irreproducible errors.
-        modules = ["math", "mpmath", "sympy"]
 
-        #Attempt to import numpy
         try:
             _import("numpy")
         except ImportError:
-            pass
+            # Use either numpy (if available) or python.math where possible.
+            # XXX: This leads to different behaviour on different systems and
+            #      might be the reason for irreproducible errors.
+            modules = ["math", "mpmath", "sympy"]
         else:
-            modules.insert(1, "numpy")
+            modules = ["numpy"]
 
     # Get the needed namespaces.
     namespaces = []


Test patch:
diff --git a/sympy/concrete/tests/test_sums_products.py b/sympy/concrete/tests/test_sums_products.py
index 5d277cd414..c0d0ade9e7 100644
--- a/sympy/concrete/tests/test_sums_products.py
+++ b/sympy/concrete/tests/test_sums_products.py
@@ -588,7 +588,7 @@ def test_eval_diff():
     assert Sum(x*y, (y, 1, 2)).diff(x) == Sum(y, (y, 1, 2))
     e = Sum(x*y, (x, 1, a))
     assert e.diff(a) == Derivative(e, a)
-    assert Sum(x*y, (x, 1, 3), (a, 2, 5)).diff(y).doit() == \
+    assert Sum(x*y, (x, 1, 3), (a, 2, 5)).diff(y) == \
         Sum(x*y, (x, 1, 3), (a, 2, 5)).doit().diff(y) == 24
 
 
@@ -940,15 +940,6 @@ def test_convergent_failing():
     assert Sum(sin(2*n)/n, (n, 1, oo)).is_convergent() is S.true
 
 
-def test_issue_6966():
-    i, k, m = symbols('i k m', integer=True)
-    z_i, q_i = symbols('z_i q_i')
-    a_k = Sum(-q_i*z_i/k,(i,1,m))
-    b_k = a_k.diff(z_i)
-    assert isinstance(b_k, Sum)
-    assert b_k == Sum(-q_i/k,(i,1,m))
-
-
 def test_issue_10156():
     cx = Sum(2*y**2*x, (x, 1,3))
     e = 2*y*Sum(2*cx*x**2, (x, 1, 9))
diff --git a/sympy/tensor/tests/test_indexed.py b/sympy/tensor/tests/test_indexed.py
index e18868adce..12750fb66e 100644
--- a/sympy/tensor/tests/test_indexed.py
+++ b/sympy/tensor/tests/test_indexed.py
@@ -222,7 +222,8 @@ def test_differentiation():
     assert Sum(expr.diff(hj), (i, -oo, oo)) == Sum(2*KroneckerDelta(i, j), (i, -oo, oo))
     assert Sum(expr, (i, -oo, oo)).diff(hj).doit() == 2
 
-    assert Sum(expr.diff(hi), (i, -oo, oo)).doit() == Sum(2, (i, -oo, oo)).doit()
+    assert Sum(expr, (i, -oo, oo)).diff(hi) == oo
+    assert Sum(expr.diff(hi), (i, -oo, oo)) == Sum(2, (i, -oo, oo))
     assert Sum(expr, (i, -oo, oo)).diff(hi).doit() == oo
 
     expr = a * hj * hj / S(2)
@@ -257,7 +258,7 @@ def test_differentiation():
     assert Sum(a*h[m], (m, -oo, oo)).diff(h[n]) == Sum(a*KroneckerDelta(m, n), (m, -oo, oo))
     assert Sum(a*h[m], (m, -oo, oo)).diff(h[n]).doit() == a
     assert Sum(a*h[m], (n, -oo, oo)).diff(h[n]) == Sum(a*KroneckerDelta(m, n), (n, -oo, oo))
-    assert Sum(a*h[m], (m, -oo, oo)).diff(h[m]).doit() == oo*a
+    assert Sum(a*h[m], (m, -oo, oo)).diff(h[m]) == oo*a
 
 
 def test_indexed_series():
diff --git a/sympy/utilities/tests/test_lambdify.py b/sympy/utilities/tests/test_lambdify.py
index ad70e02e7d..d0cefe5fe6 100644
--- a/sympy/utilities/tests/test_lambdify.py
+++ b/sympy/utilities/tests/test_lambdify.py
@@ -219,7 +219,7 @@ def test_sqrt():
 
 
 def test_trig():
-    f = lambdify([x], [cos(x), sin(x)])
+    f = lambdify([x], [cos(x), sin(x)], 'math')
     d = f(pi)
     prec = 1e-11
     assert -prec < d[0] + 1 < prec
@@ -249,7 +249,7 @@ def test_vector_discontinuous():
 
 
 def test_trig_symbolic():
-    f = lambdify([x], [cos(x), sin(x)])
+    f = lambdify([x], [cos(x), sin(x)], 'math')
     d = f(pi)
     assert abs(d[0] + 1) < 0.0001
     assert abs(d[1] - 0) < 0.0001