Adjust a Sample Mean towards the Population Mean This feels incredibly basic but I can't seem to find the answer!
Let's say I knew the pass rate for an exam in a huge population of students is 50% (let's say millions of students).
A new class of N=30 students take the test and 60% of the class pass.
Another new class of N=5000 students take the test and 55% pass.
The test is binary, only pass or fail with no scores.
Is there a statistically sound way of "adjusting" both these classes towards the population average?
For instance, for the first class - although 60% passed there's only N=30, so this is adjusted towards the population mean by a lot (let's say 51%?)
The second class has a 55% pass rate but given there's N=5000 there will be only a small adjustment (maybe 54.9%)?
This makes sense in my head but I can't seem to find the right statistical approach!
The reason I want to do this is, if we found out there was an unmarked test from one student from both these new classes - what would we predict their chances of passing the test to be?
Many Thanks

As noted in the comments, you need to the distribution of class pass rates in the population, not just the average over classes. This then becomes a Bayesian inference problem, where the prior is the distribution across classes, and the data is the number of passes and fails in a particular class.
As a simple model, let's say that pass rates are Normally distributed in the population with a mean of $\mu = .5$ and a standard deviation of $\sigma = .1$ (this is only an approximation, because this distribution doesn't rule out pass rates $<0$ or $>1$). You have data from a single class, where 15/20 students have passed. Let $\theta$ be the estimated underlying probability of passing for the class in question.
There are many ways to fit a model like this, but here's an example using rstan, which shows that the posterior estimate for the pass rate is 61%, with a 95% credible interval of [46% - 76%] (try changing the data or priors here to see how the results differ)
library(rstan)
model_code = '
data {
 real prior_mean;
 real prior_sd;
 int n_pass;
 int n_total;
}
parameters{
  real pass_rate;
}
model {
  pass_rate ~ normal(prior_mean, prior_sd);
  n_pass ~ binomial(n_total, pass_rate);
}'

data = list(
  prior_mean = .5,
  prior_sd = .1,
  n_pass = 15,
  n_total = 20
)
result = stan(model_code = model_code, data = data)  # Takes a few seconds to compile
print(result)

#   Inference for Stan model: 51931e3aee4b65fffc40e86f3ba918b6.
# 4 chains, each with iter=2000; warmup=1000; thin=1; 
# post-warmup draws per chain=1000, total post-warmup draws=4000.
# 
#             mean se_mean   sd   2.5%    25%    50%    75%  97.5%
# pass_rate   0.61    0.00 0.08   0.46   0.56   0.61   0.66   0.76
# lp__      -13.24    0.02 0.72 -15.25 -13.41 -12.96 -12.78 -12.73
# n_eff Rhat
# pass_rate  1473    1
# lp__       1534    1
# 
# Samples were drawn using NUTS(diag_e) at Sun Jun 12 14:33:35 2022.
# For each parameter, n_eff is a crude measure of effective sample size,
# and Rhat is the potential scale reduction factor on split chains (at 
# convergence, Rhat=1).
```

