flatbread 0.1.2__tar.gz → 0.1.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. {flatbread-0.1.2 → flatbread-0.1.3}/PKG-INFO +1 -1
  2. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/config/config.defaults.json +10 -1
  3. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/render/constants.py +16 -3
  4. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/render/display.py +46 -0
  5. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/render/tablespec.py +43 -5
  6. {flatbread-0.1.2 → flatbread-0.1.3}/pyproject.toml +1 -1
  7. {flatbread-0.1.2 → flatbread-0.1.3}/.gitignore +0 -0
  8. {flatbread-0.1.2 → flatbread-0.1.3}/environment.yml +0 -0
  9. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/__init__.py +0 -0
  10. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/accessors/dataframe.py +0 -0
  11. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/accessors/index.py +0 -0
  12. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/accessors/series.py +0 -0
  13. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/agg/aggregation.py +0 -0
  14. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/agg/totals.py +0 -0
  15. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/chaining.py +0 -0
  16. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/config.py +0 -0
  17. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/percentages.py +0 -0
  18. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/render/config.py +0 -0
  19. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/render/template.jinja.html +0 -0
  20. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/render/template.py +0 -0
  21. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/testing/dataframe.py +0 -0
  22. {flatbread-0.1.2 → flatbread-0.1.3}/flatbread/tooling.py +0 -0
  23. {flatbread-0.1.2 → flatbread-0.1.3}/license.md +0 -0
  24. {flatbread-0.1.2 → flatbread-0.1.3}/readme.md +0 -0
  25. {flatbread-0.1.2 → flatbread-0.1.3}/tests/__init__.py +0 -0
  26. {flatbread-0.1.2 → flatbread-0.1.3}/tests/aggregate/__init__.py +0 -0
  27. {flatbread-0.1.2 → flatbread-0.1.3}/tests/aggregate/test_percentages.py +0 -0
  28. {flatbread-0.1.2 → flatbread-0.1.3}/tests/aggregate/test_totals.py +0 -0
  29. {flatbread-0.1.2 → flatbread-0.1.3}/tests/test_axes.py +0 -0
  30. {flatbread-0.1.2 → flatbread-0.1.3}/tests/test_levels.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flatbread
3
- Version: 0.1.2
3
+ Version: 0.1.3
4
4
  Summary: Pandas extension for aggregation and tabular display
5
5
  Project-URL: Homepage, https://github.com/lcvriend/flatbread
6
6
  Author-email: "L.C. Vriend" <vanboefer@gmail.com>
@@ -13,5 +13,14 @@
13
13
  "ndigits": -1,
14
14
  "base": 1
15
15
  },
16
- "locale": null
16
+ "locale": null,
17
+ "format_presets": {
18
+ "currency_eur": {
19
+ "dtypes": ["float", "int"],
20
+ "options": {
21
+ "style": "currency",
22
+ "currency": "EUR"
23
+ }
24
+ }
25
+ }
17
26
  }
@@ -2,6 +2,19 @@
2
2
  from flatbread import DEFAULTS
3
3
 
4
4
 
5
+ USER_PRESETS = DEFAULTS.get("format_presets", {})
6
+ USER_PRESETS_BY_DTYPE = {
7
+ dtype: set()
8
+ for dtype in ["float", "int", "datetime", "str", "category"]
9
+ }
10
+
11
+ for preset_name, preset_config in USER_PRESETS.items():
12
+ preset_dtypes = preset_config.get("dtypes", ["float", "int"]) # Default to numeric
13
+ for dtype in preset_dtypes:
14
+ if dtype in USER_PRESETS_BY_DTYPE:
15
+ USER_PRESETS_BY_DTYPE[dtype].add(preset_name)
16
+
17
+
5
18
  SMART_FORMATS = {
6
19
  'percentages': {
7
20
  'labels': [DEFAULTS['percentages']['label_pct']],
@@ -43,7 +56,7 @@ NUMBER_PRESETS = {"default", "currency", "percentage", "compact", "diffs"}
43
56
  DATE_PRESETS = {"default", "date", "datetime"}
44
57
 
45
58
  DTYPE_TO_PRESETS = {
46
- "float": NUMBER_PRESETS,
47
- "int": NUMBER_PRESETS,
48
- "datetime": DATE_PRESETS
59
+ "float": NUMBER_PRESETS.union(USER_PRESETS_BY_DTYPE["float"]),
60
+ "int": NUMBER_PRESETS.union(USER_PRESETS_BY_DTYPE["int"]),
61
+ "datetime": DATE_PRESETS.union(USER_PRESETS_BY_DTYPE["datetime"]),
49
62
  }
@@ -147,6 +147,52 @@ class PitaDisplayMixin:
147
147
  self._table_spec_builder.set_formats(formats)
148
148
  return self
149
149
 
150
+ def list_format_presets(self, dtype: str = None) -> dict[str, dict]:
151
+ """List available format presets, optionally filtered by data type
152
+
153
+ Parameters
154
+ ----------
155
+ dtype : str, optional
156
+ Filter presets by data type compatibility. Options: 'float', 'int',
157
+ 'datetime', 'str', 'category'.
158
+
159
+ Returns
160
+ -------
161
+ dict
162
+ Dictionary of preset names and their configurations
163
+ """
164
+ from flatbread.render.constants import USER_PRESETS, DTYPE_TO_PRESETS
165
+
166
+ # Define built-in presets with their configurations
167
+ built_in = {
168
+ "default": {"notation": "standard"},
169
+ "currency": {"style": "currency", "currency": "USD"},
170
+ "percentage": {"style": "percent"},
171
+ "compact": {"notation": "compact"},
172
+ "date": {"dateStyle": "short"},
173
+ "datetime": {"dateStyle": "short", "timeStyle": "short"}
174
+ }
175
+
176
+ # Extract user preset options
177
+ user_options = {
178
+ name: config.get("options", {})
179
+ for name, config in USER_PRESETS.items()
180
+ }
181
+
182
+ # Combine built-in and user presets
183
+ all_presets = {**built_in, **user_options}
184
+
185
+ # Filter by dtype if specified
186
+ if dtype:
187
+ if dtype not in DTYPE_TO_PRESETS:
188
+ valid_dtypes = ", ".join(sorted(DTYPE_TO_PRESETS.keys()))
189
+ raise ValueError(f"Invalid dtype '{dtype}'. Valid options are: {valid_dtypes}")
190
+
191
+ valid_presets = DTYPE_TO_PRESETS.get(dtype, set())
192
+ return {k: v for k, v in all_presets.items() if k in valid_presets}
193
+
194
+ return all_presets
195
+
150
196
  def _repr_html_(self) -> str:
151
197
  """Generate HTML representation for Jupyter display"""
152
198
  spec = self._table_spec_builder.get_spec_as_json()
@@ -94,17 +94,51 @@ class TableSpecBuilder:
94
94
  return format_type['options']
95
95
  return None
96
96
 
97
- def set_format(self, column: str, format_spec: ColumnFormat) -> None:
97
+ def set_format(self, column: str, format_spec: str | dict[str, Any]) -> None:
98
+ """Set format options for a column
99
+
100
+ Parameters
101
+ ----------
102
+ column : str
103
+ Column to format
104
+ format_spec : str | dict
105
+ Either a preset name (e.g. 'currency') or format options dict
106
+ """
107
+ from flatbread.render.constants import USER_PRESETS, DTYPE_TO_PRESETS, DEFAULT_DTYPES
108
+
98
109
  if isinstance(format_spec, str):
110
+ # Check if it's a user-defined preset
111
+ if format_spec in USER_PRESETS:
112
+ pandas_dtype = str(self._data[column].dtype)
113
+ simple_dtype = DEFAULT_DTYPES.get(pandas_dtype, 'str')
114
+
115
+ # Get allowed dtypes for this preset
116
+ preset_config = USER_PRESETS[format_spec]
117
+ allowed_dtypes = preset_config.get("dtypes", ["float", "int"])
118
+
119
+ if simple_dtype in allowed_dtypes:
120
+ self._format_options[column] = preset_config.get("options", {})
121
+ return
122
+ else:
123
+ raise ValueError(
124
+ f"Preset '{format_spec}' is not compatible with column '{column}' "
125
+ f"of dtype {pandas_dtype} (mapped to {simple_dtype}). "
126
+ f"This preset supports: {', '.join(allowed_dtypes)}"
127
+ )
128
+
129
+ # Handle built-in presets
99
130
  pandas_dtype = str(self._data[column].dtype)
100
131
  simple_dtype = DEFAULT_DTYPES.get(pandas_dtype, 'str')
101
132
  valid_presets = DTYPE_TO_PRESETS.get(simple_dtype, set())
133
+
102
134
  if format_spec not in valid_presets:
103
135
  valid = ", ".join(sorted(valid_presets))
104
136
  raise ValueError(
105
137
  f"Invalid preset '{format_spec}' for dtype {pandas_dtype} "
106
138
  f"(mapped to {simple_dtype}). Valid presets are: {valid}"
107
139
  )
140
+
141
+ # If we reached here, either format_spec is a dict or a valid built-in preset
108
142
  self._format_options[column] = format_spec
109
143
 
110
144
  def set_formats(self, formats: FormatSpec) -> None:
@@ -112,11 +146,15 @@ class TableSpecBuilder:
112
146
 
113
147
  Parameters
114
148
  ----------
115
- formats : dict, list or callable
116
- Either dict mapping column names to format specs,
117
- a list of length columns,
118
- or function that takes DataFrame and returns such dict
149
+ formats : str, dict, list or callable
150
+ - If string: apply the same format preset to all columns
151
+ - If dict: mapping column names to format specs
152
+ - If list: format specs in same order as columns
153
+ - If callable: function that takes DataFrame and returns a dict
119
154
  """
155
+ if isinstance(formats, str):
156
+ formats = {column: formats for column in self._data.columns}
157
+
120
158
  if callable(formats):
121
159
  formats = formats(self._data)
122
160
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "flatbread"
7
- version = "0.1.2"
7
+ version = "0.1.3"
8
8
  description = "Pandas extension for aggregation and tabular display"
9
9
  readme = "readme.md"
10
10
  requires-python = ">=3.10"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes