Skip to content

Commit

Permalink
feat: convert between Row and dict
Browse files Browse the repository at this point in the history
  • Loading branch information
lars-reimann committed Apr 18, 2023
1 parent 2930a09 commit 83d0690
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 2 deletions.
40 changes: 40 additions & 0 deletions src/safeds/data/tabular/containers/_row.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

from collections.abc import Iterable, Iterator
from hashlib import md5
from typing import Any
Expand All @@ -22,6 +24,29 @@ class Row:
The schema of the row.
"""

# ------------------------------------------------------------------------------------------------------------------
# Creation
# ------------------------------------------------------------------------------------------------------------------

@staticmethod
def from_dict(data: dict[str, Any]) -> Row:
"""
Create a row from a dictionary that maps column names to column values.
Parameters
----------
data : dict[str, Any]
The data.
Returns
-------
row : Row
The generated row.
"""
row_frame = pd.DataFrame([data.values()], columns=list(data.keys()))
# noinspection PyProtectedMember
return Row(data.values(), Schema._from_dataframe(row_frame))

# ------------------------------------------------------------------------------------------------------------------
# Dunder methods
# ------------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -180,6 +205,21 @@ def count(self) -> int:
"""
return len(self._data)

# ------------------------------------------------------------------------------------------------------------------
# Conversion
# ------------------------------------------------------------------------------------------------------------------

def to_dict(self) -> dict[str, Any]:
"""
Return a dictionary that maps column names to column values.
Returns
-------
data : dict[str, Any]
Dictionary representation of the row.
"""
return {column_name: self.get_value(column_name) for column_name in self.get_column_names()}

# ------------------------------------------------------------------------------------------------------------------
# IPython integration
# ------------------------------------------------------------------------------------------------------------------
Expand Down
42 changes: 42 additions & 0 deletions tests/safeds/data/tabular/containers/test_row.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,27 @@
from safeds.data.tabular.typing import ColumnType, Integer, Schema, String


class TestFromDict:
@pytest.mark.parametrize(
("data", "expected"),
[
(
{},
Row([]),
),
(
{
"a": 1,
"b": 2,
},
Row([1, 2], schema=Schema({"a": Integer(), "b": Integer()})),
),
],
)
def test_should_create_row_from_dict(self, data: dict[str, Any], expected: Row) -> None:
assert Row.from_dict(data) == expected


class TestInit:
@pytest.mark.parametrize(
("row", "expected"),
Expand Down Expand Up @@ -209,3 +230,24 @@ class TestCount:
)
def test_should_return_the_number_of_columns(self, row: Row, expected: int) -> None:
assert row.count() == expected


class TestToDict:
@pytest.mark.parametrize(
("row", "expected"),
[
(
Row([]),
{},
),
(
Row([1, 2], schema=Schema({"a": Integer(), "b": Integer()})),
{
"a": 1,
"b": 2,
},
),
],
)
def test_should_return_dict_for_table(self, row: Row, expected: dict[str, Any]) -> None:
assert row.to_dict() == expected
4 changes: 2 additions & 2 deletions tests/safeds/data/tabular/containers/test_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class TestFromDict:
),
],
)
def test_should_create_table_from_dict(self, data: dict[str, Any], expected: Table) -> None:
def test_should_create_table_from_dict(self, data: dict[str, list[Any]], expected: Table) -> None:
assert Table.from_dict(data) == expected

def test_should_raise_if_columns_have_different_lengths(self) -> None:
Expand All @@ -49,7 +49,7 @@ class TestToDict:
),
],
)
def test_should_return_dict_for_table(self, table: Table, expected: dict[str, Any]) -> None:
def test_should_return_dict_for_table(self, table: Table, expected: dict[str, list[Any]]) -> None:
assert table.to_dict() == expected


Expand Down

0 comments on commit 83d0690

Please sign in to comment.