Since I'm a big politics nerd, I wanted to write a little script that would analyze the frequency and content of political fundraising emails. I signed up for the e-mails of 6 campaigns, donated a dollar to each so I'd get hit up for more money often, and let it sit. Unfortunately you won't be able to run the script because it uses some of my personal login details but you could fill your own in if you were really so inclined to give it a run! I was just curious to see if you wonderful people could see anything that could use improvement!
import gmail,pandas as pd,numpy as np,matplotlib.pyplot as plt, plotly.plotly as py, plotly.graph_objs as go,json
from tqdm import tqdm
from collections import Counter
from bs4 import BeautifulSoup
from textblob import TextBlob
from textblob.en.sentiments import NaiveBayesAnalyzer
import sys,indicoio
indicoio.config.api_key = '#'
reload(sys)
sys.setdefaultencoding('utf8')
r=open('emails.csv','w')
py.sign_in('#','#')
cruzbin=[];trumpbin=[];clintbin=[];rubiobin=[];christiebin=[];jebbin=[]
politicians = ['tedcruz.org','donaldjtrump.com','donaldtrump.com','hillaryclinton.com','marcorubio.com','jeb2016.com','chrischristie.com']
def start():
g = gmail.login('#','#')
return g
def sorter(g):
for _ in tqdm(g.inbox().mail(sender=politicians[0],prefetch=True)):
cruzbin.append(_)
for _ in g.inbox().mail(sender=politicians[1],prefetch=True):
trumpbin.append(_)
for _ in g.inbox().mail(sender=politicians[2],prefetch=True):
trumpbin.append(_)
for _ in g.inbox().mail(sender=politicians[3],prefetch=True):
clintbin.append(_)
for _ in g.inbox().mail(sender=politicians[4],prefetch=True):
rubiobin.append(_)
for _ in g.inbox().mail(sender=politicians[5],prefetch=True):
jebbin.append(_)
for _ in g.inbox().mail(sender=politicians[6],prefetch=True):
christiebin.append(_)
bins = [cruzbin,trumpbin,clintbin,rubiobin,jebbin,christiebin]
return bins
def counter(bins):
print 'Emails from Ted Cruz:',len(cruzbin)
print 'Emails from Donald Trump:',len(trumpbin)
print 'Emails from Hillary Clinton:',len(clintbin)
print 'Emails from Marco Rubio:',len(rubiobin)
print 'Emails from Chris Christie:',len(christiebin)
print 'Emails from Jeb Bush:',len(jebbin)
def q():
ans = input('Whose e-mails do you want to analyze?\n')
return ans
def analyzer(bins):
tc = pd.DataFrame(cruzbin)
dt = pd.DataFrame(trumpbin)
hc = pd.DataFrame(clintbin)
mr = pd.DataFrame(rubiobin)
jb = pd.DataFrame(jebbin)
cc = pd.DataFrame(christiebin)
trace0 = go.Bar(
x=['Ted Cruz','Donald Trump','Hillary Clinton','Marco Rubio','Jeb Bush','Chris Christie'],
y=[len(cruzbin),len(trumpbin),len(clintbin),len(rubiobin),len(jebbin),len(christiebin)],
marker=dict(
color=['rgb(204,204,204)','rgb(204,204,204)','rgb(204,204,204)','rgb(204,204,204)','rgb(204,204,204)','rgb(204,204,204)']),
)
data = [trace0]
layout = go.Layout(
title='Frequency of Fundraising E-Mails',
)
fig = go.Figure(data=data,layout=layout)
plot_url = py.plot(fig,filename='emailfreq')
return
def bayes(b,name):
overallpos = []
overallneg = []
i = 0
for email in tqdm(b):
try:
i = i+1
text = email.fetch()
text = str(text)
soup = BeautifulSoup(text,'lxml')
text = soup.get_text()
text = text.strip()
blob = TextBlob(text,analyzer=NaiveBayesAnalyzer())
senti = indicoio.sentiment_hq(text)
keywords = indicoio.keywords(text)
#neg = blob.sentiment.p_neg
b = blob.np_counts
c = Counter(b).most_common(10)
#print c
#overallpos.append(pos)
r.write(name)
r.write(',')
r.write(str(i))
r.write(',')
r.write('null')
r.write(',')
r.write(str(senti))
r.write(',')
r.write(str(keywords))
r.write(',')
r.write(str(c))
r.write('\n')
#overallneg.append(neg)
except UnicodeDecodeError:
print('Moving on..')
finally:
pp = (sum(overallpos))
#nn = (sum(overallneg))
pp = sum(overallpos)
#nn = sum(overallneg)
#print name,'\'s positive ranking: %s' % (pp / len(overallpos))
return
def sentiment(bins):
bayes(cruzbin,'Ted Cruz')
bayes(trumpbin,'Donald Trump')
bayes(clintbin,'Hillary Clinton')
bayes(jebbin,'Jeb Bush')
bayes(rubiobin,'Marco Rubio')
bayes(christiebin,'Chris Christie')
def shebang():
s = start()
counter(sorter(s))
analyzer(s)
sentiment(s)
return
def starter():
print('Counter will return the number of e-mails each candidate has sent. Sentiment will perform sentiment analysis on all of the candidate\'s e-mails and write the results to csv.\
Analyzer will create a visualization of the number of e-mails each candidate has sent. Shebang will do all of the above!')
ans = input('What should I do? \n')
return ans
def logo():
print """
oooo o8o .
`888 `"' .o8
oo.ooooo. .ooooo. 888 oooo .oooo.o .o888oo .ooooo. .ooooo. .oooooooo .ooooo.
888' `88b d88' `88b 888 `888 d88( "8 888 d88' `88b d88' `88b 888' `88b d88' `88b
888 888 888 888 888 888 `"Y88b. 888 888 888 888 888 888 888 888ooo888
888 888 888 888 888 888 o. )88b 888 . 888 888 888 888 `88bod8P' 888 .o
888bod8P' `Y8bod8P' o888o o888o 8""888P' "888" `Y8bod8P' `Y8bod8P' `8oooooo. `Y8bod8P'
888 d" YD
o888o "Y88888P'
How many times do politicians hit up regular people for money? How positive or negative are their e-mails?\n
What do they usually talk about? This program crunches the numbers so you don't have to!
Logging in...\n"""
return
logo()
while True:
s = start()
starter()
try:
if ans.lower()=='counter':
counter(sorter(s))
elif ans.lower()=='sentiment':
sentiment(s)
elif ans.lower()=='analyzer':
analyzer(s)
elif ans.lower()=='shebang':
shebang()
except:
print('Oops! Try again!')
#analyzer(s)
#sentiment(s)
Example output:
https://plot.ly/~ntucker1/96/frequency-of-fundraising-e-mails/ Emails from Ted Cruz: 17 Emails from Donald Trump: 5 Emails from Hillary Clinton: 25 Emails from Marco Rubio: 35 Emails from Chris Christie: 20 Emails from Jeb Bush: 17
For those that are interested, I'm hosting this app here. It's a work in progress right now as I'm trying to set up the database.