I got a lot of this from a old APBA Journal article "Summary Of Card-Makers' Theories, Investigations" by Aaron W. Shomo (I don't know the issue -if anyone does, please let me know!), supplemented by my own reseach into cards from the 1988-92 era, and some much more recent studies.

Caveat: I may be wrong about some or most of this. If so, I'd welcome comments and corrections!

I use the following stats:
AB, H, 2B, 3B, HR, BB, SO, SB, CS

HP (hit by pitch), GDP (grounded into DP), SH (sacrifice bunts),

SF (sacrifice flies), IBB (intentional walks), and the player's position.

I'd use the player's normal batting order position if I could get it. (This determines the error number result on "53".)

The basic stuff:

1. compute the player's plate appearances:

FudgeBB = BB - (2/3)*IBB

PA = AB + HP + SF + SH + FudgeBB

(Note the fudge factor on IBB. I'm completely unsure of this, but it makes pre-1992 data fit well.)

2. figure the number of 14s:

n14s = round(36*FudgeBB/PA)

3. Figure the Hit by Pitch numbers:

nHPs = (36*HP)/PA

n42s = (nHPs/0.9)

residHPs = nHPs - int(n42s)*0.9

Now, if residHPs is:

>0.6, give another 42

<0.60 and >0.45, give a 19 and a 22 if 1Bman, 3Bman or catcher

give a 15 and a 22 if an outfielder or DH,

give 2 22s otherwise

<0.45 and >0.30, give a 22

<0.30 and >0.13, give a 19 if 1Bman, 3Bman or catcher

give a 15 if an outfielder or DH

4. Figure the power numbers:

n2B = (36*2B)/PA

n3B = (36*3B)/PA

nHR = (36*HR)/PA

nXBH = n2B + n3B + nHR

You must decide if you can do a 1 column card.

If nHR is >0 and <0.9, or if the fractional part of nXBH is between 0.4 and 0.67, you must do a 2 column card.

If 1 column is still a possibility, try to fit round(nXBH) power numbers to match your n2B, n3B and nHR numbers using the following values for result numbers 1 through 6:

# nHR n3B n2B

1 1.0 0.0 0.0

2 0.044 0.956 0.0

3 0.088 0.603 0.309

4 0.071 0.356 0.573

5 0.356 0.071 0.573

6 0.027 0.027 0.946

If you like the best fit you get, then use it.

Else, use 2 columns. Assign n1 = int(nHR) 1's, then n0 = nXBH-n1 rounded up to the next integer. Assign n0 zeros, and figure the second column, assigning 36*(nHRs-n1)/n0 1's, 36*n3Bs/n0 2's, 36*n2Bs/n0 6's, and the rest 7s.

5. Figure the hit numbers:

nHits = (36-n14s-n42s)*H/AB (Note: AB *not* PA)

nSingles = nHits minus the number of 0s through 6s you assigned in step 4.

if nSingles is:

<1.25, give an 8 and a 9

>1.25 and <2.00, give a 7, an 8 and a 9

>2.00 and <3.00, give a 7, an 8 and 2 9s

>3.00 and <3.75, give a 7, 2 8s and 1 9

>3.75 and <4.25, give a 7, 2 8s and 2 9s

if nSingles>=4.25, n8s = 3 and n9s = 2, and n7s = the integer part of nSingles-4.

then if the fractional part of nSingles is >0.70, add a 7.

the fractional part of nSingles is >0.25, add an 8.

*** I think APBA has changed this fractional part bit over the years ***

6. figure speed numbers (10, 11, and 14*):

The only way I can describe this is by an algorithm that will read like code:

nSBs = 36*SB/PA

If nSBs < n7s (from step 5),

n11s = int(nSBs)

n7s = n7s - n11s

nSBs = nSBs - n11s

if (nSBs > 0.9) and (n7s>0)

n11s = n11s + 1

n7s = n7s - 1

and we're done

By this point, we've given all the first column 11s we can. If by now nSBs<0.25, we're done.

Now assign 10s:

Try for second column 11s:

n2SBs = 36*nSBs/n0s

if n2SBs <= nSecondColumn7s (from step 4)

change n2SBs second column 7s to 11s

and we're done

if instead, n2SBs > nSecondColumn7s

change nSecondColumn7s to 11s

nSB = nSBs - nSecondColumn7s*n0s/36

Now, if nSBs < 0.25, we're done.

if nSBs > 0.25 and <0.65, change an 8 to a 10 and we're done

if nSBs > 0.65, change 2 8s to 10s and reduce nSBs by 0.8

If nSB<0.25, we're done.

Otherwise, assign 14*s:

change int((nSB+0.15)/0.40) 14s to 14*s, assuming there are enough 14s.

Finally, we're done.

7. figure 13s:

nKs = (36*SO)/PA, and use this table:

nK < n13s:

1.17 0

1.90, 1 13's

3.62, 2 13's

4.66, 3 13's

5.70, 4 13's

6.74, 5 13's

8.02, 6 13's

9.26, 7 13's

10.49, 8 13's

11.32, 9 13's

12.66, 10 13's

14.0, 11 13's

15.5, 12 13's

more?

8. figure 24s:

nDPs = 36*GDP/PA, and use this table:

nDPs < n24s

0.54 0

0.82, 1 24's

1.10, 2 24's

1.35, 3 24's

1.60, 4 24's

1.91, 5 24's

2.19, 6 24's

2.40, 7 24's

2.75, 8 24's

3.10, 9 24's

more?

9. assign rare play numbers:

Position: Rare Play Numbers:

P 23, 36

C 36, 38

1B 37, 41

2B 36

3B 39

SS 23, 39

OF 40

10. compute number of 31s:

This is a complete guess. It even works sometimes.

nSO = 36*SO/PA

nHITS = number of 0s through 11s

if nSO > 6, give 1 31

if nHITS < 8, give 1 31

if nSO <= 6 and >2.5, give 2 31s

if nHITS >= 8 and < 10, give 2 31s

otherwise, give 3 31s

11. steal rating :

if attempts = 0, steal rating = "N0"

steal letter:

nSA = (SB+CS)/PA

nSA > 0.140 = "A"

nSA > 0.100 = "B"

nSA > 0.070 = "C"

nSA > 0.045 = "D"

nSA > 0.026 = "E"

nSA > 0.019 = "F"

nSA > 0.007 = "G"

otherwise = "R"

steal number:

if (SB = 0) number = 0

if (CS = 0) number = 36

otherwise

number = the lesser of int(36*(SB/(SB+CS)) + 2.5) and 36