User:Rspeer/Wikipolitical Compass/Code

This code generates the Wikipolitical Compass. It requires Pylab and Pywikipedia. I apologize for the code being a bit spaghetti. To generate the results, run these three scripts in order.

rfa.py

edit
from wikipedia import *
from numpy import *
import re, pickle

def rfa_votes(candidate, voters):
    page = Page(getSite(), 'Wikipedia:Requests for adminship/%s' % candidate)
    try:
        text = page.get()
    except:
        return {}
    value = 0
    votes = {}
    for line in text.split('\n'):
        line = line.strip()
        if line == "'''Support'''": value = 1
        elif line == "'''Oppose'''": value = -1
        elif line == "'''Neutral'''": break
        elif value and line.startswith('#'):
            if re.match(r"^#\s*[A-Za-z']", line):
                matches = re.findall(r'\[\[User:([^/\]\|]*?)\|', line)
                if matches:
                    user = matches[-1]
                    votes[user] = value
                    voters[user] = voters.get(user, 0) + 1
    return votes

def extract_failed():
    people = []
    for char in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ':
        page = Page(getSite(), 'Wikipedia:Unsuccessful_adminship_candidacies/%s' % char)
        text = page.get()
        got = re.findall(r'\[\[Wikipedia:Requests for adminship/(.*?)\|.*?2007 - [cnwrf]', text)
        print got
        people += got
    return people

def extract_success():
    page = Page(getSite(), 'Wikipedia:Successful adminship candidacies')
    text = page.get()
    recent = text.split('===April 2007===')[1]
    recent = recent.split('===December 2006===')[0]
    people = re.findall(r'\[\[Wikipedia:Requests for adminship/(.*?)\|', recent)
    # add candidacies that aren't archived yet
    people += [u'Bibliomaniac15', u'Selket', u'Matt Britt 2', u'Prolog',
    u'Croat Canuck 2', u'TwinsMetsFan', u'Stephen', u'The Rambling Man',
    u'AGK', u'Sr13']
    return people

def extract_admins():
    page = Page(getSite(), 'Wikipedia:List of administrators')
    text = page.get()
    people = re.findall(r'\{\{admin\|(.*?)\}\}', text)
    return people

def main():
    candidates = extract_failed() + extract_success()
    candidates.sort()
    voters = {}
    votechart = {}
    ordered_candidates = []
    for cand in candidates:
        votes = rfa_votes(cand, voters)
        if len(votes.keys()) >= 5:
            print votes
            votechart[cand] = votes
            ordered_candidates.append(cand)
    ordered_voters = [v for v in voters.keys() if voters[v] >= 5]
    ordered_voters.sort()
    n = len(ordered_candidates)
    m = len(ordered_voters)
    grid = mat(zeros((m, n)))
    for j in range(n):
        chart = votechart[ordered_candidates[j]]
        for i in range(m):
            grid[i,j] = chart.get(ordered_voters[i], 0)
    print ordered_voters
    print ordered_candidates
    print grid
    outf = open('chart.pickle', 'w')
    pickle.dump((ordered_voters, ordered_candidates, grid), outf)
    outf.close()

if __name__ == '__main__':
    try:
        main()
    finally:
        stopme()

plot_voters.py

edit
from pylab import *
from numpy import *
import pickle
import rfa
from matplotlib.ticker import MultipleLocator

voters, candidates, data = pickle.load(open('chart.pickle'))
u, s, vt = linalg.svd(data)
admins = [a.lower() for a in rfa.extract_admins()]
print s

for row in range(len(data)):
    u[row] = u[row] / sum(abs(data[row]))


xaxis = asarray(u)[:,0]
yaxis = asarray(u)[:,2]

xaxis_admin = []
xaxis_nonadmin = []
yaxis_admin = []
yaxis_nonadmin = []

xaxis = xaxis * 10 / max(abs(xaxis))
yaxis = yaxis * 10 / max(abs(yaxis))

figure(1, figsize=(24, 36), dpi=150)
ax = subplot(111)
grid(True)

for c in range(len(voters)):
    print '%s (%2.2f, %2.2f)' % (voters[c].encode('utf-8'), xaxis[c], yaxis[c])
    text(xaxis[c], yaxis[c], voters[c])
    if voters[c].lower() in admins:
        xaxis_admin.append(xaxis[c])
        yaxis_admin.append(yaxis[c])
    else:
        xaxis_nonadmin.append(xaxis[c])
        yaxis_nonadmin.append(yaxis[c])

plot(xaxis_admin, yaxis_admin, 'ro')
plot(xaxis_nonadmin, yaxis_nonadmin, 'bo')
ax.yaxis.set_major_locator(MultipleLocator(2))

savefig('voters.png')
rfa.stopme()

plot_candidates.py

edit
from pylab import *
from numpy import *
import pickle
import rfa

voters, candidates, data = pickle.load(open('chart.pickle'))
u, s, vt = linalg.svd(data)
successes = rfa.extract_success()

for col in range(len(candidates)):
    vt[:,col] = vt[:,col] / sum(abs(data[:,col]))

xaxis = asarray(vt)[0,:]
yaxis = asarray(vt)[2,:]

xaxis_admin = []
xaxis_nonadmin = []
yaxis_admin = []
yaxis_nonadmin = []

xaxis = xaxis * 10 / max(abs(xaxis))
yaxis = yaxis * 10 / max(abs(yaxis))

figure(1, figsize=(18, 18), dpi=150)
grid(True)

for c in range(len(candidates)):
    print '%s (%2.2f, %2.2f)' % (candidates[c].encode('utf-8'), xaxis[c], yaxis[c])
    text(xaxis[c], yaxis[c], candidates[c])
    if candidates[c] in successes:
        xaxis_admin.append(xaxis[c])
        yaxis_admin.append(yaxis[c])
    else:
        xaxis_nonadmin.append(xaxis[c])
        yaxis_nonadmin.append(yaxis[c])

plot(xaxis_admin, yaxis_admin, 'go')
plot(xaxis_nonadmin, yaxis_nonadmin, 'yo')

savefig('candidates.png')

rfa.stopme()