Repository: sympy/sympy

Issue:
Increase test coverage
As Codecov is now actively reporting the coverage status for Sympy it is also a good idea to try to increase the test coverage.

Go to: https://codecov.io/gh/sympy/sympy and click on "sympy" at the bottom where it says files. You will now see all the modules and the coverage of these. There are columns with green, yellow and red dots. Green are covered, yellow are partially covered (e.g. an if-clause which has only evaluated to true, not to false), and red which are not covered.

As you can see some modules are well covered, some less well (quite a lot of the not covered lines comes from the rubi integral module which is currently not tested at all, and if I understand correctly is not ready for use).

The task is to write tests that uses the red lines (and the yellow lines in a new way).

For test that creates exceptions one writes:
`raises(ExpextedError, lambda: function_call_that_causes_the_error)`

For the other tests it is not just about covering the code, it is also required that the result is correct. If one is unsure, there may be examples in the documentation that if nothing else can be added.

When creating a pull request please write `NO ENTRY` for the release note description.

Finally, note that some things are inherently hard to cover. For example, things that reads from and writes to files and things that rely on external libraries as these are not included in the test coverage runs (except for mpmath). The same thing for interactive commands and for plot commands.

Discussion:
Sc0rpi0n101: Can you change `Fixes #..` to something like `Related to #..` or `Work on #..` as this PR is not enough for closing the issue?

Also, it's better to describe what changes were done in the commit message instead of the issue which was solved with it. People who look at the commit and the changes in the future might not have any idea about the issue, but if the actual changes are described, that'll be more helpful to them. 
sympy-bot: :white_check_mark:

