ltc-code 0.2.25__tar.gz → 0.2.26__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 (70) hide show
  1. {ltc_code-0.2.25 → ltc_code-0.2.26}/PKG-INFO +1 -1
  2. {ltc_code-0.2.25 → ltc_code-0.2.26}/pyproject.toml +1 -1
  3. {ltc_code-0.2.25 → ltc_code-0.2.26}/pyproject.toml.orig +1 -1
  4. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/nsc/build_nsc_outcomes.py +147 -49
  5. {ltc_code-0.2.25 → ltc_code-0.2.26}/README.md +0 -0
  6. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260614_new_build_scripts_update/aspire.py +0 -0
  7. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260614_new_build_scripts_update/check_cmo_apps.do +0 -0
  8. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260614_new_build_scripts_update/christel_house.py +0 -0
  9. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260614_new_build_scripts_update/democracy_prep.py +0 -0
  10. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260614_new_build_scripts_update/green_dot.py +0 -0
  11. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260614_new_build_scripts_update/helpers.py +0 -0
  12. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260614_new_build_scripts_update/ilt.py +0 -0
  13. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260614_new_build_scripts_update/kipp_nj.py +0 -0
  14. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260614_new_build_scripts_update/main.py +0 -0
  15. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260614_new_build_scripts_update/mappings.py +0 -0
  16. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260614_new_build_scripts_update/rocketship.py +0 -0
  17. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260614_new_build_scripts_update/yes_prep.py +0 -0
  18. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260630_census_disclosure/aspire.py +0 -0
  19. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260630_census_disclosure/christel_house.py +0 -0
  20. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260630_census_disclosure/democracy_prep.py +0 -0
  21. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260630_census_disclosure/green_dot.py +0 -0
  22. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260630_census_disclosure/ilt.py +0 -0
  23. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260630_census_disclosure/kipp.py +0 -0
  24. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260630_census_disclosure/kipp_nj.py +0 -0
  25. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260630_census_disclosure/rocketship.py +0 -0
  26. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260630_census_disclosure/yes_prep.py +0 -0
  27. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260706_ceprscripts/BALANCE.do +0 -0
  28. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260706_ceprscripts/FS.do +0 -0
  29. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260706_ceprscripts/ITT.do +0 -0
  30. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260706_ceprscripts/TOT.do +0 -0
  31. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260706_ceprscripts/apps_helpers.py +0 -0
  32. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260706_ceprscripts/harmony.py +0 -0
  33. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260706_ceprscripts/main.py +0 -0
  34. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260712_uncommon_scripts/main.py +0 -0
  35. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260712_uncommon_scripts/mappings.py +0 -0
  36. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/20260712_uncommon_scripts/uncommon.py +0 -0
  37. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/__init__.py +0 -0
  38. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/aspire.py +0 -0
  39. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/check_cmo_apps.do +0 -0
  40. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/christel_house.py +0 -0
  41. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/green_dot.py +0 -0
  42. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/helpers.py +0 -0
  43. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/june13.py +0 -0
  44. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/june2.py +0 -0
  45. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/june30.py +0 -0
  46. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/june5.py +0 -0
  47. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/june7.py +0 -0
  48. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/kipp_nj.py +0 -0
  49. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/kipp_tx.py +0 -0
  50. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/main.py +0 -0
  51. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/make_summary_stats_table.py +0 -0
  52. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/mappings.py +0 -0
  53. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/may27.py +0 -0
  54. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/nsc/__init__.py +0 -0
  55. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/nsc/dhs_stem/dhs_stem_cip_additions_2024.csv +0 -0
  56. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/nsc/dhs_stem/extract_dhs_stem_cips.R +0 -0
  57. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/nsc/dhs_stem/stemList2024.pdf +0 -0
  58. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/nsc/input/.gitkeep +0 -0
  59. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/nsc/naics.py +0 -0
  60. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/nsc/output/.gitkeep +0 -0
  61. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/nsc/raw/ipeds_data.dta +0 -0
  62. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/nsc/run_nsc_outcomes.py +0 -0
  63. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/polars_dates.py +0 -0
  64. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/rocketship.py +0 -0
  65. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/schema_mapping.py +0 -0
  66. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/school_name_xwalk/__init__.py +0 -0
  67. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/school_name_xwalk/all_schools_with_ccd.csv +0 -0
  68. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/school_name_xwalk/merge_school_ccd.py +0 -0
  69. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/signal_var_calcs.py +0 -0
  70. {ltc_code-0.2.25 → ltc_code-0.2.26}/src/ltc_code/yes_prep.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ltc-code
