Skip to content

Commit

Permalink
feat: __getitem__ can accept a slice
Browse files Browse the repository at this point in the history
  • Loading branch information
lars-reimann committed Apr 22, 2023
1 parent 95c626d commit 3b4604a
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 23 deletions.
15 changes: 13 additions & 2 deletions src/safeds/data/tabular/containers/_column.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,19 @@ def __eq__(self, other: object) -> bool:
return True
return self.name == other.name and self._data.equals(other._data)

def __getitem__(self, index: int) -> _T:
return self.get_value(index)
def __getitem__(self, index: int | slice) -> _T:
if isinstance(index, int):
if index < 0 or index >= self._data.size:
raise IndexOutOfBoundsError(index)
return self._data[index]

if isinstance(index, slice):
if index.start < 0 or index.start > self._data.size:
raise IndexOutOfBoundsError(index)
if index.stop < 0 or index.stop > self._data.size:
raise IndexOutOfBoundsError(index)
data = self._data[index].reset_index(drop=True).rename(self.name)
return Column._from_pandas_series(data, self._type)

def __iter__(self) -> Iterator[_T]:
return iter(self._data)
Expand Down
4 changes: 2 additions & 2 deletions src/safeds/data/tabular/exceptions/_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ class IndexOutOfBoundsError(IndexError):
Parameters
----------
index : int
index : int | slice
The wrongly used index.
"""

def __init__(self, index: int):
def __init__(self, index: int | slice):
super().__init__(f"There is no element at index '{index}'.")


Expand Down
19 changes: 0 additions & 19 deletions tests/safeds/data/tabular/containers/_column/test_getitem.py

This file was deleted.

59 changes: 59 additions & 0 deletions tests/safeds/data/tabular/containers/test_column.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import regex as re

from safeds.data.tabular.containers import Column
from safeds.data.tabular.exceptions import IndexOutOfBoundsError
from safeds.data.tabular.typing import ColumnType, Integer, RealNumber, String, Boolean


Expand Down Expand Up @@ -68,6 +69,64 @@ def test_should_infer_type_if_not_passed(self, series: pd.Series, expected: Colu
assert Column._from_pandas_series(series).type == expected


class TestGetItem:
@pytest.mark.parametrize(
("column", "index", "expected"),
[
(Column("a", [0, 1]), 0, 0),
(Column("a", [0, 1]), 1, 1),
],
ids=[
"first item",
"second item"
],
)
def test_should_get_the_item_at_index(self, column: Column, index: int, expected: Any) -> None:
assert column[index] == expected

@pytest.mark.parametrize(
("column", "index", "expected"),
[
(Column("a", [0, 1, 2]), slice(0, 1), Column("a", [0])),
(Column("a", [0, 1, 2]), slice(2, 3), Column("a", [2])),
(Column("a", [0, 1, 2]), slice(0, 3), Column("a", [0, 1, 2])),
(Column("a", [0, 1, 2]), slice(0, 3, 2), Column("a", [0, 2])),
],
ids=[
"first item",
"last item",
"all items",
"every other item"
],
)
def test_should_get_the_items_at_slice(self, column: Column, index: slice, expected: Column) -> None:
assert column[index] == expected

@pytest.mark.parametrize(
"index",
[
-1,
2,
slice(-1, 2),
slice(0, 4),
slice(-1, 4)
],
ids=[
"negative",
"out of bounds",
"slice with negative start",
"slice with out of bounds end",
"slice with negative start and out of bounds end"
],
)
def test_should_raise_if_index_is_out_of_bounds(self, index: int | slice) -> None:
column = Column("a", [0, "1"])

with pytest.raises(IndexOutOfBoundsError):
# noinspection PyStatementEffect
column[index]


class TestContains:
@pytest.mark.parametrize(
("column", "value", "expected"),
Expand Down

0 comments on commit 3b4604a

Please sign in to comment.