I wrote a Python calculator for USCF title norms

I tried to make these instructions as simple and concise as possible for a person that doesn’t know anything other than how to open a browser. How to run this:

Windows: Download Notepad++. Download Python 2.7. Paste the code into Notepad++. Go to the Edit menu, hover over the EOL conversion button and click ‘Unix/OSX’ if it is not already selected. Save it in your C:\Python27 folder as normcalculator.py. Open a command line (search for ‘cmd’ in your programs). Type in ‘cd C:\Python27’ and press enter. Type in ‘python normcalculator.py’ and press enter. Follow the prompts.

Mac: Do the same as above, but you should download TextWrangler instead of Notepad++ and you don’t need to do the EOL conversion. Save it to wherever you installed Python. Instead of searching for ‘cmd’ to open a command line, run the ‘Terminal’ application on your Launchpad.

Linux: You probably don’t need my help.

If anyone finds errors (or problems with my instructions, it’s been a while since I set up Python from scratch and tried to run something), please let me know.

1200 corresponds to a 4-norm, 1400 to a 3, 1600 to a 2, 1800 to a 1, 2000 to a C, 2200 to an M, and 2400 to an S.

[code]# Gabriel Ewing 8/1/2014

from pprint import pprint
import sys

rounds = input('Enter the number of rounds: ')

error handling for case where norm cannot be achieved

if rounds < 4:
print ‘Not enough rounds for a norm. Exiting.’
raw_input(“Press enter to continue”)
sys.exit()

list of opponents

opps = range(0, rounds)

prompt for opponent ratings

for x in opps:
opps[x] = input('Enter the rating of the round ’ + str(x + 1) + ’ opponent: ')

dictionary with norm level and required score

levels = {‘1200’ : 0, ‘1400’ : 0, ‘1600’ : 0, ‘1800’ : 0, ‘2000’ : 0, ‘2200’ : 0, ‘2400’ : 0}

Calculating required score. Outer loop is the norm level, inner loop is each opponent.

for k, v in levels.iteritems():
for y in opps:
# Case where norm level is more than 200 above opponent rating
if int(k) - 200 > y:
levels[k] = float(levels[k] + 1)
# Case where norm level is between 200 and 0 points above opponent rating
elif int(k) > y:
levels[k] = float(levels[k] + .5) + float((int(k) - y))/400
# Case where norm level is more than 400 points below opponent rating
elif int(k) + 400 < y:
levels[k] = float(levels[k])
# Case where norm level is between 0 and 400 points below opponent rating
else:
levels[k] = float(levels[k] + .5) - float((y - int(k)))/800

Print the results

print 'If you scored MORE than the following number of points, you made the norm at that level: ’
pprint(levels)

raw_input(“Press enter to continue”)[/code]

I don’t know that I’ll have time to test this program out in the next few weeks, but, like the Excel spreadsheet that Mark Glickman has posted, any results from such a calculator is unofficial.

My apologies, I should’ve mentioned that. I have no affiliation with the USCF other than being a member and playing tournaments. I wasn’t aware that there was already a tool to do this but I’ll have to take a look at it.

Also worth noting is that since the norm calculations are based on the post-event ratings, any estimator using pre-event ratings is going to have some blips. If a tournament takes a couple days to get rated anyway, it might be better to just wait for the Wednesday norm update than try to calculate it.

My experience has been that members are rarely as patient as Mr. Ewing recommends. :slight_smile:

I have thought, and continue to think, that member efforts such as these could be coordinated and overseen by the national office. USCF should more aggressively tap into SMEs willing to donate their time and talent.

Efforts like Mr. Ewing’s (other recent examples that come to mind include work by Wayne Zimmerle and Tim Smith) should be encouraged, and where appropriate, incorporated.

I’ve created an excel sheet where the entire rating section is inputted, meaning norms and rating changes are not calculated using solely pre-tournament ratings. It is not 100% accurate though if a player in the section has played 8 games or fewer prior to the tournament.

If anyone wants to try it out, PM me.

Edited code because I can’t read (I was using outputting Ct from the formula, not Ct+1).

[code]# Gabriel Ewing 8/1/2014

from pprint import pprint
import sys

rounds = input('Enter the number of rounds: ')

error handling for case where norm cannot be achieved

if rounds < 4:
print ‘Not enough rounds for a norm. Exiting.’
raw_input(“Press enter to continue”)
sys.exit()

list of opponents

opps = range(0, rounds)

prompt for opponent ratings

for x in opps:
opps[x] = input('Enter the rating of the round ’ + str(x + 1) + ’ opponent: ')

dictionary with norm level and required score

levels = {‘1200’ : 1, ‘1400’ : 1, ‘1600’ : 1, ‘1800’ : 1, ‘2000’ : 1, ‘2200’ : 1, ‘2400’ : 1}

Calculating required score. Outer loop is the norm level, inner loop is each opponent.

for k, v in levels.iteritems():
for y in opps:
# Case where norm level is more than 200 above opponent rating
if int(k) - 200 > y:
levels[k] = float(levels[k] + 1)
# Case where norm level is between 200 and 0 points above opponent rating
elif int(k) > y:
levels[k] = float(levels[k] + .5) + float((int(k) - y))/400
# Case where norm level is more than 400 points below opponent rating
elif int(k) + 400 < y:
levels[k] = float(levels[k])
# Case where norm level is between 0 and 400 points below opponent rating
else:
levels[k] = float(levels[k] + .5) - float((y - int(k)))/800

Print the results

print 'If you scored MORE than the following number of points, you made the norm at that level: ’
pprint(levels)

raw_input(“Press enter to continue”)[/code]

If anyone has the power to edit that into my original post, I’d appreciate it.

You can only edit posts for a few days. That’s one of the downsides of posting code (which often needs to be revised) to the Forums.