From 1b252d8abe896e4e02f99e5fb3f961fbd2bbaf70 Mon Sep 17 00:00:00 2001 From: Maxim Ivanov Date: Fri, 23 Oct 2020 18:07:14 +0700 Subject: [PATCH 1/4] TST: add failing test --- pandas/tests/io/formats/test_format.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 72b28c71b6511..1511af901bb31 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -2029,6 +2029,31 @@ def test_period(self): ) assert str(df) == exp + @pytest.mark.parametrize( + "length, max_rows, min_rows, expected", + [ + (10, 10, 10, 10), + (20, 30, 10, 30), + (50, 30, 10, 10), + (100, 60, 10, 10), + ], + ) + def test_max_rows_fitted(self, length, min_rows, max_rows, expected): + """Check that display logic is correct. + + GH #37359 + + See description here: + https://pandas.pydata.org/docs/dev/user_guide/options.html#frequently-used-options + """ + formatter = fmt.DataFrameFormatter( + pd.DataFrame(np.random.rand(length, 3)), + max_rows=max_rows, + min_rows=min_rows, + ) + result = formatter.max_rows_fitted + assert result == expected + def gen_series_formatting(): s1 = Series(["a"] * 100) From 74dd42940ec177288f0774ec824612b56f03b09f Mon Sep 17 00:00:00 2001 From: Maxim Ivanov Date: Fri, 23 Oct 2020 18:07:30 +0700 Subject: [PATCH 2/4] FIX: fix display logic --- pandas/io/formats/format.py | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 6f4bd2ed8c73a..9b86450474340 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -633,20 +633,30 @@ def _calc_max_cols_fitted(self) -> Optional[int]: def _calc_max_rows_fitted(self) -> Optional[int]: """Number of rows with data fitting the screen.""" - if not self._is_in_terminal(): - return self.max_rows - - _, height = get_terminal_size() - if self.max_rows == 0: - # rows available to fill with actual data - return height - self._get_number_of_auxillary_rows() - - max_rows: Optional[int] - if self._is_screen_short(height): - max_rows = height + if self._is_in_terminal(): + _, height = get_terminal_size() + if self.max_rows == 0: + # rows available to fill with actual data + return height - self._get_number_of_auxillary_rows() + + max_rows: Optional[int] + if self._is_screen_short(height): + max_rows = height + else: + max_rows = self.max_rows else: max_rows = self.max_rows + return self._adjust_max_rows(max_rows) + + def _adjust_max_rows(self, max_rows: Optional[int]) -> Optional[int]: + """Adjust max_rows using display logic. + + See description here: + https://pandas.pydata.org/docs/dev/user_guide/options.html#frequently-used-options + + GH #37359 + """ if max_rows: if (len(self.frame) > max_rows) and self.min_rows: # if truncated, set max_rows showed to min_rows From 2bb25cbc18dcae08187dc8f8654b9fc117341c76 Mon Sep 17 00:00:00 2001 From: Maxim Ivanov Date: Fri, 23 Oct 2020 19:22:40 +0700 Subject: [PATCH 3/4] TST: add test cases --- pandas/tests/io/formats/test_format.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 1511af901bb31..62ab9fa5282f7 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -2033,9 +2033,13 @@ def test_period(self): "length, max_rows, min_rows, expected", [ (10, 10, 10, 10), - (20, 30, 10, 30), - (50, 30, 10, 10), - (100, 60, 10, 10), + (10, 10, None, 10), + (10, 8, None, 8), + (20, 30, 10, 30), # max_rows > len(frame), hence max_rows + (50, 30, 10, 10), # max_rows < len(frame), hence min_rows + (100, 60, 10, 10), # same + (60, 60, 10, 60), # edge case + (61, 60, 10, 10), # edge case ], ) def test_max_rows_fitted(self, length, min_rows, max_rows, expected): @@ -2047,7 +2051,7 @@ def test_max_rows_fitted(self, length, min_rows, max_rows, expected): https://pandas.pydata.org/docs/dev/user_guide/options.html#frequently-used-options """ formatter = fmt.DataFrameFormatter( - pd.DataFrame(np.random.rand(length, 3)), + DataFrame(np.random.rand(length, 3)), max_rows=max_rows, min_rows=min_rows, ) From 6ff4f915f5d3be3b3e6aeeeab6f7dc93bb3f0a4d Mon Sep 17 00:00:00 2001 From: Maxim Ivanov Date: Sun, 1 Nov 2020 03:09:32 +0700 Subject: [PATCH 4/4] TYP: type max_rows on top of the method --- pandas/io/formats/format.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/io/formats/format.py b/pandas/io/formats/format.py index 916bb919fa56f..8c6b3bbab8175 100644 --- a/pandas/io/formats/format.py +++ b/pandas/io/formats/format.py @@ -639,13 +639,14 @@ def _calc_max_cols_fitted(self) -> Optional[int]: def _calc_max_rows_fitted(self) -> Optional[int]: """Number of rows with data fitting the screen.""" + max_rows: Optional[int] + if self._is_in_terminal(): _, height = get_terminal_size() if self.max_rows == 0: # rows available to fill with actual data return height - self._get_number_of_auxillary_rows() - max_rows: Optional[int] if self._is_screen_short(height): max_rows = height else: