Skip to content

Commit

Permalink
Merge pull request #12 from machow/fix-gt-deps
Browse files Browse the repository at this point in the history
Fix gt deps
  • Loading branch information
machow authored Aug 23, 2024
2 parents 0e33b89 + 299c13d commit 3856082
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 12 deletions.
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,
)

0 comments on commit 3856082

Please sign in to comment.