-
Notifications
You must be signed in to change notification settings - Fork 16
/
getngrams.py
157 lines (150 loc) · 6.46 KB
/
getngrams.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env python
from ast import literal_eval
from pandas import DataFrame # http://github.com/pydata/pandas
import re
import requests # http://github.com/kennethreitz/requests
import subprocess
import sys
corpora = dict(eng_us_2012=17, eng_us_2009=5, eng_gb_2012=18, eng_gb_2009=6,
chi_sim_2012=23, chi_sim_2009=11, eng_2012=15, eng_2009=0,
eng_fiction_2012=16, eng_fiction_2009=4, eng_1m_2009=1,
fre_2012=19, fre_2009=7, ger_2012=20, ger_2009=8, heb_2012=24,
heb_2009=9, spa_2012=21, spa_2009=10, rus_2012=25, rus_2009=12,
ita_2012=22)
def getNgrams(query, corpus, startYear, endYear, smoothing, caseInsensitive):
params = dict(content=query, year_start=startYear, year_end=endYear,
corpus=corpora[corpus], smoothing=smoothing,
case_insensitive=caseInsensitive)
if params['case_insensitive'] is False:
params.pop('case_insensitive')
if '?' in params['content']:
params['content'] = params['content'].replace('?', '*')
if '@' in params['content']:
params['content'] = params['content'].replace('@', '=>')
req = requests.get('http://books.google.com/ngrams/graph', params=params)
res = re.findall('var data = (.*?);\\n', req.text)
data = {qry['ngram']: qry['timeseries'] for qry in literal_eval(res[0])}
df = DataFrame(data)
df.insert(0, 'year', range(startYear, endYear+1))
return req.url, params['content'], df
def runQuery(argumentString):
arguments = argumentString.split()
query = ' '.join([arg for arg in arguments if not arg.startswith('-')])
if '?' in query:
query = query.replace('?', '*')
if '@' in query:
query = query.replace('@', '=>')
params = [arg for arg in arguments if arg.startswith('-')]
corpus, startYear, endYear, smoothing = 'eng_2012', 1800, 2000, 3
printHelp, caseInsensitive, allData = False, False, False
toSave, toPrint, toPlot = True, True, False
# parsing the query parameters
for param in params:
if '-nosave' in param:
toSave = False
elif '-noprint' in param:
toPrint = False
elif '-plot' in param:
toPlot = True
elif '-corpus' in param:
corpus = param.split('=')[1].strip()
elif '-startYear' in param:
startYear = int(param.split('=')[1])
elif '-endYear' in param:
endYear = int(param.split('=')[1])
elif '-smoothing' in param:
smoothing = int(param.split('=')[1])
elif '-caseInsensitive' in param:
caseInsensitive = True
elif '-alldata' in param:
allData = True
elif '-help' in param:
printHelp = True
else:
print 'Did not recognize the following argument: %s' % param
if printHelp:
print 'See README file.'
else:
if '*' in query and caseInsensitive is True:
caseInsensitive = False
notifyUser = True
warningMessage = "*NOTE: Wildcard and case-insensitive " + \
"searches can't be combined, so the " + \
"case-insensitive option was ignored."
elif '_INF' in query and caseInsensitive is True:
caseInsensitive = False
notifyUser = True
warningMessage = "*NOTE: Inflected form and case-insensitive " + \
"searches can't be combined, so the " + \
"case-insensitive option was ignored."
else:
notifyUser = False
url, urlquery, df = getNgrams(query, corpus, startYear, endYear,
smoothing, caseInsensitive)
if not allData:
if caseInsensitive is True:
for col in df.columns:
if col.count('(All)') == 1:
df[col.replace(' (All)', '')] = df.pop(col)
elif col.count(':chi_') == 1 or corpus.startswith('chi_'):
pass
elif col.count(':ger_') == 1 or corpus.startswith('ger_'):
pass
elif col.count(':heb_') == 1 or corpus.startswith('heb_'):
pass
elif col.count('(All)') == 0 and col != 'year':
if col not in urlquery.split(','):
df.pop(col)
if '_INF' in query:
for col in df.columns:
if '_INF' in col:
df.pop(col)
if '*' in query:
for col in df.columns:
if '*' in col:
df.pop(col)
if toPrint:
print ','.join(df.columns.tolist())
for row in df.iterrows():
try:
print '%d,' % int(row[1].values[0]) + \
','.join(['%.12f' % s for s in row[1].values[1:]])
except:
print ','.join([str(s) for s in row[1].values])
queries = ''.join(urlquery.replace(',', '_').split())
if '*' in queries:
queries = queries.replace('*', 'WILDCARD')
if caseInsensitive is True:
word_case = 'caseInsensitive'
else:
word_case = 'caseSensitive'
filename = '%s-%s-%d-%d-%d-%s.csv' % (queries, corpus, startYear,
endYear, smoothing, word_case)
if toSave:
for col in df.columns:
if '>' in col:
df[col.replace('>', '>')] = df.pop(col)
df.to_csv(filename, index=False)
print 'Data saved to %s' % filename
if toPlot:
try:
subprocess.call(['python', 'xkcd.py', filename])
except:
if not toSave:
print 'Currently, if you want to create a plot you ' + \
'must also save the data. Rerun your query, ' + \
'removing the -nosave option.'
else:
print 'Plotting Failed: %s' % filename
if notifyUser:
print warningMessage
return df
if __name__ == '__main__':
argumentString = ' '.join(sys.argv[1:])
if argumentString == '':
argumentString = raw_input('Enter query (or -help):')
else:
try:
runQuery(argumentString)
except:
print 'An error occurred.'