ltc-code 0.1.91__tar.gz → 0.1.92__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ltc-code
3
- Version: 0.1.91
3
+ Version: 0.1.92
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.9
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ltc-code"
3
- version = "0.1.91"
3
+ version = "0.1.92"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9"
@@ -403,4 +403,163 @@ final = df.pipe(
403
403
  "waitlist": "waitlist_school",
404
404
  "withdraw": "withdraw_school",
405
405
  },
406
+ )
407
+
408
+
409
+
410
+
411
+
412
+
413
+
414
+
415
+
416
+ from typing import Mapping, Optional, Sequence, Union
417
+
418
+ import polars as pl
419
+
420
+
421
+ DEFAULT_PRIORITY_PATTERNS_BY_CMO = {
422
+ "default": {
423
+ "flags": {
424
+ "sibling": [
425
+ r"\bsibling\s+attending\b",
426
+ ],
427
+ "staff": [
428
+ r"\bemployee\b",
429
+ ],
430
+ "zoned": [
431
+ r"\bisd\b",
432
+ r"\bzoned\s+for\b",
433
+ r"\bdynamic\s+sa\b",
434
+ ],
435
+ "transfer": [
436
+ r"(?:^|\s{2,})transfer(?:\s{2,}|$)",
437
+ ],
438
+ },
439
+ "repeat_flags": {
440
+ "sib_repeat": [
441
+ r"\bsibling\s+attending\b",
442
+ ],
443
+ "zoned_repeat": [
444
+ r"\bzoned\s+for\b",
445
+ ],
446
+ },
447
+ },
448
+
449
+ # Same as default for now, but this gives you a place to customize later.
450
+ "yes_prep": {
451
+ "flags": {
452
+ "sibling": [
453
+ r"\bsibling\s+attending\b",
454
+ ],
455
+ "staff": [
456
+ r"\bemployee\b",
457
+ ],
458
+ "zoned": [
459
+ r"\bisd\b",
460
+ r"\bzoned\s+for\b",
461
+ r"\bdynamic\s+sa\b",
462
+ ],
463
+ "transfer": [
464
+ r"(?:^|\s{2,})transfer(?:\s{2,}|$)",
465
+ ],
466
+ },
467
+ "repeat_flags": {
468
+ "sib_repeat": [
469
+ r"\bsibling\s+attending\b",
470
+ ],
471
+ "zoned_repeat": [
472
+ r"\bzoned\s+for\b",
473
+ ],
474
+ },
475
+ },
476
+ }
477
+
478
+
479
+ def add_priority_flags(
480
+ df: Union[pl.DataFrame, pl.LazyFrame],
481
+ priority_col: str,
482
+ cmo: str = "default",
483
+ patterns_by_cmo: Optional[Mapping[str, Mapping[str, Mapping[str, Sequence[str]]]]] = None,
484
+ ) -> Union[pl.DataFrame, pl.LazyFrame]:
485
+ """Create priority flags from a long priority string column.
486
+
487
+ Adds:
488
+ sibling
489
+ staff
490
+ zoned
491
+ transfer
492
+ sib_repeat
493
+ zoned_repeat
494
+
495
+ The helper lowercases the priority string and normalizes dashes/pluses to
496
+ spaces before matching regex patterns.
497
+ """
498
+ if not isinstance(df, (pl.DataFrame, pl.LazyFrame)):
499
+ raise TypeError("df must be a polars DataFrame or LazyFrame.")
500
+
501
+ columns = df.collect_schema().names() if isinstance(df, pl.LazyFrame) else df.columns
502
+ if priority_col not in columns:
503
+ raise ValueError("Missing priority column: %s" % priority_col)
504
+
505
+ patterns_by_cmo = patterns_by_cmo or DEFAULT_PRIORITY_PATTERNS_BY_CMO
506
+ if cmo not in patterns_by_cmo:
507
+ raise ValueError(
508
+ "No priority pattern mapping found for cmo=%r. Available CMOs: %s"
509
+ % (cmo, sorted(patterns_by_cmo))
510
+ )
511
+
512
+ config = patterns_by_cmo[cmo]
513
+ flag_patterns = config.get("flags", {})
514
+ repeat_patterns = config.get("repeat_flags", {})
515
+
516
+ def _combined_regex(patterns: Sequence[str]) -> str:
517
+ return "|".join("(%s)" % pattern for pattern in patterns)
518
+
519
+ def _count_expr(patterns: Sequence[str]) -> pl.Expr:
520
+ if not patterns:
521
+ return pl.lit(0)
522
+ return pl.sum_horizontal(
523
+ [
524
+ pl.col("_priority_text").str.count_matches(pattern)
525
+ for pattern in patterns
526
+ ]
527
+ )
528
+
529
+ result = df.with_columns(
530
+ pl.col(priority_col)
531
+ .cast(pl.Utf8, strict=False)
532
+ .fill_null("")
533
+ .str.to_lowercase()
534
+ .str.replace_all(r"[-+]", " ")
535
+ .alias("_priority_text")
536
+ )
537
+
538
+ result = result.with_columns(
539
+ [
540
+ pl.col("_priority_text")
541
+ .str.contains(_combined_regex(patterns))
542
+ .cast(pl.Int8)
543
+ .alias(flag_name)
544
+ for flag_name, patterns in flag_patterns.items()
545
+ ]
546
+ )
547
+
548
+ result = result.with_columns(
549
+ [
550
+ (_count_expr(patterns) > 1)
551
+ .cast(pl.Int8)
552
+ .alias(flag_name)
553
+ for flag_name, patterns in repeat_patterns.items()
554
+ ]
555
+ )
556
+
557
+ return result.drop("_priority_text")
558
+
559
+
560
+
561
+ df = df.pipe(
562
+ add_priority_flags,
563
+ priority_col="priority_group_name",
564
+ cmo="yes_prep",
406
565
  )
File without changes