The personal website of Scott W Harden

Quantifying University Network Frustrations

I'm sitting in class frustrated as could be. The Internet in this room is unbelievably annoying. For some reason, everything runs fine, then functionality drops to unusable levels. Downloading files (i.e., PDFs of lectures) occurs at about 0.5kb/s (wow), and Internet browsing is hopeless. At most, I can connect to IRC and enjoy myself in #electronics, #python, and #linux. I decided to channel my frustration into productivity, and wrote a quick Python script to let me visualize the problem.

Notice the massive lag spikes around the time class begins. I think it's caused by the retarded behavior of windows update and anti-virus software updates being downloaded on a gazillion computers all at the same time which are required to connect to the network on Windows machines. Class start times were 8:30am, 9:35am, and 10:40am. Let's view it on a logarithmic scale:

Finally, the code. It's two scripts:

This script pings a website (kernel.org) every few seconds and records the ping time to "pings.txt":

import socket
import time
import os
import sys
import re


def getping():
    pingaling = os.popen("ping -q -c2 kernel.org")
    sys.stdout.flush()
    while 1:
        line = pingaling.readline()
        if not line:
            break
        line = line.split("n")
        for part in line:
            if "rtt" in part:
                part = part.split(" = ")[1]
                part = part.split('/')[1]
                print part+"ms"
                return part


def add2log(stuff):
    f = open("pings.txt", 'a')
    f.write(stuff+",")
    f.close()


while 1:
    print "pinging...",
    stuff = "[%s,%s]" % (time.time(), getping())
    print stuff
    add2log(stuff)
    time.sleep(1)

This script graphs the results:

import pylab
import time
import datetime
import numpy


def smoothTriangle(data, degree, dropVals=False):
    triangle = numpy.array(range(degree)+[degree]+range(degree)[::-1])+1
    smoothed = []
    for i in range(degree, len(data)-degree*2):
        point = data[i:i+len(triangle)]*triangle
        smoothed.append(sum(point)/sum(triangle))
    if dropVals:
        print "smoothlen:", len(smoothed)
        return smoothed
    while len(smoothed) < len(data):
        smoothed = [None]+smoothed+[None]
    if len(smoothed) > len(data):
        smoothed.pop(-1)
    return smoothed


print "reading"
f = open("pings.txt")
raw = eval("[%s]" % f.read())
f.close()

xs, ys, big = [], [], []
for item in raw:
    t = datetime.datetime.fromtimestamp(item[0])
    maxping = 20000
    if item[1] > maxping or item[1] == None:
        item[1] = maxping
        big.append(t)
    ys.append(float(item[1]))
    xs.append(t)

print "plotting"
fig = pylab.figure(figsize=(10, 7))
pylab.plot(xs, ys, 'k.', alpha=.1)
pylab.plot(xs, ys, 'k-', alpha=.1)
pylab.plot(xs, smoothTriangle(ys, 15), 'b-')
pylab.grid(alpha=.3)
pylab.axis([None, None, None, 2000])
pylab.ylabel("latency (ping kernel.org, ms)")
pylab.title("D3-3 Network Responsiveness")
fig.autofmt_xdate()
pylab.savefig('out.png')
pylab.semilogy()
pylab.savefig('out2.png')
fig.autofmt_xdate()
print "done"
Markdown source code last modified on January 18th, 2021
---
title: Quantifying University Network Frustrations
date: 2010-09-09 08:06:39
tags: python, old
---

# Quantifying University Network Frustrations

__I'm sitting in class frustrated as could be.__ The Internet in this room is unbelievably annoying.  For some reason, everything runs fine, then functionality drops to unusable levels.  Downloading files (i.e., PDFs of lectures) occurs at about 0.5kb/s (wow), and Internet browsing is hopeless.  At most, I can connect to IRC and enjoy myself in #electronics, #python, and #linux. I decided to channel my frustration into productivity, and wrote a quick Python script to let me visualize the problem.

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

[![](out_thumb.jpg)](out.png)

</div>

__Notice the massive lag spikes__ around the time class begins. I think it's caused by the retarded behavior of windows update and anti-virus software updates being downloaded on a gazillion computers all at the same time which are required to connect to the network on Windows machines. Class start times were 8:30am, 9:35am, and 10:40am.  Let's view it on a logarithmic scale:

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

[![](out2_thumb.jpg)](out2.png)

</div>

__Finally, the code.__ It's two scripts:

