The personal website of Scott W Harden
February 7th, 2009

Cheaply Create Double-Sided QSL Cards in 1 Day

I'm posting this information hoping that someone else in a position similar to mine can benefit from the experience I gained through trial and error while trying to rapidly design and develop professional-looking QSL cards at low risk. I Googled around for this information, but didn't find anything too helpful, so I figured I'd come up with something on my own and share my story.

QSL cards are like postcards which amateur radio operators often mail to one another after making long distance contacts.__ In addition to providing tangible proof of the communication, they're cool mementos to tote around to remember who you've made contact with over the years. QSL cards display information bout the contact (time, date, call sign, frequency, signal report, etc.) and sometimes contain extra pictures/graphics which make them unique and appealing.

Once I got a HF rig for my apartment (a Century 21 CW-only HF rig which puts out ~30 watts), I started making contacts and getting QSL cards myself, so I wanted to send some nice ones in return. Being a poor college student (and a graduate student at that), I was extremely cash-limited, and didn't want to sit around for weeks while my cards were professionally printed. This post describes how I created nice looking QSL cards in a few hours, for less than $0.25 each!

Step 1: Design the cards with the correct dimensions. The most cost-effective way to print nice digital images is my local Target (a store with a 1-hr photo lab which accepts JPEGs as the image source for $0.20 cents a picture), but the snag was that they only print 4'' x 6''. QSL cards need to be 3.5'' by 5.25''. I used Inkscape to create an image exactly 4'' by 6'', and inside of it I drew a border 3.5'' by 5.25''. Everything outside that border I made black. I designed my QSL card _inside _that border, such that when the images would be printed I could trim-off the black border and have a perfect 3.5'' by 5.25'' QSL card.

Step 2: Print the reverse side on full-size label paper. All I needed was some framed boxes for QSL information, so I quickly sketched up the design in Inkscape and saved it in the same format as before (4'' by 6''). I left a LOT of white space around the edges so it's very forgiving down the line. I then printed the design on full-page label paper (full-sheet stickers, available at most office stores cheaply in the printer paper section), placing 4 "backs" per page.

Here's what the adhesive paper looked like after printing:

Step 3: Attach backings to QSL cards. This part is easy if you have a paper cutter. I purchased mine ~5yrs ago and I *LOVE* it. It's almost as useful as my soldering iron. Seriously, so convenient. I wouldn't dream of doing this with scissors! Anyhow, roughly cut the sticker paper into quarters.

Next, peel and stick on the backs of cards. Don't worry about overhang, we'll take care of that later...

Step 4: Trim the edges. Make sure you do this step _after _applying the sticker. This was the secret that I wish I realized a while ago. If you trim first, sticker placement is critical and difficult. If you place the sticker _before _you trim, you get perfect edges every time.

How nice does that look? If you did your math correctly, your new dimensions should be exactly 3.5'' by 5.25''.

Step 5: fill-out information. I decided to use a metallic Sharpie to write the name of the call sign I send this to on the front of my card. How cool does that look? This is what the front/back of this card looks like after filling it out.

I hope this information helps you. If you print your own QSL cards using this (or a similar) method, let me know about it! I have to say, for ~5 / $1, these don't look to bad. It's especially useful if you only want to print a few cards! Good luck.

-- Scott, AJ4VD

Markdown source code last modified on January 18th, 2021
---
title: Cheaply Create Double-Sided QSL Cards in 1 Day
date: 2009-02-07 16:29:28
tags: amateur radio
---

# Cheaply Create Double-Sided QSL Cards in 1 Day

__I'm posting this information__ hoping that someone else in a position similar to mine can benefit from the experience I gained through trial and error while trying to rapidly design and develop professional-looking QSL cards at low risk. I Googled around for this information, but didn't find anything too helpful, so I figured I'd come up with something on my own and share my story.

__[QSL cards](http://en.wikipedia.org/wiki/QSL)__ are like postcards which amateur radio operators often mail to one another after making long distance contacts.__ In addition to providing tangible proof of the communication, they're cool mementos to tote around to remember who you've made contact with over the years. QSL cards display information bout the contact (time, date, call sign, frequency, signal report, etc.) and sometimes contain extra pictures/graphics which make them unique and appealing.

__Once I got a HF rig for my apartment__ (a Century 21 CW-only HF rig which puts out ~30 watts), I started making contacts and getting QSL cards myself, so I wanted to send some nice ones in return. Being a poor college student (and a graduate student at that), I was extremely cash-limited, and didn't want to sit around for weeks while my cards were professionally printed. This post describes how I created nice looking QSL cards in a few hours, for less than $0.25 each!

<div class="text-center img-border">

[![](12_donefront_thumb.jpg)](12_donefront.jpg)

</div>

__Step 1: Design the cards with the correct dimensions.__ The most cost-effective way to print nice digital images is my local Target (a store with a 1-hr photo lab which accepts JPEGs as the image source for $0.20 cents a picture), but the snag was that they only print 4'' x 6''. QSL cards need to be 3.5'' by 5.25''. I used [Inkscape](http://www.Inkscape.org) to create an image exactly 4'' by 6'', and inside of it I drew a border 3.5'' by 5.25''. Everything outside that border I made black. I designed my QSL card _inside _that border, such that when the images would be printed I could trim-off the black border and have a perfect 3.5'' by 5.25'' QSL card.

<div class="text-center img-border">

[![](florida_thumb.jpg)](florida.png)

[![](01_qsl_photos_thumb.jpg)](01_qsl_photos.jpg)

</div>

__Step 2: Print the reverse side on full-size label paper.__ All I needed was some framed boxes for QSL information, so I quickly sketched up the design in Inkscape and saved it in the same format as before (4'' by 6''). I left a LOT of white space around the edges so it's very forgiving down the line. I then printed the design on full-page label paper (full-sheet stickers, available at most office stores cheaply in the printer paper section), placing 4 "backs" per page.

<div class="text-center img-border">

[![](03_backs_thumb.jpg)](03_backs.jpg)

</div>

Here's what the adhesive paper looked like after printing:

<div class="text-center img-border">

[![](04_cutback_thumb.jpg)](04_cutback.jpg)

</div>

<div class="text-center img-border">

[![](05_back_thumb.jpg)](05_back.jpg)

</div>

__Step 3: Attach backings to QSL cards.__ This part is easy if you have a paper cutter. I purchased mine ~5yrs ago and I \*LOVE\* it. It's almost as useful as my soldering iron. Seriously, so convenient. I wouldn't dream of doing this with scissors! Anyhow, roughly cut the sticker paper into quarters.

<div class="text-center img-border">

[![](06_peel_thumb.jpg)](06_peel.jpg)

</div>

<div class="text-center img-border">

[![](07_overhang_thumb.jpg)](07_overhang.jpg)

</div>

Next, peel and stick on the backs of cards. Don't worry about overhang, we'll take care of that later...

<div class="text-center img-border">

[![](09_cut_thumb.jpg)](09_cut.jpg)

</div>

<div class="text-center img-border">

[![](10_nice_thumb.jpg)](10_nice.jpg)

</div>

__Step 4: Trim the edges.__ Make sure you do this step _after _applying the sticker. This was the secret that I wish I realized a while ago. If you trim first, sticker placement is critical and difficult. If you place the sticker _before _you trim, you get perfect edges every time.

<div class="text-center img-border">

[![](11_niceback_thumb.jpg)](11_niceback.jpg)

</div>

How nice does that look? If you did your math correctly, your new dimensions should be exactly 3.5'' by 5.25''.

<div class="text-center img-border">

[![](12_silver2_thumb.jpg)](12_silver2.jpg)

</div>

__Step 5: fill-out information.__ I decided to use a metallic Sharpie to write the name of the call sign I send this to on the front of my card. How cool does that look? This is what the front/back of this card looks like after filling it out.

<div class="text-center img-border">

[![](14_scribe_thumb.jpg)](14_scribe.jpg)

</div>

__I hope this information helps you.__ If you print your own QSL cards using this (or a similar) method, let me know about it! I have to say, for ~5 / $1, these don't look to bad. It's especially useful if you only want to print a few cards! Good luck.

-- Scott, AJ4VD

February 7th, 2009

InkScape to the Rescue!

After a few weeks of using InkScape, slowly working through documentation, tutorials, and practicing drawing random objects, I think I'm finally getting the feel of designing images in InkScape, and am growing to appreciate the depth of its usefulness. I'd love to have some great diagrams to include in potential publications. For example, I want a diagram to show how the autonomic nervous system innervates the mouse heart, but no such diagram exists! Here's one for humans but it's major overkill, shows every organ (I only want the heart), and doesn't go into detail as to what the nerves do when they reach the heart (something I'm researching). Also, mouse brains are very different in shape from human brains, and there aren't any good pictures of the ventral side of a mouse brain. So, I found the best one I could and re-created it with InkScape.

I used an existing image as a reference, made half a brain, and can mirror it when I'm done. It looks pretty good, right?

Markdown source code last modified on January 18th, 2021
---
title: InkScape to the Rescue!
date: 2009-02-07 16:29:55
---

# InkScape to the Rescue!

__After a few weeks of using InkScape,__ slowly working through documentation, tutorials, and practicing drawing random objects, I think I'm finally getting the feel of designing images in InkScape, and am growing to appreciate the depth of its usefulness. I'd love to have some great diagrams to include in potential publications. For example, I want a diagram to show how the autonomic nervous system innervates the mouse heart, but no such diagram exists! [Here's one for humans](http://www.demosschiropractic.com/illus/autonomic-nervous-system.gif) but it's major overkill, shows every organ (I only want the heart), and doesn't go into detail as to what the nerves do when they reach the heart (something I'm researching). Also, [mouse brains](http://tedhuntington.com/Mouse_brain.jpg) are very different in shape from human brains, and there aren't any good pictures of the ventral side of a mouse brain. So, I found the best one I could and re-created it with InkScape.

<div class="text-center img-border">

[![](inkscape_brain_thumb.jpg)](inkscape_brain.jpg)

</div>

I used an existing image as a reference, made half a brain, and can mirror it when I'm done. It looks pretty good, right?


<div class="text-center">

[![](braintest2_thumb.jpg)](braintest2.png)

</div>
February 2nd, 2009

Homemade ECG Machine: Improving Daily

⚠️ Check out my newer ECG designs:

I've been working on a homemade ECG machine over the last month. This is the most basic circuit I'm currently using, designed using two quad op-amps. I've produced some surprisingly good ECG traces and even identified an arrhythmic heartbeat. Currently the device is limited because you have to be attached to your computer, I'm working toward making it a mobile device (powered by a 9V battery) which records voltage data to a minidisc recorder . There's one problem - I need to optimally adjust the gain, but how if I cannot see the trace of the wave on a monitor? I could a VU meter to monitor the output... My minidisc recorder can take mic-in and echo it the line-out at the same time, so I'll just put the VU meter on the line-out and it shouldn't affect my trace. The result is that I can walk around for 24 hours, recording my ECG, with a device I hope to get down to the size of a cell phone. (Maybe a 1990s cell phone?)

Here's a simple LED-based digital VU meter circuit I found, along with some sample images of its (bread-boarded) construction. I have all the parts at home I think, so it should be straightforward to make. The pain now is the electrodes (which are still the junky ones made from scissor-cut aluminum cans), and I think I might splurge and buy some actual disposable ECG electrodes. I think the total cost of my device as it stands is about $4, so I don't want to spend more than I have to on electrodes.

In other news it appears I've been accepted into dental school. I got a voicemail this morning at 8am, another one at 12:30pm, and apparently one on my parents' answering machine (I listed them as an alternate number), then they sent me an email! Naturally it was the email I noticed first. Here's a snapshot from my inbox, phone call 1 and phone call 2.

Markdown source code last modified on January 18th, 2021
---
title: Homemade ECG Machine: Improving Daily
date: 2009-02-02 16:50:36
tags: diyECG
---

# Homemade ECG Machine: Improving Daily


> **⚠️ Check out my newer ECG designs:** 
* [**Sound Card ECG with AD8232**](https://swharden.com/blog/2019-03-15-sound-card-ecg-with-ad8232/)
* [**Single op-amp ECG**](https://swharden.com/blog/2016-08-08-diy-ecg-with-1-op-amp/)


__I've been working on a homemade ECG machine over the last month.__ [This is the most basic circuit](http://www.swharden.com/blog/images/diy_ecg_circuit.png) I'm currently using, designed using two quad op-amps. I've produced some [surprisingly good ECG traces](http://www.swharden.com/blog/images/nicetwopng.png) and even [identified an arrhythmic heartbeat](http://www.swharden.com/blog/images/murm2.png). Currently the device is limited because you have to be attached to your computer, I'm working toward making it a mobile device (powered by a 9V battery) which records voltage data to a [minidisc recorder](http://www.minidisc.org/images/sony_mznh900_silver_mymd.jpg) . There's one problem - I need to optimally adjust the gain, but how if I cannot see the trace of the wave on a monitor? I could a VU meter to monitor the output... My minidisc recorder can take mic-in and echo it the line-out at the same time, so I'll just put the VU meter on the line-out and it shouldn't affect my trace. The result is that I can walk around for 24 hours, recording my ECG, with a device I hope to get down to the size of a cell phone. (Maybe a 1990s cell phone?)

<div class="text-center img-border">

![](vu_meter.jpg)

![](vu_meter2.jpg)

</div>

__Here's a simple LED-based digital VU meter circuit__ I found, along with some sample images of its (bread-boarded) construction. I have all the parts at home I think, so it should be straightforward to make. The pain now is the electrodes (which are still the junky ones made from scissor-cut aluminum cans), and I think I might splurge and buy some actual disposable ECG electrodes. I think the total cost of my device as it stands is about $4, so I don't want to spend more than I have to on electrodes.

<div class="text-center">

[![](vu_circuit_thumb.jpg)](vu_circuit.png)

</div>

__In other news__ it appears I've been accepted into dental school. I got a voicemail this morning at 8am, another one at 12:30pm, and apparently one on my parents' answering machine (I listed them as an alternate number), then they sent me an email! Naturally it was the email I noticed first. Here's a snapshot from my inbox, [phone call 1](1.mp3) and [phone call 2](2.mp3).

<div class="text-center img-border">

[![](accepted_thumb.jpg)](accepted.png)

</div>
January 30th, 2009

The Internet was Moved?

I'm working late in lab (as usual) and I went to open Firefox (my default web browser), so I clicked Start and selected "Mozilla Firefox" at the top (where your default browser usually goes in XP). Nothing happened... then this message popped up! I had to take a screen shot because it's so bizarre.

I swear this is straight from my screen (PrntScrn -> mspaint (pasted) -> PNG) with no modifications. I especially love how the computer is trying to tell me what could have gone wrong; the internet might have been moved, renamed, or removed. Slick.

Markdown source code last modified on January 18th, 2021
---
title: The Internet was Moved?
date: 2009-01-30 21:55:01
---

# The Internet was Moved?

__I'm working late in lab__ (as usual) and I went to open Firefox (my default web browser), so I clicked Start and selected "Mozilla Firefox" at the top (where your default browser usually goes in XP). Nothing happened... then this message popped up! I had to take a screen shot because it's so bizarre.

<div class="text-center img-border">

[![](internet_moved_thumb.jpg)](internet_moved.png)

</div>

I swear this is straight from my screen (PrntScrn -> mspaint (pasted) -> PNG) with no modifications. I especially love how the computer is trying to tell me what could have gone wrong; the internet might have been moved, renamed, or removed. Slick.
January 29th, 2009

Analyzing my Writings with Python

I had some free time in lab today (between steps while of an immunohistochemistry experiment) so I decided to further investigate the field of bioinformatics. I was curious if it may be worth seeking a PhD in bioinformatics if I don't get into dental school. UCF offers a PhD in bioinformatics but it's a new and small department (I think there are only 4 faculty). A degree in bioinformatics combines molecular biology (DNA, proteins, etc), computer science (programming), and statistics.

I came across a paper today: Structural Alignment of Pseudoknotted RNA which is a good example of the practice of bioinformatics. Think about what goes on in a cell... the sequence of a gene (a short region of DNA) is copied (letter-by-letter) onto an RNA molecule. The RNA molecule is later read by an enzyme (called a ribosome) and converted into a protein based on its sequence. (This process is the central dogma of molecular biology) Traditionally, it was believed that RNA molecules' only function was to copy gene sequences from DNA to ribosomes, but recently (the last several years) it was discovered that some small RNA molecules are never read and turned into proteins, but rather serve their own unique functions! For example, some RNA molecules (siRNAs) can actually turn genes on and off, and have been associated with cancer development and other immune diseases. Given the human genome (the ~3 billion letter long sequence all of our DNA), how can we determine what regions form these functional RNA molecules which don't get converted into proteins? The paper I mentioned earlier addresses this. An algorithm was developed and used to test regions of DNA and predict its probability of forming small RNA molecules. Spikes in this trace (figure 7 of the paper) represent areas of the DNA which are likely to form these RNA molecules. (Is this useful? What if you were to compare these results between normal person and someone with cancer?)

After reading the article I considered how similar my current programming projects are with this one (e.g., my recent DIY ECG projects). The paper shows a trace of score (likelihood that a region of DNA forms an RNA molecule) where peaks represent likely locations of RNA formation. Just generate the trace, determine the positions of the peaks, and you're golden. How similar is this to the work I've been doing with my homemade ECG machine, where I perform signal analysis to eliminate electrical noise and then analyze the resulting trace to isolate and identify peaks corresponding to heartbeats?

I got the itch to write my own string-analysis program. It reads the content of my website (exported from a SQL query), splits it up by date, and analyzes it. Ultimately I want to track the usage of certain words, but for now I wrote a script which plots the number of words I wrote.

Pretty cool huh? Check out all those spikes between 2004 and 2005! Not only are they numerous (meaning many posts), but they're also high (meaning many words per post). As you can see by the top trace, the most significant contribution to my site occurred during this time. So, let's zoom in on it.

Here is the code I used to produce this image.

"""Convert SQL backups of my WordPress blog into charts"""

import datetime, pylab, numpy

class blogChrono():
    baseUrl="http://www.SWHarden.com/blog"
    posts=[]
    dates=[]
    def __init__(self,fname):
        self.fname=fname
        self.load()
    def load(self):
        print "loading [%s]..."%self.fname,
        f=open(self.fname)
        raw=f.readlines()
        f.close()
        for line in raw:
            if "INSERT INTO" in line
            and';' in line[-2:-1]
            and " 'post'," in line[-20:-1]:
                post={}
                line=line.split("VALUES(",1)[1][:-3]
                line=line.replace(', NULL',', None')
                line=line.replace(", '',",", None,")
                line=line.replace("''","")
                c= line.split(',',4)[4][::-1]
                c= c.split(" ,",21)
                text=c[-1]
                text=text[::-1]
                text=text[2:-1]
                text=text.replace('"""','###')
                line=line.replace(text,'blogtext')
                line=line.replace(', ,',', None,')
                line=eval("["+line+"]")
                if len(line[4])&gt;len('blogtext'):
                    x=str(line[4].split(', '))[2:-2]
                    raw=str(line)
                    raw=raw.replace(line[4],x)
                    line=eval(raw)
                post["id"]=int(line[0])
                post["date"]=datetime.datetime.strptime(line[2],
                                                        "%Y-%m-%d %H:%M:%S")
                post["text"]=eval('"""'+text+' """')
                post["title"]=line[5]
                post["url"]=line[21]
                post["comm"]=int(line[25])
                post["words"]=post["text"].count(" ")
                self.dates.append(post["date"])
                self.posts.append(post)
        self.dates.sort()
        d=self.dates[:]
        i,newposts=0,[]
        while len(self.posts)&gt;0:
            die=min(self.dates)
            for post in self.posts:
                if post["date"]==die:
                    self.dates.remove(die)
                    newposts.append(post)
                    self.posts.remove(post)
        self.posts,self.dates=newposts,d
        print "read %d posts!n"%len(self.posts)

#d=blogChrono('sml.sql')
d=blogChrono('test.sql')

fig=pylab.figure(figsize=(7,5))
dates,lengths,words,ltot,wtot=[],[],[],[0],[0]
for post in d.posts:
    dates.append(post["date"])
    lengths.append(len(post["text"]))
    ltot.append(ltot[-1]+lengths[-1])
    words.append(post["words"])
    wtot.append(wtot[-1]+words[-1])
ltot,wtot=ltot[1:],wtot[1:]

pylab.subplot(211)
#pylab.plot(dates,numpy.array(ltot)/(10.0**6),label="letters")
pylab.plot(dates,numpy.array(wtot)/(10.0**3),label="words")
pylab.ylabel("Thousand")
pylab.title("Total Blogged Words")
pylab.grid(alpha=.2)
#pylab.legend()
fig.autofmt_xdate()
pylab.subplot(212,sharex=pylab.subplot(211))
pylab.bar(dates,numpy.array(words)/(10.0**3))
pylab.title("Words Per Entry")
pylab.ylabel("Thousand")
pylab.xlabel("Date")
pylab.grid(alpha=.2)
#pylab.axis([min(d.dates),max(d.dates),None,20])
fig.autofmt_xdate()
pylab.subplots_adjust(left=.1,bottom=.13,right=.98,top=.92,hspace=.25)
width=675
pylab.savefig('out.png',dpi=675/7)
pylab.show()

print "DONE"

I wrote a Python script to analyze the word frequency of the blogs in my website (extracted from an SQL query WordPress backup file) for frequency, then I took the list to Wordie and created a word jumble. Neat, huh?

import datetime, pylab, numpy
f=open('dump.txt')
body=f.read()
f.close()
body=body.lower()
body=body.split(" ")
tot=float(len(body))
words={}
for word in body:
    for i in word:
        if 65&lt; =ord(i)&lt;=90 or 97&lt;=ord(i)&lt;=122: pass
        else: word=None
    if word:
        if not word in words:words[word]=0
        words[word]=words[word]+1
data=[]
for word in words: data.append([words[word],word])
data.sort()
data.reverse()
out= "&lt;b&gt;Out of %d words...n"%tot
xs=[]
for i in range(1000):
    d=data[i]
    out += '&lt;b&gt;"%s"&lt;/b&gt; ranks #%d used &lt;b&gt;%d&lt;/b&gt; times (%.05f%%)
n'%
                (d[1],i+1,d[0],d[0]/tot)
f=open("dump.html",'w')
f.write(out)
f.close()
print "DONE"&lt;/b&gt;

Markdown source code last modified on January 18th, 2021
---
title: Analyzing my Writings with Python
date: 2009-01-29 18:46:22
tags: python, old
---

# Analyzing my Writings with Python

__I had some free time in lab today__ (between steps while of an immunohistochemistry experiment) so I decided to further investigate the field of bioinformatics. I was curious if it may be worth seeking a PhD in bioinformatics if I don't get into dental school. UCF offers a PhD in bioinformatics but it's a new and small department (I think there are only 4 faculty). A degree in bioinformatics combines molecular biology (DNA, proteins, etc), computer science (programming), and statistics.

__I came across a paper today__: [Structural Alignment of Pseudoknotted RNA](http://cseweb.ucsd.edu/users/shzhang/app/RECOMB2005_pseudoknot.pdf) which is a good example of the practice of bioinformatics. Think about what goes on in a cell... the sequence of a gene (a short region of DNA) is copied (letter-by-letter) onto an RNA molecule. The RNA molecule is later read by an enzyme (called a ribosome) and converted into a protein based on its sequence. (This process is the central dogma of molecular biology) Traditionally, it was believed that RNA molecules' only function was to copy gene sequences from DNA to ribosomes, but recently (the last several years) it was discovered that some small RNA molecules are never read and turned into proteins, but rather serve their own unique functions! For example, some RNA molecules (siRNAs) can actually turn genes on and off, and have been associated with cancer development and other immune diseases. Given the human genome (the ~3 billion letter long sequence all of our DNA), how can we determine what regions form these functional RNA molecules which don't get converted into proteins? The paper I mentioned earlier addresses this. An algorithm was developed and used to test regions of DNA and predict its probability of forming small RNA molecules. Spikes in this trace (figure 7 of the paper) represent areas of the DNA which are likely to form these RNA molecules. (Is this useful? What if you were to compare these results between normal person and someone with cancer?)

__After reading the article__ I considered how similar my current programming projects are with this one (e.g., my recent DIY ECG projects). The paper shows a trace of score (likelihood that a region of DNA forms an RNA molecule) where peaks represent likely locations of RNA formation. Just generate the trace, determine the positions of the peaks, and you're golden. How similar is this to the work I've been doing with my homemade ECG machine, where I perform signal analysis to eliminate electrical noise and then analyze the resulting trace to isolate and identify peaks corresponding to heartbeats?

__I got the itch to write my own string-analysis program.__ It reads the content of my website (exported from a SQL query), splits it up by date, and analyzes it. Ultimately I want to track the usage of certain words, but for now I wrote a script which plots the number of words I wrote.

<div class="text-center">

[![](blog_words_thumb.jpg)](blog_words.png)

</div>

__Pretty cool huh? __Check out all those spikes between 2004 and 2005! Not only are they numerous (meaning many posts), but they're also high (meaning many words per post). As you can see by the top trace, the most significant contribution to my site occurred during this time. So, let's zoom in on it.

<div class="text-center">

[![](blog_words_zoom_thumb.jpg)](blog_words_zoom.png)

</div>

__Here is the code__ I used to produce this image.

```python
"""Convert SQL backups of my WordPress blog into charts"""

import datetime, pylab, numpy

class blogChrono():
    baseUrl="http://www.SWHarden.com/blog"
    posts=[]
    dates=[]
    def __init__(self,fname):
        self.fname=fname
        self.load()
    def load(self):
        print "loading [%s]..."%self.fname,
        f=open(self.fname)
        raw=f.readlines()
        f.close()
        for line in raw:
            if "INSERT INTO" in line
            and';' in line[-2:-1]
            and " 'post'," in line[-20:-1]:
                post={}
                line=line.split("VALUES(",1)[1][:-3]
                line=line.replace(', NULL',', None')
                line=line.replace(", '',",", None,")
                line=line.replace("''","")
                c= line.split(',',4)[4][::-1]
                c= c.split(" ,",21)
                text=c[-1]
                text=text[::-1]
                text=text[2:-1]
                text=text.replace('"""','###')
                line=line.replace(text,'blogtext')
                line=line.replace(', ,',', None,')
                line=eval("["+line+"]")
                if len(line[4])&gt;len('blogtext'):
                    x=str(line[4].split(', '))[2:-2]
                    raw=str(line)
                    raw=raw.replace(line[4],x)
                    line=eval(raw)
                post["id"]=int(line[0])
                post["date"]=datetime.datetime.strptime(line[2],
                                                        "%Y-%m-%d %H:%M:%S")
                post["text"]=eval('"""'+text+' """')
                post["title"]=line[5]
                post["url"]=line[21]
                post["comm"]=int(line[25])
                post["words"]=post["text"].count(" ")
                self.dates.append(post["date"])
                self.posts.append(post)
        self.dates.sort()
        d=self.dates[:]
        i,newposts=0,[]
        while len(self.posts)&gt;0:
            die=min(self.dates)
            for post in self.posts:
                if post["date"]==die:
                    self.dates.remove(die)
                    newposts.append(post)
                    self.posts.remove(post)
        self.posts,self.dates=newposts,d
        print "read %d posts!n"%len(self.posts)

#d=blogChrono('sml.sql')
d=blogChrono('test.sql')

fig=pylab.figure(figsize=(7,5))
dates,lengths,words,ltot,wtot=[],[],[],[0],[0]
for post in d.posts:
    dates.append(post["date"])
    lengths.append(len(post["text"]))
    ltot.append(ltot[-1]+lengths[-1])
    words.append(post["words"])
    wtot.append(wtot[-1]+words[-1])
ltot,wtot=ltot[1:],wtot[1:]

pylab.subplot(211)
#pylab.plot(dates,numpy.array(ltot)/(10.0**6),label="letters")
pylab.plot(dates,numpy.array(wtot)/(10.0**3),label="words")
pylab.ylabel("Thousand")
pylab.title("Total Blogged Words")
pylab.grid(alpha=.2)
#pylab.legend()
fig.autofmt_xdate()
pylab.subplot(212,sharex=pylab.subplot(211))
pylab.bar(dates,numpy.array(words)/(10.0**3))
pylab.title("Words Per Entry")
pylab.ylabel("Thousand")
pylab.xlabel("Date")
pylab.grid(alpha=.2)
#pylab.axis([min(d.dates),max(d.dates),None,20])
fig.autofmt_xdate()
pylab.subplots_adjust(left=.1,bottom=.13,right=.98,top=.92,hspace=.25)
width=675
pylab.savefig('out.png',dpi=675/7)
pylab.show()

print "DONE"
```

__I wrote a Python script to analyze the word frequency __of the blogs in my website (extracted from an SQL query WordPress backup file) for frequency, then I took the list to [Wordie](http://www.wordle.net/) and created a word jumble. Neat, huh?

```python
import datetime, pylab, numpy
f=open('dump.txt')
body=f.read()
f.close()
body=body.lower()
body=body.split(" ")
tot=float(len(body))
words={}
for word in body:
    for i in word:
        if 65&lt; =ord(i)&lt;=90 or 97&lt;=ord(i)&lt;=122: pass
        else: word=None
    if word:
        if not word in words:words[word]=0
        words[word]=words[word]+1
data=[]
for word in words: data.append([words[word],word])
data.sort()
data.reverse()
out= "&lt;b&gt;Out of %d words...n"%tot
xs=[]
for i in range(1000):
    d=data[i]
    out += '&lt;b&gt;"%s"&lt;/b&gt; ranks #%d used &lt;b&gt;%d&lt;/b&gt; times (%.05f%%)
n'%
                (d[1],i+1,d[0],d[0]/tot)
f=open("dump.html",'w')
f.write(out)
f.close()
print "DONE"&lt;/b&gt;
```

<div class="text-center">

[![](wordie2_thumb.jpg)](wordie2.png)

</div>

Pages