Ps Get Degrees


Posted on January 9, 2020


Introduction

A few law schools, namely Harvard, Yale, Stanford, and Berkeley, eschew the standard A-F grading scale for Pass and Honors grades (Ps and Hs).

Each school has a slightly different system. For sake of simplicity, consider a generic school that gives out Passes (Ps) and Honors (Hs) $70\%$ and $30\%$ of the time respectively. The distribution is more lopsided than it appears on its face. Namely, in a term with four classes:

The median student will get one H. A quarter of the class will get all Ps and two-thirds will receive one or fewer Hs.

Despite a student's best efforts, they will in all likelihood probably not get any higher than one H. And a significant percentage will get none! I'll leave debates about the effectiveness of the system to the professors, registrars, social scientists, and economists. Let's look at some math instead.

Individual Analysis

Let's start with the most basic of probability analyses. Assume you take $c$ classes and have a probability $p$ of getting of getting an H in each class. The expected value, $EV$, of Hs you receive is simply $EV = c\cdot p$. If $c=4$ and $p=30\%$, then $EV = 4\cdot 0.3 = 1.2$.

How likely is it that you get $0$, $1$, $2$, $3$, or $4$ heads? With some help from Pascal, the probabilities are

# of HsFormulaProbability
$0$$\binom{4}{0}\cdot 0.3^0\cdot 0.7^4$$24.01\%$
$1$$\binom{4}{1}\cdot 0.3^1\cdot 0.7^3$$41.16\%$
$2$$\binom{4}{2}\cdot 0.3^2\cdot 0.7^2$$26.46\%$
$3$$\binom{4}{3}\cdot 0.3^3\cdot 0.7^1$$7.56\%$
$4$$\binom{4}{4}\cdot 0.3^4\cdot 0.7^0$$0.81\%$

So, at it's simplest, if you have a uniform probability $30\%$ for each class, there is a $24\%$ chance of not even getting a single H.

This can be generalized to non-uniform probabilities. This is helpful when you mailed it in on your Torts final (and have a $5\%$ chance of getting an H), but are a low key Civil Procedure genius with an $85\%$ chance of getting an H. Use the calculator below to analyze this slightly more complicated situation.



Probabilty of 0 Hs: 24.01%
Probabilty of 1 H: 41.16%
Probabilty of 2 Hs: 26.46%
Probabilty of 3 Hs: 7.56%
Probabilty of 4 Hs: 0.81%

The equations are simple (but tedious) so they are not shown here. If you really want to see them, check the JavaScript ;)

Class-wide Analysis

Looking at your individual performance is sufficient to get a good grasp of where you stand. Looking at an entire class is trickier with limited data. One could conjecture about the nature of the distribution, but that seems irresponsible. The data exists, but is private, and conjecture without evidence is boring.

One valuable insight is how a lack of uniformity factors into grade distributions. Consider a 30-person class made up of three types of students:

  • $n_1$ is the number of "below average" students, with $0.5x$ relative probability of an H in each class.
  • $n_2$ is the number of "average" students, with $1.0x$ relative probability of an H in each class.
  • $n_3$ is the number of "above average" students, with $2.0x$ relative probability of an H in each class.

and $n_1+n_2+n_3=30$.

Simulations were run with $10,000$ trials each. Nothing beyond numpy's random library is needed. There is some nuance to this probability, a $2x$ probability doesn't quite mean twice the expected value, because the impact depends on the relative probabilities from the other members. Check out the implementation in the code below.


def run_sim(n1, n2, n3):
    num_simulations = 10000
    num_students = 30
    h_rate = .3
    num_honors = int(h_rate * num_students)
    num_classes = 4

    p_dist=[.5]*n1 + [1.]*n2 + [2]*n3

    array_sum = np.sum(p_dist)
    p_dist = np.array([i / array_sum for i in p_dist])

    print "\"%02d %02d %02d\":" % (n1, n2, n3),
    category = [[0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0],
                [0, 0, 0, 0, 0]]

    for _ in xrange(num_simulations):
        people = [0]* num_students

        for _ in xrange(num_classes):
            honors_recipient = np.random.choice(num_students, num_honors, p=p_dist, replace=False)
            for h in honors_recipient:
                people[h] += 1

        for i in range(len(people)):
            h=people[i] # h is the number of Hs person i received
            if i= n1 and i < n1 + n2:
                category[1][h] += 1
            else:
                category[2][h] += 1
    
    for i in range(5):
        category[3][i] = (category[0][i]+category[1][i]+category[2][i])/float(30.*num_simulations)
    category[0] = [i/float(n1*num_simulations) for i in category[0]]     category[1] = [i/float(n2*num_simulations) for i in category[1]]
    category[2] = [i/float(n3*num_simulations) for i in category[2]]

for n1 in range(1,11):
    for n3 in range(1,11):
        n2 = 30-n1-n3
        run_sim(n1, n2, n3)

Number of students with $0.5x$ relative chance, $n_1=$ $5$

1

2

3

4

5

6

7

8

9

10


Number of students with $2x$ relative chance, $n_3=$ $5$

1

2

3

4

5

6

7

8

9

10

Category0 Hs1 H2 Hs3 Hs4 Hs
$n_1$, $0.5x$
$n_2$, $1x$
$n_3$, $2x$
Class Average

Playing with the values shows that increasing the variance even to extreme values somewhat increases the number of students receiving extreme values of Hs (e.g. zero or four Hs), but has little overall impact on the distribution.

Similarly, the distribution for the "average" student doesn't change, even when the number of "above" and "below" average students changes drastically.

Takeaways

One could devise some spectacular game theory. If, for example, you knew that a disproportionately high number of people were punting Contracts, you would have an increased return on effort in that class.

More deviously, "above average" students could punt their worst class to try to guarantee 3 Hs. Or "below average" students could focus on one or two of their best classes to try to get out of the bottom quartile. Practically, such strategies are big gambles in this volatile zero-sum game, and can't be reasonably recommended, but are fun to think about.

Some text some message..