Repository: pandas-dev/pandas

Issue:
Setting option 'display.max_seq_items' to None results in TypeError when pprinting index
According to the docstring, the following is allowed:

``` Python
pd.set_option('display.max_seq_items', None)
```

With 0.16.1 this results in a TypeError when pretty printing an index. This is because the None value is compared against lenght of the index to see if we need to limit output.

``` Python
TypeError: unorderable types: int() > NoneType()
```



Discussion:
Thanks for the report!

@JWarmenhoven https://github.com/pydata/pandas/pull/10183/files should fix it. Can you try this out? (you can just change that one line in the source code)

You'll also need to change line 538 & 2559 into something like this for it to work.

``` python
max_seq_items = get_option('display.max_seq_items') or len(self) 
```

Ah, yes, python 3. Thanks. Doing that means that the 'length' will never be shown, but maybe that is most consistent (only show that when truncated)?

I see.
Why not always output the 'length' attribute, regardless whether the output has been truncated or not?


Resolving patch:
diff --git a/pandas/core/categorical.py b/pandas/core/categorical.py
--- a/pandas/core/categorical.py
+++ b/pandas/core/categorical.py
@@ -1599,6 +1599,20 @@ def describe(self):
 
         return result
 
+    def repeat(self, repeats):
+        """
+        Repeat elements of a Categorical.
+
+        See also
+        --------
+        numpy.ndarray.repeat
+
+        """
+        codes = self._codes.repeat(repeats)
+        return Categorical(values=codes, categories=self.categories,
+                           ordered=self.ordered, name=self.name, fastpath=True)
+
+
 ##### The Series.cat accessor #####
 
 class CategoricalAccessor(PandasDelegate):
diff --git a/pandas/core/index.py b/pandas/core/index.py
--- a/pandas/core/index.py
+++ b/pandas/core/index.py
@@ -443,7 +443,7 @@ def _format_data(self):
 
         n = len(self)
         sep = ','
-        max_seq_items = get_option('display.max_seq_items')
+        max_seq_items = get_option('display.max_seq_items') or n
         formatter = self._formatter_func
 
         # do we want to justify (only do so for non-objects)
@@ -534,7 +534,7 @@ def _format_attrs(self):
         attrs.append(('dtype',"'%s'" % self.dtype))
         if self.name is not None:
             attrs.append(('name',default_pprint(self.name)))
-        max_seq_items = get_option('display.max_seq_items')
+        max_seq_items = get_option('display.max_seq_items') or len(self)
         if len(self) > max_seq_items:
             attrs.append(('length',len(self)))
         return attrs
@@ -2950,7 +2950,7 @@ def _format_attrs(self):
         if self.name is not None:
             attrs.append(('name',default_pprint(self.name)))
         attrs.append(('dtype',"'%s'" % self.dtype))
-        max_seq_items = get_option('display.max_seq_items')
+        max_seq_items = get_option('display.max_seq_items') or len(self)
         if len(self) > max_seq_items:
             attrs.append(('length',len(self)))
         return attrs
diff --git a/pandas/tseries/period.py b/pandas/tseries/period.py
--- a/pandas/tseries/period.py
+++ b/pandas/tseries/period.py
@@ -783,6 +783,17 @@ def append(self, other):
                      for x in to_concat]
         return Index(com._concat_compat(to_concat), name=name)
 
+    def repeat(self, n):
+        """
+        Return a new Index of the values repeated n times.
+
+        See also
+        --------
+        numpy.ndarray.repeat
+        """
+        # overwrites method from DatetimeIndexOpsMixin
+        return self._shallow_copy(self.values.repeat(n))
+
     def __setstate__(self, state):
         """Necessary for making this object picklable"""
 


Test patch:
diff --git a/pandas/tests/test_categorical.py b/pandas/tests/test_categorical.py
--- a/pandas/tests/test_categorical.py
+++ b/pandas/tests/test_categorical.py
@@ -2714,7 +2714,6 @@ def f():
             df.append(df_wrong_categories)
         self.assertRaises(ValueError, f)
 
-
     def test_merge(self):
         # GH 9426
 
@@ -2747,6 +2746,13 @@ def test_merge(self):
         result = pd.merge(cleft, cright, how='left', left_on='b', right_on='c')
         tm.assert_frame_equal(result, expected)
 
+    def test_repeat(self):
+        #GH10183
+        cat = pd.Categorical(["a","b"], categories=["a","b"])
+        exp = pd.Categorical(["a", "a", "b", "b"], categories=["a","b"])
+        res = cat.repeat(2)
+        self.assert_categorical_equal(res, exp)
+
     def test_na_actions(self):
 
         cat = pd.Categorical([1,2,3,np.nan], categories=[1,2,3])
diff --git a/pandas/tests/test_index.py b/pandas/tests/test_index.py
--- a/pandas/tests/test_index.py
+++ b/pandas/tests/test_index.py
@@ -133,6 +133,14 @@ def test_str(self):
         self.assertTrue("'foo'" in str(idx))
         self.assertTrue(idx.__class__.__name__ in str(idx))
 
+    def test_repr_max_seq_item_setting(self):
+        # GH10182
+        idx = self.create_index()
+        idx = idx.repeat(50)
+        with pd.option_context("display.max_seq_items", None):
+            repr(idx)
+            self.assertFalse('...' in str(idx))
+
     def test_wrong_number_names(self):
         def testit(ind):
             ind.names = ["apple", "banana", "carrot"]
@@ -2857,6 +2865,14 @@ def test_get_indexer(self):
         with self.assertRaisesRegexp(ValueError, 'different freq'):
             idx.asfreq('D').get_indexer(idx)
 
+    def test_repeat(self):
+        # GH10183
+        idx = pd.period_range('2000-01-01', periods=3, freq='D')
+        res = idx.repeat(3)
+        exp = PeriodIndex(idx.values.repeat(3), freq='D')
+        self.assert_index_equal(res, exp)
+        self.assertEqual(res.freqstr, 'D')
+
 
 class TestTimedeltaIndex(DatetimeLike, tm.TestCase):
     _holder = TimedeltaIndex