spells-mtg 0.7.1__py3-none-any.whl → 0.7.2__py3-none-any.whl

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.

spells/cache.py CHANGED
@@ -78,8 +78,16 @@ def write_cache(set_code: str, cache_key: str, df: pl.DataFrame) -> None:
78
78
  df.write_parquet(cache_path_for_key(set_code, cache_key))
79
79
 
80
80
 
81
- def clear(set_code: str) -> int:
81
+ def clean(set_code: str) -> int:
82
82
  mode = "clean"
83
+
84
+ if set_code == "all":
85
+ cache_dir = data_dir_path(DataDir.CACHE)
86
+ with os.scandir(cache_dir) as set_dir:
87
+ for entry in set_dir:
88
+ clean(entry.name)
89
+ return 0
90
+
83
91
  cache_dir = cache_dir_for_set(set_code)
84
92
  if os.path.isdir(cache_dir):
85
93
  with os.scandir(cache_dir) as set_dir:
spells/draft_data.py CHANGED
@@ -59,25 +59,35 @@ def _get_card_context(
59
59
  specs: dict[str, ColSpec],
60
60
  card_context: pl.DataFrame | dict[str, dict[str, Any]] | None,
61
61
  set_context: pl.DataFrame | dict[str, Any] | None,
62
+ card_only: bool = False,
62
63
  ) -> dict[str, dict[str, Any]]:
63
64
  card_attr_specs = {
64
65
  col: spec
65
66
  for col, spec in specs.items()
66
67
  if spec.col_type == ColType.CARD_ATTR or col == ColName.NAME
67
68
  }
68
- col_def_map = _hydrate_col_defs(
69
- set_code, card_attr_specs, set_context=set_context, card_only=True
70
- )
71
69
 
72
- columns = list(col_def_map.keys())
70
+ if not card_only:
71
+ col_def_map = _hydrate_col_defs(
72
+ set_code,
73
+ card_attr_specs,
74
+ set_context=set_context,
75
+ card_context=card_context,
76
+ card_only=True,
77
+ )
78
+
79
+ columns = list(col_def_map.keys())
73
80
 
74
- fp = data_file_path(set_code, View.CARD)
75
- card_df = pl.read_parquet(fp)
76
- select_rows = _view_select(
77
- card_df, frozenset(columns), col_def_map, is_agg_view=False
78
- ).to_dicts()
81
+ fp = data_file_path(set_code, View.CARD)
82
+ card_df = pl.read_parquet(fp)
83
+ select_rows = _view_select(
84
+ card_df, frozenset(columns), col_def_map, is_agg_view=False
85
+ ).to_dicts()
79
86
 
80
- loaded_context = {row[ColName.NAME]: row for row in select_rows}
87
+ loaded_context = {row[ColName.NAME]: row for row in select_rows}
88
+ else:
89
+ names = _get_names(set_code)
90
+ loaded_context = {name: {} for name in names}
81
91
 
82
92
  if card_context is not None:
83
93
  if isinstance(card_context, pl.DataFrame):
