spells-mtg 0.3.0__tar.gz → 0.4.0__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.

Potentially problematic release.


This version of spells-mtg might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spells-mtg
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: analaysis of 17Lands.com public datasets
5
5
  Author-Email: Joel Barnes <oelarnes@gmail.com>
6
6
  License: MIT
@@ -74,7 +74,7 @@ Spells is not affiliated with 17Lands. Please review the [Usage Guidelines](http
74
74
  - Supports calculating the standard aggregations and measures out of the box with no arguments (ALSA, GIH WR, etc)
75
75
  - Caches aggregate DataFrames in the local file system automatically for instantaneous reproduction of previous analysis
76
76
  - Manages grouping and filtering by built-in and custom columns at the row level
77
- - Provides 118 explicitly specified, enumerated, documented column definitions
77
+ - Provides 121 explicitly specified, enumerated, documented column definitions
78
78
  - Supports "Deck Color Data" aggregations with built-in column definitions.
79
79
  - Provides a CLI tool `spells [add|refresh|clean|remove|info] [SET]` to download and manage external files
80
80
  - Downloads and manages public datasets from 17Lands
@@ -112,24 +112,24 @@ Spells is not affiliated with 17Lands. Please review the [Usage Guidelines](http
112
112
  ```
113
113
  - `group_by` specifies the grouping by one or more columns. By default, group by card names, but optionally group by any of a large set of fundamental and derived columns, including card attributes and your own custom extension.
114
114
  ```python
115
- >>> spells.summon('BLB', columns=["num_won", "num_games", "game_wr"], group_by=["main_colors"], filter_spec={"num_colors": 2})
116
- shape: (10, 4)
117
- ┌─────────────┬─────────┬───────────┬──────────┐
118
- │ main_colors ┆ num_won ┆ num_games ┆ game_wr │
119
- │ --- ┆ --- ┆ --- ┆ --- │
120
- │ str ┆ u32 ┆ u32 ┆ f64 │
121
- ╞═════════════╪═════════╪═══════════╪══════════╡
122
- │ BG ┆ 85022 ┆ 152863 ┆ 0.556197 │
123
- │ BR ┆ 45900 ┆ 81966 ┆ 0.559988 │
124
- │ RG ┆ 34641 ┆ 64428 ┆ 0.53767 │
125
- │ UB ┆ 30922 ┆ 57698 ┆ 0.535928 │
126
- │ UG ┆ 59879 ┆ 109145 ┆ 0.548619 │
127
- │ UR ┆ 19638 ┆ 38679 ┆ 0.507717 │
128
- │ WB ┆ 59480 ┆ 107443 ┆ 0.553596 │
129
- │ WG ┆ 76134 ┆ 136832 ┆ 0.556405 │
130
- │ WR ┆ 49712 ┆ 91224 ┆ 0.544944 │
131
- │ WU ┆ 16483 ┆ 31450 ┆ 0.524102 │
132
- └─────────────┴─────────┴───────────┴──────────┘
115
+ >>> summon('BLB', columns=["num_won", "num_games", "game_wr", "deck_mana_value_avg"], group_by=["main_colors"], filter_spec={"num_colors": 2})
116
+ shape: (10, 5)
117
+ ┌─────────────┬─────────┬───────────┬──────────┬─────────────────────┐
118
+ │ main_colors ┆ num_won ┆ num_games ┆ game_wr ┆ deck_mana_value_avg
119
+ │ --- ┆ --- ┆ --- ┆ --- ┆ ---
120
+ │ str ┆ u32 ┆ u32 ┆ f64 ┆ f64
121
+ ╞═════════════╪═════════╪═══════════╪══════════╪═════════════════════╡
122
+ │ BG ┆ 85022 ┆ 152863 ┆ 0.556197 ┆ 2.862305
123
+ │ BR ┆ 45900 ┆ 81966 ┆ 0.559988 ┆ 2.76198
124
+ │ RG ┆ 34641 ┆ 64428 ┆ 0.53767 ┆ 2.852182
125
+ │ UB ┆ 30922 ┆ 57698 ┆ 0.535928 ┆ 3.10409
126
+ │ UG ┆ 59879 ┆ 109145 ┆ 0.548619 ┆ 2.861026
127
+ │ UR ┆ 19638 ┆ 38679 ┆ 0.507717 ┆ 2.908215
128
+ │ WB ┆ 59480 ┆ 107443 ┆ 0.553596 ┆ 2.9217
129
+ │ WG ┆ 76134 ┆ 136832 ┆ 0.556405 ┆ 2.721064
130
+ │ WR ┆ 49712 ┆ 91224 ┆ 0.544944 ┆ 2.5222
131
+ │ WU ┆ 16483 ┆ 31450 ┆ 0.524102 ┆ 2.930967
132
+ └─────────────┴─────────┴───────────┴──────────┴─────────────────────┘
133
133
  ```
134
134
  - `filter_spec` specifies a row-level filter for the dataset, using an intuitive custom query formulation
135
135
  ```python
@@ -156,8 +156,7 @@ Spells is not affiliated with 17Lands. Please review the [Usage Guidelines](http
156
156
  ... name='deq_base',
157
157
  ... col_type=ColType.AGG,
158
158
  ... expr=(pl.col('gp_wr_excess') + 0.03 * (1 - pl.col('ata')/14).pow(2)) * pl.col('pct_gp'),
159
- ... dependencies=['gp_wr_excess', 'ata', 'pct_gp']
160
- ...)
159
+ ... )
161
160
  >>> spells.summon('DSK', columns=['deq_base', 'color', 'rarity'], filter_spec={'player_cohort': 'Top'}, extensions=[ext])
162
161
  ... .filter(pl.col('deq_base').is_finite())
163
162
  ... .filter(pl.col('rarity').is_in(['common', 'uncommon'])
@@ -278,13 +277,13 @@ summon(
278
277
 
279
278
  #### parameters
280
279
 
281
- - columns: a list of string or `ColName` values to select as non-grouped columns. Valid `ColTypes` are `PICK_SUM`, `NAME_SUM`, `GAME_SUM`, `CARD_ATTR`, `CARD_SUM` and `AGG`. Min/Max/Unique
280
+ - columns: a list of string or `ColName` values to select as non-grouped columns. Valid `ColTypes` are `PICK_SUM`, `NAME_SUM`, `GAME_SUM`, `CARD_ATTR`, and `AGG`. Min/Max/Unique
282
281
  aggregations of non-numeric (or numeric) data types are not supported. If `None`, use a set of columns modeled on the commonly used values on 17Lands.com/card_data.
283
282
 
284
283
  - group_by: a list of string or `ColName` values to display as grouped columns. Valid `ColTypes` are `GROUP_BY` and `CARD_ATTR`. By default, group by "name" (card name).
285
284
 
286
285
  - filter_spec: a dictionary specifying a filter, using a small number of paradigms. Columns used must be in each base view ("draft" and "game") that the `columns` and `group_by` columns depend on, so
287
- `AGG`, `CARD_SUM` and `CARD_ATTR` columns are not valid. `NAME_SUM` columns are also not supported. Derived columns are supported. No filter is applied by default. Yes, I should rewrite it to use the mongo query language. The specification is best understood with examples:
286
+ `AGG` and `CARD_ATTR` columns are not valid. Functions of card attributes in the base views can be filtered on, see the documentation for `expr` for details. `NAME_SUM` columns are also not supported. Derived columns are supported. No filter is applied by default. Yes, I should rewrite it to use the mongo query language. The specification is best understood with examples:
288
287
 
289
288
  - `{'player_cohort': 'Top'}` "player_cohort" value equals "Top".
290
289
  - `{'lhs': 'player_cohort', 'op': 'in', 'rhs': ['Top', 'Middle']}` "player_cohort" value is either "Top" or "Middle". Supported values for `op` are `<`, `<=`, `>`, `>=`, `!=`, `=`, `in` and `nin`.
@@ -297,10 +296,10 @@ aggregations of non-numeric (or numeric) data types are not supported. If `None`
297
296
  ### Enums
298
297
 
299
298
  ```python
300
- from spells.enums import ColName, ColType, View
299
+ from spells.enums import ColName, ColType
301
300
  ```
302
301
 
303
- Recommended to import `ColName` for any usage of `summon`, and to import `ColType` when defining custom extensions. You shouldn't need `VIEW`.
302
+ Recommended to import `ColName` for any usage of `summon`, and to import `ColType` when defining custom extensions.
304
303
 
305
304
  ### ColumnSpec
306
305
 
@@ -310,11 +309,8 @@ from spells.columns import ColumnSpec
310
309
  ColumnSpec(
311
310
  name: str,
312
311
  col_type: ColType,
313
- expr: pl.Expr | None = None,
314
- exprMap: Callable[[str], pl.Expr] | None = None
315
- dependencies: list[str] | None = None
312
+ expr: pl.Expr | Callable[..., pl.Expr] | None = None,
316
313
  version: str | None = None
317
- views: list[View] | None = None,
318
314
  )
319
315
  ```
320
316
 
@@ -324,19 +320,19 @@ Used to define extensions in `summon`
324
320
 
325
321
  - `name`: any string, including existing columns, although this is very likely to break dependent columns, so don't do it. For `NAME_SUM` columns, the name is the prefix without the underscore, e.g. "drawn".
326
322
 
327
- - `col_type`: one of the `ColType` enum values, `FILTER_ONLY`, `GROUP_BY`, `PICK_SUM`, `NAME_SUM`, `GAME_SUM`, `CARD_ATTR`, `CARD_SUM`, and `AGG`. See documentation for `summon` for usage. All columns except `CARD_ATTR`, `CARD_SUM` and `AGG` must be derivable at the individual row level on one or both base views. `CARD_ATTR` must be derivable at the individual row level from the card file. `AGG` can depend on any column present after summing over groups, and can include polars Expression aggregations. `CARD_SUM` columns are expressed similarly to `AGG`, but they are calculated before grouping by card name and are summed before the `AGG` selection stage (for example, to calculate average mana value. See example notebook "Card Attributes"). Arbitrarily long chains of aggregate dependencies are supported.
328
-
329
- - `expr`: A polars expression giving the derivation of the column value at the first level where it is defined. For `NAME_SUM` columns the `exprMap` attribute must be used instead. `AGG` columns that depend on `NAME_SUM` columns reference the prefix (`cdef.name`) only, since the unpivot has occured prior to selection.
323
+ - `col_type`: one of the `ColType` enum values, `FILTER_ONLY`, `GROUP_BY`, `PICK_SUM`, `NAME_SUM`, `GAME_SUM`, `CARD_ATTR`, and `AGG`. See documentation for `summon` for usage. All columns except `CARD_ATTR`
324
+ and `AGG` must be derivable at the individual row level on one or both base views. `CARD_ATTR` must be derivable at the individual row level from the card file. `AGG` can depend on any column present after
325
+ summing over groups, and can include polars Expression aggregations. Arbitrarily long chains of aggregate dependencies are supported.
330
326
 
331
- - `exprMap`: A function of card name that returns the expression for a `NAME_SUM` column.
332
-
333
- - `dependencies`: A list of column names. All dependencies must be declared by name.
327
+ - `expr`: A polars expression or function returning a polars expression giving the derivation of the column value at the first level where it is defined.
328
+ - For `NAME_SUM` columns, `expr` must be a function of `name` which will result in a list of expressions mapped over all card names.
329
+ - `PICK_SUM` columns can also be functions on `name`, in which case the value will be a function of the value of the `PICK` field.
330
+ - `AGG` columns that depend on `NAME_SUM` columns reference the prefix (`cdef.name`) only, since the unpivot has occured prior to selection.
331
+ - The possible arguments to `expr`, in addition to `name` when appropriate, include the full `names` array as well as a dictionary called `card_context` which contains card dict objects with all `CARD_ATTR` values, including custom extensions. See example notebooks for more details.
334
332
 
335
333
  - `version`: When defining a column using a python function, as opposed to Polars expressions, add a unique version number so that the unique hashed signature of the column specification can be derived
336
334
  for caching purposes, since Polars cannot generate a serialization natively. When changing the definition, be sure to increment the version value. Otherwise you do not need to use this parameter.
337
335
 
338
- - `views`: Not needed for custom columns.
339
-
340
336
  ### Columns
341
337
 
342
338
  A table of all included columns. Columns can be referenced by enum or by string value in arguments and filter specs. The string value is always the lowercase version of the enum attribute.
@@ -424,6 +420,9 @@ A table of all included columns. Columns can be referenced by enum or by string
424
420
  | `CARD_TYPE` | `"card_type"` | `CARD` | `CARD_ATTR` | | String |
425
421
  | `SUBTYPE` | `"subtype"` | `CARD` | `CARD_ATTR` | | String |
426
422
  | `MANA_VALUE` | `"mana_value"` | `CARD` | `CARD_ATTR` | | Float |
423
+ | `DECK_MANA_VALUE` | `"deck_mana_value"` | | `NAME_SUM` | `DECK` * `MANA_VALUE` | Float |
424
+ | `DECK_LANDS` | `"deck_lands"` | | `NAME_SUM` | Number of lands in deck | Float |
425
+ | `DECK_SPELLS` | `"deck_spells"` | | `NAME_SUM` | Number of spells in deck | Float |
427
426
  | `MANA_COST` | `"mana_cost"` | `CARD` | `CARD_ATTR` | | String |
428
427
  | `POWER` | `"power"` | `CARD` | `CARD_ATTR` | | Float |
429
428
  | `TOUGHNESS` | `"toughness"` | `CARD` | `CARD_ATTR` | | Float |
@@ -462,6 +461,9 @@ A table of all included columns. Columns can be referenced by enum or by string
462
461
  | `GIH_WR_VAR` | `"gih_wr_var"` | | `AGG` | Game-weighted Variance | Float |
463
462
  | `GIH_WR_STDEV` | `"gh_wr_stdev"` | | `AGG` | Sqrt of `GIH_WR_VAR` | Float |
464
463
  | `GIH_WR_Z` | `"gih_wr_z"` | | `AGG` |`GIH_WR_EXCESS` / `GIH_WR_STDEV` | Float |
464
+ | `DECK_MANA_VALUE_AVG` | `"deck_mana_value_avg"` | | `AGG` | `DECK_MANA_VALUE ` / `DECK_SPELLS` | Float |
465
+ | `DECK_LANDS_AVG` | `"deck_lands_avg"` | | `AGG` | `DECK_LANDS ` / `NUM_GAMES` | Float |
466
+ | `DECK_SPELLS_AVG` | `"deck_spells_avg"` | | `AGG` | `DECK_SPELLS ` / `NUM_GAMES` | Float |
465
467
 
466
468
  # Roadmap to 1.0
467
469
 
@@ -63,7 +63,7 @@ Spells is not affiliated with 17Lands. Please review the [Usage Guidelines](http
63
63
  - Supports calculating the standard aggregations and measures out of the box with no arguments (ALSA, GIH WR, etc)
64
64
  - Caches aggregate DataFrames in the local file system automatically for instantaneous reproduction of previous analysis
65
65
  - Manages grouping and filtering by built-in and custom columns at the row level
66
- - Provides 118 explicitly specified, enumerated, documented column definitions
66
+ - Provides 121 explicitly specified, enumerated, documented column definitions
67
67
  - Supports "Deck Color Data" aggregations with built-in column definitions.
68
68
  - Provides a CLI tool `spells [add|refresh|clean|remove|info] [SET]` to download and manage external files
69
69
  - Downloads and manages public datasets from 17Lands
@@ -101,24 +101,24 @@ Spells is not affiliated with 17Lands. Please review the [Usage Guidelines](http
101
101
  ```
102
102
  - `group_by` specifies the grouping by one or more columns. By default, group by card names, but optionally group by any of a large set of fundamental and derived columns, including card attributes and your own custom extension.
103
103
  ```python
104
- >>> spells.summon('BLB', columns=["num_won", "num_games", "game_wr"], group_by=["main_colors"], filter_spec={"num_colors": 2})
105
- shape: (10, 4)
106
- ┌─────────────┬─────────┬───────────┬──────────┐
107
- │ main_colors ┆ num_won ┆ num_games ┆ game_wr │
108
- │ --- ┆ --- ┆ --- ┆ --- │
109
- │ str ┆ u32 ┆ u32 ┆ f64 │
110
- ╞═════════════╪═════════╪═══════════╪══════════╡
111
- │ BG ┆ 85022 ┆ 152863 ┆ 0.556197 │
112
- │ BR ┆ 45900 ┆ 81966 ┆ 0.559988 │
113
- │ RG ┆ 34641 ┆ 64428 ┆ 0.53767 │
114
- │ UB ┆ 30922 ┆ 57698 ┆ 0.535928 │
115
- │ UG ┆ 59879 ┆ 109145 ┆ 0.548619 │
116
- │ UR ┆ 19638 ┆ 38679 ┆ 0.507717 │
117
- │ WB ┆ 59480 ┆ 107443 ┆ 0.553596 │
118
- │ WG ┆ 76134 ┆ 136832 ┆ 0.556405 │
119
- │ WR ┆ 49712 ┆ 91224 ┆ 0.544944 │
120
- │ WU ┆ 16483 ┆ 31450 ┆ 0.524102 │
121
- └─────────────┴─────────┴───────────┴──────────┘
104
+ >>> summon('BLB', columns=["num_won", "num_games", "game_wr", "deck_mana_value_avg"], group_by=["main_colors"], filter_spec={"num_colors": 2})
105
+ shape: (10, 5)
106
+ ┌─────────────┬─────────┬───────────┬──────────┬─────────────────────┐
107
+ │ main_colors ┆ num_won ┆ num_games ┆ game_wr ┆ deck_mana_value_avg
108
+ │ --- ┆ --- ┆ --- ┆ --- ┆ ---
109
+ │ str ┆ u32 ┆ u32 ┆ f64 ┆ f64
110
+ ╞═════════════╪═════════╪═══════════╪══════════╪═════════════════════╡
111
+ │ BG ┆ 85022 ┆ 152863 ┆ 0.556197 ┆ 2.862305
112
+ │ BR ┆ 45900 ┆ 81966 ┆ 0.559988 ┆ 2.76198
113
+ │ RG ┆ 34641 ┆ 64428 ┆ 0.53767 ┆ 2.852182
114
+ │ UB ┆ 30922 ┆ 57698 ┆ 0.535928 ┆ 3.10409
115
+ │ UG ┆ 59879 ┆ 109145 ┆ 0.548619 ┆ 2.861026
116
+ │ UR ┆ 19638 ┆ 38679 ┆ 0.507717 ┆ 2.908215
117
+ │ WB ┆ 59480 ┆ 107443 ┆ 0.553596 ┆ 2.9217
118
+ │ WG ┆ 76134 ┆ 136832 ┆ 0.556405 ┆ 2.721064
119
+ │ WR ┆ 49712 ┆ 91224 ┆ 0.544944 ┆ 2.5222
120
+ │ WU ┆ 16483 ┆ 31450 ┆ 0.524102 ┆ 2.930967
121
+ └─────────────┴─────────┴───────────┴──────────┴─────────────────────┘
122
122
  ```
123
123
  - `filter_spec` specifies a row-level filter for the dataset, using an intuitive custom query formulation
124
124
  ```python
@@ -145,8 +145,7 @@ Spells is not affiliated with 17Lands. Please review the [Usage Guidelines](http
145
145
  ... name='deq_base',
146
146
  ... col_type=ColType.AGG,
147
147
  ... expr=(pl.col('gp_wr_excess') + 0.03 * (1 - pl.col('ata')/14).pow(2)) * pl.col('pct_gp'),
148
- ... dependencies=['gp_wr_excess', 'ata', 'pct_gp']
149
- ...)
148
+ ... )
150
149
  >>> spells.summon('DSK', columns=['deq_base', 'color', 'rarity'], filter_spec={'player_cohort': 'Top'}, extensions=[ext])
151
150
  ... .filter(pl.col('deq_base').is_finite())
152
151
  ... .filter(pl.col('rarity').is_in(['common', 'uncommon'])
@@ -267,13 +266,13 @@ summon(
267
266
 
268
267
  #### parameters
269
268
 
270
- - columns: a list of string or `ColName` values to select as non-grouped columns. Valid `ColTypes` are `PICK_SUM`, `NAME_SUM`, `GAME_SUM`, `CARD_ATTR`, `CARD_SUM` and `AGG`. Min/Max/Unique
269
+ - columns: a list of string or `ColName` values to select as non-grouped columns. Valid `ColTypes` are `PICK_SUM`, `NAME_SUM`, `GAME_SUM`, `CARD_ATTR`, and `AGG`. Min/Max/Unique
271
270
  aggregations of non-numeric (or numeric) data types are not supported. If `None`, use a set of columns modeled on the commonly used values on 17Lands.com/card_data.
272
271
 
273
272
  - group_by: a list of string or `ColName` values to display as grouped columns. Valid `ColTypes` are `GROUP_BY` and `CARD_ATTR`. By default, group by "name" (card name).
274
273
 
275
274
  - filter_spec: a dictionary specifying a filter, using a small number of paradigms. Columns used must be in each base view ("draft" and "game") that the `columns` and `group_by` columns depend on, so
276
- `AGG`, `CARD_SUM` and `CARD_ATTR` columns are not valid. `NAME_SUM` columns are also not supported. Derived columns are supported. No filter is applied by default. Yes, I should rewrite it to use the mongo query language. The specification is best understood with examples:
275
+ `AGG` and `CARD_ATTR` columns are not valid. Functions of card attributes in the base views can be filtered on, see the documentation for `expr` for details. `NAME_SUM` columns are also not supported. Derived columns are supported. No filter is applied by default. Yes, I should rewrite it to use the mongo query language. The specification is best understood with examples:
277
276
 
278
277
  - `{'player_cohort': 'Top'}` "player_cohort" value equals "Top".
279
278
  - `{'lhs': 'player_cohort', 'op': 'in', 'rhs': ['Top', 'Middle']}` "player_cohort" value is either "Top" or "Middle". Supported values for `op` are `<`, `<=`, `>`, `>=`, `!=`, `=`, `in` and `nin`.
@@ -286,10 +285,10 @@ aggregations of non-numeric (or numeric) data types are not supported. If `None`
286
285
  ### Enums
287
286
 
288
287
  ```python
289
- from spells.enums import ColName, ColType, View
288
+ from spells.enums import ColName, ColType
290
289
  ```
291
290
 
292
- Recommended to import `ColName` for any usage of `summon`, and to import `ColType` when defining custom extensions. You shouldn't need `VIEW`.
291
+ Recommended to import `ColName` for any usage of `summon`, and to import `ColType` when defining custom extensions.
293
292
 
294
293
  ### ColumnSpec
295
294
 
@@ -299,11 +298,8 @@ from spells.columns import ColumnSpec
299
298
  ColumnSpec(
300
299
  name: str,
301
300
  col_type: ColType,
302
- expr: pl.Expr | None = None,
303
- exprMap: Callable[[str], pl.Expr] | None = None
304
- dependencies: list[str] | None = None
301
+ expr: pl.Expr | Callable[..., pl.Expr] | None = None,
305
302
  version: str | None = None
306
- views: list[View] | None = None,
307
303
  )
308
304
  ```
309
305
 
@@ -313,19 +309,19 @@ Used to define extensions in `summon`
313
309
 
314
310
  - `name`: any string, including existing columns, although this is very likely to break dependent columns, so don't do it. For `NAME_SUM` columns, the name is the prefix without the underscore, e.g. "drawn".
315
311
 
316
- - `col_type`: one of the `ColType` enum values, `FILTER_ONLY`, `GROUP_BY`, `PICK_SUM`, `NAME_SUM`, `GAME_SUM`, `CARD_ATTR`, `CARD_SUM`, and `AGG`. See documentation for `summon` for usage. All columns except `CARD_ATTR`, `CARD_SUM` and `AGG` must be derivable at the individual row level on one or both base views. `CARD_ATTR` must be derivable at the individual row level from the card file. `AGG` can depend on any column present after summing over groups, and can include polars Expression aggregations. `CARD_SUM` columns are expressed similarly to `AGG`, but they are calculated before grouping by card name and are summed before the `AGG` selection stage (for example, to calculate average mana value. See example notebook "Card Attributes"). Arbitrarily long chains of aggregate dependencies are supported.
317
-
318
- - `expr`: A polars expression giving the derivation of the column value at the first level where it is defined. For `NAME_SUM` columns the `exprMap` attribute must be used instead. `AGG` columns that depend on `NAME_SUM` columns reference the prefix (`cdef.name`) only, since the unpivot has occured prior to selection.
312
+ - `col_type`: one of the `ColType` enum values, `FILTER_ONLY`, `GROUP_BY`, `PICK_SUM`, `NAME_SUM`, `GAME_SUM`, `CARD_ATTR`, and `AGG`. See documentation for `summon` for usage. All columns except `CARD_ATTR`
313
+ and `AGG` must be derivable at the individual row level on one or both base views. `CARD_ATTR` must be derivable at the individual row level from the card file. `AGG` can depend on any column present after
314
+ summing over groups, and can include polars Expression aggregations. Arbitrarily long chains of aggregate dependencies are supported.
319
315
 
320
- - `exprMap`: A function of card name that returns the expression for a `NAME_SUM` column.
321
-
322
- - `dependencies`: A list of column names. All dependencies must be declared by name.
316
+ - `expr`: A polars expression or function returning a polars expression giving the derivation of the column value at the first level where it is defined.
317
+ - For `NAME_SUM` columns, `expr` must be a function of `name` which will result in a list of expressions mapped over all card names.
318
+ - `PICK_SUM` columns can also be functions on `name`, in which case the value will be a function of the value of the `PICK` field.
319
+ - `AGG` columns that depend on `NAME_SUM` columns reference the prefix (`cdef.name`) only, since the unpivot has occured prior to selection.
320
+ - The possible arguments to `expr`, in addition to `name` when appropriate, include the full `names` array as well as a dictionary called `card_context` which contains card dict objects with all `CARD_ATTR` values, including custom extensions. See example notebooks for more details.
323
321
 
324
322
  - `version`: When defining a column using a python function, as opposed to Polars expressions, add a unique version number so that the unique hashed signature of the column specification can be derived
325
323
  for caching purposes, since Polars cannot generate a serialization natively. When changing the definition, be sure to increment the version value. Otherwise you do not need to use this parameter.
326
324
 
327
- - `views`: Not needed for custom columns.
328
-
329
325
  ### Columns
330
326
 
331
327
  A table of all included columns. Columns can be referenced by enum or by string value in arguments and filter specs. The string value is always the lowercase version of the enum attribute.
@@ -413,6 +409,9 @@ A table of all included columns. Columns can be referenced by enum or by string
413
409
  | `CARD_TYPE` | `"card_type"` | `CARD` | `CARD_ATTR` | | String |
414
410
  | `SUBTYPE` | `"subtype"` | `CARD` | `CARD_ATTR` | | String |
415
411
  | `MANA_VALUE` | `"mana_value"` | `CARD` | `CARD_ATTR` | | Float |
412
+ | `DECK_MANA_VALUE` | `"deck_mana_value"` | | `NAME_SUM` | `DECK` * `MANA_VALUE` | Float |
413
+ | `DECK_LANDS` | `"deck_lands"` | | `NAME_SUM` | Number of lands in deck | Float |
414
+ | `DECK_SPELLS` | `"deck_spells"` | | `NAME_SUM` | Number of spells in deck | Float |
416
415
  | `MANA_COST` | `"mana_cost"` | `CARD` | `CARD_ATTR` | | String |
417
416
  | `POWER` | `"power"` | `CARD` | `CARD_ATTR` | | Float |
418
417
  | `TOUGHNESS` | `"toughness"` | `CARD` | `CARD_ATTR` | | Float |
@@ -451,6 +450,9 @@ A table of all included columns. Columns can be referenced by enum or by string
451
450
  | `GIH_WR_VAR` | `"gih_wr_var"` | | `AGG` | Game-weighted Variance | Float |
452
451
  | `GIH_WR_STDEV` | `"gh_wr_stdev"` | | `AGG` | Sqrt of `GIH_WR_VAR` | Float |
453
452
  | `GIH_WR_Z` | `"gih_wr_z"` | | `AGG` |`GIH_WR_EXCESS` / `GIH_WR_STDEV` | Float |
453
+ | `DECK_MANA_VALUE_AVG` | `"deck_mana_value_avg"` | | `AGG` | `DECK_MANA_VALUE ` / `DECK_SPELLS` | Float |
454
+ | `DECK_LANDS_AVG` | `"deck_lands_avg"` | | `AGG` | `DECK_LANDS ` / `NUM_GAMES` | Float |
455
+ | `DECK_SPELLS_AVG` | `"deck_spells_avg"` | | `AGG` | `DECK_SPELLS ` / `NUM_GAMES` | Float |
454
456
 
455
457
  # Roadmap to 1.0
456
458
 
@@ -11,7 +11,7 @@ dependencies = [
11
11
  ]
12
12
  requires-python = ">=3.11"
13
13
  readme = "README.md"
14
- version = "0.3.0"
14
+ version = "0.4.0"
15
15
 
16
16
  [project.license]
17
17
  text = "MIT"
@@ -0,0 +1,5 @@
1
+ from spells import columns
2
+ from spells import enums
3
+ from spells.draft_data import summon
4
+
5
+ __all__ = ["summon", "enums", "columns"]
@@ -76,7 +76,10 @@ def _extract_value(set_code: str, name: str, card_dict: dict, field: CardAttr):
76
76
 
77
77
  def card_df(draft_set_code: str, names: list[str]) -> pl.DataFrame:
78
78
  draft_set_json = _fetch_mtg_json(draft_set_code)
79
- set_codes = draft_set_json["data"]["booster"]["play"]["sourceSetCodes"]
79
+ booster_info = draft_set_json["data"]["booster"]
80
+
81
+ booster_type = "play" if "play" in booster_info else "draft"
82
+ set_codes = booster_info[booster_type]["sourceSetCodes"]
80
83
  set_codes.reverse()
81
84
 
82
85
  card_data_map = {}