Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix gt deps #12

Merged
merged 8 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ jobs:
# we are using the -e flag, so that code cov finds the source.
# this is not ideal, since installing an editable can technically
# differ from a normal install in surprising ways.
python -m pip install "git+https://github.com/posit-dev/great-tables.git@feat-interactive"
pip install -e '.[all]'
- name: Unit tests
run: |
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ jobs:
python-version: "3.10"
- name: Install dependencies
run: |
python -m pip install "git+https://github.com/posit-dev/great-tables.git@feat-interactive"
python -m pip install ".[dev]"
- uses: quarto-dev/quarto-actions/setup@v2
with:
Expand Down
32 changes: 31 additions & 1 deletion reactable/_tbl_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from datetime import datetime, date, time
from functools import singledispatch
from typing import TYPE_CHECKING, Any, Union, Literal
from typing import TYPE_CHECKING, Any, Union, Literal, Optional
from typing_extensions import TypeAlias

from abc import ABC
Expand Down Expand Up @@ -163,3 +163,33 @@ def _(data: PdDataFrame) -> "list[str]":
@column_names.register
def _(data: SimpleFrame) -> "list[str]":
return list(data.columns)


# subset_frame --------------------------------------------------------
@singledispatch
def subset_frame(
data: DataFrameLike, row: Optional[list[int]], column: Optional[list[str]]
) -> DataFrameLike:
raise TypeError(f"Unsupported type: {type(data)}")


@subset_frame.register
def _(
data: PdDataFrame, rows: Optional[list[int]] = None, cols: Optional[list[str]] = None
) -> PdDataFrame:

cols_indx = slice(None) if cols is None else data.columns.get_indexer_for(cols)
rows_indx = slice(None) if rows is None else rows

return data.iloc[rows_indx, cols_indx]


@subset_frame.register
def _(
data: PlDataFrame, rows: Optional[list[int]] = None, cols: Optional[list[str]] = None
) -> PlDataFrame:

cols_indx = slice(None) if cols is None else cols
rows_indx = slice(None) if rows is None else rows

return data[rows_indx, cols_indx]
33 changes: 24 additions & 9 deletions reactable/render_gt.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,30 @@
import ipywidgets

from great_tables import GT
from great_tables._tbl_data import n_rows, subset_frame
from great_tables._tbl_data import n_rows
from great_tables._helpers import random_id
from great_tables._text import _process_text
from great_tables._gt_data import ColInfoTypeEnum
from great_tables._scss import compile_scss
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Any

from .models import Column, Language, Theme, ColGroup
from . import Reactable
from .tags import as_react_style, to_widget
from ._tbl_data import subset_frame, to_dict

if TYPE_CHECKING:
from great_tables._gt_data import Locale, Spanners, Heading, Footnotes, SourceNotes
from great_tables._gt_data import Locale, Spanners, Heading, Footnotes, SourceNotes, Options


class OptWrapper:
_d: Options

def __init__(self, d: Options):
self._d = d

def __getitem__(self, k: str) -> Any:
return getattr(self._d, k).value


def dict_to_css(dict_: dict[str, str]) -> str:
Expand Down Expand Up @@ -48,8 +59,14 @@ def create_col_groups(spanners: Spanners) -> list[ColGroup]:
return col_groups


def _is_empty(heading: Heading):
# TODO: this should be moved into great tables
self = heading
return self.title is None and self.subtitle is None and self.preheader is None


def create_heading(heading: Heading, use_search: bool) -> html.Tag | None:
if heading.is_empty():
if _is_empty(heading):
return None

el = html.div(
Expand Down Expand Up @@ -117,8 +134,6 @@ def extract_cells(
from great_tables._tbl_data import (
cast_frame_to_string,
replace_null_frame,
subset_frame,
to_column_dict,
)

if rows is not None:
Expand All @@ -137,7 +152,7 @@ def extract_cells(

# TODO: get_cell gets individual cell, need one that gets columns
df_subset = subset_frame(df_stringified, cols=columns)
return to_column_dict(df_subset)
return to_dict(df_subset)


def _render(self: GT):
Expand All @@ -146,7 +161,7 @@ def _render(self: GT):

# add_css_styles()

table_id = self._options["table_id"] or random_id()
table_id = OptWrapper(self._options)["table_id"] or random_id()
locale = self._locale

# generate Language -------------------------------------------------------
Expand Down Expand Up @@ -243,7 +258,7 @@ def _render(self: GT):
)

# Generate theme ----------------------------------------------------------
opts = self._options
opts = OptWrapper(self._options)
theme = Theme(
color=opts["table_font_color"],
background_color=opts["table_background_color"],
Expand Down
40 changes: 40 additions & 0 deletions tests/test_tbl_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import pandas as pd
import polars as pl
import polars.testing
import pytest

from reactable._tbl_data import subset_frame, SimpleFrame, SimpleColumn

params_frames = [pytest.param(pd.DataFrame, id="pandas"), pytest.param(pl.DataFrame, id="polars")]
params_series = [pytest.param(pd.Series, id="pandas"), pytest.param(pl.Series, id="polars")]


@pytest.fixture(params=params_frames, scope="function")
def df(request) -> pd.DataFrame:
return request.param({"col1": [1, 2, 3], "col2": ["a", "b", "c"], "col3": [4.0, 5.0, 6.0]})


@pytest.fixture(params=params_series, scope="function")
def ser(request):
return request.param([1.0, 2.0, None])


def assert_frame_equal(src, target, include_index=True):
if isinstance(src, pd.DataFrame):
if not include_index:
src = src.reset_index(drop=True)
target = target.reset_index(drop=True)
pd.testing.assert_frame_equal(src, target)
elif isinstance(src, pl.DataFrame):
pl.testing.assert_frame_equal(src, target)
else:
raise NotImplementedError(f"Unsupported data type: {type(src)}")


def test_subset_frame(df):
res = subset_frame(df, rows=[0, 2], cols=["col1", "col3"])
assert_frame_equal(
res,
df.__class__({"col1": [1, 3], "col3": [4.0, 6.0]}),
include_index=False,
)
Loading