How we score schools
SweetSpot doesn't rank California public schools. It scores them — and then lets you decide what counts. Here's how.
Data from CDE SARC, cycles 22-23, 23-24, 24-25. Last refreshed 2026-05-15.
How we score
Every California public school is scored against 9dimensions, drawn directly from the state's annual School Accountability Report Card (SARC) filings. For each dimension, we map the school's raw number (test proficiency, suspension rate, teacher credentialing %, etc.) to a 0–10 score using absolute anchor tables — never against its peers. A school's fit score is the weighted average of those dimension scores, with weights you control.
Move a slider on the priorities panel, and every school's fit score re-computes in real time. Nothing about the score depends on rank, curve, or which other schools happen to be near it.
Where the data comes from
Every number on this site comes from the California Department of Education's SARC files, published annually. We don't scrape, infer, or generate — we map columns from CDE's official tables to the dimensions we score on. The 3-cycle report covers school years 22-23 through 24-25.
Source URLs and per-metric file lineage are documented in the appendix below.
Three things we deliberately don't do
- No peer-relative ranking.
- A school's score doesn't depend on which county you pulled it up in. A 50%-disadvantaged school in Marin and one in Imperial get the same score on the same numbers. We picked the anchor tables once, and they apply statewide.
- No rolling averages.
- Every score reflects the most recent cycle's data, full stop. We don't smooth bad years into trailing averages — that hides what actually happened.
- No hidden algorithm.
- The full anchor tables, direction-flipping logic, and metric lineage are below. No black box. No “proprietary blend”.
Appendix
For journalists, skeptics, and anyone who wants to verify a number.
Anchor tables
Each dimension's raw → 0–10 mapping. Percentile cutoffs are computed once at build time from the full statewide distribution.
High math proficiency
Higher is betterColumn: SMATH_Y1
| Percentile | Raw value | Score |
|---|---|---|
| 5th | 1 | 0 |
| 50th | 29 | 5 |
| 95th | 75 | 10 |
Values between the 5th and 95th percentile are linearly interpolated. Outside that range, scores clamp at 0 or 10.
High reading proficiency
Higher is betterColumn: SELA_Y1
| Percentile | Raw value | Score |
|---|---|---|
| 5th | 11 | 0 |
| 50th | 41 | 5 |
| 95th | 80 | 10 |
Values between the 5th and 95th percentile are linearly interpolated. Outside that range, scores clamp at 0 or 10.
Strong science scores
Higher is betterColumn: SSCI_Y1
| Percentile | Raw value | Score |
|---|---|---|
| 5th | 4.41 | 0 |
| 50th | 24.24 | 5 |
| 95th | 67.07 | 10 |
Values between the 5th and 95th percentile are linearly interpolated. Outside that range, scores clamp at 0 or 10.
Small class sizes
Lower is betterColumn: AVG_SIZE
| Percentile | Raw value | Score |
|---|---|---|
| 5th | 13.12 | 10 |
| 50th | 23.62 | 5 |
| 95th | 30 | 0 |
Values between the 5th and 95th percentile are linearly interpolated. Outside that range, scores clamp at 0 or 10.
Low suspension rates
Lower is betterColumn: SSUSP_Y1
| Percentile | Raw value | Score |
|---|---|---|
| 5th | 0 | 10 |
| 50th | 1.52 | 5 |
| 95th | 13.04 | 0 |
Values between the 5th and 95th percentile are linearly interpolated. Outside that range, scores clamp at 0 or 10.
Strong attendance
Lower is betterColumn: RALL
| Percentile | Raw value | Score |
|---|---|---|
| 5th | 4.3 | 10 |
| 50th | 18.9 | 5 |
| 95th | 65.9 | 0 |
Values between the 5th and 95th percentile are linearly interpolated. Outside that range, scores clamp at 0 or 10.
Fully credentialed teachers
Higher is betterColumn: SPFUL_Y1
| Percentile | Raw value | Score |
|---|---|---|
| 5th | 38.17 | 0 |
| 50th | 88 | 5 |
| 95th | 100 | 10 |
Values between the 5th and 95th percentile are linearly interpolated. Outside that range, scores clamp at 0 or 10.
Less administrative overhead
Higher is betterColumn: PTCHSAL
| Percentile | Raw value | Score |
|---|---|---|
| 5th | 22.74 | 0 |
| 50th | 28.87 | 5 |
| 95th | 35.34 | 10 |
Values between the 5th and 95th percentile are linearly interpolated. Outside that range, scores clamp at 0 or 10.
High graduation rate
Higher is betterColumn: SGR_Y1
| Percentile | Raw value | Score |
|---|---|---|
| 5th | 27.28 | 0 |
| 50th | 90.5 | 5 |
| 95th | 99.51 | 10 |
Values between the 5th and 95th percentile are linearly interpolated. Outside that range, scores clamp at 0 or 10.
Data lineage
| Metric | SARC file | Available in |
|---|---|---|
| Math proficiency (% met/exceeded) | caall.xlsx · CAASPP math | 22-23, 23-24, 24-25 |
| Reading proficiency (% met/exceeded) | caall.xlsx · CAASPP ELA | 22-23, 23-24, 24-25 |
| Science proficiency (% met/exceeded) | caallsci.xlsx · CAST | 22-23, 23-24, 24-25 |
| Average class size | acselm.xlsx + acssec.xlsx · class size | 22-23, 23-24, 24-25 |
| Suspension rate (%) | susexp.xlsx · suspensions | 22-23, 23-24, 24-25 |
| Chronic absenteeism rate (%) | chronic.xlsx · chronic absenteeism | 22-23, 23-24, 24-25 |
| Fully credentialed teachers (%) | teacherprep.xlsx · fully credentialed | 22-23, 23-24, 24-25 |
| Teacher pay share of total compensation (%) | salary.xlsx · teacher pay share | 22-23, 23-24, 24-25 |
| 4-year graduation rate (%) | cohort.xlsx · 4-year graduation | 22-23, 23-24, 24-25 |
Known limitations
- Small-sample noise.Schools with fewer than 50 students often have suppressed or volatile values for state-tested metrics. We don't drop them — we render whatever CDE published — but treat single-year movements at small schools with skepticism.
- School closures.Schools listed in one cycle's SARC may not appear in the next. We don't backfill — the movers leaderboard only includes schools present in both 23/24 and 24/25.
- Demographic-target reversal. Some dimensions (PERDI, PEREL, PERSD) score based on whether a school matches a parent-selected demographic target, not whether the value is high or low. See
scoring_tables.pyfor the precise reversal logic. - Why some metrics start at 23/24.CDE occasionally renames or restructures columns between cycles. When a metric's column isn't present (or isn't comparable) across all three cycles, the chart starts at the first cycle where it stabilizes. The Available in column above shows the actual span.