ltc-code 0.1.85__tar.gz → 0.1.87__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.85
3
+ Version: 0.1.87
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.85"
3
+ version = "0.1.87"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9"
@@ -20,6 +20,14 @@ def _second_word_expr(col: str) -> pl.Expr:
20
20
  return pl.col(col).cast(pl.String).str.split(" ").list.get(1, null_on_oob=True)
21
21
 
22
22
 
23
+ def _compact_expr(expr: pl.Expr) -> pl.Expr:
24
+ return (
25
+ expr.cast(pl.String)
26
+ .str.to_uppercase()
27
+ .str.replace_all(r"[^A-Z]", "")
28
+ )
29
+
30
+
23
31
  def _build_lookup(
24
32
  census: pl.DataFrame,
25
33
  *,
@@ -27,7 +35,13 @@ def _build_lookup(
27
35
  lname_expr: pl.Expr,
28
36
  dob_col: str,
29
37
  label: str,
38
+ compact: bool = False,
30
39
  ) -> pl.DataFrame:
40
+
41
+ if compact:
42
+ fname_expr = _compact_expr(fname_expr)
43
+ lname_expr = _compact_expr(lname_expr)
44
+
31
45
  lookup = (
32
46
  census
33
47
  .select(
@@ -37,6 +51,10 @@ def _build_lookup(
37
51
  pl.col("sid_cepr"),
38
52
  )
39
53
  .drop_nulls(["_fname_key", "_lname_key", "_dob_key", "sid_cepr"])
54
+ .filter(
55
+ pl.col("_fname_key").cast(pl.String).str.len_chars().gt(0)
56
+ & pl.col("_lname_key").cast(pl.String).str.len_chars().gt(0)
57
+ )
40
58
  .group_by(["_fname_key", "_lname_key", "_dob_key"])
41
59
  .agg(pl.col("sid_cepr").unique().alias("_sids"))
42
60
  .select(
@@ -57,13 +75,16 @@ def _add_name_lookups(
57
75
  *,
58
76
  prefix: str,
59
77
  dob_col: str,
78
+ compact: bool = False,
60
79
  ) -> None:
80
+
61
81
  lookups[f"{prefix}exact"] = _build_lookup(
62
82
  census,
63
83
  fname_expr=pl.col("fname"),
64
84
  lname_expr=pl.col("lname"),
65
85
  dob_col=dob_col,
66
86
  label=f"{prefix}exact",
87
+ compact=compact,
67
88
  )
68
89
 
69
90
  lookups[f"{prefix}mname"] = _build_lookup(
@@ -72,6 +93,7 @@ def _add_name_lookups(
72
93
  lname_expr=pl.col("lname"),
73
94
  dob_col=dob_col,
74
95
  label=f"{prefix}right fname + mname",
96
+ compact=compact,
75
97
  )
76
98
 
77
99
  lookups[f"{prefix}mname_lname"] = _build_lookup(
@@ -80,6 +102,7 @@ def _add_name_lookups(
80
102
  lname_expr=pl.concat_str([pl.col("mname"), pl.col("lname")], separator=" "),
81
103
  dob_col=dob_col,
82
104
  label=f"{prefix}right mname + lname",
105
+ compact=compact,
83
106
  )
84
107
 
85
108
  lookups[f"{prefix}mname_nospace"] = _build_lookup(
@@ -88,6 +111,7 @@ def _add_name_lookups(
88
111
  lname_expr=pl.col("lname"),
89
112
  dob_col=dob_col,
90
113
  label=f"{prefix}right fname + mname no space",
114
+ compact=compact,
91
115
  )
92
116
 
93
117
  lookups[f"{prefix}suffix"] = _build_lookup(
@@ -96,6 +120,7 @@ def _add_name_lookups(
96
120
  lname_expr=pl.concat_str([pl.col("lname"), pl.col("suffix")], separator=" "),
97
121
  dob_col=dob_col,
98
122
  label=f"{prefix}right lname + suffix",
123
+ compact=compact,
99
124
  )
100
125
 
101
126
  lookups[f"{prefix}suffix_fname"] = _build_lookup(
@@ -104,6 +129,7 @@ def _add_name_lookups(
104
129
  lname_expr=pl.col("lname"),
105
130
  dob_col=dob_col,
106
131
  label=f"{prefix}right fname + suffix",
132
+ compact=compact,
107
133
  )
108
134
 
109
135
  lookups[f"{prefix}suffix_fname_nospace"] = _build_lookup(
@@ -112,6 +138,7 @@ def _add_name_lookups(
112
138
  lname_expr=pl.col("lname"),
113
139
  dob_col=dob_col,
114
140
  label=f"{prefix}right fname + suffix no space",
141
+ compact=compact,
115
142
  )
116
143
 
117
144
  lookups[f"{prefix}suffix_lname_nospace"] = _build_lookup(
@@ -120,6 +147,7 @@ def _add_name_lookups(
120
147
  lname_expr=pl.concat_str([pl.col("lname"), pl.col("suffix")], separator=""),
121
148
  dob_col=dob_col,
122
149
  label=f"{prefix}right lname + suffix no space",
150
+ compact=compact,
123
151
  )
124
152
 
125
153
  lookups[f"{prefix}fname_first_word"] = _build_lookup(
@@ -128,6 +156,7 @@ def _add_name_lookups(
128
156
  lname_expr=pl.col("lname"),
129
157
  dob_col=dob_col,
130
158
  label=f"{prefix}right fname first word",
159
+ compact=compact,
131
160
  )
132
161
 
133
162
  lookups[f"{prefix}lname_first_word"] = _build_lookup(
@@ -136,6 +165,7 @@ def _add_name_lookups(
136
165
  lname_expr=_first_word_expr("lname"),
137
166
  dob_col=dob_col,
138
167
  label=f"{prefix}right lname first word",
168
+ compact=compact,
139
169
  )
140
170
 
141
171
  lookups[f"{prefix}lname_second_word"] = _build_lookup(
@@ -144,6 +174,7 @@ def _add_name_lookups(
144
174
  lname_expr=_second_word_expr("lname"),
145
175
  dob_col=dob_col,
146
176
  label=f"{prefix}right lname second word",
177
+ compact=compact,
147
178
  )
148
179
 
149
180
 
@@ -223,26 +254,23 @@ def build_census_lookups(*, cmo_name: str) -> dict[str, pl.DataFrame]:
223
254
 
224
255
  lookups = {}
225
256
 
226
- _add_name_lookups(
227
- lookups,
228
- census,
229
- prefix="",
230
- dob_col="dob",
231
- )
257
+ # Normal full-DOB lookups.
258
+ _add_name_lookups(lookups, census, prefix="", dob_col="dob", compact=False)
232
259
 
233
- _add_name_lookups(
234
- lookups,
235
- census,
236
- prefix="md_",
237
- dob_col="dob_md",
238
- )
260
+ # Compact full-DOB lookups.
261
+ _add_name_lookups(lookups, census, prefix="compact_", dob_col="dob", compact=True)
239
262
 
240
- _add_name_lookups(
241
- lookups,
242
- census,
243
- prefix="mdi_",
244
- dob_col="dob_imp_md",
245
- )
263
+ # Normal month-day lookups using dob.
264
+ _add_name_lookups(lookups, census, prefix="md_", dob_col="dob_md", compact=False)
265
+
266
+ # Compact month-day lookups using dob.
267
+ _add_name_lookups(lookups, census, prefix="compact_md_", dob_col="dob_md", compact=True)
268
+
269
+ # Normal month-day lookups using dob_imp.
270
+ _add_name_lookups(lookups, census, prefix="mdi_", dob_col="dob_imp_md", compact=False)
271
+
272
+ # Compact month-day lookups using dob_imp.
273
+ _add_name_lookups(lookups, census, prefix="compact_mdi_", dob_col="dob_imp_md", compact=True)
246
274
 
247
275
  lookups["dob_imp"] = _build_lookup(
248
276
  census,
@@ -252,6 +280,15 @@ def build_census_lookups(*, cmo_name: str) -> dict[str, pl.DataFrame]:
252
280
  label="dob_imp",
253
281
  )
254
282
 
283
+ lookups["compact_dob_imp"] = _build_lookup(
284
+ census,
285
+ fname_expr=pl.col("fname"),
286
+ lname_expr=pl.col("lname"),
287
+ dob_col="dob_imp",
288
+ label="compact dob_imp",
289
+ compact=True,
290
+ )
291
+
255
292
  for offset, key in [
256
293
  ("-1y", "dob_imp_minus_1"),
257
294
  ("1y", "dob_imp_plus_1"),
@@ -266,6 +303,15 @@ def build_census_lookups(*, cmo_name: str) -> dict[str, pl.DataFrame]:
266
303
  label=key,
267
304
  )
268
305
 
306
+ lookups[f"compact_{key}"] = _build_lookup(
307
+ census.with_columns(pl.col("dob_imp").dt.offset_by(offset).alias(key)),
308
+ fname_expr=pl.col("fname"),
309
+ lname_expr=pl.col("lname"),
310
+ dob_col=key,
311
+ label=f"compact {key}",
312
+ compact=True,
313
+ )
314
+
269
315
  return lookups
270
316
 
271
317
 
@@ -277,9 +323,15 @@ def _run_match_stage(
277
323
  lname_expr: pl.Expr,
278
324
  dob_expr: pl.Expr,
279
325
  label: str,
326
+ compact: bool = False,
280
327
  ) -> tuple[pl.DataFrame, pl.DataFrame]:
328
+
281
329
  before = len(unmatched)
282
330
 
331
+ if compact:
332
+ fname_expr = _compact_expr(fname_expr)
333
+ lname_expr = _compact_expr(lname_expr)
334
+
283
335
  stage = (
284
336
  unmatched
285
337
  .with_columns(
@@ -312,7 +364,9 @@ def _run_right_side_name_stages(
312
364
  prefix: str,
313
365
  dob_expr: pl.Expr,
314
366
  label_prefix: str,
367
+ compact: bool = False,
315
368
  ) -> pl.DataFrame:
369
+
316
370
  for label, key in [
317
371
  ("left exact -> right fname + mname", f"{prefix}mname"),
318
372
  ("left exact -> right mname + lname", f"{prefix}mname_lname"),
@@ -332,6 +386,7 @@ def _run_right_side_name_stages(
332
386
  lname_expr=pl.col(f"{cols['lname']}_clean"),
333
387
  dob_expr=dob_expr,
334
388
  label=f"{label_prefix}{label}",
389
+ compact=compact,
335
390
  )
336
391
  matched_frames.append(matched)
337
392
 
@@ -347,7 +402,9 @@ def _run_left_side_name_stages(
347
402
  exact_key: str,
348
403
  dob_expr: pl.Expr,
349
404
  label_prefix: str,
405
+ compact: bool = False,
350
406
  ) -> pl.DataFrame:
407
+
351
408
  for label, fname_expr, lname_expr in [
352
409
  (
353
410
  "left fname first word -> right exact",
@@ -372,6 +429,7 @@ def _run_left_side_name_stages(
372
429
  lname_expr=lname_expr,
373
430
  dob_expr=dob_expr,
374
431
  label=f"{label_prefix}{label}",
432
+ compact=compact,
375
433
  )
376
434
  matched_frames.append(matched)
377
435
 
@@ -411,6 +469,7 @@ def _run_left_side_name_stages(
411
469
  lname_expr=lname_expr,
412
470
  dob_expr=dob_expr,
413
471
  label=f"{label_prefix}{label}",
472
+ compact=compact,
414
473
  )
415
474
  matched_frames.append(matched)
416
475
 
@@ -458,6 +517,7 @@ def _run_left_side_name_stages(
458
517
  lname_expr=lname_expr,
459
518
  dob_expr=dob_expr,
460
519
  label=f"{label_prefix}{label}",
520
+ compact=compact,
461
521
  )
462
522
  matched_frames.append(matched)
463
523
 
@@ -496,6 +556,7 @@ def lookup_sid_cepr(
496
556
  matched_frames = []
497
557
  unmatched = current
498
558
 
559
+ # Exact full DOB.
499
560
  matched, unmatched = _run_match_stage(
500
561
  unmatched,
501
562
  lookup=lookups["exact"],
@@ -506,6 +567,18 @@ def lookup_sid_cepr(
506
567
  )
507
568
  matched_frames.append(matched)
508
569
 
570
+ # Compact exact full DOB. Handles SALDAN A vs SALDANA, apostrophes, hyphens, backticks, etc.
571
+ matched, unmatched = _run_match_stage(
572
+ unmatched,
573
+ lookup=lookups["compact_exact"],
574
+ fname_expr=pl.col(f"{cols['fname']}_clean"),
575
+ lname_expr=pl.col(f"{cols['lname']}_clean"),
576
+ dob_expr=pl.col(f"{cols['dob']}_clean"),
577
+ label="compact exact",
578
+ compact=True,
579
+ )
580
+ matched_frames.append(matched)
581
+
509
582
  unmatched = _run_right_side_name_stages(
510
583
  unmatched,
511
584
  matched_frames,
@@ -514,6 +587,7 @@ def lookup_sid_cepr(
514
587
  prefix="",
515
588
  dob_expr=pl.col(f"{cols['dob']}_clean"),
516
589
  label_prefix="",
590
+ compact=False,
517
591
  )
518
592
 
519
593
  unmatched = _run_left_side_name_stages(
@@ -524,6 +598,29 @@ def lookup_sid_cepr(
524
598
  exact_key="exact",
525
599
  dob_expr=pl.col(f"{cols['dob']}_clean"),
526
600
  label_prefix="",
601
+ compact=False,
602
+ )
603
+
604
+ unmatched = _run_right_side_name_stages(
605
+ unmatched,
606
+ matched_frames,
607
+ cols=cols,
608
+ lookups=lookups,
609
+ prefix="compact_",
610
+ dob_expr=pl.col(f"{cols['dob']}_clean"),
611
+ label_prefix="compact ",
612
+ compact=True,
613
+ )
614
+
615
+ unmatched = _run_left_side_name_stages(
616
+ unmatched,
617
+ matched_frames,
618
+ cols=cols,
619
+ lookups=lookups,
620
+ exact_key="compact_exact",
621
+ dob_expr=pl.col(f"{cols['dob']}_clean"),
622
+ label_prefix="compact ",
623
+ compact=True,
527
624
  )
528
625
 
529
626
  for key in [
@@ -532,6 +629,11 @@ def lookup_sid_cepr(
532
629
  "dob_imp_plus_1",
533
630
  "dob_imp_minus_2",
534
631
  "dob_imp_plus_2",
632
+ "compact_dob_imp",
633
+ "compact_dob_imp_minus_1",
634
+ "compact_dob_imp_plus_1",
635
+ "compact_dob_imp_minus_2",
636
+ "compact_dob_imp_plus_2",
535
637
  ]:
536
638
  matched, unmatched = _run_match_stage(
537
639
  unmatched,
@@ -540,9 +642,11 @@ def lookup_sid_cepr(
540
642
  lname_expr=pl.col(f"{cols['lname']}_clean"),
541
643
  dob_expr=pl.col(f"{cols['dob']}_clean"),
542
644
  label=key,
645
+ compact=key.startswith("compact_"),
543
646
  )
544
647
  matched_frames.append(matched)
545
648
 
649
+ # Month-day fallback on RHS dob.
546
650
  matched, unmatched = _run_match_stage(
547
651
  unmatched,
548
652
  lookup=lookups["md_exact"],
@@ -553,6 +657,17 @@ def lookup_sid_cepr(
553
657
  )
554
658
  matched_frames.append(matched)
555
659
 
660
+ matched, unmatched = _run_match_stage(
661
+ unmatched,
662
+ lookup=lookups["compact_md_exact"],
663
+ fname_expr=pl.col(f"{cols['fname']}_clean"),
664
+ lname_expr=pl.col(f"{cols['lname']}_clean"),
665
+ dob_expr=pl.col("_lhs_dob_md"),
666
+ label="compact month-day exact dob",
667
+ compact=True,
668
+ )
669
+ matched_frames.append(matched)
670
+
556
671
  unmatched = _run_right_side_name_stages(
557
672
  unmatched,
558
673
  matched_frames,
@@ -561,6 +676,7 @@ def lookup_sid_cepr(
561
676
  prefix="md_",
562
677
  dob_expr=pl.col("_lhs_dob_md"),
563
678
  label_prefix="month-day dob: ",
679
+ compact=False,
564
680
  )
565
681
 
566
682
  unmatched = _run_left_side_name_stages(
@@ -571,8 +687,32 @@ def lookup_sid_cepr(
571
687
  exact_key="md_exact",
572
688
  dob_expr=pl.col("_lhs_dob_md"),
573
689
  label_prefix="month-day dob: ",
690
+ compact=False,
574
691
  )
575
692
 
693
+ unmatched = _run_right_side_name_stages(
694
+ unmatched,
695
+ matched_frames,
696
+ cols=cols,
697
+ lookups=lookups,
698
+ prefix="compact_md_",
699
+ dob_expr=pl.col("_lhs_dob_md"),
700
+ label_prefix="compact month-day dob: ",
701
+ compact=True,
702
+ )
703
+
704
+ unmatched = _run_left_side_name_stages(
705
+ unmatched,
706
+ matched_frames,
707
+ cols=cols,
708
+ lookups=lookups,
709
+ exact_key="compact_md_exact",
710
+ dob_expr=pl.col("_lhs_dob_md"),
711
+ label_prefix="compact month-day dob: ",
712
+ compact=True,
713
+ )
714
+
715
+ # Month-day fallback on RHS dob_imp.
576
716
  matched, unmatched = _run_match_stage(
577
717
  unmatched,
578
718
  lookup=lookups["mdi_exact"],
@@ -583,6 +723,17 @@ def lookup_sid_cepr(
583
723
  )
584
724
  matched_frames.append(matched)
585
725
 
726
+ matched, unmatched = _run_match_stage(
727
+ unmatched,
728
+ lookup=lookups["compact_mdi_exact"],
729
+ fname_expr=pl.col(f"{cols['fname']}_clean"),
730
+ lname_expr=pl.col(f"{cols['lname']}_clean"),
731
+ dob_expr=pl.col("_lhs_dob_md"),
732
+ label="compact month-day dob_imp exact",
733
+ compact=True,
734
+ )
735
+ matched_frames.append(matched)
736
+
586
737
  unmatched = _run_right_side_name_stages(
587
738
  unmatched,
588
739
  matched_frames,
@@ -591,6 +742,7 @@ def lookup_sid_cepr(
591
742
  prefix="mdi_",
592
743
  dob_expr=pl.col("_lhs_dob_md"),
593
744
  label_prefix="month-day dob_imp: ",
745
+ compact=False,
594
746
  )
595
747
 
596
748
  unmatched = _run_left_side_name_stages(
@@ -601,6 +753,29 @@ def lookup_sid_cepr(
601
753
  exact_key="mdi_exact",
602
754
  dob_expr=pl.col("_lhs_dob_md"),
603
755
  label_prefix="month-day dob_imp: ",
756
+ compact=False,
757
+ )
758
+
759
+ unmatched = _run_right_side_name_stages(
760
+ unmatched,
761
+ matched_frames,
762
+ cols=cols,
763
+ lookups=lookups,
764
+ prefix="compact_mdi_",
765
+ dob_expr=pl.col("_lhs_dob_md"),
766
+ label_prefix="compact month-day dob_imp: ",
767
+ compact=True,
768
+ )
769
+
770
+ unmatched = _run_left_side_name_stages(
771
+ unmatched,
772
+ matched_frames,
773
+ cols=cols,
774
+ lookups=lookups,
775
+ exact_key="compact_mdi_exact",
776
+ dob_expr=pl.col("_lhs_dob_md"),
777
+ label_prefix="compact month-day dob_imp: ",
778
+ compact=True,
604
779
  )
605
780
 
606
781
  result = (
@@ -0,0 +1,63 @@
1
+ from typing import Union, List
2
+ import polars as pl
3
+
4
+
5
+ FINAL_APPS_SCHEMA = [
6
+ "cmo_name",
7
+ "cmo_region",
8
+ "ren_num",
9
+ "sid_cepr",
10
+ "school_name",
11
+ "school_set",
12
+ "school_year",
13
+ "entry_grade_clean",
14
+ "school_accept",
15
+ "offer",
16
+ "initial_offer",
17
+ "waitlist_offer",
18
+ "priority_group",
19
+ "priority_group_name",
20
+ "risk_id",
21
+ "birth_cohort",
22
+ "age",
23
+ "enroll",
24
+ "offer_accepted",
25
+ "enroll_years",
26
+ "enroll_school",
27
+ "withdraw",
28
+ "application_cancel",
29
+ "waitlist",
30
+ "waitlist_number",
31
+ "lottery_number",
32
+ "late_app",
33
+ "offer_date",
34
+ "application_date",
35
+ "sibling",
36
+ "staff",
37
+ "zoned",
38
+ ]
39
+
40
+
41
+
42
+ def keep_final_apps_schema(
43
+ df: Union[pl.DataFrame, pl.LazyFrame],
44
+ ) -> Union[pl.DataFrame, pl.LazyFrame]:
45
+
46
+ cols = (
47
+ df.columns
48
+ if isinstance(df, pl.DataFrame)
49
+ else df.collect_schema().names()
50
+ )
51
+
52
+ keep_cols = [
53
+ col for col in FINAL_APPS_SCHEMA
54
+ if col in cols
55
+ ]
56
+
57
+ return df.select(keep_cols)
58
+
59
+
60
+ df = (
61
+ df
62
+ .pipe(keep_final_apps_schema)
63
+ )
File without changes