sfmagic.org Rewrite: Player Page

20:35 Tue 25 Dec 2007
[, , ]

I finished duplicating the functionality of the old player info page tonight. I’m pretty happy with how that went.

The page shows a list of all the tournaments a player has participated in, as well as a summary of their results overall. Both the list and the summary can b e narrowed down by criteria such as year, block, format, etc.

The old page is incredibly slow. The new one seems reasonably speedy even on this old laptop, which I take as a good sign.

I like being able to generate the SQL queries with SAlchemy, even without the ORM stuff. In order to populate the dropdown menus that allow the user to select criteria for narrowing down the results, I need to have a list of unique values for each of those criteria. This was pretty easy:

distincts = {}
for each in ('format', 'type', 'bestof', 'superset', 'sets', 'seeding_type'):
    call = select([tournaments_table.c[each]]).distinct()
    result = conn.execute(call)
    distincts[each] = result
c.distincts = distincts

It’s not quite as clean in the template, where each dropdown looks like this:

<select name="superset">
    <option value="*">Any</option>
    <py:for each="value in c.distincts.superset">
        <option value="${value}" py:if="value[0] != str(c.gparams.superset)">${value}</option>
        <option value="${value}" py:if="value[0] == str(c.gparams.superset)" selected="selected">${value}</option>

Still, the combination of those two things is far, far better than the intermingled PHP that I had in the old version.

That value[0] in each of the if clauses cost me a lot of time to find—I forgot that the results from the database query would come back as single-value tuples, which were translated into strings by Genshi (which is why they display and work just fine outside of the if clauses) but would not evaluate as equal to an apparently identical string when tested.

In the old version, the summarizing of the player’s results would take place as part of a database query, with a lot of SUM functions in the SQL. This time around, I did the results before the summary, and then simply did the summarizing in Python. One less database call, and I suspect that Python is just as fast as, if not faster than, MySQL at doing math of that kind.

For the most part, I’m quite happy with the code, and it certainly looks a lot more rational, and legible, than the old version. One area that does look rather ugly is the part that works out various percentages for the summary:

player_summary['match_win_percentage'] = "%2.2f" % (100 * float((player_summary['matches_won'] + float(player_summary['matches_drawn'])/3)) /float(player_summary['matches_won'] + player_summary['matches_lost'] +player_summary['matches_drawn']))
player_summary['game_win_percentage'] = "%2.2f" % (100 * float((player_summary['games_won'] + float(player_summary['games_drawn'])/3))/float(player_summary['games_won'] + player_summary['games_lost'] +player_summary['games_drawn']))
player_summary['tournament_win_percentage'] = "%2.2f" % (100 * float(player_summary['tournament_wins'])/float(player_summary['tournaments']))
player_summary['max_point_percentage'] = "%2.2f" % (100 * float(player_summary['points'])/float(player_summary['max_possible_points']))

There’s probably a way to make that look far, far nicer, but I wasn’t able to come up with it this evening (and didn’t want that particular block to take up lots of lines, although I might change my mind about that later).

In any case, I’m happy with today’s progress. I think I’ll go on to the standings next, which is where the real complexity in the whole thing lies, and so might take a while. I should probably try to follow the stages of: getting overall standings to work; getting standings with some constraints to work, getting standings with date range constraints to work; getting standings for the last ten weeks to work; getting standings for each player’s last ten tournaments to work; getting standings for each player’s last ten tournaments from a specific time point to work; getting standings for each player’s last ten tournaments from a specific time point to work with rank change tracking from the previous week.

Leave a Reply