This script pings a website (kernel.org) every few seconds and records the ping time to "pings.txt":

```python
import socket
import time
import os
import sys
import re


def getping():
    pingaling = os.popen("ping -q -c2 kernel.org")
    sys.stdout.flush()
    while 1:
        line = pingaling.readline()
        if not line:
            break
        line = line.split("n")
        for part in line:
            if "rtt" in part:
                part = part.split(" = ")[1]
                part = part.split('/')[1]
                print part+"ms"
                return part


def add2log(stuff):
    f = open("pings.txt", 'a')
    f.write(stuff+",")
    f.close()


while 1:
    print "pinging...",
    stuff = "[%s,%s]" % (time.time(), getping())
    print stuff
    add2log(stuff)
    time.sleep(1)
```

This script graphs the results:

```python
import pylab
import time
import datetime
import numpy


def smoothTriangle(data, degree, dropVals=False):
    triangle = numpy.array(range(degree)+[degree]+range(degree)[::-1])+1
    smoothed = []
    for i in range(degree, len(data)-degree*2):
        point = data[i:i+len(triangle)]*triangle
        smoothed.append(sum(point)/sum(triangle))
    if dropVals:
        print "smoothlen:", len(smoothed)
        return smoothed
    while len(smoothed) < len(data):
        smoothed = [None]+smoothed+[None]
    if len(smoothed) > len(data):
        smoothed.pop(-1)
    return smoothed


print "reading"
f = open("pings.txt")
raw = eval("[%s]" % f.read())
f.close()

xs, ys, big = [], [], []
for item in raw:
    t = datetime.datetime.fromtimestamp(item[0])
    maxping = 20000
    if item[1] > maxping or item[1] == None:
        item[1] = maxping
        big.append(t)
    ys.append(float(item[1]))
    xs.append(t)

print "plotting"
fig = pylab.figure(figsize=(10, 7))
pylab.plot(xs, ys, 'k.', alpha=.1)
pylab.plot(xs, ys, 'k-', alpha=.1)
pylab.plot(xs, smoothTriangle(ys, 15), 'b-')
pylab.grid(alpha=.3)
pylab.axis([None, None, None, 2000])
pylab.ylabel("latency (ping kernel.org, ms)")
pylab.title("D3-3 Network Responsiveness")
fig.autofmt_xdate()
pylab.savefig('out.png')
pylab.semilogy()
pylab.savefig('out2.png')
fig.autofmt_xdate()
print "done"
```

Prime Failure 1 Year in the Making

My expression is completely flat right now. I simply cannot believe I'm about to say what I'm preparing to say. I spent nearly a year cracking large prime numbers. In short, I took-on a project I called The Flowering N'th Prime Project, where I used my SheevaPlug to generate a list of every [every millionth] prime number. The current "golden standard" is this page where one can look-up the N'th prime up to 1 trillion. My goal was to reach over 1 trillion, which I did just this morning! I was planning on being the only source on the web to allow lookups of prime numbers greater than 1 trillion.

However, when I went to look at the logs, I realized that the software had a small, fatal bug in it. Apparently every time the program restarted (which happened a few times over the months), although it resumed at its most recent prime number, it erased the previous entries. As a result, I have no logs below N=95 billion. In other words, although I reached my target this morning, it's completely irrelevant since I don't have all the previous data to prove it. I'm completely beside myself, and have no idea what I'm going to do. I can start from the beginning again, but that would take another YEAR. [sigh]

So here's the screw-up. Apparently I coded everything correctly on paper, but due to my lack of experience I overlooked the potential for multiple appends to occur simultaneously. I can only assume that's what screwed it up, but I cannot be confident. Honestly, I still don't know specifically what the problem is. All in all, it looks good to me. Here is the relevant Python code.

def add2log(c,v):
 f=open(logfile,'a')
 f.write("%d,%dn"%(c,v))
 f.close()

def resumeFromLog():
 f=open('log.txt')
 raw=f.readlines()[-1]
 f.close()
 return eval("["+raw+"]")

For what it's worth, this is what remains of the log file:

953238,28546251136703
953239,28546282140203
953240,28546313129849
...
1000772,30020181524029
1000773,30020212566353
1000774,30020243594723
Markdown source code last modified on January 18th, 2021
---
title: Prime Failure 1 Year in the Making
date: 2010-08-11 07:49:58
tags: python, old
---

# Prime Failure 1 Year in the Making