3
- Version: 0.2.25
3
+ Version: 0.2.26
4
4
  Summary: Add your description here
5
5
  Requires-Dist: fastexcel>=0.16,<0.20
6
6
  Requires-Dist: polars>=1.36.1,<1.42
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ltc-code"
3
- version = "0.2.25"
3
+ version = "0.2.26"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ltc-code"
3
- version = "0.2.25"
3
+ version = "0.2.26"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9"
@@ -461,7 +461,7 @@ ipeds_completion = (
461
461
 
462
462
  # Use the graduation cohort itself as the student weight. Summing completers and
463
463
  # cohorts is equivalent to weighting each college's rate by its IPEDS denominator.
464
- ipeds_sector_rates = (
464
+ ipeds_completion_with_sector = (
465
465
  ipeds_completion
466
466
  .join(
467
467
  ipeds_2013.select("unitid", "years_ipeds_2013"),
@@ -501,6 +501,10 @@ ipeds_sector_rates = (
501
501
  .otherwise(pl.lit("2yr_or_less"))
502
502
  .alias("college_sector")
503
503
  )
504
+ )
505
+
506
+ ipeds_sector_rates = (
507
+ ipeds_completion_with_sector
504
508
  .group_by("college_sector")
505
509
  .agg(
506
510
  pl.col("completers_150pct_ip").sum().alias("completers"),
@@ -1120,6 +1124,7 @@ enroll = (
1120
1124
  pl.col("cohort_18").first(),
1121
1125
  pl.col("college").first(),
1122
1126
  pl.col("college_name").first(),
1127
+ pl.col("unitid").drop_nulls().first(),
1123
1128
  pl.col("college_years").first(),
1124
1129
  pl.col("college_any").max(),
1125
1130
  pl.col("college_4yr").max(),
@@ -1331,6 +1336,7 @@ first_institution = (
1331
1336
  .first()
1332
1337
  .alias("college_name_firstinst"),
1333
1338
  pl.col("college_years").first().alias("college_years_firstinst"),
1339
+ pl.col("unitid").first().alias("unitid_firstinst"),
1334
1340
  pl.col("completion_rate_150pct_ip")
1335
1341
  .first()
1336
1342
  .alias("completion_rate_150pct_firstinst"),
@@ -1725,61 +1731,132 @@ for age in AGE_ATTENDANCE_RANGE:
1725
1731
  )
1726
1732
 
1727
1733
 
1728
- # Define expected completion over the cumulative by-Y4 attendance window. The
1729
- # detailed measure uses the first institution's rate (with the tier-median fill
1730
- # above), gives observed nonattenders zero, and leaves attendee rates missing
1731
- # when neither the institution rate nor its tier median is available.
1732
- nsc_outcomes = nsc_outcomes.with_columns(
1733
- pl.when(pl.col("att_any_byY4") == 0)
1734
- .then(None)
1735
- .otherwise(pl.col("completion_rate_150pct_ip"))
1736
- .alias("completion_rate_150pct_ip")
1734
+ # Calculate coarse averages, restricted to the first institutions among observed by-Y4 attendees
1735
+ sample_firstinst_unitids = (
1736
+ nsc_outcomes.filter(pl.col("att_any_byY4") == 1)
1737
+ .select(pl.col("unitid_firstinst").alias("unitid"))
1738
+ .drop_nulls()
1739
+ .unique()
1740
+ )
1741
+
1742
+ ipeds_sample_sector_rates = (
1743
+ ipeds_completion_with_sector.join(
1744
+ sample_firstinst_unitids,
1745
+ on="unitid",
1746
+ how="semi",
1747
+ )
1748
+ .group_by("college_sector")
1749
+ .agg(
1750
+ pl.len().alias("institutions"),
1751
+ pl.col("completers_150pct_ip").sum().alias("completers"),
1752
+ pl.col("cohort_adj_150pct_ip").sum().alias("cohort"),
1753
+ )
1754
+ .with_columns(
1755
+ (pl.col("completers") / pl.col("cohort")).alias("cmp_rate_coarse_sample")
1756
+ )
1737
1757
  )
1738
1758
 
1759
+ cmp_rate_4yr_coarse_sample = ipeds_sample_sector_rates.filter(
1760
+ pl.col("college_sector") == "4yr"
1761
+ ).item(0, "cmp_rate_coarse_sample")
1762
+ cmp_rate_2yr_coarse_sample = ipeds_sample_sector_rates.filter(
1763
+ pl.col("college_sector") == "2yr_or_less"
1764
+ ).item(0, "cmp_rate_coarse_sample")
1765
+ sample_4yr_institutions = ipeds_sample_sector_rates.filter(
1766
+ pl.col("college_sector") == "4yr"
1767
+ ).item(0, "institutions")
1768
+ sample_2yr_institutions = ipeds_sample_sector_rates.filter(
1769
+ pl.col("college_sector") == "2yr_or_less"
1770
+ ).item(0, "institutions")
1771
+
1772
+ for label, value in {
1773
+ "sample four-year completion rate": cmp_rate_4yr_coarse_sample,
1774
+ "sample two-year-or-less completion rate": cmp_rate_2yr_coarse_sample,
1775
+ }.items():
1776
+ if value is None or not 0 <= value <= 1:
1777
+ raise ValueError(f"Invalid IPEDS-cohort-weighted {label}: {value}")
1778
+
1779
+
1780
+ # Define completion-rate measures over the cumulative by-Y4 attendance window, just for attendees
1739
1781
  nsc_outcomes = nsc_outcomes.with_columns(
1740
- pl.col("completion_rate_150pct_ip").alias("cmp_rate"),
1741
- pl.when(pl.col("att_any_byY4").is_null())
1742
- .then(None)
1743
- .when(pl.col("att_4yr_byY4") == 1)
1744
- .then(cmp_rate_4yr_coarse)
1745
- .when(pl.col("att_2yr_byY4") == 1)
1746
- .then(cmp_rate_2yr_coarse)
1747
- .when(pl.col("att_any_byY4") == 0)
1748
- .then(0.0)
1782
+ # Detailed cmp rate
1783
+ pl.when(pl.col("att_any_byY4") == 1)
1784
+ .then(pl.col("completion_rate_150pct_ip"))
1785
+ .otherwise(None)
1786
+ .alias("cmp_rate"),
1787
+ # Coarse cmp rate
1788
+ pl.when(pl.col("att_any_byY4") == 1)
1789
+ .then(
1790
+ pl.when(pl.col("college_years_firstinst") == 4)
1791
+ .then(cmp_rate_4yr_coarse)
1792
+ .when(pl.col("college_years_firstinst").is_in([1, 2]))
1793
+ .then(cmp_rate_2yr_coarse)
1794
+ .otherwise(None)
1795
+ )
1749
1796
  .otherwise(None)
1750
1797
  .alias("cmp_rate_coarse"),
1798
+ # Coarse cmp rate, using in-sample avgs
1799
+ pl.when(pl.col("att_any_byY4") == 1)
1800
+ .then(
1801
+ pl.when(pl.col("college_years_firstinst") == 4)
1802
+ .then(cmp_rate_4yr_coarse_sample)
1803
+ .when(pl.col("college_years_firstinst").is_in([1, 2]))
1804
+ .then(cmp_rate_2yr_coarse_sample)
1805
+ .otherwise(None)
1806
+ )
1807
+ .otherwise(None)
1808
+ .alias("cmp_rate_coarse_sample"),
1809
+ # Coarsen only the 4yr cmp rates
1810
+ pl.when(pl.col("att_any_byY4") == 1)
1811
+ .then(
1812
+ pl.when(pl.col("college_years_firstinst") == 4)
1813
+ .then(cmp_rate_4yr_coarse)
1814
+ .when(pl.col("college_years_firstinst").is_in([1, 2]))
1815
+ .then(pl.col("completion_rate_150pct_ip"))
1816
+ .otherwise(None)
1817
+ )
1818
+ .otherwise(None)
1819
+ .alias("cmp_rate_coarsen_4yr"),
1820
+ # Coarsen only the 2yr cmp rates
1821
+ pl.when(pl.col("att_any_byY4") == 1)
1822
+ .then(
1823
+ pl.when(pl.col("college_years_firstinst") == 4)
1824
+ .then(pl.col("completion_rate_150pct_ip"))
1825
+ .when(pl.col("college_years_firstinst").is_in([1, 2]))
1826
+ .then(cmp_rate_2yr_coarse)
1827
+ .otherwise(None)
1828
+ )
1829
+ .otherwise(None)
1830
+ .alias("cmp_rate_coarsen_2yr"),
1751
1831
  )
1752
1832
 
1833
+ # Now set observed nonattenders to zero for each measure
1753
1834
  nsc_outcomes = nsc_outcomes.with_columns(
1754
- pl.when(pl.col("att_any_byY4").is_null())
1755
- .then(None)
1756
- .when(pl.col("att_any_byY4") == 0)
1835
+ # Detailed cmp rate
1836
+ pl.when(pl.col("att_any_byY4") == 0)
1757
1837
  .then(0.0)
1758
1838
  .otherwise(pl.col("cmp_rate"))
1759
1839
  .alias("adj_cmp_rate"),
1760
- pl.col("cmp_rate_coarse")
1761
- .alias("adj_cmp_rate_coarse"),
1762
- ).with_columns(
1763
- pl.when(pl.col("att_any_byY4").is_null())
1764
- .then(None)
1765
- .otherwise(pl.col("cmp_rate"))
1766
- .alias("cmp_rate"),
1767
- pl.when(pl.col("att_any_byY4").is_null())
1768
- .then(None)
1769
- .otherwise(pl.col("adj_cmp_rate"))
1770
- .alias("adj_cmp_rate"),
1771
- pl.when(pl.col("att_any_byY4").is_null())
1772
- .then(None)
1840
+ # Coarse cmp rate
1841
+ pl.when(pl.col("att_any_byY4") == 0)
1842
+ .then(0.0)
1773
1843
  .otherwise(pl.col("cmp_rate_coarse"))
1774
- .alias("cmp_rate_coarse"),
1775
- pl.when(pl.col("att_any_byY4").is_null())
1776
- .then(None)
1777
- .otherwise(pl.col("adj_cmp_rate_coarse"))
1778
1844
  .alias("adj_cmp_rate_coarse"),
1779
- pl.when(pl.col("att_any_byY4").is_null())
1780
- .then(None)
1781
- .otherwise(pl.col("adj_cmp_rate"))
1782
- .alias("predicted_completion"),
1845
+ # Coarse cmp rate, using in-sample avgs
1846
+ pl.when(pl.col("att_any_byY4") == 0)
1847
+ .then(0.0)
1848
+ .otherwise(pl.col("cmp_rate_coarse_sample"))
1849
+ .alias("adj_cmp_rate_coarse_sample"),
1850
+ # Coarsen only the 4yr cmp rates
1851
+ pl.when(pl.col("att_any_byY4") == 0)
1852
+ .then(0.0)
1853
+ .otherwise(pl.col("cmp_rate_coarsen_4yr"))
1854
+ .alias("adj_cmp_rate_coarsen_4yr"),
1855
+ # Coarsen only the 2yr cmp rates
1856
+ pl.when(pl.col("att_any_byY4") == 0)
1857
+ .then(0.0)
1858
+ .otherwise(pl.col("cmp_rate_coarsen_2yr"))
1859
+ .alias("adj_cmp_rate_coarsen_2yr"),
1783
1860
  )
1784
1861
 
1785
1862
 
@@ -1855,9 +1932,10 @@ keep_columns = [
1855
1932
  "completion_rate_150pct_ip",
1856
1933
  "cmp_rate",
1857
1934
  "adj_cmp_rate",
1858
- "cmp_rate_coarse",
1859
1935
  "adj_cmp_rate_coarse",
1860
- "predicted_completion",
1936
+ "adj_cmp_rate_coarse_sample",
1937
+ "adj_cmp_rate_coarsen_4yr",
1938
+ "adj_cmp_rate_coarsen_2yr",
1861
1939
  "ID_FSC_firstinst",
1862
1940
  "college_name_firstinst",
1863
1941
  "tier_firstinst",
@@ -1902,6 +1980,13 @@ print(
1902
1980
  f"completion 2yr-or-less={cmp_rate_2yr_coarse:.4f}; "
1903
1981
  "observed by-Y4 nonattender completion=0"
1904
1982
  )
1983
+ print(
1984
+ "Sample-institution IPEDS-cohort-weighted coarse values: "
1985
+ f"completion 4yr={cmp_rate_4yr_coarse_sample:.4f} "
1986
+ f"({sample_4yr_institutions} institutions), "
1987
+ f"completion 2yr-or-less={cmp_rate_2yr_coarse_sample:.4f} "
1988
+ f"({sample_2yr_institutions} institutions)"
1989
+ )
1905
1990
 
1906
1991
  observable_y4 = nsc_outcomes.filter(pl.col("att_any_byY4").is_not_null())
1907
1992
  coarse_audit = observable_y4.select(
@@ -1914,6 +1999,15 @@ coarse_audit = observable_y4.select(
1914
1999
  .alias("adj_cmp_rate_coarse_missing"),
1915
2000
  pl.col("adj_cmp_rate_coarse").min().alias("adj_cmp_rate_coarse_min"),
1916
2001
  pl.col("adj_cmp_rate_coarse").max().alias("adj_cmp_rate_coarse_max"),
2002
+ pl.col("adj_cmp_rate_coarse_sample")
2003
+ .null_count()
2004
+ .alias("adj_cmp_rate_coarse_sample_missing"),
2005
+ pl.col("adj_cmp_rate_coarse_sample")
2006
+ .min()
2007
+ .alias("adj_cmp_rate_coarse_sample_min"),
2008
+ pl.col("adj_cmp_rate_coarse_sample")
2009
+ .max()
2010
+ .alias("adj_cmp_rate_coarse_sample_max"),
1917
2011
  )
1918
2012
 
1919
2013
  if coarse_audit.item(0, "k_mean_coarse_missing") > 0:
@@ -1922,6 +2016,10 @@ if coarse_audit.item(0, "adj_cmp_rate_coarse_missing") > 0:
1922
2016
  raise ValueError(
1923
2017
  "adj_cmp_rate_coarse is unexpectedly missing for observable students."
1924
2018
  )
2019
+ if coarse_audit.item(0, "adj_cmp_rate_coarse_sample_missing") > 0:
2020
+ raise ValueError(
2021
+ "adj_cmp_rate_coarse_sample is unexpectedly missing for observable students."
2022
+ )
1925
2023
 
1926
2024
  print("Coarse outcome audit:")
1927
2025
  print(coarse_audit)
@@ -1940,22 +2038,22 @@ attendee_completion_audit = (
1940
2038
  )
1941
2039
  .sum()
1942
2040
  .alias("filled_by_tier_median"),
1943
- pl.col("predicted_completion")
2041
+ pl.col("adj_cmp_rate")
1944
2042
  .is_null()
1945
2043
  .sum()
1946
2044
  .alias("missing_after_tier_median"),
1947
- pl.col("predicted_completion")
2045
+ pl.col("adj_cmp_rate")
1948
2046
  .is_null()
1949
2047
  .mean()
1950
2048
  .alias("missing_after_tier_median_share"),
1951
2049
  (
1952
- pl.col("predicted_completion").is_null()
2050
+ pl.col("adj_cmp_rate").is_null()
1953
2051
  & pl.col("tier_firstinst").is_null()
1954
2052
  )
1955
2053
  .sum()
1956
2054
  .alias("missing_after_tier_median_no_tier"),
1957
2055
  (
1958
- pl.col("predicted_completion").is_null()
2056
+ pl.col("adj_cmp_rate").is_null()
1959
2057
  & pl.col("tier_firstinst").is_not_null()
1960
2058
  )
1961
2059
  .sum()
File without changes