Making of "Spam: Leihgaben ausgewertet" · Jun 16, 19:44 von stargaming
Die tolle Grafik in Spam: Leihgaben ausgewertet wurden anhand dieses Codeschnipsels erstellt.
Ich hab’s mit Python 2.5 getestet. Dazu braucht man noch Matplotlib zum Plotten.
Die Daten werden aus Mbox-Dateien extrahiert — solche legt z. B. Thunderbird im Benutzerordner an. In der aktuellen Einstellung werden da einfach nur alle Beträge in Dollar rausgelesen.
Benutzt wird das Programm mit keinen Programmparametern (dann erwartet es die Daten in der Datei “Test”), sonst kann auch die Quelldatei über die Befehlszeile angegeben werden. Ausgabe passiert immer nach “loans.png”. Die Transparenz (wie im Artikel) habe ich mit Gimp nachgebessert, da ich sonst noch PIL (Python Imaging Library) oder sonstiges benutzen hätte müssen.
- #!/usr/bin/env python
- # encoding: utf-8
- #
- #
- from __future__ import with_statement, division
- # logging
- from logging import *
- basicConfig(level=DEBUG,
- datefmt='%M:%S',
- format='%(relativeCreated)05d %(levelname)8s: %(message)s')
- debug('Enabled log.')
- # reading mbox-format Mailboxes (Mozilla/Netscape)
- debug('Loading mailbox reader..')
- from mailbox import mbox
- # parsing utilites
- debug('Loading email parsers..')
- import datetime as _dt
- _strptime = _dt.datetime.strptime
- from re import compile as _compile
- from operator import itemgetter as _item
- from collections import defaultdict as _dict
- # plotting framework
- debug('Loading plotting framework..')
- import pylab
- info('All packages included.')
- money = _compile(r'''\$(\d{1,3}),000''')
- avg = lambda *a:sum(a) // len(a)
- def main(path):
- info('Opening mbox..')
- repo = mbox(path)
- info('Creating database..')
- loan = _dict(list)
- info('Parsing %d emails..', len(repo))
- for mail in repo.itervalues():
- amount = money.search(mail.as_string())
- if amount:
- date = _strptime(mail.get_from(), '- %a %b %d %H:%M:%S %Y')
- amount = int(amount.group(1).replace(',', ''))
- loan[date].append(amount)
- del repo
- info('Matched %d emails.', len(loan))
- info('Building an average value of every date..')
- loanavg = list()
- for date, amounts in loan.iteritems():
- loanavg.append((date, avg(*amounts)))
- del loan
- info('Sorting results..')
- loanavg.sort(key=_item(0))
- info('Extracting information..')
- x, y = zip(*loanavg)
- x = pylab.date2num(x)
- del loanavg
- info('Plotting %d dates..', len(x))
- debug('Drawing first plot..')
- pylab.xlabel('date')
- pylab.ylabel('loan in $1000')
- pylab.plot_date(x,
- y,
- xdate=True,
- linestyle='-',
- markersize=0.01,
- )
- pylab.axis('tight')
- info('Saving plot to file..')
- pylab.savefig('loans.png', facecolor='white')
- info('Showing plot..')
- pylab.show()
- if __name__ == '__main__':
- from sys import argv
- if len(argv) >= 2:
- main(' '.join(argv[1:]))
- else:
- main('Test')

