Repository: sunpy/sunpy

Issue:
MapSequence doesn't have `__repr__()`
`MapSequence` doesn't have `__repr__()`, which seems lazy.

```python
>>> from sunpy.data.sample import AIA_171_IMAGE
>>> from sunpy.map import Map

>>> Map(AIA_171_IMAGE)
SunPy Map
---------
Observatory:             SDO
Instrument:              AIA 3
Detector:                AIA
Measurement:             171.0 Angstrom
Wavelength:              171.0 Angstrom
Observation Date:        2011-06-07 06:33:02
Exposure Time:           0.234256 s
Dimension:               [1024. 1024.] pix
Coordinate System:       helioprojective
Scale:                   [2.402792 2.402792] arcsec / pix
Reference Pixel:         [512.5 512.5] pix
Reference Coord:         [3.22309951 1.38578135] arcsec
array([[ -95.92475  ,    7.076416 ,   -1.9656711, ..., -127.96519  ,
        -127.96519  , -127.96519  ],
       [ -96.97533  ,   -5.1167884,    0.       , ...,  -98.924576 ,
        -104.04137  , -127.919716 ],
       [ -93.99607  ,    1.0189276,   -4.0757103, ...,   -5.094638 ,
         -37.95505  , -127.87541  ],
       ...,
       [-128.01454  , -128.01454  , -128.01454  , ..., -128.01454  ,
        -128.01454  , -128.01454  ],
       [-127.899666 , -127.899666 , -127.899666 , ..., -127.899666 ,
        -127.899666 , -127.899666 ],
       [-128.03072  , -128.03072  , -128.03072  , ..., -128.03072  ,
        -128.03072  , -128.03072  ]], dtype=float32)

>>> Map(AIA_171_IMAGE, AIA_171_IMAGE, sequence=True)
<sunpy.map.mapsequence.MapSequence object at 0x000002C6894B2C88>
```


Discussion:
@ayshih I would like to take up this issue
I believe calling `__repr__` for every element present in the `MapSequence` object and concatenating them will do the trick.

While that would work, how about something far briefer like:
```python
>>> Map(AIA_171_IMAGE, AIA_171_IMAGE, sequence=True)
MapSequence of 2 elements (AIAMap)

>>> Map(AIA_171_IMAGE, AIA_171_IMAGE, EIT_195_IMAGE, sequence=True)
MapSequence of 3 elements (AIAMap, EITMap)
```
That is, the user sees the number of elements and the type(s) of maps in the sequence.  This provides the critical information at a glance, even for long sequences.
Yeah the `Map` repr is really long, concatenating them all would be very verbose.

Resolving patch:
diff --git a/sunpy/map/mapsequence.py b/sunpy/map/mapsequence.py
--- a/sunpy/map/mapsequence.py
+++ b/sunpy/map/mapsequence.py
@@ -83,6 +83,10 @@ def __len__(self):
         """Return the number of maps in a mapsequence."""
         return len(self.maps)
 
+    def __repr__(self):
+        names = set([m.__class__.__name__ for m in self.maps])
+        return f'MapSequence of {len(self.maps)} elements, with maps from {", ".join(names)}'
+
     # Sorting methods
     @classmethod
     def _sort_by_date(cls):


Test patch:
diff --git a/sunpy/map/tests/test_mapsequence.py b/sunpy/map/tests/test_mapsequence.py
--- a/sunpy/map/tests/test_mapsequence.py
+++ b/sunpy/map/tests/test_mapsequence.py
@@ -22,6 +22,16 @@ def aia_map():
     return sunpy.map.Map(aia_file)
 
 
+@pytest.fixture
+def eit_map():
+    """
+    Load SunPy's test EIT image.
+    """
+    testpath = sunpy.data.test.rootdir
+    eit_file = os.path.join(testpath, "EIT", "efz20040301.020010_s.fits")
+    return sunpy.map.Map(eit_file)
+
+
 @pytest.fixture
 def masked_aia_map(aia_map):
     """
@@ -42,6 +52,14 @@ def mapsequence_all_the_same(aia_map):
     return sunpy.map.Map([aia_map, aia_map], sequence=True)
 
 
+@pytest.fixture
+def mapsequence_different_maps(aia_map, eit_map):
+    """
+    Simple `sunpy.map.mapsequence` for testing, in which there are different maps
+    """
+    return sunpy.map.Map([aia_map, eit_map], sequence=True)
+
+
 @pytest.fixture
 def mapsequence_all_the_same_all_have_masks(masked_aia_map):
     """ Simple `sunpy.map.mapsequence` for testing, in which all the maps have
@@ -147,6 +165,25 @@ def test_all_meta(mapsequence_all_the_same):
     assert np.all(np.asarray([meta[i] == mapsequence_all_the_same[i].meta for i in range(0, len(meta))]))
 
 
+def test_repr(mapsequence_all_the_same, mapsequence_different_maps):
+    """
+    Tests that overidden __repr__ functionality works as expected. Test
+    for mapsequence of same maps as well that of different maps.
+    """
+    # Test the case of MapSequence having same maps
+    expected_out = f'MapSequence of 2 elements, with maps from AIAMap'
+    obtained_out = repr(mapsequence_all_the_same)
+    assert len(mapsequence_all_the_same) == 2
+    assert obtained_out == expected_out
+
+    # Test the case of MapSequence having different maps
+    expected_out1 = f'MapSequence of 2 elements, with maps from AIAMap, EITMap'
+    expected_out2 = f'MapSequence of 2 elements, with maps from EITMap, AIAMap'
+    obtained_out = repr(mapsequence_different_maps)
+    assert len(mapsequence_different_maps) == 2
+    assert obtained_out == expected_out1 or obtained_out == expected_out2
+
+
 def test_derotate():
     with pytest.raises(NotImplementedError):
         mapsequence = sunpy.map.MapSequence(derotate=True)