Hi, I am the [SymPy bot](https://github.com/sympy/sympy-bot) (v158). I'm here to help you write a release notes entry. Please read the [guide on how to write release notes](https://github.com/sympy/sympy/wiki/Writing-Release-Notes).



* No release notes entry will be added for this pull request.

Note: This comment will be updated with the latest check if you edit the pull request. You need to reload the page to see it. <details><summary>Click here to see the pull request description that was parsed.</summary>

     On branch iss_16318
     Changes to be committed:
    	modified:   sympy/algebras/tests/test_quaternion.py


    #### References to other Issues or PRs 
    Related to issue #16318



    #### Brief description of what is fixed or changed 
    Added two tests to test_quaternion.py to increase the test coverage, as reported from Codecov. 
    1. for the rtruediv() to raise ValueError when dividing by a quaternion with zero norm.
    2. for the rotate_point(pin,r) to assert that the result is correct, when r is of the form (vector, angle).



    #### Release Notes 
    <!-- BEGIN RELEASE NOTES -->
    NO ENTRY
    <!-- END RELEASE NOTES -->

</details><p>

BasileiosKal: @Sc0rpi0n101 Thank you very much for the help. I hope the description is beter know. Please let me know if theres anything else i can improve.
Sc0rpi0n101: The description does look good and clear now. Great Job. 

But what I meant was the commit message. You can read https://github.com/sympy/sympy/wiki/Development-workflow#writing-commit-messages to know more about it. 

Patch:
diff --git a/sympy/crypto/crypto.py b/sympy/crypto/crypto.py
index ee46f3e678..6c1f41126c 100644
--- a/sympy/crypto/crypto.py
+++ b/sympy/crypto/crypto.py
@@ -81,7 +81,7 @@ def AZ(s=None):
 bifid10 = printable
 
 
-def padded_key(key, symbols):
+def padded_key(key, symbols, filter=True):
     """Return a string of the distinct characters of ``symbols`` with
     those of ``key`` appearing first, omitting characters in ``key``
     that are not in ``symbols``. A ValueError is raised if a) there are
@@ -111,8 +111,7 @@ def padded_key(key, symbols):
             'characters in key but not symbols: %s' % ''.join(
             sorted(extra)))
     key0 = ''.join(list(uniq(key)))
-    # remove from syms characters in key0
-    return key0 + translate(''.join(syms), None, key0)
+    return key0 + ''.join([i for i in syms if i not in key0])
 
 
 def check_and_join(phrase, symbols=None, filter=None):
@@ -482,7 +481,7 @@ def encipher_atbash(msg, symbols=None):
     decipher_atbash
 
     """
-    return encipher_affine(msg, (25, 25), symbols)
+    return encipher_affine(msg, (25,25), symbols)
 
 
 def decipher_atbash(msg, symbols=None):
@@ -521,7 +520,7 @@ def decipher_atbash(msg, symbols=None):
     encipher_atbash
 
     """
-    return decipher_affine(msg, (25, 25), symbols)
+    return decipher_affine(msg, (25,25), symbols)
 
 #################### substitution cipher ###########################
 
@@ -2900,42 +2899,37 @@ def _random_coprime_stream(n, seed=None):
 
 def gm_private_key(p, q, a=None):
     """
-    Check if ``p`` and ``q`` can be used as private keys for
+    Check if p and q can be used as private keys for
     the Goldwasser-Micali encryption. The method works
     roughly as follows.
 
-    $\\cdot$ Pick two large primes $p$ and $q$.
-
-    $\\cdot$ Call their product $N$.
-
-    $\\cdot$ Given a message as an integer $i$, write $i$ in its
-    bit representation $b_0$ , $\\dotsc$ , $b_n$ .
-
-    $\\cdot$ For each $k$ ,
+    Pick two large primes p ands q. Call their product N.
+    Given a message as an integer i, write i in its
+    bit representation b_0,...,b_n. For each k,
 
-     if $b_k$ = 0:
-        let $a_k$ be a random square
-        (quadratic residue) modulo $p q$
-        such that $jacobi \\_symbol(a, p q) = 1$
-     if $b_k$ = 1:
-        let $a_k$ be a random non-square
-        (non-quadratic residue) modulo $p q$
-        such that $jacobi \\_ symbol(a, p q) = 1$
+     if b_k = 0:
+        let a_k be a random square
+        (quadratic residue) modulo p * q
+        such that jacobi_symbol(a, p * q) = 1
+     if b_k = 1:
+        let a_k be a random non-square
+        (non-quadratic residue) modulo p * q
+        such that jacobi_symbol(a, p * q) = 1
 
-    returns [$a_1$ , $a_2$ , $\\dotsc$ ]
+    return [a_1, a_2,...]
 
-    $b_k$ can be recovered by checking whether or not
-    $a_k$ is a residue. And from the $b_k$ 's, the message
+    b_k can be recovered by checking whether or not
+    a_k is a residue. And from the b_k's, the message
     can be reconstructed.
 
-    The idea is that, while $jacobi \\_ symbol(a, p q)$
-    can be easily computed (and when it is equal to $-1$ will
-    tell you that $a$ is not a square mod $p q$ ), quadratic
+    The idea is that, while jacobi_symbol(a, p * q)
+    can be easily computed (and when it is equal to -1 will
+    tell you that a is not a square mod p * q), quadratic
     residuosity modulo a composite number is hard to compute
     without knowing its factorization.
 
-    Moreover, approximately half the numbers coprime to $p q$ have
-    $jacobi \\_ symbol$ equal to $1$ . And among those, approximately half
+    Moreover, approximately half the numbers coprime to p * q have
+    jacobi_symbol equal to 1. And among those, approximately half
     are residues and approximately half are not. This maximizes the
     entropy of the code.
 
diff --git a/sympy/matrices/expressions/__init__.py b/sympy/matrices/expressions/__init__.py
index 0e60f05039..70ad1fa812 100644
--- a/sympy/matrices/expressions/__init__.py
+++ b/sympy/matrices/expressions/__init__.py
@@ -46,7 +46,8 @@
 
     'hadamard_product', 'HadamardProduct', 'hadamard_power', 'HadamardPower',
 
-    'DiagonalMatrix', 'DiagonalOf', 'DiagMatrix', 'diagonalize_vector',
+    'DiagonalMatrix', 'DiagonalOf', 'DiagMatrix', 'DiagonalizeVector',
+    'diagonalize_vector',
 
     'DotProduct',
 
diff --git a/sympy/solvers/ode/single.py b/sympy/solvers/ode/single.py
index 4c76fb430e..2219fdc60c 100644
--- a/sympy/solvers/ode/single.py
+++ b/sympy/solvers/ode/single.py
@@ -538,20 +538,20 @@ class Bernoulli(SinglePatternODESolver):
                     d                n
         P(x)*f(x) + --(f(x)) = Q(x)*f (x)
                     dx
-        >>> pprint(dsolve(genform, f(x), hint='Bernoulli_Integral'), num_columns=110)
-                                                                                                              -1
-                                                                                                             -----
-                                                                                                             n - 1
-               //         /                                /                           \                    \
-               ||        |                                |                            |                    |
-               ||        |                 /              |                 /          |            /       |
-               ||        |                |               |                |           |           |        |
-               ||        |       (1 - n)* | P(x) dx       |       (1 - n)* | P(x) dx   |  (n - 1)* | P(x) dx|
-               ||        |                |               |                |           |           |        |
-               ||        |               /                |               /            |          /         |
-        f(x) = ||C1 - n* | Q(x)*e                   dx +  | Q(x)*e                   dx|*e                  |
-               ||        |                                |                            |                    |
-               \\       /                                /                             /                    /
+        >>> pprint(dsolve(genform, f(x), hint='Bernoulli_Integral'), num_columns=100)
+                                                                                           1
+                                                                                         -----
+                                                                                         1 - n
+               //               /                                  \                    \
+               ||              |                                   |                    |
+               ||              |            /           /          |            /       |
+               ||              |           |           |           |           |        |
+               ||              |       -n* | P(x) dx   | P(x) dx   |  (n - 1)* | P(x) dx|
+               ||              |           |           |           |           |        |
+               ||              |          /           /            |          /         |
+        f(x) = ||C1 - (n - 1)* | Q(x)*e             *e           dx|*e                  |
+               ||              |                                   |                    |
+               \\             /                                    /                    /
 
 
     Note that the equation is separable when `n = 1` (see the docstring of
@@ -579,8 +579,10 @@ class Bernoulli(SinglePatternODESolver):
     >>> pprint(dsolve(Eq(x*f(x).diff(x) + f(x), log(x)*f(x)**2),
     ... f(x), hint='Bernoulli'))
                     1
-    f(x) =  -----------------
-            C1*x + log(x) + 1
+    f(x) = -------------------
+            /     log(x)   1\
+            x*|C1 + ------ + -|
+            \       x      x/
 
     References
     ==========
@@ -611,16 +613,11 @@ def _get_general_solution(self, *, simplify: bool = True):
         fx = self.ode_problem.func
         x = self.ode_problem.sym
         (C1,) = self.ode_problem.get_numbered_constants(num=1)
-        if n==1:
-            gensol = Eq(log(fx), (
-            (C1 + Integral((-P + Q),x)
-        )))
-        else:
-            gensol = Eq(fx**(1-n), (
-                (C1 - (n - 1) * Integral(Q*exp(-n*Integral(P, x))
-                            * exp(Integral(P, x)), x)
-                ) * exp(-(1 - n)*Integral(P, x)))
-            )
+        gensol = Eq(fx, (
+            (C1 - (n - 1) * Integral(Q*exp(-n*Integral(P, x))
+                          * exp(Integral(P, x)), x)
+            ) * exp(-(1 - n)*Integral(P, x)))**(1/(1 - n))
+        )
         return [gensol]
 
 


Test patch:
diff --git a/sympy/algebras/tests/test_quaternion.py b/sympy/algebras/tests/test_quaternion.py
index aa1cc5ac49..724a7d2411 100644
--- a/sympy/algebras/tests/test_quaternion.py
+++ b/sympy/algebras/tests/test_quaternion.py
@@ -172,3 +172,18 @@ def test_quaternion_multiplication():
 
     assert z * q == z_quat * q
     assert q * z == q * z_quat
+
+
+def test_issue_16318():
+    #for rtruediv
+    q0 = Quaternion(0, 0, 0, 0)
+    raises(ValueError, lambda: 1/q0)
+    #for rotate_point
+    q = Quaternion(1, 2, 3, 4)
+    (axis, angle) = q.to_axis_angle()
+    assert Quaternion.rotate_point((1, 1, 1), (axis, angle)) == (S.One / 5, 1, S(7) / 5)
+    #test for to_axis_angle
+    q = Quaternion(-1, 1, 1, 1)
+    axis = (-sqrt(3)/3, -sqrt(3)/3, -sqrt(3)/3)
+    angle = 2*pi/3
+    assert (axis, angle) == q.to_axis_angle()
diff --git a/sympy/solvers/ode/tests/test_single.py b/sympy/solvers/ode/tests/test_single.py
index 531e2507c0..df889c0f01 100644
--- a/sympy/solvers/ode/tests/test_single.py
+++ b/sympy/solvers/ode/tests/test_single.py
@@ -294,15 +294,5 @@ def test_Bernoulli():
     # Type: Bernoulli, f'(x) + p(x)*f(x) == q(x)*f(x)**n
     eq = Eq(x*f(x).diff(x) + f(x) - f(x)**2, 0)
     sol = dsolve(eq, f(x), hint='Bernoulli')
-    assert sol == Eq(f(x), 1/(C1*x + 1))
+    assert sol == Eq(f(x), 1/(x*(C1 + 1/x)))
     assert checkodesol(eq, sol, order=1, solve_for_func=False)[0]
-
-    eq = f(x).diff(x) - y*f(x)
-    sol = dsolve(eq, hint='Bernoulli')
-    assert sol == Eq(f(x), C1*exp(x*y))
-    assert checkodesol(eq, sol)[0]
-
-    eq = f(x)*f(x).diff(x) - 1
-    sol = dsolve(eq,hint='Bernoulli')
-    assert sol == [Eq(f(x), -sqrt(C1 + 2*x)), Eq(f(x), sqrt(C1 + 2*x))]
-    assert checkodesol(eq, sol) == [(True, 0), (True, 0)]