Python compare dict with csr_matrices as values
Question: I have two variables `r` and `e` which both are dictionaries, with strings as
keys and csr_matrices as values. Now I want to assert that they are equal. How
do I do this?

**Try 1:**

    
    
    from scipy.sparse.csr import csr_matrix
    import numpy as np
    
    def test_dict_equals(self):
        r = {'a': csr_matrix([[0, 0 ,1], [0, 1, 0], [1, 0, 0]])}
        e = {'a': csr_matrix([[0, 0 ,1], [0, 1, 0], [1, 0, 0]])}
        self.assertDictEqual(r, e)
    

This does not work:

    
    
    ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all().
    

**Try 2:**

    
    
    def test_dict_equals(self):
        r = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
        e = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
        self.assertListEqual(r.keys(), e.keys())
        for k in r.keys():
            np.testing.assert_allclose(r[k], e[k])
    

This does also not work:

    
    
    AssertionError: First sequence is not a list: dict_keys(['a'])
    

**Try 3:**

    
    
    def test_dict_equals(self):
        r = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
        e = {'a': csr_matrix([[0, 0 ,1.01], [0, 1, 0], [1, 0, 0]])}
        self.assertListEqual(list(r.keys()), list(e.keys()))
        for k in r.keys():
            np.testing.assert_allclose(r[k], e[k])
    

This does also not work:

    
    
    TypeError: ufunc 'isinf' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
    


Answer: The `assertDictEqual` function will invoke the `__eq__` method of objects. In
the source code of `csr_matrix`, you can see there is no `__eq__` method.

You have to write a subclass of `csr_matrix` and then do the assertion. Here
is an example for `numpy.ndarray` for you. Code must be similar.

    
    
    import copy
    import numpy
    import unittest
    
    class SaneEqualityArray(numpy.ndarray):
        def __eq__(self, other):
            return (isinstance(other, SaneEqualityArray) and
                    self.shape == other.shape and
                    numpy.ndarray.__eq__(self, other).all())
    
    class TestAsserts(unittest.TestCase):
    
        def testAssert(self):
            tests = [
                [1, 2],
                {'foo': 2},
                [2, 'foo', {'d': 4}],
                SaneEqualityArray([1, 2]),
                {'foo': {'hey': SaneEqualityArray([2, 3])}},
                [{'foo': SaneEqualityArray([3, 4]), 'd': {'doo': 3}},
                 SaneEqualityArray([5, 6]), 34]
            ]
            for t in tests:
                self.assertEqual(t, copy.deepcopy(t))
    
    if __name__ == '__main__':
        unittest.main()
    

Hope it helps.:)

