Skip to content

Commit

Permalink
fixup! update find_table to return correct behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
lavigne958 committed Aug 19, 2024
1 parent c5fa638 commit d62efb0
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 50 deletions.
31 changes: 22 additions & 9 deletions gspread/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1030,10 +1030,12 @@ def find_table(
* ``TableDirection.right``: expands right until the first empty cell
* ``TableDirection.down``: expands down until the first empty cell
* ``TableDirection.table``: expands right until the first empty cell, then down until the first empty cell
* ``TableDirection.table``: expands right until the first empty cell and down until first empty cell
Regardless of the direction this function always returns a matrix of data, even if it has
only one column.
In case of empty result an empty list is restuned.
When the given ``start_range`` is outside the given matrix of values the exception
`~gspread.exceptions.InvalidInputValue` is raised.
Example::
Expand All @@ -1052,7 +1054,7 @@ def find_table(
.. note::
the ``TableDirection.table`` will first look right, then look down.
the ``TableDirection.table`` will look right from starting cell then look down from starting cell.
It will not check cells located inside the table. This could lead to
potential empty values located in the middle of the table.
Expand All @@ -1071,20 +1073,31 @@ def find_table(
row -= 1
col -= 1

if row >= len(values):
raise InvalidInputValue(
"given row for start_range is outside given values: start range row ({}) >= rows in values {}".format(
row, len(values)
)
)

if col >= len(values[row]):
raise InvalidInputValue(
"given collumn for start_range is outside given values: start range column ({}) >= columns in values {}".format(
col, len(values[row])
)
)

if direction == TableDirection.down:
rightMost = col
bottomMost = _expand_bottom(values, row, len(values), col)

if direction == TableDirection.right:
if row >= len(values):
rightMost = len(values) - 1
else:
rightMost = _expand_right(values, col, len(values[row]), row)
bottomMost = row
rightMost = _expand_right(values, col, len(values[row]), row)

if direction == TableDirection.table:
rightMost = _expand_right(values, col, len(values[row]), row)
bottomMost = _expand_bottom(values, row, len(values), col)
rightMost = _expand_right(values, col, len(values[bottomMost]), bottomMost)

result = []

Expand Down
26 changes: 13 additions & 13 deletions gspread/worksheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -3350,31 +3350,31 @@ def expand(
* ``TableDirection.right``: expands right until the first empty cell
* ``TableDirection.down``: expands down until the first empty cell
* ``TableDirection.table``: expands right until the first empty cell, then down until the first empty cell
* ``TableDirection.table``: expands right until the first empty cell and down until the first empty cell
Regardless of the direction this function always returns a matrix of data, even if it has
only one column.
In case of empty result an empty list is restuned.
When the given ``start_range`` is outside the given matrix of values the exception
`~gspread.exceptions.InvalidInputValue` is raised.
Example::
values = [
['', '', '', '' , '' , ''],
['', 'B2', 'C2', 'D2', '' , 'F2'],
['', 'B3', '' , 'D3', '' , 'F3'],
['', 'B4', 'C4', 'D4', '' , 'F4'],
['', '' , '' , '' , '' , 'F5'],
['', '', '', '', '' ],
['', 'B2', 'C2', '', 'E2'],
['', 'B3', 'C3', '', 'E3'],
['', '' , '' , '', 'E4'],
]
>>> worksheet.expand_table(TableDirection.table, 'B2')
>>> utils.find_table(TableDirection.table, 'B2')
[
['B2', 'C2', 'D2],
['B3', '' , 'D3'],
['B4', 'C4', 'D4'],
['B2', 'C2'],
['B3', 'C3'],
]
.. note::
the ``TableDirection.table`` will first look right, then look down.
the ``TableDirection.table`` will look right from starting cell then look down from starting cell.
It will not check cells located inside the table. This could lead to
potential empty values located in the middle of the table.
Expand Down
58 changes: 30 additions & 28 deletions tests/utils_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,43 +528,45 @@ def test_find_table_simple(self):
"B2",
utils.TableDirection.down,
)
single = utils.find_table(values, "C3", utils.TableDirection.table)
single = utils.find_table(values, "D1", utils.TableDirection.table)
no_values = utils.find_table(values, "A2", utils.TableDirection.table)

table_values = [
["B2", "C2", "", "E2"],
["B3", "C3", "D3", "E3"],
["B2", "C2"],
["B3", "C3"],
]
for rowindex, row in enumerate(table):
self.assertListEqual(row, table_values[rowindex])
for rowindex, row in enumerate(table_values):
self.assertListEqual(row, table[rowindex])

right_values = [
["B2", "C2"],
]
for rowindex, row in enumerate(right):
self.assertListEqual(row, right_values[rowindex])
for rowindex, row in enumerate(right_values):
self.assertListEqual(row, right[rowindex])

bottom_values = [
["B2"],
["B3"],
]
for rowindex, row in enumerate(down):
self.assertListEqual(row, bottom_values[rowindex])
for rowindex, row in enumerate(bottom_values):
self.assertListEqual(row, down[rowindex])

self.assertEqual(single[0][0], "C3")
self.assertEqual(len(single), 1)
self.assertEqual(len(single[0]), 1)
self.assertEqual(single[0][0], "D1")
self.assertEqual(no_values, [])

def test_find_table_header_gap(self):
def test_find_table_inner_gap(self):
"""Test find table with gap in header"""
values = [
["A1", "", "C1", ""],
["A2", "B2", "C2", ""],
["A1", "B1", "C1", ""],
["A2", "", "C2", ""],
["A3", "B3", "C3", ""],
["", "", "", ""],
]
expected_table = [
["A1", "", "C1"],
["A2", "B2", "C2"],
["A1", "B1", "C1"],
["A2", "", "C2"],
["A3", "B3", "C3"],
]

Expand All @@ -574,21 +576,21 @@ def test_find_table_header_gap(self):
utils.TableDirection.table,
)

for rowindex, row in enumerate(table):
self.assertListEqual(row, expected_table[rowindex])
for rowindex, row in enumerate(expected_table):
self.assertListEqual(row, table[rowindex])

def test_find_table_empty_first_cell(self):
def test_find_table_first_row_gap(self):
"""Test find table with first cell empty"""
values = [
["", "B1", "C1", ""],
["A1", "", "C1", ""],
["A2", "B2", "C2", ""],
["A3", "B3", "C3", ""],
["", "", "", ""],
]
expected_table = [
["", "B1", "C1"],
["A2", "B2", "C2"],
["A3", "B3", "C3"],
["A1"],
["A2"],
["A3"],
]

table = utils.find_table(
Expand All @@ -597,8 +599,8 @@ def test_find_table_empty_first_cell(self):
utils.TableDirection.table,
)

for rowindex, row in enumerate(table):
self.assertListEqual(row, expected_table[rowindex])
for rowindex, row in enumerate(expected_table):
self.assertListEqual(row, table[rowindex])

def test_find_table_first_column_gap(self):
"""Test find table with a gap in first column"""
Expand All @@ -618,8 +620,8 @@ def test_find_table_first_column_gap(self):
utils.TableDirection.table,
)

for rowindex, row in enumerate(table):
self.assertListEqual(row, expected_table[rowindex])
for rowindex, row in enumerate(expected_table):
self.assertListEqual(row, table[rowindex])

def test_find_table_last_column_gap(self):
"""Test find table with a gap in last column"""
Expand All @@ -641,5 +643,5 @@ def test_find_table_last_column_gap(self):
utils.TableDirection.table,
)

for rowindex, row in enumerate(table):
self.assertListEqual(row, expected_table[rowindex])
for rowindex, row in enumerate(expected_table):
self.assertListEqual(row, table[rowindex])

0 comments on commit d62efb0

Please sign in to comment.