__My expression is completely flat right now.__ I simply cannot believe I'm about to say what I'm preparing to say. I spent nearly a year cracking large prime numbers. In short, I took-on a project I called [_The Flowering N'th Prime Project_](http://swharden.dyndns.org:8081/), where I used my [SheevaPlug](http://en.wikipedia.org/wiki/SheevaPlug) to generate a list of every \[every millionth\] prime number. The current "golden standard" is [this page](http://primes.utm.edu/nthprime/) where one can look-up the N'th prime up to 1 trillion. My goal was to reach over 1 trillion, which I did just this morning! I was planning on being the only source on the web to allow lookups of prime numbers greater than 1 trillion.

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

[![](flowering_primes_thumb.jpg)](flowering_primes.png)

</div>

__However, when I went to look at the logs,__ I realized that the software had a small, fatal bug in it. Apparently every time the program restarted (which happened a few times over the months), although it resumed at its most recent prime number, it erased the previous entries. As a result, I have no logs below N=95 billion. In other words, although I reached my target this morning, it's completely irrelevant since I don't have all the previous data to prove it. I'm completely beside myself, and have no idea what I'm going to do. I can start from the beginning again, but that would take another YEAR. \[sigh\]

__So here's the screw-up.__ Apparently I coded everything correctly on paper, but due to my lack of experience I overlooked the potential for multiple appends to occur simultaneously. I can only assume that's what screwed it up, but I cannot be confident. Honestly, I still don't know specifically what the problem is. All in all, it looks good to me. Here is the relevant Python code.

```python
def add2log(c,v):
 f=open(logfile,'a')
 f.write("%d,%dn"%(c,v))
 f.close()

def resumeFromLog():
 f=open('log.txt')
 raw=f.readlines()[-1]
 f.close()
 return eval("["+raw+"]")
```

__For what it's worth,__ this is what remains of the log file:

```python
953238,28546251136703
953239,28546282140203
953240,28546313129849
...
1000772,30020181524029
1000773,30020212566353
1000774,30020243594723
```

Converting Numbers to Morse Code with GCC

One of my microcontroller projects requires me to measure values and transmit then in Morse code. There may be code out there to do this already, but I couldn't find it. I'm sure there are more elegant and efficient ways to handle the conversion, but this works for me. Hopefully someone will find it useful!

#include <stdio.h>

//Morse code numbers from 0 to 9
char *array[10] = {"-----", ".----", "..---", "...--", "....-",
                   ".....", "-....", "--...", "---..", "----."};

void beep(char v)
{
    // beep (or print) Morse code as necessary
    printf("%s ", array[v]);
}

void send(int l)
{
    // convert a number into Morse code
    char d = 0;
    int t = 0;
    int val = 0;
    for (t = 100000; t > 0; t = t / 10)
    { //number of digits here
        if (l > t)
        {
            d = l / t;
            beep(d);
            l -= d * t;
        }
        else
        {
            beep(0);
        }
    }
    printf("n");
}

void main()
{
    // program starts here
    int l = 0b1111111111; //sample number (maximum 10-bit)
    printf("%d ", l);
    send(l);
    l = 0b11010001100101100011; //larger sample number
    printf("%d ", l);
    send(l);
}
Markdown source code last modified on January 18th, 2021
---
title: Converting Numbers to Morse Code with GCC
date: 2010-08-09 07:55:47
tags: python, qrss, old
---

# Converting Numbers to Morse Code with GCC

__One of my microcontroller projects__ requires me to measure values and transmit then in Morse code. There may be code out there to do this already, but I couldn't find it. I'm sure there are more elegant and efficient ways to handle the conversion, but this works for me. Hopefully someone will find it useful!

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

[![](binary_to_Morse_thumb.jpg)](binary_to_Morse.png)

</div>

```c
#include <stdio.h>

//Morse code numbers from 0 to 9
char *array[10] = {"-----", ".----", "..---", "...--", "....-",
                   ".....", "-....", "--...", "---..", "----."};

void beep(char v)
{
    // beep (or print) Morse code as necessary
    printf("%s ", array[v]);
}

void send(int l)
{
    // convert a number into Morse code
    char d = 0;
    int t = 0;
    int val = 0;
    for (t = 100000; t > 0; t = t / 10)
    { //number of digits here
        if (l > t)
        {
            d = l / t;
            beep(d);
            l -= d * t;
        }
        else
        {
            beep(0);
        }
    }
    printf("n");
}

void main()
{
    // program starts here
    int l = 0b1111111111; //sample number (maximum 10-bit)
    printf("%d ", l);
    send(l);
    l = 0b11010001100101100011; //larger sample number
    printf("%d ", l);
    send(l);
}
```

Idea: vdFSK modulation

My goal is to create a QRPP (extremely low power) transmitter and modulation method to send QRSS (extremely slow, frequency shifting data) efficiently, able to be decoded visually or with automated image analysis software. This evolving post will document the thought process and development behind AJ4VD's Frequency Shift Keying method, vdFSK.

Briefly, this is what my idea is. Rather than standard 2-frequencies (low for space, high for tone) QRSS3 (3 seconds per dot), I eliminate the need for pauses between dots by using 3 frequencies (low for a space between letters, medium for dot, high for dash). The following images compare my call sign (AJ4VD) being sent with the old method, and the vdFSK method.

Again, both of these images say the same thing: AJ4VD, .- .--- ....- ...- -.. However, note that the above image has greater than a 3 second dot, so it's unfairly long if you look at the time scale. Until I get a more fairly representative image, just appreciate it graphically. It's obviously faster to send 3 frequencies rather than two. In my case, it's over 200% faster.

This is the code to generate audio files converting a string of text into vdFSK audio, saving the output as a WAV file. Spectrographs can be created from these WAV files.

generate_audio.py

# converts a string into vdFSK audio saved as a WAV file

import numpy
import wave
from morse import *


def makeTone(freq, duration=1, samplerate=5000, shape=True):
    signal = numpy.arange(duration*samplerate) / \
        float(samplerate)*float(freq)*3.14*2
    signal = numpy.sin(signal)*16384
    if shape == True:  # soften edges
        for i in range(100):
            signal[i] = signal[i]*(i/100.0)
            signal[-i] = signal[-i]*(i/100.0)
    ssignal = ''
    for i in range(len(signal)):  # make it binary
        ssignal += wave.struct.pack('h', signal[i])
    return ssignal


def text2tone(msg, base=800, sep=5):
    audio = ''
    mult = 3  # secs per beep
    msg = " "+msg+" "
    for char in msg.lower():
        morse = lookup[char]
        print char, morse
        audio += makeTone(base, mult)
        for step in lookup[char]:
            if step[0] == ".":
                audio += makeTone(base+sep, int(step[1])*mult)
            if step[0] == "-":
                audio += makeTone(base+sep*2, int(step[1])*mult)
            if step[0] == "|":
                audio += makeTone(base, 3*mult)
    return audio


msg = "aj4vd"
file = wave.open('test.wav', 'wb')
file.setparams((1, 2, 5000, 5000*4, 'NONE', 'noncompressed'))
file.writeframes(text2tone(msg))
file.close()

print 'file written'

morse.py

# library for converting between text and Morse code
raw_lookup="""
a.- b-... c-.-. d-.. e. f..-. g--. h.... i.. j.--- k-- l.-.. m--
n-. o--- p.--. q--.- r.-. s... t- u.- v...- w.-- x-..- y-.-- z--..
0----- 1.---- 2..--- 3...-- 4....- 5..... 6-.... 7--... 8---.. 9----.
..-.-.- =-...- :---... ,--..-- /-..-. --....-
""".replace("n","").split(" ")

lookup={}
lookup[" "]=["|1"]
for char in raw_lookup:
    """This is a silly way to do it, but it works."""
    char,code=char[0],char[1:]
    code=code.replace("-----","x15 ")
    code=code.replace("----","x14 ")
    code=code.replace("---","x13 ")
    code=code.replace("--","x12 ")
    code=code.replace("-","x11 ")
    code=code.replace(".....","x05 ")
    code=code.replace("....","x04 ")
    code=code.replace("...","x03 ")
    code=code.replace("..","x02 ")
    code=code.replace(".","x01 ")
    code=code.replace("x0",'.')
    code=code.replace("x1",'-')
    code=code.split(" ")[:-1]
    #print char,code
    lookup[char]=code

Automated decoding is trivial. The image above was analyzed, turned into the image below, and the string (AJ4VD) was extracted:

decode.py

# given an image, it finds peaks and pulls data out
from PIL import Image
from PIL import ImageDraw
import pylab
import numpy

pixelSeek = 10
pixelShift = 15


def findPeak(data):
    maxVal = 0
    maxX = 0
    for x in range(len(data)):
        if data[x] > maxVal:
            maxVal, maxX = data[x], x
    return maxX


def peaks2morse(peaks):
    baseFreq = peaks[0]
    lastSignal = peaks[0]
    lastChange = 0
    directions = []
    for i in range(len(peaks)):
        if abs(peaks[i]-baseFreq) < pixelSeek:
            baseFreq = peaks[i]
        if abs(peaks[i]-lastSignal) < pixelSeek and i < len(peaks)-1:
            lastChange += 1
        else:
            if abs(baseFreq-lastSignal) < pixelSeek:
                c = " "
            if abs(baseFreq-lastSignal) < pixelSeek:
                c = " "
            if abs(baseFreq-lastSignal) < pixelSeek:
                c = " "
            directions.append(
                [lastSignal, lastChange, baseFreq, baseFreq-lastSignal])
            lastChange = 0
        lastSignal = peaks[i]
    return directions


def morse2image(directions):
    im = Image.new("L", (300, 100), 0)
    draw = ImageDraw.Draw(im)
    lastx = 0
    for d in directions:
        print d
        draw.line((lastx, d[0], lastx+d[1], d[0]), width=5, fill=255)
        lastx = lastx+d[1]
    im.show()


im = Image.open('raw.png')
pix = im.load()
data = numpy.zeros(im.size)
for x in range(im.size[0]):
    for y in range(im.size[1]):
        data[x][y] = pix[x, y]

peaks = []
for i in range(im.size[0]):
    peaks.append(findPeak(data[i]))

morse = peaks2morse(peaks)
morse2image(morse)
print morse
Markdown source code last modified on January 18th, 2021
---
title: Idea: vdFSK modulation
date: 2010-07-22 12:39:54
tags: python, qrss, old
---

# Idea: vdFSK modulation

<blockquote class="wp-block-quote"><p>My goal is to create a QRPP (extremely low power) transmitter and modulation method to send QRSS (extremely slow, frequency shifting data) efficiently, able to be decoded visually or with automated image analysis software. This evolving post will document the thought process and development behind AJ4VD's Frequency Shift Keying method, <b>vdFSK</b>.</p></blockquote>

__Briefly, this is what my idea is.__ Rather than standard 2-frequencies (low for space, high for tone) QRSS3 (3 seconds per dot), I eliminate the need for pauses between dots by using 3 frequencies (low for a space between letters, medium for dot, high for dash). The following images compare my call sign (AJ4VD) being sent with the old method, and the vdFSK method.

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

[![](traditional_thumb.jpg)](traditional.png)

</div>

__Again,__ both of these images say the same thing: AJ4VD, `.- .--- ....- ...- -..` However, note that the above image has greater than a 3 second dot, so it's unfairly long if you look at the time scale. Until I get a more fairly representative image, just appreciate it graphically. It's obviously faster to send 3 frequencies rather than two. In my case, it's over 200% faster.

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

[![](modulation_thumb.jpg)](modulation.png)

</div>

__This is the code to generate audio files__ converting a string of text into vdFSK audio, saving the output as a WAV file. Spectrographs can be created from these WAV files.

### generate_audio.py

```python
# converts a string into vdFSK audio saved as a WAV file

import numpy
import wave
from morse import *


def makeTone(freq, duration=1, samplerate=5000, shape=True):
    signal = numpy.arange(duration*samplerate) / \
        float(samplerate)*float(freq)*3.14*2
    signal = numpy.sin(signal)*16384
    if shape == True:  # soften edges
        for i in range(100):
            signal[i] = signal[i]*(i/100.0)
            signal[-i] = signal[-i]*(i/100.0)
    ssignal = ''
    for i in range(len(signal)):  # make it binary
        ssignal += wave.struct.pack('h', signal[i])
    return ssignal


def text2tone(msg, base=800, sep=5):
    audio = ''
    mult = 3  # secs per beep
    msg = " "+msg+" "
    for char in msg.lower():
        morse = lookup[char]
        print char, morse
        audio += makeTone(base, mult)
        for step in lookup[char]:
            if step[0] == ".":
                audio += makeTone(base+sep, int(step[1])*mult)
            if step[0] == "-":
                audio += makeTone(base+sep*2, int(step[1])*mult)
            if step[0] == "|":
                audio += makeTone(base, 3*mult)
    return audio


msg = "aj4vd"
file = wave.open('test.wav', 'wb')
file.setparams((1, 2, 5000, 5000*4, 'NONE', 'noncompressed'))
file.writeframes(text2tone(msg))
file.close()

print 'file written'
```

### morse.py

```python
# library for converting between text and Morse code
raw_lookup="""
a.- b-... c-.-. d-.. e. f..-. g--. h.... i.. j.--- k-- l.-.. m--
n-. o--- p.--. q--.- r.-. s... t- u.- v...- w.-- x-..- y-.-- z--..
0----- 1.---- 2..--- 3...-- 4....- 5..... 6-.... 7--... 8---.. 9----.
..-.-.- =-...- :---... ,--..-- /-..-. --....-
""".replace("n","").split(" ")

lookup={}
lookup[" "]=["|1"]
for char in raw_lookup:
    """This is a silly way to do it, but it works."""
    char,code=char[0],char[1:]
    code=code.replace("-----","x15 ")
    code=code.replace("----","x14 ")
    code=code.replace("---","x13 ")
    code=code.replace("--","x12 ")
    code=code.replace("-","x11 ")
    code=code.replace(".....","x05 ")
    code=code.replace("....","x04 ")
    code=code.replace("...","x03 ")
    code=code.replace("..","x02 ")
    code=code.replace(".","x01 ")
    code=code.replace("x0",'.')
    code=code.replace("x1",'-')
    code=code.split(" ")[:-1]
    #print char,code
    lookup[char]=code

```

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

[![](produced_thumb.jpg)](produced.png)

</div>

__Automated decoding__ is trivial. The image above was analyzed, turned into the image below, and the string (AJ4VD) was extracted:

### decode.py

```python
# given an image, it finds peaks and pulls data out
from PIL import Image
from PIL import ImageDraw
import pylab
import numpy

pixelSeek = 10
pixelShift = 15


def findPeak(data):
    maxVal = 0
    maxX = 0
    for x in range(len(data)):
        if data[x] > maxVal:
            maxVal, maxX = data[x], x
    return maxX


def peaks2morse(peaks):
    baseFreq = peaks[0]
    lastSignal = peaks[0]
    lastChange = 0
    directions = []
    for i in range(len(peaks)):
        if abs(peaks[i]-baseFreq) < pixelSeek:
            baseFreq = peaks[i]
        if abs(peaks[i]-lastSignal) < pixelSeek and i < len(peaks)-1:
            lastChange += 1
        else:
            if abs(baseFreq-lastSignal) < pixelSeek:
                c = " "
            if abs(baseFreq-lastSignal) < pixelSeek:
                c = " "
            if abs(baseFreq-lastSignal) < pixelSeek:
                c = " "
            directions.append(
                [lastSignal, lastChange, baseFreq, baseFreq-lastSignal])
            lastChange = 0
        lastSignal = peaks[i]
    return directions


def morse2image(directions):
    im = Image.new("L", (300, 100), 0)
    draw = ImageDraw.Draw(im)
    lastx = 0
    for d in directions:
        print d
        draw.line((lastx, d[0], lastx+d[1], d[0]), width=5, fill=255)
        lastx = lastx+d[1]
    im.show()


im = Image.open('raw.png')
pix = im.load()
data = numpy.zeros(im.size)
for x in range(im.size[0]):
    for y in range(im.size[1]):
        data[x][y] = pix[x, y]

peaks = []
for i in range(im.size[0]):
    peaks.append(findPeak(data[i]))

morse = peaks2morse(peaks)
morse2image(morse)
print morse
```

Getting GTK, Glade, and Python to Work in Windows

These screenshots show me running the Py2EXE-compiled script I wrote last weekend on a Windows 7 machine. Additionally there is a screenshot of the "Add/Remove Programs" window demonstrating which versions of which libraries were required.

Markdown source code last modified on January 18th, 2021
---
title: Getting GTK, Glade, and Python to Work in Windows
date: 2010-06-28 09:46:26
tags: python, old
---

# Getting GTK, Glade, and Python to Work in Windows

__These screenshots__ show me running the Py2EXE-compiled script I wrote last weekend on a Windows 7 machine. Additionally there is a screenshot of the "Add/Remove Programs" window demonstrating which versions of which libraries were required.

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

[![](glade_exe_thumb.jpg)](glade_exe.png)

[![](needToInstall_thumb.jpg)](needToInstall.png)

</div>

Pages