`__ e.g 'rcl'
+ for 3 columns
"""
- return self.builder.get_result()
+ buf.write(f"\\begin{{longtable}}{{{column_format}}}\n")
- @property
- def builder(self) -> TableBuilderAbstract:
- """Concrete table builder.
+ if self.caption is not None or self.label is not None:
+ if self.caption is None:
+ pass
+ else:
+ buf.write(f"\\caption{{{self.caption}}}")
- Returns
- -------
- TableBuilder
- """
- builder = self._select_builder()
- return builder(
- formatter=self.fmt,
- column_format=self.column_format,
- multicolumn=self.multicolumn,
- multicolumn_format=self.multicolumn_format,
- multirow=self.multirow,
- caption=self.caption,
- short_caption=self.short_caption,
- label=self.label,
- position=self.position,
- )
+ if self.label is None:
+ pass
+ else:
+ buf.write(f"\\label{{{self.label}}}")
- def _select_builder(self) -> Type[TableBuilderAbstract]:
- """Select proper table builder."""
- if self.longtable:
- return LongTableBuilder
- if any([self.caption, self.label, self.position]):
- return RegularTableBuilder
- return TabularBuilder
-
- @property
- def column_format(self) -> Optional[str]:
- """Column format."""
- return self._column_format
-
- @column_format.setter
- def column_format(self, input_column_format: Optional[str]) -> None:
- """Setter for column format."""
- if input_column_format is None:
- self._column_format = (
- self._get_index_format() + self._get_column_format_based_on_dtypes()
- )
- elif not isinstance(input_column_format, str):
- raise ValueError(
- f"column_format must be str or unicode, "
- f"not {type(input_column_format)}"
- )
+ # a double-backslash is required at the end of the line
+ # as discussed here:
+ # https://tex.stackexchange.com/questions/219138
+ buf.write("\\\\\n")
else:
- self._column_format = input_column_format
+ pass
- def _get_column_format_based_on_dtypes(self) -> str:
- """Get column format based on data type.
-
- Right alignment for numbers and left - for strings.
+ @staticmethod
+ def _write_longtable_end(buf):
"""
+ Write the end of a longtable environment.
- def get_col_type(dtype):
- if issubclass(dtype.type, np.number):
- return "r"
- return "l"
+ Parameters
+ ----------
+ buf : string or file handle
+ File path or object. If not specified, the result is returned as
+ a string.
- dtypes = self.frame.dtypes._values
- return "".join(map(get_col_type, dtypes))
-
- def _get_index_format(self) -> str:
- """Get index column format."""
- return "l" * self.frame.index.nlevels if self.fmt.index else ""
-
-
-def _escape_symbols(row: Sequence[str]) -> List[str]:
- """Carry out string replacements for special symbols.
-
- Parameters
- ----------
- row : list
- List of string, that may contain special symbols.
-
- Returns
- -------
- list
- list of strings with the special symbols replaced.
- """
- return [
- (
- x.replace("\\", "\\textbackslash ")
- .replace("_", "\\_")
- .replace("%", "\\%")
- .replace("$", "\\$")
- .replace("#", "\\#")
- .replace("{", "\\{")
- .replace("}", "\\}")
- .replace("~", "\\textasciitilde ")
- .replace("^", "\\textasciicircum ")
- .replace("&", "\\&")
- if (x and x != "{}")
- else "{}"
- )
- for x in row
- ]
-
-
-def _convert_to_bold(crow: Sequence[str], ilevels: int) -> List[str]:
- """Convert elements in ``crow`` to bold."""
- return [
- f"\\textbf{{{x}}}" if j < ilevels and x.strip() not in ["", "{}"] else x
- for j, x in enumerate(crow)
- ]
-
-
-if __name__ == "__main__":
- import doctest
-
- doctest.testmod()
+ """
+ buf.write("\\end{longtable}\n")
diff --git a/venv/lib/python3.8/site-packages/pandas/io/formats/printing.py b/venv/lib/python3.8/site-packages/pandas/io/formats/printing.py
index 128e50d..1cf79dc 100644
--- a/venv/lib/python3.8/site-packages/pandas/io/formats/printing.py
+++ b/venv/lib/python3.8/site-packages/pandas/io/formats/printing.py
@@ -12,7 +12,6 @@ from typing import (
Mapping,
Optional,
Sequence,
- Sized,
Tuple,
TypeVar,
Union,
@@ -206,7 +205,7 @@ def pprint_thing(
translate = escape_chars
escape_chars = list(escape_chars.keys())
else:
- escape_chars = escape_chars or ()
+ escape_chars = escape_chars or tuple()
result = str(thing)
for c in escape_chars:
@@ -244,7 +243,7 @@ def pprint_thing_encoded(
return value.encode(encoding, errors)
-def enable_data_resource_formatter(enable: bool) -> None:
+def _enable_data_resource_formatter(enable: bool) -> None:
if "IPython" not in sys.modules:
# definitely not in IPython
return
@@ -308,7 +307,7 @@ def format_object_summary(
name : name, optional
defaults to the class name of the obj
indent_for_name : bool, default True
- Whether subsequent lines should be indented to
+ Whether subsequent lines should be be indented to
align with the name.
line_break_each_value : bool, default False
If True, inserts a line break for each value of ``obj``.
@@ -322,7 +321,7 @@ def format_object_summary(
summary string
"""
from pandas.io.formats.console import get_console_size
- from pandas.io.formats.format import get_adjustment
+ from pandas.io.formats.format import _get_adjustment
display_width, _ = get_console_size()
if display_width is None:
@@ -351,7 +350,7 @@ def format_object_summary(
is_truncated = n > max_seq_items
# adj can optionally handle unicode eastern asian width
- adj = get_adjustment()
+ adj = _get_adjustment()
def _extend_line(
s: str, line: str, value: str, display_width: int, next_line_prefix: str
@@ -500,11 +499,11 @@ def _justify(
# error: Incompatible return value type (got "Tuple[List[Sequence[str]],
# List[Sequence[str]]]", expected "Tuple[List[Tuple[str, ...]],
# List[Tuple[str, ...]]]")
- return head, tail # type: ignore[return-value]
+ return head, tail # type: ignore
def format_object_attrs(
- obj: Sized, include_dtype: bool = True
+ obj: Sequence, include_dtype: bool = True
) -> List[Tuple[str, Union[str, int]]]:
"""
Return a list of tuples of the (attr, formatted_value)
@@ -513,7 +512,7 @@ def format_object_attrs(
Parameters
----------
obj : object
- Must be sized.
+ must be iterable
include_dtype : bool
If False, dtype won't be in the returned list
@@ -524,17 +523,15 @@ def format_object_attrs(
"""
attrs: List[Tuple[str, Union[str, int]]] = []
if hasattr(obj, "dtype") and include_dtype:
- # error: "Sized" has no attribute "dtype"
- attrs.append(("dtype", f"'{obj.dtype}'")) # type: ignore[attr-defined]
+ # error: "Sequence[Any]" has no attribute "dtype"
+ attrs.append(("dtype", f"'{obj.dtype}'")) # type: ignore
if getattr(obj, "name", None) is not None:
- # error: "Sized" has no attribute "name"
- attrs.append(("name", default_pprint(obj.name))) # type: ignore[attr-defined]
- # error: "Sized" has no attribute "names"
- elif getattr(obj, "names", None) is not None and any(
- obj.names # type: ignore[attr-defined]
- ):
- # error: "Sized" has no attribute "names"
- attrs.append(("names", default_pprint(obj.names))) # type: ignore[attr-defined]
+ # error: "Sequence[Any]" has no attribute "name"
+ attrs.append(("name", default_pprint(obj.name))) # type: ignore
+ # error: "Sequence[Any]" has no attribute "names"
+ elif getattr(obj, "names", None) is not None and any(obj.names): # type: ignore
+ # error: "Sequence[Any]" has no attribute "names"
+ attrs.append(("names", default_pprint(obj.names))) # type: ignore
max_seq_items = get_option("display.max_seq_items") or len(obj)
if len(obj) > max_seq_items:
attrs.append(("length", len(obj)))
diff --git a/venv/lib/python3.8/site-packages/pandas/io/formats/string.py b/venv/lib/python3.8/site-packages/pandas/io/formats/string.py
deleted file mode 100644
index 4ebb78f..0000000
--- a/venv/lib/python3.8/site-packages/pandas/io/formats/string.py
+++ /dev/null
@@ -1,201 +0,0 @@
-"""
-Module for formatting output data in console (to string).
-"""
-from shutil import get_terminal_size
-from typing import Iterable, List, Optional
-
-import numpy as np
-
-from pandas.io.formats.format import DataFrameFormatter
-from pandas.io.formats.printing import pprint_thing
-
-
-class StringFormatter:
- """Formatter for string representation of a dataframe."""
-
- def __init__(self, fmt: DataFrameFormatter, line_width: Optional[int] = None):
- self.fmt = fmt
- self.adj = fmt.adj
- self.frame = fmt.frame
- self.line_width = line_width
-
- def to_string(self) -> str:
- text = self._get_string_representation()
- if self.fmt.should_show_dimensions:
- text = "".join([text, self.fmt.dimensions_info])
- return text
-
- def _get_strcols(self) -> List[List[str]]:
- strcols = self.fmt.get_strcols()
- if self.fmt.is_truncated:
- strcols = self._insert_dot_separators(strcols)
- return strcols
-
- def _get_string_representation(self) -> str:
- if self.fmt.frame.empty:
- return self._empty_info_line
-
- strcols = self._get_strcols()
-
- if self.line_width is None:
- # no need to wrap around just print the whole frame
- return self.adj.adjoin(1, *strcols)
-
- if self._need_to_wrap_around:
- return self._join_multiline(strcols)
-
- return self._fit_strcols_to_terminal_width(strcols)
-
- @property
- def _empty_info_line(self) -> str:
- return (
- f"Empty {type(self.frame).__name__}\n"
- f"Columns: {pprint_thing(self.frame.columns)}\n"
- f"Index: {pprint_thing(self.frame.index)}"
- )
-
- @property
- def _need_to_wrap_around(self) -> bool:
- return bool(self.fmt.max_cols is None or self.fmt.max_cols > 0)
-
- def _insert_dot_separators(self, strcols: List[List[str]]) -> List[List[str]]:
- str_index = self.fmt._get_formatted_index(self.fmt.tr_frame)
- index_length = len(str_index)
-
- if self.fmt.is_truncated_horizontally:
- strcols = self._insert_dot_separator_horizontal(strcols, index_length)
-
- if self.fmt.is_truncated_vertically:
- strcols = self._insert_dot_separator_vertical(strcols, index_length)
-
- return strcols
-
- def _insert_dot_separator_horizontal(
- self, strcols: List[List[str]], index_length: int
- ) -> List[List[str]]:
- strcols.insert(self.fmt.tr_col_num + 1, [" ..."] * index_length)
- return strcols
-
- def _insert_dot_separator_vertical(
- self, strcols: List[List[str]], index_length: int
- ) -> List[List[str]]:
- n_header_rows = index_length - len(self.fmt.tr_frame)
- row_num = self.fmt.tr_row_num
- for ix, col in enumerate(strcols):
- cwidth = self.adj.len(col[row_num])
-
- if self.fmt.is_truncated_horizontally:
- is_dot_col = ix == self.fmt.tr_col_num + 1
- else:
- is_dot_col = False
-
- if cwidth > 3 or is_dot_col:
- dots = "..."
- else:
- dots = ".."
-
- if ix == 0:
- dot_mode = "left"
- elif is_dot_col:
- cwidth = 4
- dot_mode = "right"
- else:
- dot_mode = "right"
-
- dot_str = self.adj.justify([dots], cwidth, mode=dot_mode)[0]
- col.insert(row_num + n_header_rows, dot_str)
- return strcols
-
- def _join_multiline(self, strcols_input: Iterable[List[str]]) -> str:
- lwidth = self.line_width
- adjoin_width = 1
- strcols = list(strcols_input)
-
- if self.fmt.index:
- idx = strcols.pop(0)
- lwidth -= np.array([self.adj.len(x) for x in idx]).max() + adjoin_width
-
- col_widths = [
- np.array([self.adj.len(x) for x in col]).max() if len(col) > 0 else 0
- for col in strcols
- ]
-
- assert lwidth is not None
- col_bins = _binify(col_widths, lwidth)
- nbins = len(col_bins)
-
- if self.fmt.is_truncated_vertically:
- assert self.fmt.max_rows_fitted is not None
- nrows = self.fmt.max_rows_fitted + 1
- else:
- nrows = len(self.frame)
-
- str_lst = []
- start = 0
- for i, end in enumerate(col_bins):
- row = strcols[start:end]
- if self.fmt.index:
- row.insert(0, idx)
- if nbins > 1:
- if end <= len(strcols) and i < nbins - 1:
- row.append([" \\"] + [" "] * (nrows - 1))
- else:
- row.append([" "] * nrows)
- str_lst.append(self.adj.adjoin(adjoin_width, *row))
- start = end
- return "\n\n".join(str_lst)
-
- def _fit_strcols_to_terminal_width(self, strcols: List[List[str]]) -> str:
- from pandas import Series
-
- lines = self.adj.adjoin(1, *strcols).split("\n")
- max_len = Series(lines).str.len().max()
- # plus truncate dot col
- width, _ = get_terminal_size()
- dif = max_len - width
- # '+ 1' to avoid too wide repr (GH PR #17023)
- adj_dif = dif + 1
- col_lens = Series([Series(ele).apply(len).max() for ele in strcols])
- n_cols = len(col_lens)
- counter = 0
- while adj_dif > 0 and n_cols > 1:
- counter += 1
- mid = int(round(n_cols / 2.0))
- mid_ix = col_lens.index[mid]
- col_len = col_lens[mid_ix]
- # adjoin adds one
- adj_dif -= col_len + 1
- col_lens = col_lens.drop(mid_ix)
- n_cols = len(col_lens)
-
- # subtract index column
- max_cols_fitted = n_cols - self.fmt.index
- # GH-21180. Ensure that we print at least two.
- max_cols_fitted = max(max_cols_fitted, 2)
- self.fmt.max_cols_fitted = max_cols_fitted
-
- # Call again _truncate to cut frame appropriately
- # and then generate string representation
- self.fmt.truncate()
- strcols = self._get_strcols()
- return self.adj.adjoin(1, *strcols)
-
-
-def _binify(cols: List[int], line_width: int) -> List[int]:
- adjoin_width = 1
- bins = []
- curr_width = 0
- i_last_column = len(cols) - 1
- for i, w in enumerate(cols):
- w_adjoined = w + adjoin_width
- curr_width += w_adjoined
- if i_last_column == i:
- wrap = curr_width + 1 > line_width and i > 0
- else:
- wrap = curr_width + 2 > line_width and i > 0
- if wrap:
- bins.append(i)
- curr_width = w_adjoined
-
- bins.append(len(cols))
- return bins
diff --git a/venv/lib/python3.8/site-packages/pandas/io/formats/style.py b/venv/lib/python3.8/site-packages/pandas/io/formats/style.py
index 6ed31f3..3bbb527 100644
--- a/venv/lib/python3.8/site-packages/pandas/io/formats/style.py
+++ b/venv/lib/python3.8/site-packages/pandas/io/formats/style.py
@@ -1,6 +1,7 @@
"""
Module for applying conditional formatting to DataFrames and Series.
"""
+
from collections import defaultdict
from contextlib import contextmanager
import copy
@@ -17,7 +18,7 @@ from typing import (
Tuple,
Union,
)
-from uuid import uuid4
+from uuid import uuid1
import numpy as np
@@ -32,11 +33,10 @@ from pandas.core.dtypes.common import is_float
import pandas as pd
from pandas.api.types import is_dict_like, is_list_like
-from pandas.core import generic
import pandas.core.common as com
from pandas.core.frame import DataFrame
from pandas.core.generic import NDFrame
-from pandas.core.indexing import maybe_numeric_slice, non_reducing_slice
+from pandas.core.indexing import _maybe_numeric_slice, _non_reducing_slice
jinja2 = import_optional_dependency("jinja2", extra="DataFrame.style requires jinja2.")
@@ -89,12 +89,6 @@ class Styler:
.. versionadded:: 1.0.0
- uuid_len : int, default 5
- If ``uuid`` is not specified, the length of the ``uuid`` to randomly generate
- expressed in hex characters, in range [0, 32].
-
- .. versionadded:: 1.2.0
-
Attributes
----------
env : Jinja2 jinja2.Environment
@@ -150,7 +144,6 @@ class Styler:
table_attributes: Optional[str] = None,
cell_ids: bool = True,
na_rep: Optional[str] = None,
- uuid_len: int = 5,
):
self.ctx: DefaultDict[Tuple[int, int], List[str]] = defaultdict(list)
self._todo: List[Tuple[Callable, Tuple, Dict]] = []
@@ -166,10 +159,7 @@ class Styler:
self.index = data.index
self.columns = data.columns
- if not isinstance(uuid_len, int) or not uuid_len >= 0:
- raise TypeError("``uuid_len`` must be an integer in range [0, 32].")
- self.uuid_len = min(32, uuid_len)
- self.uuid = (uuid or uuid4().hex[: self.uuid_len]) + "_"
+ self.uuid = uuid
self.table_styles = table_styles
self.caption = caption
if precision is None:
@@ -181,8 +171,6 @@ class Styler:
self.cell_ids = cell_ids
self.na_rep = na_rep
- self.cell_context: Dict[str, Any] = {}
-
# display_funcs maps (row, col) -> formatting function
def default_display_func(x):
@@ -204,11 +192,7 @@ class Styler:
"""
return self.render()
- @doc(
- NDFrame.to_excel,
- klass="Styler",
- storage_options=generic._shared_docs["storage_options"],
- )
+ @doc(NDFrame.to_excel, klass="Styler")
def to_excel(
self,
excel_writer,
@@ -262,7 +246,7 @@ class Styler:
precision = self.precision
hidden_index = self.hidden_index
hidden_columns = self.hidden_columns
- uuid = self.uuid
+ uuid = self.uuid or str(uuid1()).replace("-", "_")
ROW_HEADING_CLASS = "row_heading"
COL_HEADING_CLASS = "col_heading"
INDEX_NAME_CLASS = "index_name"
@@ -278,7 +262,7 @@ class Styler:
idx_lengths = _get_level_lengths(self.index)
col_lengths = _get_level_lengths(self.columns, hidden_columns)
- cell_context = self.cell_context
+ cell_context = dict()
n_rlvls = self.data.index.nlevels
n_clvls = self.data.columns.nlevels
@@ -343,7 +327,7 @@ class Styler:
colspan = col_lengths.get((r, c), 0)
if colspan > 1:
es["attributes"] = [
- format_attr({"key": "colspan", "value": f'"{colspan}"'})
+ format_attr({"key": "colspan", "value": colspan})
]
row_es.append(es)
head.append(row_es)
@@ -389,7 +373,7 @@ class Styler:
rowspan = idx_lengths.get((c, r), 0)
if rowspan > 1:
es["attributes"] = [
- format_attr({"key": "rowspan", "value": f'"{rowspan}"'})
+ format_attr({"key": "rowspan", "value": rowspan})
]
row_es.append(es)
@@ -433,16 +417,16 @@ class Styler:
else:
table_attr += ' class="tex2jax_ignore"'
- return {
- "head": head,
- "cellstyle": cellstyle,
- "body": body,
- "uuid": uuid,
- "precision": precision,
- "table_styles": table_styles,
- "caption": caption,
- "table_attributes": table_attr,
- }
+ return dict(
+ head=head,
+ cellstyle=cellstyle,
+ body=body,
+ uuid=uuid,
+ precision=precision,
+ table_styles=table_styles,
+ caption=caption,
+ table_attributes=table_attr,
+ )
def format(self, formatter, subset=None, na_rep: Optional[str] = None) -> "Styler":
"""
@@ -491,7 +475,7 @@ class Styler:
row_locs = range(len(self.data))
col_locs = range(len(self.data.columns))
else:
- subset = non_reducing_slice(subset)
+ subset = _non_reducing_slice(subset)
if len(subset) == 1:
subset = subset, self.data.columns
@@ -515,69 +499,6 @@ class Styler:
self._display_funcs[(i, j)] = formatter
return self
- def set_td_classes(self, classes: DataFrame) -> "Styler":
- """
- Add string based CSS class names to data cells that will appear within the
- `Styler` HTML result. These classes are added within specified `` elements.
-
- Parameters
- ----------
- classes : DataFrame
- DataFrame containing strings that will be translated to CSS classes,
- mapped by identical column and index values that must exist on the
- underlying `Styler` data. None, NaN values, and empty strings will
- be ignored and not affect the rendered HTML.
-
- Returns
- -------
- self : Styler
-
- Examples
- --------
- >>> df = pd.DataFrame(data=[[1, 2, 3], [4, 5, 6]], columns=["A", "B", "C"])
- >>> classes = pd.DataFrame([
- ... ["min-val red", "", "blue"],
- ... ["red", None, "blue max-val"]
- ... ], index=df.index, columns=df.columns)
- >>> df.style.set_td_classes(classes)
-
- Using `MultiIndex` columns and a `classes` `DataFrame` as a subset of the
- underlying,
-
- >>> df = pd.DataFrame([[1,2],[3,4]], index=["a", "b"],
- ... columns=[["level0", "level0"], ["level1a", "level1b"]])
- >>> classes = pd.DataFrame(["min-val"], index=["a"],
- ... columns=[["level0"],["level1a"]])
- >>> df.style.set_td_classes(classes)
-
- Form of the output with new additional css classes,
-
- >>> df = pd.DataFrame([[1]])
- >>> css = pd.DataFrame(["other-class"])
- >>> s = Styler(df, uuid="_", cell_ids=False).set_td_classes(css)
- >>> s.hide_index().render()
- ''
- ''
- ' '
- ' 0 | '
- ' '
- ' '
- ' 1 | '
- ' '
- ' '
- """
- classes = classes.reindex_like(self.data)
-
- mask = (classes.isna()) | (classes.eq(""))
- self.cell_context["data"] = {
- r: {c: [str(classes.iloc[r, c])]}
- for r, rn in enumerate(classes.index)
- for c, cn in enumerate(classes.columns)
- if not mask.iloc[r, c]
- }
-
- return self
-
def render(self, **kwargs) -> str:
"""
Render the built up styles to HTML.
@@ -688,7 +609,6 @@ class Styler:
Returns None.
"""
self.ctx.clear()
- self.cell_context = {}
self._todo = []
def _compute(self):
@@ -713,7 +633,7 @@ class Styler:
**kwargs,
) -> "Styler":
subset = slice(None) if subset is None else subset
- subset = non_reducing_slice(subset)
+ subset = _non_reducing_slice(subset)
data = self.data.loc[subset]
if axis is not None:
result = data.apply(func, axis=axis, result_type="expand", **kwargs)
@@ -805,7 +725,7 @@ class Styler:
func = partial(func, **kwargs) # applymap doesn't take kwargs?
if subset is None:
subset = pd.IndexSlice[:]
- subset = non_reducing_slice(subset)
+ subset = _non_reducing_slice(subset)
result = self.data.loc[subset].applymap(func)
self._update_ctx(result)
return self
@@ -832,8 +752,7 @@ class Styler:
See Also
--------
- Styler.where: Updates the HTML representation with a style which is
- selected in accordance with the return value of a function.
+ Styler.where
"""
self._todo.append(
(lambda instance: getattr(instance, "_applymap"), (func, subset), kwargs)
@@ -874,7 +793,7 @@ class Styler:
See Also
--------
- Styler.applymap: Updates the HTML representation with the result.
+ Styler.applymap
"""
if other is None:
other = ""
@@ -903,7 +822,7 @@ class Styler:
Set the table attributes.
These are the items that show up in the opening ```` tag
- in addition to automatic (by default) id.
+ in addition to to automatic (by default) id.
Parameters
----------
@@ -934,7 +853,7 @@ class Styler:
See Also
--------
- Styler.use: Set the styles on the current Styler.
+ Styler.use
"""
return self._todo
@@ -955,7 +874,7 @@ class Styler:
See Also
--------
- Styler.export : Export the styles to applied to the current Styler.
+ Styler.export
"""
self._todo.extend(styles)
return self
@@ -990,46 +909,20 @@ class Styler:
self.caption = caption
return self
- def set_table_styles(self, table_styles, axis=0, overwrite=True) -> "Styler":
+ def set_table_styles(self, table_styles) -> "Styler":
"""
Set the table styles on a Styler.
These are placed in a `` |