@@ -139,25 +149,25 @@ def _determine_expression(
139
149
 
140
150
  elif spec.expr is not None:
141
151
  if isinstance(spec.expr, Callable):
142
- assert not spec.col_type == ColType.AGG, f"AGG column {col} must be a pure spells expression"
152
+ assert (
153
+ not spec.col_type == ColType.AGG
154
+ ), f"AGG column {col} must be a pure spells expression"
143
155
  params = seed_params(spec.expr)
144
156
  if (
145
- spec.col_type == ColType.PICK_SUM
157
+ spec.col_type in (ColType.PICK_SUM, ColType.CARD_ATTR)
146
158
  and "name" in signature(spec.expr).parameters
147
159
  ):
160
+ condition_col = (
161
+ ColName.PICK if spec.col_type == ColType.PICK_SUM else ColName.NAME
162
+ )
148
163
  expr = pl.lit(None)
149
164
  for name in names:
150
165
  name_params = {"name": name, **params}
151
166
  expr = (
152
- pl.when(pl.col(ColName.PICK) == name)
167
+ pl.when(pl.col(condition_col) == name)
153
168
  .then(spec.expr(**name_params))
154
169
  .otherwise(expr)
155
170
  )
156
- elif (
157
- spec.col_type == ColType.CARD_ATTR
158
- and "name" in signature(spec.expr).parameters
159
- ):
160
- expr = spec.expr(**{"name": pl.col("name"), **params})
161
171
  else:
162
172
  expr = spec.expr(**params)
163
173
  else:
@@ -256,10 +266,9 @@ def _hydrate_col_defs(
256
266
 
257
267
  set_context = _get_set_context(set_code, set_context)
258
268
 
259
- if card_only:
260
- card_context = {}
261
- else:
262
- card_context = _get_card_context(set_code, specs, card_context, set_context)
269
+ card_context = _get_card_context(
270
+ set_code, specs, card_context, set_context, card_only=card_only
271
+ )
263
272
 
264
273
  assert len(names) > 0, "there should be names"
265
274
  hydrated = {}
@@ -393,9 +402,7 @@ def _base_agg_df(
393
402
  sum_col_df = base_df.select(nonname_gb + name_col_tuple + sum_cols)
394
403
 
395
404
  grouped = sum_col_df.group_by(group_by) if group_by else sum_col_df
396
- join_dfs.append(
397
- grouped.sum().collect(streaming=use_streaming)
398
- )
405
+ join_dfs.append(grouped.sum().collect(streaming=use_streaming))
399
406
 
400
407
  name_sum_cols = tuple(
401
408
  c for c in cols_for_view if m.col_def_map[c].col_type == ColType.NAME_SUM
@@ -423,8 +430,12 @@ def _base_agg_df(
423
430
  )
424
431
 
425
432
  if not is_name_gb:
426
- grouped = unpivoted.drop("name").group_by(nonname_gb) if nonname_gb else unpivoted.drop("name")
427
- df = grouped.sum() .collect(streaming=use_streaming)
433
+ grouped = (
434
+ unpivoted.drop("name").group_by(nonname_gb)
435
+ if nonname_gb
436
+ else unpivoted.drop("name")
437
+ )
438
+ df = grouped.sum().collect(streaming=use_streaming)
428
439
  else:
429
440
  df = unpivoted.collect(streaming=use_streaming)
430
441
 
@@ -436,7 +447,7 @@ def _base_agg_df(
436
447
  join_dfs,
437
448
  )
438
449
  else:
439
- joined_df = pl.concat(join_dfs, how='horizontal')
450
+ joined_df = pl.concat(join_dfs, how="horizontal")
440
451
 
441
452
  return joined_df
442
453
 
@@ -475,14 +486,14 @@ def summon(
475
486
  concat_dfs = []
476
487
  for code in codes:
477
488
  if isinstance(card_context, pl.DataFrame):
478
- set_card_context = card_context.filter(pl.col('expansion') == code)
489
+ set_card_context = card_context.filter(pl.col("expansion") == code)
479
490
  elif isinstance(card_context, dict):
480
491
  set_card_context = card_context[code]
481
492
  else:
482
493
  set_card_context = None
483
494
 
484
495
  if isinstance(set_context, pl.DataFrame):
485
- this_set_context = set_context.filter(pl.col('expansion') == code)
496
+ this_set_context = set_context.filter(pl.col("expansion") == code)
486
497
  elif isinstance(set_context, dict):
487
498
  this_set_context = set_context[code]
488
499
  else:
@@ -511,13 +522,17 @@ def summon(
511
522
  card_cols = m.view_cols[View.CARD].union({ColName.NAME})
512
523
  fp = data_file_path(code, View.CARD)
513
524
  card_df = pl.read_parquet(fp)
514
- select_df = _view_select(card_df, card_cols, m.col_def_map, is_agg_view=False)
525
+ select_df = _view_select(
526
+ card_df, card_cols, m.col_def_map, is_agg_view=False
527
+ )
515
528
  agg_df = agg_df.join(select_df, on="name", how="outer", coalesce=True)
516
529
  concat_dfs.append(agg_df)
517
530
 
518
- full_agg_df = pl.concat(concat_dfs, how='vertical')
531
+ full_agg_df = pl.concat(concat_dfs, how="vertical")
519
532
 
520
- assert m is not None, "What happened? We mean to use one of the sets manifest, it shouldn't matter which."
533
+ assert (
534
+ m is not None
535
+ ), "What happened? We mean to use one of the sets manifest, it shouldn't matter which."
521
536
 
522
537
  if m.group_by:
523
538
  full_agg_df = full_agg_df.group_by(m.group_by).sum()
spells/external.py CHANGED
@@ -53,6 +53,7 @@ def cli() -> int:
53
53
  cache.spells_print("spells", f"[data home]={data_dir}")
54
54
  print()
55
55
  usage = """spells [add|refresh|remove|clean] [set_code]
56
+ spells clean all
56
57
  spells info
57
58
 
58
59
  add: Download draft and game files from 17Lands.com and card file from MTGJSON.com and save to path
@@ -67,7 +68,7 @@ def cli() -> int:
67
68
 
68
69
  remove: Delete the [data home]/external/[set code] and [data home]/local/[set code] directories and their contents
69
70
 
70
- clean: Delete [data home]/local/[set code] data directory (your cache of aggregate parquet files).
71
+ clean: Delete [data home]/local/[set code] data directory (your cache of aggregate parquet files), or all of them.
71
72
 
72
73
  info: No set code argument. Print info on all external and local files.
73
74
  """
@@ -94,7 +95,7 @@ def cli() -> int:
94
95
  case "remove":
95
96
  return _remove(sys.argv[2])
96
97
  case "clean":
97
- return cache.clear(sys.argv[2])
98
+ return cache.clean(sys.argv[2])
98
99
  case _:
99
100
  print_usage()
100
101
  return 1
@@ -236,8 +237,11 @@ def _process_zipped_file(gzip_path, target_path):
236
237
  df.sink_parquet(target_path)
237
238
  except ComputeError:
238
239
  df = pl.scan_csv(csv_path)
239
- cache.spells_print('error', 'Bad schema found, loading dataset into memory'\
240
- + ' and attempting to cast to correct schema')
240
+ cache.spells_print(
241
+ "error",
242
+ "Bad schema found, loading dataset into memory"
243
+ + " and attempting to cast to correct schema",
244
+ )
241
245
  select = [pl.col(name).cast(dtype) for name, dtype in schema(csv_path).items()]
242
246
  cast_df = df.select(select).collect()
243
247
  cast_df.write_parquet(target_path)
spells/manifest.py CHANGED
@@ -162,7 +162,11 @@ def create(
162
162
  group_by: list[str] | None = None,
163
163
  filter_spec: dict | None = None,
164
164
  ):
165
- gbs = (ColName.NAME, ColName.COLOR, ColName.RARITY) if group_by is None else tuple(group_by)
165
+ gbs = (
166
+ (ColName.NAME, ColName.COLOR, ColName.RARITY)
167
+ if group_by is None
168
+ else tuple(group_by)
169
+ )
166
170
 
167
171
  if columns is None:
168
172
  cols = tuple(spells.columns.default_columns)
spells/schema.py CHANGED
@@ -136,6 +136,7 @@ COLUMN_TYPES = (
136
136
  (re.compile(r"^oppo_total_cards_drawn_or_tutored$"), pl.Int8),
137
137
  )
138
138
 
139
+
139
140
  def schema(
140
141
  filename: str, print_missing: bool = False
141
142
  ) -> Dict[str, pl.datatypes.DataType]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spells-mtg
3
- Version: 0.7.1
3
+ Version: 0.7.2
4
4
  Summary: analaysis of 17Lands.com public datasets
5
5
  Author-Email: Joel Barnes <oelarnes@gmail.com>
6
6
  License: MIT
@@ -0,0 +1,16 @@
1
+ spells/__init__.py,sha256=iyX74sLFJIQ_5ShZ7KDOeBlbYLm21ibWxwyzCGnKdg8,169
2
+ spells/cache.py,sha256=YpTmlW-U2EosvGCH9gRQdQc8gRjjcGbgQovn5gfA_WE,3165
3
+ spells/cards.py,sha256=EOXAB_F2yedjf6KquCERCIHl0TSIJIoOe1jv8g4JzOc,3601
4
+ spells/columns.py,sha256=kWeDofGL0bYcxq4OOfUwkU4Ty3fm0xux6R9774v9HVQ,18053
5
+ spells/draft_data.py,sha256=Le_w7_sOptRR4bbzWgvdDo0JHJPb4vjXYsH_DMlpT8s,17190
6
+ spells/enums.py,sha256=DL7e1xDEvrsTMbA7vJB_Et1DaYkyO4rIEzvIQDz3MZk,4871
7
+ spells/extension.py,sha256=CcKRdDfFrt2L-53-m2tQrurX-LbIkaRokOD8CuupzW0,6538
8
+ spells/external.py,sha256=PN0PkwdKnvx-4HkApFhI1_ZwRvBUDMUd3Vfbky0xSJA,11786
9
+ spells/filter.py,sha256=J-YTOOAzOQpvIX29tviYL04RVoOUlfsbjBXoQBDCEdQ,3380
10
+ spells/manifest.py,sha256=GlA5e7vW00zggsqP1grZBdy4SO8WUWBMrO3dv2_q9_Y,8171
11
+ spells/schema.py,sha256=DbMvV8PIThJTp0Xzp_XIorlW6JhE1ud1kWRGf5SQ4_c,6406
12
+ spells_mtg-0.7.2.dist-info/METADATA,sha256=PUmlvOsgFMddKiLjAAtvZayvBTcRcQ8DwZnXmlYXLOY,46731
13
+ spells_mtg-0.7.2.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
14
+ spells_mtg-0.7.2.dist-info/entry_points.txt,sha256=a9Y1omdl9MdnKuIj3aOodgrp-zZII6OCdvqwgP6BFvI,63
15
+ spells_mtg-0.7.2.dist-info/licenses/LICENSE,sha256=tS54XYbJSgmq5zuHhbsQGbNQLJPVgXqhF5nu2CSRMig,1068
16
+ spells_mtg-0.7.2.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- spells/__init__.py,sha256=iyX74sLFJIQ_5ShZ7KDOeBlbYLm21ibWxwyzCGnKdg8,169
2
- spells/cache.py,sha256=4v7h8D3TtaT0R_EdiRNhdcQrXzdH_CukezO6oAXvNEY,2956
3
- spells/cards.py,sha256=EOXAB_F2yedjf6KquCERCIHl0TSIJIoOe1jv8g4JzOc,3601
4
- spells/columns.py,sha256=kWeDofGL0bYcxq4OOfUwkU4Ty3fm0xux6R9774v9HVQ,18053
5
- spells/draft_data.py,sha256=evVzhvo_luKrYzw27QglpSJL6KvuU4ehtnRxyBa86FQ,16873
6
- spells/enums.py,sha256=DL7e1xDEvrsTMbA7vJB_Et1DaYkyO4rIEzvIQDz3MZk,4871
7
- spells/extension.py,sha256=CcKRdDfFrt2L-53-m2tQrurX-LbIkaRokOD8CuupzW0,6538
8
- spells/external.py,sha256=tuh86xsbyo2pMb4YOtbcXM1v5UVxrC7GXIfxf77aSbQ,11703
9
- spells/filter.py,sha256=J-YTOOAzOQpvIX29tviYL04RVoOUlfsbjBXoQBDCEdQ,3380
10
- spells/manifest.py,sha256=4_jiPgRyjNzFQJzaJgVcClFxYkXK1uRrB42EOg0rfXQ,8139
11
- spells/schema.py,sha256=NY2orqXvtiUMtVJf0xEEwsaP_LzATRO6FcxoQA6Jx3U,6405
12
- spells_mtg-0.7.1.dist-info/METADATA,sha256=FxJFakGHf1jgDcaGuuu9F_zrJDRk_9HZ0lEB16R4kDk,46731
13
- spells_mtg-0.7.1.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
14
- spells_mtg-0.7.1.dist-info/entry_points.txt,sha256=a9Y1omdl9MdnKuIj3aOodgrp-zZII6OCdvqwgP6BFvI,63
15
- spells_mtg-0.7.1.dist-info/licenses/LICENSE,sha256=tS54XYbJSgmq5zuHhbsQGbNQLJPVgXqhF5nu2CSRMig,1068
16
- spells_mtg-0.7.1.dist-info/RECORD,,