<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    
    <id>http://issackelly.com/blog/feeds/all/</id>
    
    <title>issackelly.com Blog: All</title>
    
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/" />
    <link rel="self" type="application/atom+xml" href="http://issackelly.com/blog/feeds/all/" />
    
    <updated>2015-09-22T00:00:01Z</updated>
    
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2015/09/22/looking-gigs/</id>
    <title>Looking for Gigs</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2015/09/22/looking-gigs/"/>
    
    <updated></updated>
    <published>2015-09-22T00:00:01Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I’ve given notice to Nonchalance of my departure as Director of Technology.
You’re seeing this because I have to be a little self-promotional to get my next gig.</p>
        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I’ve given notice to Nonchalance of my departure as Director of Technology.
You’re seeing this because I have to be a little self-promotional to get my next gig.</p>
<p>I am seeking contract gigs (2 weeks to 3 months probably part or full time)</p>
<p>Things I can do for you:</p>
<ul>
<li>Line of business applications
<ul>
<li>Intranets</li>
<li>Integrations with third party software</li>
<li>eCommerce</li>
<li>Industrial Automation</li>
<li>Systems design to support operational efficiency</li>
</ul>
</li>
<li>Application and Web development</li>
<li>Technical Architecture, Writing, Documentation</li>
<li>Embedded Hardware and Software</li>
<li>Rapid Prototyping (Physical or Digital products)</li>
<li>API Design</li>
<li>Help Determine engineering hiring needs and job descriptions</li>
</ul>
<p>My specialties are in Engineering Management, Infrastructure design, Python/Django/web development and operational efficiency. My favorite work is in real world interactive experiences and computer-human interfaces. I’m a very apt generalist with an entrepreneurial mindset.</p>
<p>Over the next several months I’ll be aiming to find permanent work in one or more of the following areas:</p>
<ul>
<li>Interactive and/or Installation Art</li>
<li>Experience Design</li>
<li>Electronics Design and Production</li>
<li>Game Design</li>
<li>Lighting Design</li>
<li>Engineering Management</li>
</ul>
<p>If you’ve got any of this, I’m located in the East Bay and I’m an SF commuter. I am open to remote and on-site work, with possible occasional travel. I’ll also get a coffee with anybody. I can be reached at <a href="mailto:issac@issackelly.com">issac@issackelly.com</a></p>
<p>If you’re reading this and are just a friend, acquaintance or stranger who hasn’t said “hello” in a while, let me know. I’ve got some time to catch up starting October first.</p>
<p>If you'd just like to keep up with me and some silly projects I'm working on, drop your email in the box on the right.

</p><p>P.S.</p>
<p>While I’ve got your attention, I have two other former co-workers I can vouch for looking for their next move. One is an EE Tech with a heart of gold. The other is a very talented artist and experience/situational designer and transmedia storyteller who deftly filled several operational burdens in our time working together (community management, events coordination and production). I’ll happily make an intro to anybody reading this.</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2015/05/02/django-migration-gotcha/</id>
    <title>Django Migration &quot;gotcha&quot;</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2015/05/02/django-migration-gotcha/"/>
    
    <updated></updated>
    <published>2015-05-02T10:00:00Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>The Model Class used by  <code>SomeModel = apps.get_model('some_app', 'SomeModel')</code>
is not the model class you wrote.</p>
        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>The Model Class used by  <code>SomeModel = apps.get_model('some_app', 'SomeModel')</code>
is not the model class you wrote.</p>
<p>Consider this example.</p>
<pre><code>Inventory(models.Model):
    quantity = models.IntegerField()

LogEntry(models.Model):
    text = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    inventory = models.ForeignKey(Inventory, related_name="logs")

    def __unicode__(self):
        return self.text
</code></pre>
<p>We want to cache the last logentry as a field on Inventory. Don't ask why, we just do.</p>
<p>We'll change the model like this:</p>
<pre><code>Inventory(models.Model):
    quantity = models.IntegerField()
    last_log_entry = models.TextField()

LogEntry(models.Model):
    text = models.TextField()
    created = models.DateTimeField(auto_now_add=True)
    inventory = models.ForeignKey(Inventory, related_name="logs")

    def __unicode__(self):
        return self.text

    def save(self, *args, **kwargs):
        super(LogEntry, self).save(*args, **kwargs)
        self.inventory.last_log_entry = unicode(self)
        self.inventory.save()
</code></pre>
<p>Which is great! It does what we thought. Now let's make a migration.</p>
<pre><code>$&gt; python manage.py makemigrations
</code></pre>
<p>This makes the schema migration to add our new field, but we should backfill the data.</p>
<pre><code>$&gt; python manage.py makemigrations inventory --empty
</code></pre>
<p>This makes the data migration. You might think it would look something like this:</p>
<pre><code># -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations


def forwards(apps, schema_editor):
    Inventory = apps.get_model('inventory', 'Inventory')
    for inv in Inventory.objects.all():
        log = inv.logs.order_by('-created').first()
        inv.last_log_text = unicode(log)
        inv.save()


class Migration(migrations.Migration):

    dependencies = [
        ('inventory', '0003_add_last_log_text'),
    ]

    operations = [
         migrations.RunPython(forwards),
    ]
</code></pre>
<p>But then you run the migration, and all of your Inventory objects have the following for last_log_text</p>
<pre><code>&lt;LogEntry: &gt;
</code></pre>
<p>If you read the opening sentence, you're probably a little ahead of me right now.
Your Model class is not the Model class that django uses during migrations.</p>
<p>Your forwards function should have been:</p>
<pre><code>def forwards(apps, schema_editor):
    Inventory = apps.get_model('inventory', 'Inventory')
    for inv in Inventory.objects.all():
        log = inv.logs.order_by('-created').first()
        inv.last_log_text = log.text
        inv.save()
</code></pre>
<p>Edit: This is sort of covered <a href="https://docs.djangoproject.com/en/1.8/topics/migrations/#historical-models">here: </a></p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2015/03/31/django-form-data-for-beginners/</id>
    <title>Dealing with Django form data for beginners.</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2015/03/31/django-form-data-for-beginners/"/>
    
    <updated></updated>
    <published>2015-03-31T22:39:00Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I have a continual interest in finding the rough edges of learning  Django. Some of the points of form and request handling have been coming up for me recently. What follows is an attempt at some explanation of the difference between <code>request.POST</code> or <code>request.GET</code> and <code>form.cleaned_data</code> of a valid Django Form.</p>

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I have a continual interest in finding the rough edges of learning  Django. Some of the points of form and request handling have been coming up for me recently. What follows is an attempt at some explanation of the difference between <code>request.POST</code> or <code>request.GET</code> and <code>form.cleaned_data</code> of a valid Django Form.</p>
<p>There are two different ways to get the info that you're looking for.</p>
<p><code>request.POST[somekey]</code>  Where somekey is a string representing the associated html <code>&lt;input name="somekey" /&gt;</code>.</p>
<p>There is also <code>forms.cleaned_data[somekey]</code> where somekey is the name of the attribute on the <code>forms.Form</code> subclass that you've initialzed and checked the validation of earlier.</p>
<p>When you get it from request.POST it might not be valid, and it won't be convered into the proper python type. for example:</p>
<p>Consider the form:</p>
<pre><code>from django import forms
class BirthDayForm(forms.Form):
    birth_month = forms.IntegerField(min_value=1, max_value=12)
    birth_day = forms.IntegerField(min_value=1, max_value=31)
    birth_year = forms.IntegerField(min_value=1900, max_value=2014)
</code></pre>
<p>In your view you could implement this in this way:</p>
<pre><code>from .forms import BirthDayForm

def birthday_view(request):
    bday_form = BirthDayForm(request.POST or None)

    if form.is_valid():
        print bday.cleaned_data['birth_year']

    return TemplateResponse(request, 'some_template.html', {"form": bday_form})
</code></pre>
<p>and in your template</p>
<pre><code>    &lt;form method="POST"&gt;
         {{ form.as_p }}
         &lt;input type="submit"&gt;
    &lt;/form&gt;
</code></pre>
<p>When you get the form it will print:</p>
<pre><code>        &lt;form method="POST"&gt;
         &lt;input type="number" name="birth_month" id="id_birth_month" /&gt;
         &lt;input type="number" name="birth_day" id="id_birth_day" /&gt;
         &lt;input type="number" name="birth_year" id="id_birth_year" /&gt;
         &lt;input type="submit"&gt;
    &lt;/form&gt;
</code></pre>
<p>Now if you were to put a pdb into your view like this:</p>
<pre><code>from .forms import BirthDayForm

def birthday_view(request):
    bday_form = BirthDayForm(request.POST or None)

    if form.is_valid():
        import pdb; pdb.set_trace()
        print bday.cleaned_data['birth_year']

    return TemplateResponse(request, 'some_template.html', {"form": bday_form})
</code></pre>
<p>You would see (forgive me for not being exact, I haven't tested all this):</p>
<pre><code>(pdb) type(request.POST['birth_year'])
&gt; string
(pdb) type(form.cleaned_data['birth_year'])
&gt; int
</code></pre>
<p>There are also several other complexities. You can add a "prefix" to a form, which would change the key of the request.POST dictionary, but it would NOT change the key of the cleaned_data.</p>
<p>consider:</p>
<pre><code>from .forms import BirthDayForm

def birthday_view(request):
    #add bday prefix to the form, because later we're going to have another form on this page with the same names, because it's a quiz page about your birthday, and the birthday of several dead presidents. sort of a "which dead president are you" quiz page for buzzfeed. It's not very fun.
    bday_form = BirthDayForm(request.POST or None, prefix="bday")

    if form.is_valid():
        print bday.cleaned_data['birth_year']

    return TemplateResponse(request, 'some_template.html', {"form": bday_form})
</code></pre>
<p>This would render as:</p>
<pre><code>        &lt;form method="POST"&gt;
         &lt;input type="number" name="bday-birth_month" id="id_bday_birth_month" /&gt;
         &lt;input type="number" name="bday-birth_day" id="id_bday_birth_day" /&gt;
         &lt;input type="number" name="bday-birth_year" id="id_bday_birth_year" /&gt;
         &lt;input type="submit"&gt;
    &lt;/form&gt;
</code></pre>
<p>You can see that it changed the name and id attributes of the rendered form.</p>
<p>This would mean that if you put the PDB at the exact same spot...</p>
<pre><code>(pdb) type(request.POST['birth_year'])
&gt; KeyError, request.POST has no key birth_year
(pdb) request.POST.keys()
&gt; ["bday-birth_month", "bday-birth_day", "bday-birth_year"]
</code></pre>
<p>But notice that the form.cleaned_data turns the keys back into the exact same name as the fields on the BirthDayForm that we defined earlier.</p>
<pre><code>(pdb) type(form.cleaned_data['birth_year'])
&gt; int
</code></pre>
<p>I think we could keep expanding this BirthDayForm concept to tease out the other things are conceptually a little difficult, like the validation process, converting crappy request.POST data into good python data, validating multiple fields together (my birthday is suddenly February 30th! because your form let me do that!)</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2014/08/03/experimenting-toga/</id>
    <title>Experimenting with Toga</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2014/08/03/experimenting-toga/"/>
    
    <updated></updated>
    <published>2014-08-03T15:56:54Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I heard about <a href="http://toga.readthedocs.org/en/latest/introduction/tutorial-0.html">Toga</a> from twitter. Apparently it was introduced at PyConAU. I took
an hour to whip up a small app that will let you touch buttons to launch fabric
tasks.</p>
        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I heard about <a href="http://toga.readthedocs.org/en/latest/introduction/tutorial-0.html">Toga</a> from twitter. Apparently it was introduced at PyConAU. I took
an hour to whip up a small app that will let you touch buttons to launch fabric
tasks.

</p>
<p>None of them can take arguments, so it relies on defaults and a fully-stocked
set of 'env' variables, but that's ok, this is just a silly hack to explore a new
gui framework.

</p>
<strike>I'll say it's not exceptional in anything other than how easy it was to make the
simple app work as advertised.</strike>
<p>What I mean is, it seems to have a long way to go in the documentation front before I'd use it for anything serious, but I'm excited for the possibilities and it was impressive how easy it was writing a quick app as compared to my experiences with pyobjectivec and pygtk.

</p>
<p>If you have an existing fabfile, you can <code>pip install toga</code> and run this little
app.

</p>
<pre><code>from __future__ import print_function, unicode_literals, absolute_import
import os
import toga
from fabric import state
from fabric.main import load_fabfile
from fabric.tasks import execute

BASE_DIR = os.path.dirname(os.path.dirname(__file__))
FABFILE = os.path.join(BASE_DIR, 'fabfile.py')

docstring, callables, default = load_fabfile(FABFILE)
state.commands.update(callables)


def button_handler(widget, *args, **kwargs):
    execute(
        widget.label,
        hosts=[],
        roles=[],
        exclude_hosts=[],
        *args, **kwargs
    )

if __name__ == '__main__':

    app = toga.App('Fabric App', 'com.issackelly.fabricapp')
    container = toga.Container()

    btn_height = 20
    this_height = container.TOP

    for name in callables:
        button = toga.Button(name, on_press=button_handler)
        container.add(button)
        container.constrain(button.TOP == this_height)
        container.constrain(button.HEIGHT == btn_height)
        container.constrain(button.WIDTH == 150)
        this_height += btn_height

    app.main_window.size = (150, btn_height * (len(callables) + 1))
    app.main_window.content = container
    app.main_loop()</code></pre>

        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2014/07/28/snow-white-3/</id>
    <title>Snow White, Part Three</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2014/07/28/snow-white-3/"/>
    
    <updated></updated>
    <published>2014-07-28T00:00:02Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <h1>Snow White Part 3: Image Manipulation </h1>
<p>I'm writing about an interactive art piece I brough to PyOhio and how I built it.</p>
<p>This one is about image manipulation</p>
        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <h1>Snow White Part 3: Image Manipulation </h1>
<p>I'm writing about an interactive art piece I brough to PyOhio and how I built it.</p>
<p>Josh Boles got a (picture)[https://twitter.com/joshboles/status/493466700684091392/photo/1] I like, of the piece while I was talking about something else and the room was playing tetris (More on that soon!)</p>
<p>This post is about the image manipulation.</p>
<p>The piece I built had 20 of the 8 by 8 NeoPixel Matrices to make a canvas. It was arranged like so:</p>
<pre><code>[ 0] [ 1] [ 2] [ 3]
[ 4] [ 5] [ 6] [ 7]
[ 8] [ 9] [10] [11]
[12] [13] [14] [15]
[16] [17] [18] [19]
</code></pre>
<p>So, Four columns, and 5 rows. 20 different individual matrices. Each one had 64 LEDs in it's own matrix, represented to the underlying hardware as a list of LEDs, each with three color values (more in the last post)</p>
<p>In the last post, I showed how to get the pixel values out of an 8 by 8 image and then how to send those out to a single channel of a single fadecandy board.</p>
<p>This time, I'm just going to cover working with an image, or a series of images (animated gifs) to get it to the right format and dimensions.</p>
<p>PIL and/or Pillow are the standard for image manipulation with python. It's actually incredibly easy.</p>
<p>In my code, I kept a config file (utils.py) of sorts with the dimensions of the LED array (32 pixels by 40 pixels) and how the layout of the overall piece was represented as a single string of LEDs.</p>
<p>The layout variable was a list of 2-tuples representing the edges of a square within the array. The first was 0,0 to 7,7, The Second (matrix 1) was 8, 0 to 15, 7, moving all the way to #19 representing pixels 24, 32 to 31, 39.</p>
<p>To say this another way, I have a list of the top left and bottom right pixels of every individual matrix of LEDs. Then I match that up to an image of the same size as my array, and I get  every pixel of that image and put it at the right spot in my list. Then I display the image.</p>
<p>Let's start with opening an image and resizing it to fit the piece. Most images aren't meant to be displayed at 32 by 40, but we'll go with it anyway.</p>
<p>I adapted this code from the sorl-thumbnail package, which did the thing I wanted already. Don't rewrite code if somebody else does the thing you want already unless you have a good reason.</p>
<p>The following code will fit an image to the desired "size", and will crop to the center.</p>
<pre><code>from PIL import  Image
size = (32, 40)
img = Image.open('~/path/to/image.jpg')

# Get current and desired ratio for the images
img_ratio = img.size[0] / float(img.size[1])
ratio = size[0] / float(size[1])
#The image is scaled/cropped vertically or horizontally depending on the ratio
if ratio &gt; img_ratio:
    img = img.resize((size[0], size[0] * img.size[1] / img.size[0]),
            Image.ANTIALIAS)
    # Crop middle
    box = (0, (img.size[1] - size[1]) / 2, img.size[0], (img.size[1] + size[1]) / 2)
    img = img.crop(box)
elif ratio &lt; img_ratio:
    img = img.resize((size[1] * img.size[0] / img.size[1], size[1]),
            Image.ANTIALIAS)
    # Crop in the middle
    box = ((img.size[0] - size[0]) / 2, 0, (img.size[0] + size[0]) / 2, img.size[1])
    img = img.crop(box)
else :
    img = img.resize((size[0], size[1]), Image.ANTIALIAS)
    # If the scale is the same, we do not need to crop
</code></pre>
<p>First you compare the ratios of the image and the desired size, then you crop them to the same ratio.</p>
<p>After that, a resize operation brings it to the right dimensions.</p>
<p>Animated gifs or videos basically repeat the same proceess once for every frame. Due to compression optimizations, it's a little more complicated than that, but it's basically the same.</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2014/07/28/snow-white-2/</id>
    <title>Snow White, Part Two, LEDs and Python</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2014/07/28/snow-white-2/"/>
    
    <updated></updated>
    <published>2014-07-28T00:00:01Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <h1>Snow White Part 2: Driving LEDs with Python</h1>
<p>The state of python on embedded systems isn't great. That's not bad news though!
Raspberry Pis are cheap and run python pretty darn well.</p>
        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <h1>Snow White Part 2: Driving LEDs with Python</h1>
<p>The state of python on embedded systems isn't great. That's not bad news though!
Raspberry Pis are cheap and run python pretty darn well.</p>
<p>If you want to drive a single LED on a Raspberry Pi with python, I'm not going to cover that here.
I'm going to talk about running a few thousand LEDs, but let's start with some basics.</p>
<p>I like[1] the World Semi set of LEDs called the WS281X series, there are several variations, and working
with them with an arduino is REALLY straight forward. Adafruit sells several variations of these under the "NeoPixel" brand name. Sparkfun sells them too. You can get them from way cheaper from vendors in China off of AliExpress if you are patient and trusting.</p>
<p>If you want to code these in python, there is a special brand of microcontroller which makes it really easy.
Micah Scott created a project called (FadeCandy)[https://github.com/scanlime/fadecandy/] based on a Teensy Microcontroller (Arduino Compatible, Open Source, ARM chipset).</p>
<p>Fadecandy, combined with (Open Pixel Control)[http://openpixelcontrol.org/] make it very simple to control a string of serial LEDs from many languages, python included.</p>
<p>Fadecandy costs about $24 from Adafruit or Sparkfun and can drive 512 of these serial LEDs on 8 different channels (64 in series per channel, though that's abstracted from you). It's as easy as building a python list of LEDs and their associated RGB value, and feeding that to a python client which is as simple as requests.</p>
<p>FadeCandy boards plug into USB, and you can run tons of them off of the same computer. A simple config file manages the locations of the channels. A single process runs an OPC server and spits all the right values to the right channels to color your display, whatever the configuration.</p>
<p>Open Pixel Control also includes an OpenGL sample server. You can view a simple representation of your LED display and test it and write code for it while you're on vacation, and when you get back to your device several weeks later, you won't be surprised at how it looks.</p>
<p>What I mean to say is, You get to stand on the shoulders of giants if you are trying to write python (or many other languages) to interface with LEDs in any configuration you can imagine. If you can imagine and wire your LEDs in a single line, Linux, OpenPixel, FadeCandy, and WS281(1|2)[ab]{0,1} LEDs can make this a reality.</p>
<p>I built a python script for turning the adafruit grids of LEDs into an OpenPixel layout for the OpenGl server. That is on (this file)[https://github.com/issackelly/snowwhite/blob/master/opc/opc_layout.py].</p>
<p>Now that we're this far, what I'm saying, is buy a fadecandy board, and run a fadecandy server and all of this gets super easy. A fadecandy board and some LEDs will cost you anywhere from $40 to $200.</p>
<p>The LEDs that I used were arranged in an array, but as far as the LEDs are concerned, and how they pass data, they're arranged in a line.</p>
<p>The Adafruit NeoPixel 8x8 Matrix looks like this</p>
<pre><code>o    o    o    o    o    o    o    o
o    o    o    o    o    o    o    o
o    o    o    o    o    o    o    o
o    o    o    o    o    o    o    o
o    o    o    o    o    o    o    o
o    o    o    o    o    o    o    o
o    o    o    o    o    o    o    o
o    o    o    o    o    o    o    o
</code></pre>
<p>But it's arranged like this</p>
<pre><code>0    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
</code></pre>
<p>The LEDs think they're in a line.</p>
<p>You need to compensate for this if you want to make 2D art. Not all display matrices are set up like this, but these are.</p>
<p>Let's make the canvas of a single array blue. First, run a fadecandy server (read her readme for this).</p>
<p>Next, copy the OPC.py from her examples folder or my code into your project.</p>
<p>Now we'll write the following in a python shell</p>
<pre><code>import opc
pattern = [ 0, 0, 255 ] * 8 * 8
client = opc.Client('localhost:7890')
client.put_pixels(pattern)
</code></pre>
<p>If everything is hooked up correctly, your display will be blue.</p>
<p>You might recognize the 3-tuple from line 2 as an RGB value. An RGB value is a set of three numbers, typically from 0-255 for mathematical reasons regarding powers of 2. This one says "this color is 0% red, 0% green, and 100% blue". Colors from a display are a mixture of red green and blue, and from these three your eye understands a variety of colors. If you're interested in this concept you should explore pointillism, modern displays work in the same way.</p>
<p>Let's make something slightly more recognizable. Or less. I made a silly image of pink and green and white.</p>
<p>You don't get much resolution at 8 by 8.</p>
<p>If you start with an image of 8 by 8 you can just open it up with PIL and read every RGB value and put that back to the client.</p>
<pre><code>import opc
client = opc.Client('localhost:7890')

im = Image.open('~/path/to/image.png')

i = 0
j = 0
pix = []
while j &lt;= 7:
    while i &lt;= 7:
        pix.append(im.getpixel((i,j))[:3]) # Only want RGB, not RGBA
        i+=1
    j+=1
    i = 0
client.put_pixels(pix)
</code></pre>
<p>I'm going to skip over the pil stuff, that's in the next post.</p>
<p>This is a pretty naive algorithm which iterates over the top left of an image which is greater or equal to 8x8px. This reads the first 64 pixels, in the same pattern as our led array. It makes a single list, which it sends to the OPC server.</p>
<p>This is roughly all you need to start Writing to LEDs with python, NeoPixels and Fadecandy.</p>
<p>Next up: Image Manipulation.</p>
<p>My code is ugly! My writing is bad! As always, email me your feedback! I love to hear from people who read my posts, and I'd like to edit things that are wrong or unclear.</p>
<p>[1] Mostly, There are caveats to using these at scale, full-time, but they're beyond
the scope of these posts. If you're super interested in using these for an installation,
let me know and we can discuss the positives and negatives, maybe it will be a future post.</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2014/07/28/snow-white-1/</id>
    <title>Snow White, Part One</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2014/07/28/snow-white-1/"/>
    
    <updated></updated>
    <published>2014-07-28T00:00:00Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <h1>Snow White, Part One: Motivation.</h1>
<p>I made a project. It's silly and wonderful. There are many parts and it had some restrictings which drove the decisions I made. Any project has restrictions, mine were sort of arbitrary.</p>
        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <h1>Snow White, Part One: Motivation.</h1>
<p>I made a project. It's silly and wonderful. There are many parts and it had some restrictings which drove the decisions I made. Any project has restrictions, mine were sort of arbitrary.</p>
<ol>
<li>As much of the project would be written in python as possible.</li>
<li>It has to fit in a briefcase so I can carry it through the airport.</li>
<li>It has to present well for a conference talk or a small group.</li>
</ol>
<p>I'm going to write a series of blog posts about how I built this. This is the first of the series.</p>
<h2>On Python</h2>
<p>Python is my favorite language to work with. It's quick, it's stable, the community is wonderful.
I build immersive worlds for a living at Nonchalance. Think along the lines of a museum installation, or an amusement park. That's a close enough approximation for these purposes. Python makes my job easy in a hundred different ways, and I wanted to show that off to the python community.</p>
<p>I proposed a talk. Moving backwards in time, a whole day ago, I gave this talk. I think I didn't do a great job showing off Python, I was mostly showing off. I think it made for a great talk, some other people did too, but I'm not sure I was explainatory enough to get ALL the stuff I wanted across. Also I only had 40 minutes and I showed 0 lines of code in my talk.</p>
<p>This series of blog posts exists to rectify this. </p>
<h2>On the Briefcase</h2>
<p>I brought up that this was an art piece for a conference talk. This conference was across the country. This proposes its own problems. On the way to the talk I was randomly chosen for TSA Pre Check, and I was carrying
my wild device on, so it was nice that they didn't particularly care that I brought (very innocous) home-made electronics, and the tools to repair them should they be damaged in transit.</p>
<p>As I write this post, I've checked this briefcase. I've entrusted it's safe arrival back to my home in Oakland to Southwest Airlines. I'll update on its arrival in a future post.</p>
<h2>On Presentation</h2>
<p>From the reactions, I think this piece may have presented better to a group of 5-10 then a room of 40-60. This seems to be a function of restriction #2. You'll have to ask my audience for confirmation.</p>
<p>I do think that one particular part of it went quite well for a very large group (PyOhio Plays Tetris). If you weren't there, you'll need to stay tuned...</p>
<p>Post #2 is going to be about controlling the LEDs from python. </p>
<p>As always, email me your feedback! I love to hear from people who read my posts.</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2014/02/16/machining-pla-from-reprap/</id>
    <title>Machining PLA from my RepRap</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2014/02/16/machining-pla-from-reprap/"/>
    
    <updated></updated>
    <published>2014-02-16T23:30:00Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I've got a Taz 2.1 from Lulzbot. It's tons of fun, but I had really hoped I'd find
some joy in the ability to use it for rapid prototyping. I've done some minor stuff
with it, but this weekend I finally got to build a thing which I designed that was
not trivial.
</p>
        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I've got a Taz 2.1 from Lulzbot. It's tons of fun, but I had really hoped I'd find
some joy in the ability to use it for rapid prototyping. I've done some minor stuff
with it, but this weekend I finally got to build a thing which I designed that was
not trivial.

<img src="http://issackelly.com.s3.amazonaws.com/IMG_20140216_115628.jpg" style="width:100%;" />
</p><p>One of the final pieces being printed</p>
<p>I also took all the scraps and did some ad hoc materials testing. A 6mm standoff
will take a 1/16" drill bit just fine, and then the resulting hole will hold an M3
screw pretty well.

</p><p>On larger flat surfaces, drilling was also easy, though with a larger bit and too
much force, layer separation can occur. Being able to get in 0.1mm tolerances
is pretty impressive.

<img src="http://issackelly.com.s3.amazonaws.com/IMG_20140216_142134.jpg" style="width:100%;" />
</p><p>Layer Separation, and a screw hole</p>
<img src="http://issackelly.com.s3.amazonaws.com/IMG_20140216_142202.jpg" style="width:100%;" />
<p>Super glue works surprisingly well on unsanded PLA, but I can't get my corners to stay down perfectly</p>
<img src="http://issackelly.com.s3.amazonaws.com/IMG_20140216_142213.jpg" style="width:100%;" />
<p>More Separation, More Screws.</p>
<p>I haven't tried cutting it yet, I assume that a very fine blade is going to be
the most useful.
</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2014/02/16/wake-me-up/</id>
    <title>Wake Me Up!</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2014/02/16/wake-me-up/"/>
    
    <updated></updated>
    <published>2014-02-16T20:30:00Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Wake me up!</p>
<p>Alarms are alarming. They’re super fine and useful if you really need to be up at a certain time and it’s hard for you to hit it. Otherwise, they are the harbingers of morning terrorism.</p>

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Wake me up!</p>
<p>Alarms are alarming. They’re super fine and useful if you really need to be up at a certain time and it’s hard for you to hit it. Otherwise, they are the harbingers of morning terrorism.</p>
<p>I got my lights to slowly turn on to tell me it’s time to get up. It takes 15 minutes to go from 0 to full brightness, at the time I specify.</p>
<p>I’m finally back on a hacking/automation kick. For a number of reasons which I won’t write about, for everybody’s sake, It’s been a while. This is nowhere near the intentions I have for the Plum Garage controller/automation system, but it’s the sort of results I want to see.</p>
<p>This small hack took two steps, first was the python script to slowly open the lights (based on my python-hue work) and the second is running that on a cron job on a raspberry pi. That’s it.</p>
<p>Script wakemeup.py:</p>
<pre><code>#!/usr/bin/env python

from hue import Hue

def wakemeup():
    h = Hue()
    h.station_ip = &#39;192.168.42.89&#39;
    h.get_state()

    minutes = 15
    transition = minutes * 60 * 10

    h.lights[&#39;l1&#39;].off()
    h.lights[&#39;l1&#39;].set_state({
        &quot;on&quot;: True,
        &quot;bri&quot;: 255,
        &quot;transitiontime&quot;: transition
    })


if __name__ == &quot;__main__&quot;:
    wakemeup()</code></pre>
<p>Cron Task:</p>
<pre><code>45 6 * * * /home/pi/python-hue/wakemeup.py</code></pre>

        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2013/10/17/password-security-primer-1/</id>
    <title>Password Security Primer 1</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2013/10/17/password-security-primer-1/"/>
    
    <updated></updated>
    <published>2013-10-17T00:15:35Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>This weekend my sister's Twitter account was a victim of one sort of attack or another. She spammed me some advertising over direct message. It could be one of several things, but I'm going to drop some password advice for everybody.</p>
<p>Most sites and applications use a password for the base of their security and their ability to identify and authorize you to change things on your account with them. Having some knowledge about how to make and use good passwords is very important to staying secure online.</p>
        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>This weekend my sister's Twitter account was a victim of one sort of attack or another. She spammed me some advertising over direct message. It could be one of several things, but I'm going to drop some password advice for everybody.</p>
<p>Most sites and applications use a password for the base of their security and their ability to identify and authorize you to change things on your account with them. Having some knowledge about how to make and use good passwords is very important to staying secure online.</p>
<h3>
<a name="why-you-should-use-good-password-practices" class="anchor" href="#why-you-should-use-good-password-practices"><span class="mini-icon mini-icon-link"></span></a>Why you should use good password practices:</h3>
<ol>
<li>
<strong>It's the key to your house</strong>. Maybe not yet, but it's probably the only thing between your bank account and a bad guy. It's almost certainly the only thing between all your emails and a bad guy. Some may put out advertisements as if they came from you which can be embarrassing and can even ruin your reputation.</li>
<li>
<strong>You don't know who you're trusting</strong>. Every time you type your password in, you're not sure who you're trusting with your password and what they're doing with it. In many cases you also aren't sure that it is only you and the other site who are in the "conversation". Having good password practices helps minimize your vulnerability. Some sites might have very good password policies, others might just keep a list of your passwords next to your email.</li>
</ol><p>Following the below principles makes your password harder to crack if it is found, and makes is so that if someone finds your Facebook password, they can't get into your bank account (for example).</p>
<h3>
<a name="how-to-make-a-good-password" class="anchor" href="#how-to-make-a-good-password"><span class="mini-icon mini-icon-link"></span></a>How to make a good password:</h3>
<ol>
<li>
<strong>Make it long.</strong> Typically, the longer the better, at least 16 characters should be your aim.</li>
<li>
<strong>Nothing associated with you personally.</strong> Not your birthday, not your grade school. Not your grandmother's first name. </li>
<li>
<strong>Use a phrase.</strong> Not one from a book or one that's been written down before, but one you can make up and remember.</li>
</ol><p>Maybe aim for like, 6 or more words, the more random/obscure the better, and if you can mix in uppercase, lowercase, numbers and symbols, that's better.</p>
<h3>
<a name="what-to-do-when-a-password-is-no-longer-good" class="anchor" href="#what-to-do-when-a-password-is-no-longer-good"><span class="mini-icon mini-icon-link"></span></a>What to do when a password is no longer good:</h3>
<ol>
<li>
<strong>Change it.</strong> Typically this is under your account settings, your user profile, you can also figure this out typically by clicking the "forgot password" link on the sign in page or searching the web for "Change <em>(twitter)</em> password".</li>
<li>
<strong>Review which 3rd party applications you've allowed to use your data.</strong> Twitter, Facebook, Google and many other popular services allow you to share and give permission to other apps. Review that list and remove anything you don't actively use, and especially anything which you don't recognize.</li>
</ol><h3>
<a name="how-to-use-a-good-password" class="anchor" href="#how-to-use-a-good-password"><span class="mini-icon mini-icon-link"></span></a>How to use a good password:</h3>
<ol>
<li>
<strong>Don't use it in two places.</strong> If you're going to ignore this advice, then you should at least know that anything with out the HTTPS (green) lock and bar on the web, and anything you do over email is <strong>as secure as a postcard</strong> Anybody in the middle can read it. Don't reuse passwords between protected and unprotected sites <strong>under any circumstances.</strong> Any password you have ever used on an unprotected (HTTP) site, you should <strong>assume is insecure</strong>.</li>
<li>
<strong>Change it frequently.</strong> Set a date, maybe your half-birthday or the Ides of March, and change all your passwords, maybe even totally deactivate accounts you don't use any more.</li>
<li>
<strong>Don't share them.</strong> This is semi obvious, but you shouldn't share passwords with other people. Most services allow some sort of multi-user capabilities if you're meant to work together with things. Share projects and accounts, not passwords.</li>
</ol><p>A nice program which I like for this process is 1Password, it's available for Windows, Mac, iPhone and Android, and it can stay in sync over wifi or with Dropbox. There are plusses and minuses of syncing over dropbox, but for the large part, you're better off than if you use the same password everywhere. It has a browser plugin so that it can automatically save a different password for every site and automatically fill in that password when you go there. There are many others like it, PasswordSafe is one I previously used and is free, but there is no mobile client. LastPass is another one. It's "OK" but they do one thing in particular that I do not like which is effectively lying to you about sharing your passwords with others. They suggest that you can securely share passwords with others without them knowing the plain text password. This is not true and I have some resentment for any one who would suggest that it is possible. </p>
<p>You could do very very well for yourself by using 1password, making all of your other passwords totally random, and using a very long passphrase to use 1password. The first time you make it, write it down somewhere safe until you're sure you've memorized it. Don't tape it to your monitor, keep it on your person.</p>
<p>There are many other things which you should learn about protecting yourself, if you're interested, please let me know. </p>
<p>Thanks <a href="https://caremad.io/">Donald Stufft</a> for help with some of the specifics</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2012/11/10/philips-hue-api-hacking/</id>
    <title>Philips Hue API Hacking</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2012/11/10/philips-hue-api-hacking/"/>
    
    <updated></updated>
    <published>2012-11-10T14:48:28Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Here it is! My Python client for the Philips Hue system is done.</p>
<p>The Short:</p>
<p>It's available on <a href="https://github.com/issackelly/python-hue">Github</a>.</p>

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Here it is! My Python client for the Philips Hue system is done.</p>
<p>The Short:</p>
<p>It's available on <a href="https://github.com/issackelly/python-hue">Github</a>.</p>
<p>Sample Usage:</p>
<pre><code>from hue import Hue
h = Hue() # Initialize the class
h.station_ip = "192.168.1.222" # your base station IP
h.get_state() # Authenticate, bootstrap your lighting system
# The first time, you have a minute between calling get_state() and pushing
# the button on your base station to authenticate your machine. It should
# Log and tell you if that is going to happen or not.
l = h.lights.get('l3') # get bulb #3
l.bri(0) # Dimmest
l.bri(255) # Brightest
l.rgb(120, 120, 0) # [0-255 rgb values]
l.rgb("#9af703") # Hex string
l.on()
l.off()
l.toggle()
l.alert() # short alert
l.alert("lselect") # long alert
l.setState({"bri": 220, "alert": "select"}) # Complex send
</code></pre>
<h2>The Long</h2>
<p>Philips Hue is a red/green/blue LED bulb and base-station system. The light
quality is nice but the bulbs are pricey ($60 per after the base station, which
is 3 bulbs and base for $200). You can also only buy them from apple right now,
which is totally crazy because they have an android app too. I assume this is
just a temporary exclusivity deal and they'll have wider availability soon.</p>
<p>As soon as I got them I wanted to hack them, the base station is ethernet on one
end (between apps, the philips website) and zigbee on the other (to talk to the lights)</p>
<p>The API to the base station is actually quite nice, very RESTful, and much easier
than the <a href="/blog/wemo-api-hacking/">Wemo API</a>. Straight HTTP over port 80 between
the apps and device, but disappointingly on one hand (security), nice on the other
(reverse engineering) also HTTP over port 80 to phone-home to two different Philips
sites.</p>
<h3>A typical request</h3>
<p>A typical request to the Philips Hue base station API looks like this:</p>
<pre><code>GET http://&lt;base station ip&gt;/api/&lt;client id string&gt;
</code></pre>
<p>This request returns the entire state of the system.  Mine is</p>
<pre><code>{
    "config": {
        "UTC": "2012-11-10T22:31:57", 
        "dhcp": true, 
        "gateway": "192.168.1.1", 
        "ipaddress": "192.168.1.130", 
        "linkbutton": false, 
        "mac": "&lt;mac is here&gt;", 
        "name": "Philips hue", 
        "netmask": "255.255.255.0", 
        "portalservices": true, 
        "proxyaddress": "", 
        "proxyport": 0, 
        "swupdate": {
            "notify": false, 
            "text": "", 
            "updatestate": 0, 
            "url": ""
        }, 
        "swversion": "01003542", 
        "whitelist": {
            "22a828f1898a4257c3f181e75324f557": {
                "create date": "2012-11-10T19:23:15", 
                "last use date": "2012-11-10T22:31:57", 
                "name": "python-hue"
            },
            ... # more client info
        }
    }, 
    "groups": {}, 
    "lights": {
        "1": {
            "modelid": "LCT001", 
            "name": "Hue Lamp 1", 
            "pointsymbol": {
                "1": "none", 
                "2": "none", 
                "3": "none", 
                "4": "none", 
                "5": "none", 
                "6": "none", 
                "7": "none", 
                "8": "none"
            }, 
            "state": {
                "alert": "none", 
                "bri": 20, 
                "colormode": "ct", 
                "ct": 369, 
                "effect": "none", 
                "hue": 14922, 
                "on": true, 
                "reachable": true, 
                "sat": 144, 
                "xy": [
                    0.4595, 
                    0.4105
                ]
            }, 
            "swversion": "65003148", 
            "type": "Extended color light"
        }, 
        "2": {
            "modelid": "LCT001", 
            "name": "Hue Lamp 2", 
            "pointsymbol": {
                "1": "none", 
                "2": "none", 
                "3": "none", 
                "4": "none", 
                "5": "none", 
                "6": "none", 
                "7": "none", 
                "8": "none"
            }, 
            "state": {
                "alert": "none", 
                "bri": 20, 
                "colormode": "ct", 
                "ct": 369, 
                "effect": "none", 
                "hue": 14922, 
                "on": true, 
                "reachable": true, 
                "sat": 144, 
                "xy": [
                    0.4595, 
                    0.4105
                ]
            }, 
            "swversion": "65003148", 
            "type": "Extended color light"
        }, 
        "3": {
            "modelid": "LCT001", 
            "name": "Hue Lamp 3", 
            "pointsymbol": {
                "1": "none", 
                "2": "none", 
                "3": "none", 
                "4": "none", 
                "5": "none", 
                "6": "none", 
                "7": "none", 
                "8": "none"
            }, 
            "state": {
                "alert": "none", 
                "bri": 254, 
                "colormode": "xy", 
                "ct": 153, 
                "effect": "none", 
                "hue": 34073, 
                "on": true, 
                "reachable": true, 
                "sat": 254, 
                "xy": [
                    0.3136, 
                    0.3297
                ]
            }, 
            "swversion": "65003148", 
            "type": "Extended color light"
        }
    }, 
    "schedules": {}
}
</code></pre>
<p>There are some interesting things in there, not the least of which being that it
has a "schedules" and "alert" function which is not available to the app.</p>
<p>You won't get this request the first time just by shooting a request to your base
with cURL, you first have to authenticate.</p>
<h3>Authentication</h3>
<p>The process looks like this:</p>
<ul>
<li>Try to send a normal request</li>
<li>Get the error message about authentication</li>
<li>Send a put request with your device information</li>
<li><ul><li>devicetype - some string</li></ul></li>
<li><ul><li>username - some hash (important that you keep it, python-hue uses the FQDN of your machine)</li></ul></li>
<li>Push the button on the Hue Base Station to approve the authentication.</li>
</ul>
<p>Example:</p>
<pre><code>curl -XPOST http://192.168.1.130/api/ -d '{"devicetype": "1337 client", "username": "22a828f1898a4257c3f181e753241337" }'
[{"error":{"type":101,"address":"/","description":"link button not pressed"}}]
# Go press the button!
curl -XPOST http://192.168.1.130/api/ -d '{"devicetype": "1337 client", "username": "22a828f1898a4257c3f181e753241337" }'
[{"success":{"username":"22a828f1898a4257c3f181e753241337"}}]
</code></pre>
<h3>Sending more requests</h3>
<p>Once you've authenticated, your device ID is in the URI of every request. It's an
interesting decision on the part of their API designers, but it works just fine
once you realize that's what's going on.</p>
<p>Examples:</p>
<pre><code>curl http://192.168.1.130/api/22a828f1898a4257c3f181e753241337/lights/3

{
    "modelid": "LCT001", 
    "name": "Hue Lamp 3", 
    "pointsymbol": {
        "1": "none", 
        "2": "none", 
        "3": "none", 
        "4": "none", 
        "5": "none", 
        "6": "none", 
        "7": "none", 
        "8": "none"
    }, 
    "state": {
        "alert": "none", 
        "bri": 254, 
        "colormode": "xy", 
        "ct": 153, 
        "effect": "none", 
        "hue": 34073, 
        "on": true, 
        "reachable": true, 
        "sat": 254, 
        "xy": [
            0.3136, 
            0.3297
        ]
    }, 
    "swversion": "65003148", 
    "type": "Extended color light"
}

curl -XPUT http://192.168.1.130/api/22a828f1898a4257c3f181e753241337/lights/3/state -d '{"bri": 0}'
[{"success":{"/lights/3/state/bri":0}}]

curl -XPUT http://192.168.1.130/api/22a828f1898a4257c3f181e753241337/lights/3/state -d '{"alert":"select"}'
[{"success":{"/lights/3/state/alert":"select"}}]
</code></pre>
<p>That's it!</p>
<p>Let me know if you're using it, or if you'd like to see more functionality out of the client,
File issues on Github, or let me know what else you'd like to see me write about.</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2012/08/04/wemo-api-hacking/</id>
    <title>WeMo API Hacking</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2012/08/04/wemo-api-hacking/"/>
    
    <updated></updated>
    <published>2012-08-04T23:00:00Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>WeMo Hacking part two!</p>
<p>In short! It works! miranda, with some tweaks and fixes is a good tool for tinkering with your Belkin WeMo switch with Python</p>
        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>WeMo Hacking part two!</p>
<p>In short! It works! miranda, with some tweaks and fixes is a good tool for tinkering with your Belkin WeMo switch with Python. I'd suggest starting with my toolkit here: <a href="https://github.com/issackelly/wemo">https://github.com/issackelly/wemo</a></p>
<p>The WeMo is communicating over pretty standard UPnP, though like anything else, it has some quirks. </p>
<p>It wanted a very specific namespace string for the SOAP envelope that contained a trailing slash and Miranda wasn't sending that. </p>
<p>I also added the same User-Agent that the mobile app uses for the HTTP (via UDP for UPnP) headers, and fixed the character encoding, and used consistent namespacing with the mobile app.</p>
<p>If you poke at Miranda you'll see that you should be able to figure out how to set schedules, and settings pragmatically through the SOAP interface, it's all there.</p>
<p>A simple session would go like this:</p>
<pre><code>rivendell:~/P/p/wemo [master] 
$ ./miranda.py 
upnp&gt; msearch

Entering discovery mode for 'upnp:rootdevice', Ctl+C to stop...

****************************************************************
SSDP reply message from 192.168.1.1:5431
XML file is located at http://192.168.1.1:5431/dyndev/uuid:0016-b639-af9e00408084
Device is running Custom/1.0 UPnP/1.0 Proc/Ver
****************************************************************

****************************************************************
SSDP reply message from 192.168.1.133:49153
XML file is located at http://192.168.1.133:49153/setup.xml
Device is running Linux/2.6.21, UPnP/1.0, Portable SDK for UPnP devices/1.6.6
****************************************************************

^CDiscover mode halted...

# You'll see that the first device found by miranda is my router, you can tell by the IP address, that leaves the other device as the WeMo
upnp&gt; host get 1 

Requesting device and service info for 192.168.1.133:49153 (this could take a few seconds)...

Host data enumeration complete!

upnp&gt; host send 1 controllee ### tab completion is very nice in miranda!
WiFiSetup        basicevent       firmwareupdate   metainfo         remoteaccess     rules            timesync         
upnp&gt; host send 1 controllee basicevent GetSerialNo 

SOAP request failed with error code: 500 Internal Server Error
SOAP error message: Action Failed

upnp&gt; host send 1 controllee basicevent GetBinaryState 

BinaryState : 1

upnp&gt; host send 1 controllee basicevent SetBinaryState 

Required argument:
    Argument Name:  BinaryState
    Data Type:      Boolean
    Allowed Values: []
    Set BinaryState value to: 2


upnp&gt; host send 1 controllee basicevent SetBinaryState

Required argument:
    Argument Name:  BinaryState
    Data Type:      Boolean
    Allowed Values: []
    Set BinaryState value to: 1


upnp&gt; host send 1 controllee basicevent SetBinaryState

Required argument:
    Argument Name:  BinaryState
    Data Type:      Boolean
    Allowed Values: []
    Set BinaryState value to: 0
</code></pre>
<p>If you want to use my utility on top of miranda, it <em>should</em> work for you. No promises
Get it from github: <a href="https://github.com/issackelly/wemo/zipball/master">https://github.com/issackelly/wemo/zipball/master</a></p>
<p>Open a shell and locate the wemo directory</p>
<pre><code>$ cd ~/Downloads/
$ unzip issackelly-wemo-1afe45d.zip
$ cd wemo
$ python
&gt;&gt;&gt; from wemo import on, off, get
&gt;&gt;&gt; on()
True
&gt;&gt;&gt; get()
True
&gt;&gt;&gt; off()
True
&gt;&gt;&gt; get()
False
</code></pre>
<p>Read through wemo.py to get a better understanding of scripting miranda. (again, start with my miranda.py, as it's tailored to the WeMo)</p>
<p>If you'd like to buy a WeMo, I'd certainly appreciate you using my referral link:</p>
<p><a href="http://www.amazon.com/gp/product/B0089WFPRO/ref=as_li_qf_sp_asin_il?ie=UTF8&amp;tag=isskel-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B0089WFPRO"><img border="0" src="http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;Format=_SL110_&amp;ASIN=B0089WFPRO&amp;MarketPlace=US&amp;ID=AsinImage&amp;WS=1&amp;tag=isskel-20&amp;ServiceVersion=20070822" /></a><br />
<a href="http://www.amazon.com/gp/product/B0089WFPRO/ref=as_li_qf_sp_asin_il?ie=UTF8&amp;tag=isskel-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B0089WFPRO">Belkin WeMo Switch</a>
<img src="http://www.assoc-amazon.com/e/ir?t=isskel-20&amp;l=as2&amp;o=1&amp;a=B0089WFPRO" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2012/07/30/wemo-hacking/</id>
    <title>Things I Know about the WeMo boxes</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2012/07/30/wemo-hacking/"/>
    
    <updated></updated>
    <published>2012-07-30T23:49:00Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I'm working on hacking my wemo. I'd like to determine how it talks back and forth over the network. 
What I know at this time is that when the mobile app is running both the mobile app and the wemo device are talking over UPnP</p>
        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I'm working on hacking my wemo. I'd like to determine how it talks back and forth over the network. 
What I know at this time is that when the mobile app is running both the mobile app and the wemo device are talking over UPnP</p>
<p><a href="http://www.amazon.com/gp/product/B0089WFPRO/ref=as_li_qf_sp_asin_il?ie=UTF8&amp;tag=isskel-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B0089WFPRO"><img border="0" src="http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&amp;Format=_SL110_&amp;ASIN=B0089WFPRO&amp;MarketPlace=US&amp;ID=AsinImage&amp;WS=1&amp;tag=isskel-20&amp;ServiceVersion=20070822" /></a><br />
<a href="http://www.amazon.com/gp/product/B0089WFPRO/ref=as_li_qf_sp_asin_il?ie=UTF8&amp;tag=isskel-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B0089WFPRO">Belkin WeMo Switch</a>
<img src="http://www.assoc-amazon.com/e/ir?t=isskel-20&amp;l=as2&amp;o=1&amp;a=B0089WFPRO" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></p>
<p>I had to turn off UPnP on my router to use the following tools. I determined the protocol was UPnP by jumping onto my DD-WRT router, installing tcpdump and capturing several packet dumps and examining them.</p>
<p>The best thing UPnP analysis tool I found was miranda. You can get it from the downloads page here:
<a href="http://code.google.com/p/mirandaupnptool/downloads/detail?name=miranda-1.0.tar.gz">Miranda</a></p>
<p>Under the covers it uses python twisted and Coherence:
<a href="http://coherence.beebits.net/">Coherence</a></p>
<p>Read more about miranda:
<a href="http://www.ethicalhacker.net/content/view/220/24/">Miranda Article</a></p>
<p>Some particulars:
<ul>
<li>The LOCATION of the services file doesn't change, http://host/setup.xml
</li><li>The PORT of the UPnP device does change, I've seen 49152-49154 so far
</li></ul></p>
<p>You'll see if you read the logs below that the host number changes, I had to keep restarting the program, rediscovering the device, and that changes the order in miranda.</p>
<p>I think with this I've got everything I need to start making requests</p>
<script src="https://gist.github.com/3214468.js"> </script>
<p>I had some issues with miranda printing out the whole device info that it gathered, I'm checking into that, but in the gist they are pulled out of python and pretty-printed:</p>
<p>I have two guesses at how things work with IFFT. I'll be exploring those soon and update the post.</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2012/03/13/pycon-scII-recap/</id>
    <title>PyCon Starcraft II Recap</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2012/03/13/pycon-scII-recap/"/>
    
    <updated></updated>
    <published>2012-03-13T00:00:01Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Saturday night we had the first PyCon Starcraft II Tournament. This was a joint effort between myself and <a href="https://twitter.com/#!/daniellindsley">Daniel Lindsley</a>, with the help of <a href="https://twitter.com/#!/mintchaos">Christian Metts</a>, the PyCon organizers (<a href="https://twitter.com/#!/dougnap">Doug Napoleone</a> in particular) and lots of open source software.</p>
        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Saturday night we had the first PyCon Starcraft II Tournament. This was a joint effort between myself and <a href="https://twitter.com/#!/daniellindsley">Daniel Lindsley</a>, with the help of <a href="https://twitter.com/#!/mintchaos">Christian Metts</a>, the PyCon organizers (<a href="https://twitter.com/#!/dougnap">Doug Napoleone</a> in particular) and lots of open source software.</p>
<p>16 competitors from unranked through platinum competed for next-to-nothing in prizes.<br />
</p><p>We ended up writing a bit of custom software to assist. We also started on Tuesday, so it was rougher than I would have liked. It's all up on <a href="https://github.com/issackelly/sc2tourney/">github.com/issackelly/sc2tourney</a>.</p>
<h3>Etc</h3>
<p>I promised some players that the first matches would be geared to be even. This means that you were probably likely to play your best competitor first. This is a stupid-ass way to run a competitive tournament, but really fun to play in-person matches with people you don't know. I believe that this setup was the inspiration for <a href="http://watbutton.com/">http://watbutton.com/</a></p>
<p>We also had a 'second try' bracket for those who lost in the first round. It quickly devolved because of the number of machines we had available to play.</p>

<p>Next time the brackets will be thought out.</p>
<h3>Favorite Match</h3>
<p>The favorite match will get a prize, so please cast a vote.</p>
<p>Please download and watch replays, and vote on a favorite game by reaching out to me on twitter or email issac.kelly@gmail.com.  Any suggestions I'll put up here.</p>
<h4><a href="http://pyconsc2.issackelly.com/sc2/match/">All Replays</a></h4>
<ul>
<li><a href="http://pyconsc2.issackelly.com/sc2/match/40/">http://pyconsc2.issackelly.com/sc2/match/40/</a> [1]</li>
<li><a href="http://pyconsc2.issackelly.com/sc2/match/14/">http://pyconsc2.issackelly.com/sc2/match/14/</a> [0] &lt;- I played here, so I'm not voting</li>
</ul>
<h3>Results</h3>
<p>The finals were commentated by <a href="https://twitter.com/#!/thauber">Tony Hauber</a> and <a href="https://twitter.com/#!/lazzlazzlazz">Eddie</a> -</p>
<h3>Finals: <a href="http://www.justin.tv/tonyhauber/b/311311166">http://www.justin.tv/tonyhauber/b/311311166</a> [skip to 2:00 for introductions, or 7:30 for the game]
</h3><h3><br /></h3>
<p><i>Highlight to see the Spoilers Below.</i></p>
<p><font color="#FFFFFF"><a href="https://twitter.com/#!/megakwood" style="color:white;">Kevin Wood</a> of Guidebook ended up winning the tournament in two games against PyPy, CPython and Django core developer <a href="https://twitter.com/#!/alex_gaynor" style="color:white;">Alex Gaynor</a>. Alex was seeded almost last, it was a pretty wild set of games and I suggest you watch the replays if you're into that sort of thing.</font><br /></p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2011/03/16/On_Django_Migrations_South_vs_Na/</id>
    <title>On Django Migrations: South vs Nashvegas</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2011/03/16/On_Django_Migrations_South_vs_Na/"/>
    
    <updated>2011-06-24T02:14:34Z</updated>
    <published>2011-03-16T23:49:00Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            3... 2.. 1.. Draw

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>If you're writing your models with Django and not using migrations, that's crazy.</p>
<p>South and Nashvegas are two options for managing your migrations (really the only two I've ever heard of in practice). &nbsp;I use both, almost daily.</p>
<p>Nashvegas, is far and away the newer and lesser used. &nbsp;It doesn't do backwards migrations at all, and migrations are DB specific (although, much SQL is close enough that you can still use many migrations on other databases). &nbsp;That being said, it does one thing really well that south doesn't touch: your whole project. &nbsp;</p>
<p>South is app-centric, not project-centric. &nbsp;Much care has been made to make sure that you can start using south on your app part-way through development, where Nashvegas should really be used from the start. &nbsp;Converting to Nashvegas with a team requires though and planning, and with South, it requires one management command from each person (per app).</p>
<p>My "Daily Driver" is South, but it will be interesting to see if and where NashVegas gains momentum.</p>
<p>&nbsp;</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2010/08/14/Things_to_Love_about_Geektime/</id>
    <title>Things to Love about Geektime</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2010/08/14/Things_to_Love_about_Geektime/"/>
    
    <updated>2010-08-14T14:19:14Z</updated>
    <published>2010-08-14T13:56:00Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            The old 0x8B00 to 0xE000

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>The idea behind <a href="http://geektime.org" target="_blank">geektime</a> is to fit the seconds in the day into 4 bytes (65536 geekseconds in a day, instead of 86400 old seconds).<br /><br />This, initially seems like the musings of a sleep deprived geek, and, it possibly is. &nbsp;The stroke of genius in geektime is that it implies a timezone (UTC).</p>
<p>Days are just marked as an ascending date from Jan 1 (in UTC).</p>
<p>Djangodash is this weekend. &nbsp;It started at 0x0E0 0x3580 and it will end on 0x0E2 0x3580.</p>
<p>There is no longer confusion, or the possibility to skip over the quantifier (UTC -6...actually UTC -5 because it's daylight savings time in Central Time... Who started late?) because it's all implied.<br /><br />I've also found that it's a genius way to coordinate across timezones (airlines should pick it up.. or rather, I'd love a chrome extension to fix the times on southwest.com). &nbsp;"I'll be back online in the morning" becomes "I'll be back online at 0x09" You lose all ambiguity.<br /><br />I encourage you to try out geektime for a week if you ever deal with anything in a different timezone.</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2010/05/18/State_of_Affairs/</id>
    <title>State of Affairs</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2010/05/18/State_of_Affairs/"/>
    
    <updated>2010-05-18T17:57:30Z</updated>
    <published>2010-05-18T17:53:00Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            Things are swell!

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I've been writing at <a href="http://www.kellycreativetech.com/blog">kellycreativetech.com/blog</a> lately, (ok, once) and this has been largely abandoned.<br /><br />We're working on some very cool things:<br /><br />A new version of our killer software <a href="http://www.servee.com">Servee</a> on top of the excellent platform Django. &nbsp;</p>
<p>Some excellent volunteer management tools (albeit a bit under wraps for now)</p>
<p>and <a href="http://www.shotblox.com/home/">ShotBlox</a> [blogs for photographers]</p>
<p>Too busy to write here. &nbsp;It's probably going to turn back into a personal site, as I've quit doing individual consulting and contracting in favor of working through <a href="http://www.kellycreativetech.com">KCT</a>.&nbsp;</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/04/24/In_School_Broadband_and_Ohio_HB-/</id>
    <title>In School Broadband and Ohio HB-4</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/04/24/In_School_Broadband_and_Ohio_HB-/"/>
    
    <updated>2009-04-24T14:09:23Z</updated>
    <published>2009-04-24T13:57:47Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I have found that I have a strong passion for education.&nbsp; To some of my closest friends that may come as a surprise, because I dropped out of high school and college, expressing a large amount of disdain along the way.&nbsp; I've found that largely my disdain came from school and classroom bureaucracy that gets in the way of learning.</p>
<p>Students need broadband.&nbsp; I firmly believe this.&nbsp; Depriving them of that is crazy.&nbsp; Students don't need facebook or flash games.&nbsp; They need TED talks and Wikipedia.</p>
<p><a href="http://tech4ohio.org/hb4.php" target="_blank">Please Support HB-4.&nbsp; Send the Education Committee your thoughts.</a></p>
<p>Representative,&nbsp; <br /><br />I am in strong support of the distance learning project HB 4<br />&nbsp;<br />I left my High School because there were not enough opportunities.&nbsp; I then left College, and pursued much my learning through online sources, and have now started a Columbus Ohio Small Business in the Technology field.&nbsp; This worked in my situation but I have also seen many advanced and remedial students not given the opportunities that they need.&nbsp; Advanced access to broadband could help that significantly.&nbsp; Since High School, the majority of my learning has been online.&nbsp; <br /><br />The statistic quoted to me was that 28% of ohio high schools have 1.5Mbs of Bandwidth or less.&nbsp; That is ridiculous.&nbsp; In my home I have 7Mbs of bandwidth for just me.&nbsp; I'm sure in your home, you have 768kbs (.7Mbs) AT LEAST.&nbsp; <br /><br />These days, not giving students (fast) access to the internet is like not giving them textbooks.&nbsp; <br /><br />Support HB 4. <br /><br />Sincerely, <br />Issac Kelly<br />&lt;addresss&gt;</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/03/20/Please_upgrade_your_Internet_Exp/</id>
    <title>Please upgrade your Internet Explorer</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/03/20/Please_upgrade_your_Internet_Exp/"/>
    
    <updated>2009-03-20T13:55:13Z</updated>
    <published>2009-03-20T13:27:06Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            Please Pay attention if you're on Windows XP or Below

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Please, Please, Please Quit using Versions of Internet Explorer Less than IE 7.<br /><br />Please send this to all of your friends and relatives, and even the people who you don't like.<br /><br />Internet Explorer 6 came out in August of 2001.&nbsp; By most business standards, this might not seem like a long time, but by my Industry Standards, that's like driving a car from the 1980's.&nbsp; With IE6, it's not just any old car, it is The Pinto, without the safety kit.</p>
<p>Now, <a href="http://ie8.msn.com">IE 8</a> has just launched, so if you're using IE 6, you're two free upgrades behind everybody else.&nbsp;</p>
<p>There are also lots of BETTER free options, like <a title="Firefox 3" href="http://getfirefox.com" target="_blank">Firefox</a>, <a title="Chrome" href="http://www.google.com/chrome" target="_blank">Chrome</a>, and <a title="Safari" href="http://www.apple.com/safari/" target="_blank">Safari</a>.<br /><br />Please switch to one of these as your primary browser.&nbsp; You'll find a faster, more secure, better looking internet in there.&nbsp; I promise.<br /><br />What questions do you have about upgrading? Ask them here! Please! If something is keeping you from upgrading, tell me about it.</p>
<p><a href="http://bringdownie6.com"><img src="http://www.netmag.co.uk/files/bd.png" alt="bringdownie6" /></a></p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/03/12/Amazon_Web_Services_Resources/</id>
    <title>Amazon Web Services Resources</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/03/12/Amazon_Web_Services_Resources/"/>
    
    <updated>2010-07-28T20:26:32Z</updated>
    <published>2009-03-12T17:58:00Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            Compiled for my presentation at the Columbus PHP Meetup

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p><a href="http://aws.amazon.com" target="_blank">AWS Home</a></p>
<p>EC2 Tools</p>
<ul>
<li><a href="http://www.hens-teeth.net/html/products/cross_browser_testing.php" target="_blank">Browser Testing</a></li>
<li>Dimdim (contact me for details..not public yet)</li>
<li><a href="http://developer.amazonwebservices.com/connect/entry.jspa?entryID=609" target="_blank">ElasticFox</a></li>
<li><a href="http://wiki.apache.org/hadoop/AmazonEC2" target="_blank">Hadoop on EC2</a></li>
<li><a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=442" target="_blank">PHP EC2 Manager</a></li>
</ul>
<p>S3 Tools</p>
<ul>
<li><a href="http://www.panic.com/transmit/" target="_blank">Transmit (Mac)<br /></a></li>
<li><a href="https://addons.mozilla.org/en-US/firefox/addon/3247" target="_blank">S3Fox</a></li>
<li><a href="http://www.cloudberrylab.com/default.aspx?id=7" target="_blank">S3 Explorer (Windows)</a></li>
<li><a href="http://undesigned.org.za/2007/10/22/amazon-s3-php-class" target="_blank">PHP Classes</a></li>
</ul>
<p>Slides</p>
<div id="__ss_1138077" style="width: 425px; text-align: left;"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" title="Introduction to Amazon Web Services for Developers and System Administrators" href="http://www.slideshare.net/issackelly/introduction-to-amazon-web-services-for-developers-and-system-administrators?type=presentation">Introduction to Amazon Web Services for Developers and System Administrators</a>
<object style="margin:0px" width="425" height="355" data="http://static.slideshare.net/swf/ssplayer2.swf?doc=phpmeetupaws-090312153316-phpapp01&amp;stripped_title=introduction-to-amazon-web-services-for-developers-and-system-administrators" type="application/x-shockwave-flash">
<param name="allowFullScreen" value="true">
</param><param name="allowScriptAccess" value="always">
</param><param name="src" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=phpmeetupaws-090312153316-phpapp01&amp;stripped_title=introduction-to-amazon-web-services-for-developers-and-system-administrators">
</param><param name="allowfullscreen" value="true">
</param></object>
<div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/issackelly">issackelly</a>.</div>
</div>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/03/02/Startup_Lessons_Find_your_audien/</id>
    <title>Startup Lessons: Find your audience</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/03/02/Startup_Lessons_Find_your_audien/"/>
    
    <updated>2009-03-02T04:41:20Z</updated>
    <published>2009-03-02T04:41:20Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/31/My_Twitter_Notebook_is_Open_Sour/</id>
    <title>My Twitter Notebook is Open Source</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/31/My_Twitter_Notebook_is_Open_Sour/"/>
    
    <updated>2009-01-31T21:45:48Z</updated>
    <published>2009-01-31T21:34:44Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p><a href="http://www.mytwitternotebook.com" target="_blank">My Twitter Notebook</a> is now open source. I'd like to see what other people would do with it, given the opportunity.</p>
<p>It's hosted at github and the url is <a href="http://github.com/issackelly/my-twitter-notebook/" target="_blank">http://github.com/issackelly/my-twitter-notebook/</a></p>
<h3>My Twitter Notebook: The Story.</h3>
<p>I'd like to start off by saying: I'm not an organized person.&nbsp; I get by pretty well with lists, but overall I don't plan things more than a week in advance, and I don't do a good job remembering things for more than a few days at a time.&nbsp; I decided that I wanted to get better about that, but didn't know where to start.&nbsp; I bought a scanner, and that has helped tremendously; I've also started keeping lists and making quick short notes (I was never much for taking notes, school or otherwise).&nbsp; For that end, I wanted to use my cell phone (calls and text messages only though) to take notes.&nbsp; I thought that I could e-mail myself or DM my own twitter account, but that was a little too primitative, because notes are only good to me if I can search through them, browse, tag, etc as they happen.<br /><br />I made my twitter notebook in the first couple days of 2009, and I've been very happy with it.&nbsp; Since then, it's made some "Top xx" lists, and also been mentioned (as an aside really) on an <a href="http://www.msnbc.msn.com/id/28623823/" target="_blank">MSNBC</a> blog.</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/29/Task_And_Time_Management/</id>
    <title>Task And Time Management</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/29/Task_And_Time_Management/"/>
    
    <updated>2009-01-29T21:24:35Z</updated>
    <published>2009-01-29T21:08:10Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I'm tinkering with how to manage my tasks and my time.<br /><br />I'd sort of like a system where I can name all of my tasks, and then sort out into a couple of different columns, really, a cross between <a href="http://www.rescuetime.com/" target="_blank">rescue time</a>, gmail, and <a href="http://www.tweetdeck.com/beta/">tweetdeck</a>, if that makes any sense.<br /><br />Things that I'd like to be able to do:</p>
<ul>
<li>Name a Project, and list the 'next task' as well as a list of all tasks associated with the project.&nbsp; </li>
</ul>
<ul>
<li>For any given task, I'd like to be able to have tags like 'location' 'waiting on' 'time estimate' 'due', typical stuff.</li>
<li>I'd like a timer, one that counts up when I hit start, and when I hit stop, I assign the time to task(s).</li>
</ul>
<p>How do you manage your time and tasks?&nbsp; A fair amount of this functionality is included with fogbugz, but the interface for it is clunky, as it's really only made to be a bug tracker and software planner, not a general task/time manager.<br /><br />What would help you to do this? What sorts of input/output mechanisims would it need? Reports, etc?<br /><br />I'd like to make this happen, and I'm willing to do it open-source if I get some help.</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/24/What_does_my_app_need_to_be_succ/</id>
    <title>What does my app need to be successful...</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/24/What_does_my_app_need_to_be_succ/"/>
    
    <updated>2010-07-28T20:54:52Z</updated>
    <published>2009-01-24T14:08:00Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Yesterday, on one of my favorite news sites, <a href="http://hackernews.com" target="_blank">hacker news</a>; Someone asked "What does my twitter app need to be successful in 8 days".&nbsp; It was in reference to a twitter mashup made for the two teams playing in the Super Bowl next weekend.&nbsp; You can see it <a href="http://www.twitterbowl2009.com/">here</a>.<br />The responses were mostly negative, 'get a less obnixous design', 'solve a problem people have', 'cleveland isn't even in the superbowl'&lt;--which you have to look pretty closely to even notice why this is criticism.</p>
<p>All of the criticism was unfounded.&nbsp; What exists is a niche app with a limited lifespan.&nbsp; Spending money on a professional designer or photography you didn't take yourself seems exorbitent.</p>
<p>Lots of apps 'don't solve a problem people have'. Many of the iPhone app store apps don't solve any real problems, honestly, who needs an application to make fart noises?</p>
<p>So, if you're into football and social media, see what other people are saying about Arizona and Pittsburgh for the next week or so.&nbsp; If not, don't worry about it.<br /><br />When it comes down to it, what an application needs to be successful isn't design, or solving problems, it's usually just <em>getting in front of people</em>. Lots of beautiful utilitarian tools get underutilized, and lots of ugly useless crap gets lots of attention, money, and users; the difference is people.<br /><br />What's your favorite ugly or uselsess app? Mine is minesweeper.</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/23/Site_Design_2009/</id>
    <title>Site Design 2009</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/23/Site_Design_2009/"/>
    
    <updated>2009-01-23T20:24:16Z</updated>
    <published>2009-01-23T20:21:05Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>From <a href="http://www.kkellydesign.com" target="_blank">Kasey</a>, who can't keep his hands off of a design for more than 12 months given the opportunity, comes the new design, which I like a lot.</p>
<p>With that, I've added much more emphasis on my blog (its the homepage) utilized servee's display rule functionality to make it beautiful, and removed my resume (not looking for work...plenty happy with <a href="http://www.servee.com" target="_blank">servee</a> :)</p>
<p>What do you think?</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/20/Demand_More_from_your_Website/</id>
    <title>Demand More from your Website</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/20/Demand_More_from_your_Website/"/>
    
    <updated>2009-02-25T18:11:15Z</updated>
    <published>2009-01-20T15:10:34Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>If you're like any of the dozens of business owners or organization leads that I meet with week in and week out; then you don't give a second thought to the business that you are losing online every day.<br /> <br /> Let me tell you a story:<br /> <br /> A business owner I know in South-east Ohio was looking for a mobile paper shredding service.<br /> She delegated the task to an intern, who immediately went to Google; They hired the company from a hit on a website, without ever opening the yellow pages.<br /> The company had good reviews from clients, and a local phone number.&nbsp; The business owner was astounded that they didn't come from the yellow pages.<br /> <br /> In the homes of most of my colleagues, the yellow pages are sitting firmly beneath some heavy door, and have been for years.<br /> <br /> Friends, the internet is now truly everywhere and if you don't have a website, you're not in the game.<br /> <br /> In 1998, to have an internet presence was 'pretty cool' for the typical Small or Medium company but you wouldn't see any new volume from it.<br /> In 2000, it seemed like you could find anything online;<br /> By 2005, if you didn't have a website, people noticed and<br /> In 2009, if your website isn't working for you; then it's working against you.<br /> <br /> The good news is that its simple to get _more_ from your website.<br /> <br /> If you don't have a website or need help figuring this stuff out; <a href="/Contact_Me">contact me</a> to get you started, and do not be dismayed because it's often easier to start from scratch.<br /> <br /> Here are the <strong>five simple rules</strong> of getting more out of your website</p>
<ol>
<li>Make your website easy to use </li>
<li>Make your website easy to find and search </li>
<li>Give something back and create an audience </li>
<li>Gather as much data as possible </li>
<li>Convert audience to clients </li>
</ol>
<p><br /> <strong>Make your website easy to use<br /> Your website is the face of your business; If your website is cumbersome, and flashy, but has nothing to offer, that's going to reflect on your work.<br /> Anyone can make a website with off-the-shelf software; This is fine if you want to show off your great-uncle's fishing lure collection, but please, don't do this to your business.<br /> There is a lot that goes on behind-the-scenes of the initial set-up of a website that requires professional attention and expertise to make it easy to use, easy to navigate, accessible to people with disabilities, and ultimately, effective at converting visitors to clients.<br /> <br /> That being said, some web-professionals will want to bring you back in for every piddly update;&nbsp; This means that when your staff or product changes at all, you would pay them high hourly rates to make minor adjustments.<br /> Part of having a website that is easy to use, is the ability to easily make updates;&nbsp; Work with a web-professional to get your site setup with simple tools for managing your website.<br /> <br /></strong></p>
<ul>
<li><strong> Make sure that every page has one clear objective and contains only enough content to get your point across;&nbsp; Audiences on the internet don't read, they skim.&nbsp; </strong></li>
</ul>
<p><strong><br /> </strong><strong>Make your website easy to find and search<br /> There are lots of things you can do here, and this is another area where getting a professional to do the initial leg work (and using software to maintain it behind-the-scenes) is of vital importance.<br /> As the one who oversees the website you have to do the following things:<br /> <br /> </strong><strong>Non-Technical Things <br /> <br /></strong></p>
<ul>
<li><strong></strong><strong></strong><strong> Add your website to the footer or by-line of your e-mails and community forms (where allowed); you can do this automatically in outlook, Apple Mail, or Gmail<br /> Here is an example<br /> From: Issac Kelly &lt;issac@servee.com&gt;<br /> To: Josh Boles &lt;josh@joshboles.com&gt;<br /> Subject: Project Management<br /> <br /> Josh,<br /> <br /> What are you using for project management? I've been looking around for something web-based.&nbsp; Thanks<br /> --<br /> Issac Kelly<br /> servee.com<br /> -------------------<br /> <br /> This is a simple step that increased my website visitors by 10%. You're sending a message that says "There is more info about my business here" and its some of the least obtrusive, and cost-effective self-promotion you can do. </strong></li>
<li><strong></strong><strong></strong><strong> Make sure that your website is on the print materials you already use; This is a no-brainer.&nbsp; No matter what you're advertising you should be able to point curious people to more information online. There are really limitless possibilities here that are beyond the scope of this paper. </strong></li>
<li><strong></strong><strong></strong><strong> Make lots of content; put up FAQs and hilarious videos about your industry;&nbsp; Become the expert, the place that people go; and link to.&nbsp; The more people that link to your site, the better for your search engine rankings CAVEAT: </strong><strong>Do Not</strong> pay people to link to your site; this is considered cheating, and will get you banned from the search engines. </li>
<li><strong></strong><strong></strong><strong> Comment on other people's sites and blogs in your industry or locale.&nbsp; Build up your reputation, and on most places where you can comment, you can also leave a link. </strong></li>
</ul>
<p><strong></strong><strong></strong><strong><br /> </strong><strong>Technical Things<br /> <br /> </strong></p>
<ul>
<li><strong></strong><strong></strong><strong></strong><strong> Make sure your site has good titles on every page<br /> Example of a bad title: 'Page 14'<br /> Example of a good title: 'FAQ - Widget Consulting, Madison WI' </strong></li>
<li><strong></strong><strong></strong><strong></strong><strong> Make sure your site has good urls<br /> Example of a bad url:<br /> http://www.a-fake-site.com/controller.asp?page=14&amp;time=11233239&amp;aspsessid=9384089&amp;referrer=http://www.failblog.com/&amp;more=things<br /> Example of a good url:<br /> http://www.clevelandmarathon.com/Registration/ </strong></li>
<li><strong></strong><strong></strong><strong></strong><strong> Make sure that your software or website includes a file for search engines called 'sitemap.xml'&nbsp; This is different than the sitemap for your users, this is just for search engines, and good web-management generates this automatically </strong></li>
<li><strong></strong><strong></strong><strong></strong><strong> Ask an independent web-professional to take a quick look at the code of your website; tell them you're concerned with accessability and you want to know if you have semantic markup.<br /> Semantic markup enables search engines and people with disabilities to use computer tools to read through your website.&nbsp; </strong></li>
</ul>
<p><strong></strong><strong></strong><strong></strong><strong><br /> Again, this is the bare bones of what you need to know, and there is a lot more that is well beyond the scope of this document.<br /> <br /> </strong><strong>Give something back and create an audience<br /> <br /> You, have the opportunity to provide a service through your website that can be mutually beneficial to you and your visitors.<br /> <br /> Let's explore one option, create a 'question and answer' service.&nbsp; On your website promote a page that says 'Ask the expert!'; direct your other forms of marketing online, as it's often the quickest and easiest way for your potential customers to explore your organization and its message.<br /> Allow visitors to submit questions to you, for you to answer.&nbsp; Whatever your profession is, people have questions about it. For you, an expert in your field, to be able to answer them provides credibility, adds to your reputation, and ultimately, will increase the visitors to your site and turn into increased sales.<br /> <br /> The second benefit of a question and answer service is for your website to increase rank in google's search engine and show up in more results.<br /> If you are answering specific questions, the first thing that most people will do is search google for their question; if you come up, and answer their question, you will get increased visitors, and again, increased sales.<br /> <br /> </strong><strong>Gather As Much Data as Possible<br /> <br /> Step 1) Use an analytics package provided as part of your website setup, or use a third party.<br /> Analytics packages will track where your visitors are coming from, what they searched to get to your site, what they looked at, which region they live in, and many many more aspects.&nbsp; These are key to determining if your website is effective or not.&nbsp; <br /> <br /> Step 2) Make it easy, and give users an incentive to submit their data, build up an e-mail list, and use it.<br /> <br /> <br /> </strong><strong>Convert your audience to clients<br /> <br /> This is the most important step, but if you've done the rest right, it's the easiest.<br /> <br /> You've got an audience, you have dozens or hundreds of people coming to your site each week to get information; you've gotten many of them to give you <em>permission</em> to contact them personally, now what?<br /> <br /> This is where you get back to the basics, and the personalized approach that you take to your small business becomes your most valuable asset again.&nbsp; You let them know about promotions that you're giving to your mailing list, you offer incentives to come in (10% off tire alignment if you say 'thanks for the e-mail Mark!')<br /></strong></p>
<h2><strong></strong><strong></strong><strong></strong><strong></strong><strong></strong><strong></strong><strong></strong><strong>More Info</strong></h2>
<p><strong></strong><strong></strong><strong></strong><strong></strong><strong></strong><strong></strong><strong><br /> For questions, or how to get started with any of these things, e-mail me at <a id="r7xu" title="issac@servee.com" href="mailto:issac@servee.com">issac@servee.com</a></strong></p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/How_to_use_your_new_iPod_or_iPho/</id>
    <title>How to use your new iPod or iPhone</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/How_to_use_your_new_iPod_or_iPho/"/>
    
    <updated>2009-01-11T20:09:10Z</updated>
    <published>2009-01-11T20:10:22Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>My new (second) mom and dad (<a href="http://www.mariakellydesign.com">Maria</a>'s Parents) both got iPods for Christmas this year (actually, dad's was won in a raffle months ago, but they just got a computer with a working USB port..)</p>
<p>I thought I'd put this together for reference, beyond the typical, 'setup your iPod, buy from the iTunes store'</p>
<h3>Put your CDs into iTunes (then your iPod)</h3>
<p>Just because you got an iPod, doesn't mean you have to ditch your current collection of CDs</p>
<p><em>Here's What you do</em></p>
<p>Open up iTunes and put one of your favorite CDs into your computer. Chances are high that iTunes will start 'ripping' your CDs automatically, if not, click the cd icon and then click 'import'. The default settings are 'pretty good' for not using a lot of space, and keeping good music quality. You can change these in the iTunes settings, under 'Advanced-&gt;Importing'</p>
<h3>Listen To Podcasts</h3>
<p>Podcasts are like on-demand radio broadcasts and shows. You can subscribe to exactly what you want, and major players like NPR give out their content for free.</p>
<p><em>Here's What you Do</em></p>
<p>First click on the podcast button in iTunes, then click on 'Podcast Directory' Now you've made your way into the realm of podcasts, you can browse and subscribe to as many as you want. After you've subscribed to a few, right click on your iPod icon and change the settings. You want to go to the podcast tab and choose which ones you want on your iPod, typically the newest ones.</p>
<h3>Buy Books from Audible</h3>
<p>You can get a subscription to audible to listen to audio books, or buy one book at a time at a typical rate.</p>
<p><em>Here's What you do</em></p>
<p>Buy a book or subscription from them, and there are detailed instructions on how to get them on your iPod or iPhone.</p>
<p>&nbsp;</p>
<p>What other tips do you have for using a new iPod to it's fullest? Put them in the comments</p>
<p>&nbsp;</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/Hands_on_with_Small_Basic/</id>
    <title>Hands on with Small Basic</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/Hands_on_with_Small_Basic/"/>
    
    <updated>2009-01-11T20:09:09Z</updated>
    <published>2009-01-11T20:10:21Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            or Encode and Decode messages to your friends!

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I started playing with small basic last night.<br /><br />Turns out, it's a very good introduction to programming (I started with JavaScript, then C++, and this is much more simple/powerful in the early stages)<br />It's very similar in syntax to ASP or VB.</p>
<p>Since it's a variant of Basic, it has some things that I'm not a fan of (goto), but really, I won't hold that against it, goto makes sense in english, so it makes sense for a beginning language.<br /><br />I took a few minutes and downloaded small basic, .Net 3.5 and the getting started guide from: <a href="http://msdn.microsoft.com/en-us/devlabs/cc950524.aspx" target="_blank">http://msdn.microsoft.com/en-us/devlabs/cc950524.aspx</a></p>
<p>It was simple to setup, and the guide was definitely directed to the absolute beginer. *(sort of frustrating for their lack of documentation)<br /><br />Here is my first small basic program:<br />It does trivial encoding and decoding.&nbsp; Encode a message with a passcode, and send it to a friend, who can then decode it with the same passcode.<br />This is also a primer on how 'shared-key encryption' works.</p>
<p>&nbsp;</p>
<blockquote>
<p>start:<br />TextWindow.Write("(E)ncode or (D)ecode ")<br />a = TextWindow.Read()<br />If (a = "E") Then<br />&nbsp;&nbsp;&nbsp; TextWindow.Write("String to Encode ")<br />&nbsp;&nbsp;&nbsp; estring = TextWindow.Read()<br />&nbsp;&nbsp;&nbsp; TextWindow.Write("Encryption Key ")<br />&nbsp;&nbsp;&nbsp; password = TextWindow.Read()<br />&nbsp;&nbsp;&nbsp; t = Network.GetWebPageContents("http://www.issackelly.com/string.php?action=encode&amp;string="+estring+"&amp;key="+password)&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; TextWindow.WriteLine(t)<br />&nbsp;&nbsp;&nbsp; Goto start<br />Else<br />&nbsp;&nbsp;&nbsp; If (a = "D") Then<br />&nbsp;&nbsp;&nbsp; TextWindow.Write("String to Decode ")<br />&nbsp;&nbsp;&nbsp; estring = TextWindow.Read()<br />&nbsp;&nbsp;&nbsp; TextWindow.Write("Encryption Key ")<br />&nbsp;&nbsp;&nbsp; password = TextWindow.Read()<br />&nbsp;&nbsp;&nbsp; t = Network.GetWebPageContents("http://www.issackelly.com/string.php?action=decode&amp;string="+estring+"&amp;key="+password)&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp; TextWindow.WriteLine(t)<br />&nbsp;&nbsp;&nbsp; Goto start<br />&nbsp;&nbsp;&nbsp; EndIf<br />EndIf</p>
</blockquote>
<p>What you wil notice is Network.GetWebPageContents(....&nbsp; I didn't actually do the encoding or decoding with small basic.&nbsp; It lacked the basic math or character functions that I needed, so I had to fill in the gaps with PHP (I could have written an extension, but the documentation is too sparce)</p>
<p>So, here is my challenge.&nbsp; Can you guess what I did to encrypt the string?<br /><br />I'll give a free year of <a href="http://www.servee.com" target="_blank">servee</a> hosting and subscription to the first person who figures it out in the comments.<br /></p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/In_Defense_of_jQuery/</id>
    <title>In Defense of jQuery</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/In_Defense_of_jQuery/"/>
    
    <updated>2009-01-11T20:09:08Z</updated>
    <published>2009-01-11T20:10:20Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Not that it doesn't stand up on its own right, but I have to throw my $0.02 in.</p>
<p>I came across this article on '<a href="http://juliocapote.com/post/52467447/why-mootools-or-why-not-jquery" target="_blank">why mootools and not jquery</a>' from Julio Capote in my feed this morning.</p>
<p><br />I'm going to do a point by point here.</p>
<ol>
<li><strong>Classes</strong>: "Eventually you'll want real classes to structure your UI logic". While This is what you want, the better I get at jQuery the more I use chaining. I also lean toward functional programming and not OO programming, so...yeah. I'm just saying that this isn't necessarily a global drawback as much as a design choice.</li>
<li><strong>Learning Curve</strong>: I buy that learning jQuery takes a bit of practice, but again, I see it as a preference thing, because before jQuery, to me 'regular javascript' just wasn't that good</li>
<li><strong>Speed</strong>: jQuery IS faster.</li>
<li><strong>Animations</strong>: I don't do animations much.. but in my experience jQuery's have been...sufficient.  Moo Tools animations do look pretty good</li>
<li><strong>New Element Creation</strong>: Making a new element _is_ easy: $("&lt;a href='http://www.servee.com'&gt;done&lt;/a&gt;");</li>
<li><strong>Modularity</strong>: Mootools is modular..you can get the libraries you need:&nbsp; You can do this with jquery from SVN...but when&nbsp; the whole library is 12kbs I think it's really unnecessary.</li>
<li><strong>The Documentation</strong>: I've never checked out the mootools documentation, My experience with jQuery doc has been very good, and my experience with the #jquery on <a href="http://irc.freenode.net/">irc.freenode.net</a> has been very good as well</li>
<li><strong>Extensibility</strong>: I haven't done anything outside of 'basic usage' with mootools, but jquery isn't an 'unintelligible mess' by any means.</li>
<li><strong>Namespace vs Prototype</strong>: Yeah, this is just preference, but unobtrusive (Namespace/jQuery) is worth it, especially if you have to have two versions of the same library on a page.</li>
<li><strong>Final</strong>: I for one welcome our new namespaced overlords.</li>
</ol>
<p>&nbsp;</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/Sample_Agreement_Generator/</id>
    <title>Sample Agreement Generator</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/Sample_Agreement_Generator/"/>
    
    <updated>2009-01-11T20:09:06Z</updated>
    <published>2009-01-11T20:10:18Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Here is another post about some little tool I've made..</p>
<p>This one will take a set of checkboxes and radio buttons (anywhere on a page, doesn't have to be in a table or anything) and turn it into a block of text.<br /><br />Caveat:&nbsp; you can't have any other checkboxes or radio buttons on the page with this snippet, it will behave poorly.</p>
<p>Check out the source below to see how it works.&nbsp; 21 Lines long, the value="" can be as long as you want.&nbsp; Post a comment if you have any questions.<br /><br />This could be used for any type of text generation.</p>
<table border="0">
<tbody>
<tr>
<td><input type="checkbox" value="This is a long paragraph of text that explains this part of the agreement" /></td>
<td>Sample</td>
</tr>
<tr>
<td><input name="1A" type="radio" value="A paragraph of text explaining that the client gets the code. A paragraph of text explaining that the client gets the code. A paragraph of text explaining that the client gets the code. A paragraph of text explaining that the client gets the code. A paragraph of text explaining that the client gets the code A paragraph of text explaining that the client gets the code." /></td>
<td>Client gets the code</td>
</tr>
<tr>
<td><input name="1A" type="radio" value="I get this code!!! I get this code!!! I get this code!!! I get this code!!! I get this code!!! I get this code!!! I get this code!!! I get this code!!! I get this code!!! " /></td>
<td>I get the code</td>
</tr>
</tbody>
</table>
<p>Agreement<br /> <textarea id="agreement" cols="40" rows="6"></textarea> <br /><br /> <button onclick="process()">Process</button>
<script type="text/javascript">&lt;!--
function process()
{
   var agr = "";
   $("input:checked").each(function(i){
   agr += $(this).val() + "\n\n";
   });
   $("#agreement").val(agr); 
}
// --&gt;</script>
</p>
<blockquote>&lt;script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.2.6.pack.js"&gt;&lt;/script&gt; &lt;table&gt; &lt;tr&gt;&lt;td&gt;&lt;input type="checkbox" value="This is a long paragraph of text that explains this part of the agreement" /&gt;&lt;/td&gt;&lt;td&gt;Sample&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td&gt;&lt;input type="radio" name="1A" value="A paragraph of text explaining that the client gets the code. A paragraph of text explaining that the client gets the code. A paragraph of text explaining that the client gets the code. A paragraph of text explaining that the client gets the code. A paragraph of text explaining that the client gets the code A paragraph of text explaining that the client gets the code." /&gt;&lt;/td&gt;&lt;td&gt;Client gets the code&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt;&lt;td&gt;&lt;input type="radio" name="1A" value="I get this code!!! I get this code!!! I get this code!!! I get this code!!! I get this code!!! I get this code!!! I get this code!!! I get this code!!! I get this code!!! " /&gt;&lt;/td&gt;&lt;td&gt;I get the code&lt;/td&gt;&lt;/tr&gt; &lt;/table&gt; Agreement&lt;br /&gt; &lt;textarea rows="6" cols="40" id="agreement"&gt;&lt;/textarea&gt; &lt;br/&gt;&lt;br/&gt; &lt;button onclick="process()"&gt;Process&lt;/button&gt;  &lt;script type="text/javascript"&gt; function process() {    var agr = "";    $("input:checked").each(function(i){    agr += $(this).val() + "\n\n";    });    $("#agreement").val(agr);  } &lt;/script&gt;</blockquote>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/JS_Sudoku_Solver/</id>
    <title>JS Sudoku Solver</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/JS_Sudoku_Solver/"/>
    
    <updated>2009-01-11T20:09:05Z</updated>
    <published>2009-01-11T20:10:17Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            Version 2.0 with code.

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Here it is, plugin a puzzle, hit try.  If it doesn't work, hit Try again.  If it doesn't work after a few times, hit possibilities, put that in the comments, and I'll see if I can sort it out.  Happy sudoku-ruining</p>
<p>
<script src="http://jquery.com/src/jquery-latest.pack.js" type="text/javascript"></script>
<script type="text/javascript">&lt;!--
	given = new Array();
	possibilities = new Array();
	var i,j,k;
	
	function doGo()
	{
		initThis();
		for(var z=0;z&lt;99;z++)
		{
			attempt();
			possibilitiesToGivens();
			//oneInBox();
			possibilitiesToGivens();
			givensClearPossibilities();
			oneInRowCol();
			possibilitiesToGivens();
		}
		givenToBoard();
	}

	function initThis()
	{
		for(i = 0; i &lt; 9; i++)
		{
			possibilities[i] = new Array();
			given[i] = new Array();
			for(j = 0; j &lt; 9; j++)
			{
				possibilities[i][j] = new Array();
				for(k = 1; k &lt; 10; k++)
				{
					possibilities[i][j][k] = true;
				}
				if(isNaN(parseInt($("#a"+i+'x'+j).val())))
				{
					given[i][j] = 0;
				}
				else
				{
					given[i][j] = parseInt($("#a"+i+'x'+j).val());
					for(var l=1; l&lt;10; l++)	possibilities[i][j][l] = false;
				}
			}
		}
	}

	function attempt()
	{
		//brute out impossible combinations
		for(i = 0; i &lt; 9; i++)
		{
			for(j = 0; j &lt; 9; j++)
			{
				if(given[i][j] &gt; 0)
				{
					filterRowCol(i,j);
					filterBox(i,j);
				}
			}
		}
	}
	
	function oneInBox()
	{
		for(i=0;i&lt;9;i++)
		{
			for(j=0;j&lt;9;j++)
			{
				if(given[i][j] == 0)
				{
					if((i==0) || (i==1) || (i==2))
					{ 
						iLow = 0; iHigh = 3;
					}
					else if((i==3) || (i==4) || (i==5))
					{ 
						iLow = 3; iHigh = 6;
					}
					else
					{ 
						iLow = 6; iHigh = 9;
					}
					if((j==0) || (j==1) || (j==2))
					{ 
						jLow = 0; jHigh = 3;
					}
					else if((j==3) || (j==4) || (j==5))
					{ 
						jLow = 3; jHigh = 6;
					}
					else
					{ 
						jLow = 6; jHigh = 9;
					}
					var trues = 0,trueL=10,trueM=10,trueN=10;
					for(n=1;n&lt;10;n++)
					{
						if(possibilities[i][j][n])
						{
							for(var l=iLow;l&lt;iHigh;l++)
							{
								for(var m=jLow;m&lt;jHigh;m++)
								{
									if(possibilities[l][m][n])
									{
										trues++;
									}
									if(trues == 1)
									{
										given[i][j] = n;
										givensClearPossibilities();
										//filterRowCol(i,j);
									}
						
								}
							}
						}
					}
				}
			}
		}
	}
	
	function oneInRowCol()
	{
		for(i=0;i&lt;9;i++)
		{	
			for(j=0;j&lt;9;j++)
			{
				if(given[i][j] == 0) //we haven't found it yet
				{
					for(n=1;n&lt;10;n++) 
					{
						trues = 0;
						truess = 0;
						if(possibilities[i][j][n])
						{
							for(m=0;m&lt;9;m++) //for this row
							{
								if(possibilities[i][m][n])
								{
									trues++;
								}
							}
							if(trues == 1)
							{
								given[i][j] = n;
							}
						
							for(l=0;l&lt;9;l++) //for this row
							{
								if(possibilities[l][j][n])
								{
									truess++;
								}
							}
							if(truess == 1)
							{
								given[i][j] = n;
							}
						}
					}
				}
			}
		}
	}
	
	function givensClearPossibilities()
	{
		for(i=0;i&lt;9;i++)
		{
			for(j=0;j&lt;9;j++)
			{
				if(given[i][j] &gt; 0)
				{
					for(k=1;k&lt;10;k++)
					{
						possibilities[i][j][k] == false;
					}
				}
			}	
		}
	}
	function filterRowCol(i,j)
	{
		val = given[i][j];
		for(var l=0; l&lt;9; l++)
		{
			possibilities[i][l][val] = false;
			possibilities[l][j][val] = false;
		}

	}
	function filterBox(i,j)
	{
		var iLow,jLoq,iHigh,jHigh;
		//boxNum = findBox(i,j);
		val = given[i][j];
		if((i==0) || (i==1) || (i==2))
		{ 
			iLow = 0; iHigh = 3;
		}
		else if((i==3) || (i==4) || (i==5))
		{ 
			iLow = 3; iHigh = 6;
		}
		else
		{ 
			iLow = 6; iHigh = 9;
		}
		if((j==0) || (j==1) || (j==2))
		{ 
			jLow = 0; jHigh = 3;
		}
		else if((j==3) || (j==4) || (j==5))
		{ 
			jLow = 3; jHigh = 6;
		}
		else
		{ 
			jLow = 6; jHigh = 9;
		}

		for(var l=iLow;l&lt;iHigh;l++)
		{
			for(var m=jLow;m&lt;jHigh;m++)
			{
				possibilities[l][m][val] = false;
			}
		}
	}
	function possibilitiesToGivens() //turns one possibility into a given.
	{
		var l,m,n,trues=0;
		for(l=0;l&lt;9;l++)
		{
			for(m=0;m&lt;9;m++)
			{
				if(given[l][m] == 0)
				{
					for(n=1;n&lt;10;n++)
					{
						if(possibilities[l][m][n]) trues++;
					}
					if(trues == 1)
					{
						for(n=1;n&lt;10;n++)
						{
							if(possibilities[l][m][n]) given[l][m] = n;
						}
					}
				}
				trues = 0;
			}
		}
	}
	function givenToBoard()
	{
		for(i=0;i&lt;9;i++)
		{
			for(j=0;j&lt;9;j++)
			{
				if(given[i][j] &gt; 0) $("#a"+i+'x'+j).val(given[i][j]);
			}
		}
	}
	
	function displayPossibilities()
	{
		var l,m,n,trues ='';
		for(l=0;l&lt;9;l++)
		{
			for(m=0;m&lt;9;m++)
			{
		    	if(given[l][m] == 0)
               	{
               		trues += l+ 'x'+m+' - ';
               		for(n=1;n&lt;10;n++)
               		{
               			if(possibilities[l][m][n] == true) trues += n+',';
		        	}
				}
				else 
				{
					trues += l+'x'+m+' - '+given[l][m];
				}
				trues += " : ";
		    }
			trues+= '&lt;br  /&gt;';
		}
		$("#possibilities").html(trues);
	}
// --&gt;</script>
</p>
<table border="0">
<tbody>
<tr>
<td><input id="a0x0" style="width: 26px;" /></td>
<td><input id="a0x1" style="width: 26px;" /></td>
<td><input id="a0x2" style="width: 26px;" /></td>
<td style="border-width:1px; border-color:black;" rowspan="11">&nbsp;</td>
<td><input id="a0x3" style="width: 26px;" /></td>
<td><input id="a0x4" style="width: 26px;" /></td>
<td><input id="a0x5" style="width: 26px;" /></td>
<td style="border-width:1px; border-color:black;" rowspan="11">&nbsp;</td>
<td><input id="a0x6" style="width: 26px;" /></td>
<td><input id="a0x7" style="width: 26px;" /></td>
<td><input id="a0x8" style="width: 26px;" /></td>
</tr>
<tr>
<td><input id="a1x0" style="width: 26px;" /></td>
<td><input id="a1x1" style="width: 26px;" /></td>
<td><input id="a1x2" style="width: 26px;" /></td>
<td><input id="a1x3" style="width: 26px;" /></td>
<td><input id="a1x4" style="width: 26px;" /></td>
<td><input id="a1x5" style="width: 26px;" /></td>
<td><input id="a1x6" style="width: 26px;" /></td>
<td><input id="a1x7" style="width: 26px;" /></td>
<td><input id="a1x8" style="width: 26px;" /></td>
</tr>
<tr>
<td><input id="a2x0" style="width: 26px;" /></td>
<td><input id="a2x1" style="width: 26px;" /></td>
<td><input id="a2x2" style="width: 26px;" /></td>
<td><input id="a2x3" style="width: 26px;" /></td>
<td><input id="a2x4" style="width: 26px;" /></td>
<td><input id="a2x5" style="width: 26px;" /></td>
<td><input id="a2x6" style="width: 26px;" /></td>
<td><input id="a2x7" style="width: 26px;" /></td>
<td><input id="a2x8" style="width: 26px;" /></td>
</tr>
<tr>
<td style="border-width:1px; border-color:black;" colspan="11">&nbsp;</td>
</tr>
<tr>
<td><input id="a3x0" style="width: 26px;" /></td>
<td><input id="a3x1" style="width: 26px;" /></td>
<td><input id="a3x2" style="width: 26px;" /></td>
<td><input id="a3x3" style="width: 26px;" /></td>
<td><input id="a3x4" style="width: 26px;" /></td>
<td><input id="a3x5" style="width: 26px;" /></td>
<td><input id="a3x6" style="width: 26px;" /></td>
<td><input id="a3x7" style="width: 26px;" /></td>
<td><input id="a3x8" style="width: 26px;" /></td>
</tr>
<tr>
<td><input id="a4x0" style="width: 26px;" /></td>
<td><input id="a4x1" style="width: 26px;" /></td>
<td><input id="a4x2" style="width: 26px;" /></td>
<td><input id="a4x3" style="width: 26px;" /></td>
<td><input id="a4x4" style="width: 26px;" /></td>
<td><input id="a4x5" style="width: 26px;" /></td>
<td><input id="a4x6" style="width: 26px;" /></td>
<td><input id="a4x7" style="width: 26px;" /></td>
<td><input id="a4x8" style="width: 26px;" /></td>
</tr>
<tr>
<td><input id="a5x0" style="width: 26px;" /></td>
<td><input id="a5x1" style="width: 26px;" /></td>
<td><input id="a5x2" style="width: 26px;" /></td>
<td><input id="a5x3" style="width: 26px;" /></td>
<td><input id="a5x4" style="width: 26px;" /></td>
<td><input id="a5x5" style="width: 26px;" /></td>
<td><input id="a5x6" style="width: 26px;" /></td>
<td><input id="a5x7" style="width: 26px;" /></td>
<td><input id="a5x8" style="width: 26px;" /></td>
</tr>
<tr>
<td style="border-width:1px; border-color:black;" colspan="11">&nbsp;</td>
</tr>
<tr>
<td><input id="a6x0" style="width: 26px;" /></td>
<td><input id="a6x1" style="width: 26px;" /></td>
<td><input id="a6x2" style="width: 26px;" /></td>
<td><input id="a6x3" style="width: 26px;" /></td>
<td><input id="a6x4" style="width: 26px;" /></td>
<td><input id="a6x5" style="width: 26px;" /></td>
<td><input id="a6x6" style="width: 26px;" /></td>
<td><input id="a6x7" style="width: 26px;" /></td>
<td><input id="a6x8" style="width: 26px;" /></td>
</tr>
<tr>
<td><input id="a7x0" style="width: 26px;" /></td>
<td><input id="a7x1" style="width: 26px;" /></td>
<td><input id="a7x2" style="width: 26px;" /></td>
<td><input id="a7x3" style="width: 26px;" /></td>
<td><input id="a7x4" style="width: 26px;" /></td>
<td><input id="a7x5" style="width: 26px;" /></td>
<td><input id="a7x6" style="width: 26px;" /></td>
<td><input id="a7x7" style="width: 26px;" /></td>
<td><input id="a7x8" style="width: 26px;" /></td>
</tr>
<tr>
<td><input id="a8x0" style="width: 26px;" /></td>
<td><input id="a8x1" style="width: 26px;" /></td>
<td><input id="a8x2" style="width: 26px;" /></td>
<td><input id="a8x3" style="width: 26px;" /></td>
<td><input id="a8x4" style="width: 26px;" /></td>
<td><input id="a8x5" style="width: 26px;" /></td>
<td><input id="a8x6" style="width: 26px;" /></td>
<td><input id="a8x7" style="width: 26px;" /></td>
<td><input id="a8x8" style="width: 26px;" /></td>
</tr>
</tbody>
</table>
<p><button id="doGo" onclick="doGo()">Try!</button><button id="showPossibles" onclick="displayPossibilities()">Show Possibilities</button><button id="clear" onclick="$(\">Clear</button></p>
<div id="possibilities">&nbsp;If you want, you can embed this as an iFrame</div>
<div>http://www.issackelly.com/sudoku.html, but please, backlink here.<br /></div>
<div><br /></div>
<h4>And the Code...</h4>
<p>Actually, you're probably best to view source, as the lines aren't properly broken here.</p>
<blockquote>&lt;script type="text/javascript" src="http://jquery.com/src/jquery-latest.pack.js"&gt;&lt;/script&gt; 		&lt;script type="text/javascript"&gt; 		given = new Array(); 		possibilities = new Array(); 		var i,j,k;  		function doGo() 		{ 			initThis(); 			for(var z=0;z&lt;99;z++) 			{ 				attempt(); 				possibilitiesToGivens(); 				//oneInBox(); 				possibilitiesToGivens(); 				givensClearPossibilities(); 				oneInRowCol(); 				possibilitiesToGivens(); 			} 			givenToBoard(); 		}  		function initThis() 		{ 			for(i = 0; i &lt; 9; i++) 			{ 				possibilities[i] = new Array(); 				given[i] = new Array(); 				for(j = 0; j &lt; 9; j++) 				{ 					possibilities[i][j] = new Array(); 					for(k = 1; k &lt; 10; k++) 					{ 						possibilities[i][j][k] = true; 					} 					if(isNaN(parseInt($("#a"+i+'x'+j).val()))) 					{ 						given[i][j] = 0; 					} 					else 					{ 						given[i][j] = parseInt($("#a"+i+'x'+j).val()); 						for(var l=1; l&lt;10; l++)	possibilities[i][j][l] = false; 					} 				} 			} 		}  		function attempt() 		{ 			//brute out impossible combinations 			for(i = 0; i &lt; 9; i++) 			{ 				for(j = 0; j &lt; 9; j++) 				{ 					if(given[i][j] &gt; 0) 					{ 						filterRowCol(i,j); 						filterBox(i,j); 					} 				} 			} 		}  		function oneInBox() 		{ 			for(i=0;i&lt;9;i++) 			{ 				for(j=0;j&lt;9;j++) 				{ 					if(given[i][j] == 0) 					{ 						if((i==0) || (i==1) || (i==2)) 						{  							iLow = 0; iHigh = 3; 						} 						else if((i==3) || (i==4) || (i==5)) 						{  							iLow = 3; iHigh = 6; 						} 						else 						{  							iLow = 6; iHigh = 9; 						} 						if((j==0) || (j==1) || (j==2)) 						{  							jLow = 0; jHigh = 3; 						} 						else if((j==3) || (j==4) || (j==5)) 						{  							jLow = 3; jHigh = 6; 						} 						else 						{  							jLow = 6; jHigh = 9; 						} 						var trues = 0,trueL=10,trueM=10,trueN=10; 						for(n=1;n&lt;10;n++) 						{ 							if(possibilities[i][j][n]) 							{ 								for(var l=iLow;l&lt;iHigh;l++) 								{ 									for(var m=jLow;m&lt;jHigh;m++) 									{ 										if(possibilities[l][m][n]) 										{ 											trues++; 										} 										if(trues == 1) 										{ 											given[i][j] = n; 											givensClearPossibilities(); 											//filterRowCol(i,j); 										}  									} 								} 							} 						} 					} 				} 			} 		}  		function oneInRowCol() 		{ 			for(i=0;i&lt;9;i++) 			{	 				for(j=0;j&lt;9;j++) 				{ 					if(given[i][j] == 0) //we haven't found it yet 					{ 						for(n=1;n&lt;10;n++)  						{ 							trues = 0; 							truess = 0; 							if(possibilities[i][j][n]) 							{ 								for(m=0;m&lt;9;m++) //for this row 								{ 									if(possibilities[i][m][n]) 									{ 										trues++; 									} 								} 								if(trues == 1) 								{ 									given[i][j] = n; 								}  								for(l=0;l&lt;9;l++) //for this row 								{ 									if(possibilities[l][j][n]) 									{ 										truess++; 									} 								} 								if(truess == 1) 								{ 									given[i][j] = n; 								} 							} 						} 					} 				} 			} 		}  		function givensClearPossibilities() 		{ 			for(i=0;i&lt;9;i++) 			{ 				for(j=0;j&lt;9;j++) 				{ 					if(given[i][j] &gt; 0) 					{ 						for(k=1;k&lt;10;k++) 						{ 							possibilities[i][j][k] == false; 						} 					} 				}	 			} 		} 		function filterRowCol(i,j) 		{ 			val = given[i][j]; 			for(var l=0; l&lt;9; l++) 			{ 				possibilities[i][l][val] = false; 				possibilities[l][j][val] = false; 			}  		} 		function filterBox(i,j) 		{ 			var iLow,jLoq,iHigh,jHigh; 			//boxNum = findBox(i,j); 			val = given[i][j]; 			if((i==0) || (i==1) || (i==2)) 			{  				iLow = 0; iHigh = 3; 			} 			else if((i==3) || (i==4) || (i==5)) 			{  				iLow = 3; iHigh = 6; 			} 			else 			{  				iLow = 6; iHigh = 9; 			} 			if((j==0) || (j==1) || (j==2)) 			{  				jLow = 0; jHigh = 3; 			} 			else if((j==3) || (j==4) || (j==5)) 			{  				jLow = 3; jHigh = 6; 			} 			else 			{  				jLow = 6; jHigh = 9; 			}  			for(var l=iLow;l&lt;iHigh;l++) 			{ 				for(var m=jLow;m&lt;jHigh;m++) 				{ 					possibilities[l][m][val] = false; 				} 			} 		} 		function possibilitiesToGivens() //turns one possibility into a given. 		{ 			var l,m,n,trues=0; 			for(l=0;l&lt;9;l++) 			{ 				for(m=0;m&lt;9;m++) 				{ 					if(given[l][m] == 0) 					{ 						for(n=1;n&lt;10;n++) 						{ 							if(possibilities[l][m][n]) trues++; 						} 						if(trues == 1) 						{ 							for(n=1;n&lt;10;n++) 							{ 								if(possibilities[l][m][n]) given[l][m] = n; 							} 						} 					} 					trues = 0; 				} 			} 		} 		function givenToBoard() 		{ 			for(i=0;i&lt;9;i++) 			{ 				for(j=0;j&lt;9;j++) 				{ 					if(given[i][j] &gt; 0) $("#a"+i+'x'+j).val(given[i][j]); 				} 			} 		}  		function displayPossibilities() 		{ 			var l,m,n,trues =''; 			for(l=0;l&lt;9;l++) 			{ 				for(m=0;m&lt;9;m++) 				{ 			    	if(given[l][m] == 0) 	               	{ 	               		trues += l+ 'x'+m+' - '; 	               		for(n=1;n&lt;10;n++) 	               		{ 	               			if(possibilities[l][m][n] == true) trues += n+','; 			        	} 					} 					else  					{ 						trues += l+'x'+m+' - '+given[l][m]; 					} 					trues += " : "; 			    } 				trues+= '&lt;br/&gt;'; 			} 			$("#possibilities").html(trues); 		} 		&lt;/script&gt; 	&lt;table&gt; 	&lt;tr&gt;&lt;td&gt;&lt;input style="width:26px" style="width:26px" id="a0x0" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a0x1" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a0x2" /&gt;&lt;/td&gt;&lt;td rowspan="11" style="border-width:1px; border-color:black;"&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a0x3" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a0x4" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a0x5" /&gt;&lt;/td&gt;&lt;td rowspan="11" style="border-width:1px; border-color:black;"&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a0x6" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a0x7" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a0x8" /&gt;&lt;/td&gt;&lt;/tr&gt;  	&lt;tr&gt;&lt;td&gt;&lt;input style="width:26px" id="a1x0" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a1x1" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a1x2" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a1x3" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a1x4" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a1x5" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a1x6" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a1x7" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a1x8" /&gt;&lt;/td&gt;&lt;/tr&gt;  	&lt;tr&gt;&lt;td&gt;&lt;input style="width:26px" id="a2x0" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a2x1" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a2x2" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a2x3" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a2x4" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a2x5" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a2x6" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a2x7" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a2x8" /&gt;&lt;/td&gt;&lt;/tr&gt;  	&lt;tr&gt;&lt;td colspan="11" style="border-width:1px; border-color:black;"&gt;&lt;/td&gt;&lt;/tr&gt;  	&lt;tr&gt;&lt;td&gt;&lt;input style="width:26px" id="a3x0" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a3x1" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a3x2" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a3x3" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a3x4" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a3x5" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a3x6" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a3x7" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a3x8" /&gt;&lt;/td&gt;&lt;/tr&gt;  	&lt;tr&gt;&lt;td&gt;&lt;input style="width:26px" id="a4x0" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a4x1" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a4x2" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a4x3" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a4x4" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a4x5" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a4x6" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a4x7" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a4x8" /&gt;&lt;/td&gt;&lt;/tr&gt;  	&lt;tr&gt;&lt;td&gt;&lt;input style="width:26px" id="a5x0" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a5x1" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a5x2" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a5x3" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a5x4" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a5x5" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a5x6" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a5x7" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a5x8" /&gt;&lt;/td&gt;&lt;/tr&gt;  	&lt;tr&gt;&lt;td colspan="11" style="border-width:1px; border-color:black;"&gt;&lt;/td&gt;&lt;/tr&gt;  	&lt;tr&gt;&lt;td&gt;&lt;input style="width:26px" id="a6x0" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a6x1" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a6x2" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a6x3" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a6x4" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a6x5" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a6x6" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a6x7" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a6x8" /&gt;&lt;/td&gt;&lt;/tr&gt;  	&lt;tr&gt;&lt;td&gt;&lt;input style="width:26px" id="a7x0" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a7x1" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a7x2" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a7x3" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a7x4" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a7x5" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a7x6" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a7x7" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a7x8" /&gt;&lt;/td&gt;&lt;/tr&gt;  	&lt;tr&gt;&lt;td&gt;&lt;input style="width:26px" id="a8x0" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a8x1" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a8x2" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a8x3" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a8x4" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a8x5" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a8x6" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a8x7" /&gt;&lt;/td&gt;&lt;td&gt;&lt;input style="width:26px" id="a8x8" /&gt;&lt;/td&gt;&lt;/tr&gt; 	&lt;/table&gt; 	&lt;button id="doGo" onclick="doGo()"&gt;Try!&lt;/button&gt;&lt;button id="showPossibles" onclick="displayPossibilities()"&gt;Show Possibilities&lt;/button&gt;&lt;button id="clear" onclick="$(\"input\").val('')"&gt;Clear&lt;/button&gt; 	&lt;div id="possibilities"&gt;&amp;nbsp;&lt;/div&gt;</blockquote>
<blockquote><br /></blockquote>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/Sudoku_Solver_v1/</id>
    <title>JavaScript Sudoku Solver v1</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/Sudoku_Solver_v1/"/>
    
    <updated>2009-01-11T20:09:04Z</updated>
    <published>2009-01-11T20:10:16Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>If you have a problem case, hit "show Possibilities" and put the output into the comments, I may get back to it.</p>
<p>
<script src="http://jquery.com/src/jquery-latest.pack.js" type="text/javascript"></script>
<script type="text/javascript">&lt;!--
	given = new Array();
	possibilities = new Array();
	var i,j,k;
	
	$(document).ready(function(){
		doGo();
	});
	function doGo()
	{
		initThis();
		attempt();
		possibilitiesToGivens();
		givenToBoard();
		attempt();
		possibilitiesToGivens();
		givenToBoard();
		attempt();
		possibilitiesToGivens();
		givenToBoard();
		attempt();
		possibilitiesToGivens();
		givenToBoard();
		attempt();
		possibilitiesToGivens();
		givenToBoard();
		attempt();
		possibilitiesToGivens();
		givenToBoard();
		attempt();
		possibilitiesToGivens();
		givenToBoard();
		attempt();
		possibilitiesToGivens();
		givenToBoard();
		attempt();
		possibilitiesToGivens();
		givenToBoard();
		attempt();
		possibilitiesToGivens();
		givenToBoard();
		attempt();
		possibilitiesToGivens();
		givenToBoard();
	}

	function initThis()
	{
		for(i = 0; i &lt; 9; i++)
		{
			possibilities[i] = new Array();
			given[i] = new Array();
			for(j = 0; j &lt; 9; j++)
			{
				possibilities[i][j] = new Array();
				for(k = 1; k &lt; 10; k++)
				{
					possibilities[i][j][k] = true;
				}
				if(isNaN(parseInt($("#a"+i+'x'+j).val())))
				{
					given[i][j] = 0;
				}
				else
				{
					given[i][j] = parseInt($("#a"+i+'x'+j).val());
					for(var l=1; l&lt;10; l++)	possibilities[i][j][l] = false;
				}
			}
		}
	}

	function attempt()
	{
		for(i = 0; i &lt; 9; i++)
		{
			for(j = 0; j &lt; 9; j++)
			{
				if(given[i][j] &gt; 0)
				{
					filterRowCol(i,j);
					filterBox(i,j);
				}
			}
		}
	}

	function filterRowCol(i,j)
	{
		val = given[i][j];
		for(var l=0; l&lt;9; l++)
		{
			possibilities[i][l][val] = false;
			possibilities[l][j][val] = false;
		}

	}
	function filterBox(i,j)
	{
		var iLow,jLoq,iHigh,jHigh;
		//boxNum = findBox(i,j);
		val = given[i][j];
		if((i==0) || (i==1) || (i==2))
		{ 
			iLow = 0; iHigh = 3;
		}
		else if((i==3) || (i==4) || (i==5))
		{ 
			iLow = 3; iHigh = 6;
		}
		else
		{ 
			iLow = 6; iHigh = 9;
		}
		if((j==0) || (j==1) || (j==2))
		{ 
			jLow = 0; jHigh = 3;
		}
		else if((j==3) || (j==4) || (j==5))
		{ 
			jLow = 3; jHigh = 6;
		}
		else
		{ 
			jLow = 6; jHigh = 9;
		}

		for(var l=iLow;l&lt;iHigh;l++)
		{
			for(var m=jLow;m&lt;jHigh;m++)
			{
				possibilities[l][m][val] = false;
			}
		}
	}
	function possibilitiesToGivens()
	{
		var l,m,n,trues=0;
		for(l=0;l&lt;9;l++)
		{
			for(m=0;m&lt;9;m++)
			{
				if(given[l][m] == 0)
				{
					for(n=1;n&lt;10;n++)
					{
						if(possibilities[l][m][n]) trues++;
					}
					if(trues == 1)
					{
						for(n=1;n&lt;10;n++)
						{
							if(possibilities[l][m][n]) given[l][m] = n;
						}
					}
				}
				trues = 0;
			}
		}
	}
	function givenToBoard()
	{
		for(i=0;i&lt;9;i++)
		{
			for(j=0;j&lt;9;j++)
			{
				if(given[i][j] &gt; 0) $("#a"+i+'x'+j).val(given[i][j]);
			}
		}
	}
	
	function displayPossibilities()
	{
		var l,m,n,trues ='';
		for(l=0;l&lt;9;l++)
		{
			for(m=0;m&lt;9;m++)
			{
		    	if(given[l][m] == 0)
               	{
               		trues += l+ 'x'+m+' - ';
               		for(n=1;n&lt;10;n++)
               		{
               			if(possibilities[l][m][n] == true) trues += n+',';
		        	}
				}
				else 
				{
					trues += l+'x'+m+' - '+given[l][m];
				}
				trues += " : ";
		    }
			trues+= '&lt;br  /&gt;';
		}
		$("#possibilities").html(trues);
	}
// --&gt;</script>
</p>
<table border="0">
<tbody>
<tr>
<td><input id="a0x0" style="width: 26px;" /></td>
<td><input id="a0x1" style="width: 26px;" /></td>
<td><input id="a0x2" style="width: 26px;" /></td>
<td style="border-width:1px; border-color:black;" rowspan="11">&nbsp;</td>
<td><input id="a0x3" style="width: 26px;" /></td>
<td><input id="a0x4" style="width: 26px;" /></td>
<td><input id="a0x5" style="width: 26px;" /></td>
<td style="border-width:1px; border-color:black;" rowspan="11">&nbsp;</td>
<td><input id="a0x6" style="width: 26px;" /></td>
<td><input id="a0x7" style="width: 26px;" /></td>
<td><input id="a0x8" style="width: 26px;" /></td>
</tr>
<tr>
<td><input id="a1x0" style="width: 26px;" /></td>
<td><input id="a1x1" style="width: 26px;" /></td>
<td><input id="a1x2" style="width: 26px;" /></td>
<td><input id="a1x3" style="width: 26px;" /></td>
<td><input id="a1x4" style="width: 26px;" /></td>
<td><input id="a1x5" style="width: 26px;" /></td>
<td><input id="a1x6" style="width: 26px;" /></td>
<td><input id="a1x7" style="width: 26px;" /></td>
<td><input id="a1x8" style="width: 26px;" /></td>
</tr>
<tr>
<td><input id="a2x0" style="width: 26px;" /></td>
<td><input id="a2x1" style="width: 26px;" /></td>
<td><input id="a2x2" style="width: 26px;" /></td>
<td><input id="a2x3" style="width: 26px;" /></td>
<td><input id="a2x4" style="width: 26px;" /></td>
<td><input id="a2x5" style="width: 26px;" /></td>
<td><input id="a2x6" style="width: 26px;" /></td>
<td><input id="a2x7" style="width: 26px;" /></td>
<td><input id="a2x8" style="width: 26px;" /></td>
</tr>
<tr>
<td style="border-width:1px; border-color:black;" colspan="11">&nbsp;</td>
</tr>
<tr>
<td><input id="a3x0" style="width: 26px;" /></td>
<td><input id="a3x1" style="width: 26px;" /></td>
<td><input id="a3x2" style="width: 26px;" /></td>
<td><input id="a3x3" style="width: 26px;" /></td>
<td><input id="a3x4" style="width: 26px;" /></td>
<td><input id="a3x5" style="width: 26px;" /></td>
<td><input id="a3x6" style="width: 26px;" /></td>
<td><input id="a3x7" style="width: 26px;" /></td>
<td><input id="a3x8" style="width: 26px;" /></td>
</tr>
<tr>
<td><input id="a4x0" style="width: 26px;" /></td>
<td><input id="a4x1" style="width: 26px;" /></td>
<td><input id="a4x2" style="width: 26px;" /></td>
<td><input id="a4x3" style="width: 26px;" /></td>
<td><input id="a4x4" style="width: 26px;" /></td>
<td><input id="a4x5" style="width: 26px;" /></td>
<td><input id="a4x6" style="width: 26px;" /></td>
<td><input id="a4x7" style="width: 26px;" /></td>
<td><input id="a4x8" style="width: 26px;" /></td>
</tr>
<tr>
<td><input id="a5x0" style="width: 26px;" /></td>
<td><input id="a5x1" style="width: 26px;" /></td>
<td><input id="a5x2" style="width: 26px;" /></td>
<td><input id="a5x3" style="width: 26px;" /></td>
<td><input id="a5x4" style="width: 26px;" /></td>
<td><input id="a5x5" style="width: 26px;" /></td>
<td><input id="a5x6" style="width: 26px;" /></td>
<td><input id="a5x7" style="width: 26px;" /></td>
<td><input id="a5x8" style="width: 26px;" /></td>
</tr>
<tr>
<td style="border-width:1px; border-color:black;" colspan="11">&nbsp;</td>
</tr>
<tr>
<td><input id="a6x0" style="width: 26px;" /></td>
<td><input id="a6x1" style="width: 26px;" /></td>
<td><input id="a6x2" style="width: 26px;" /></td>
<td><input id="a6x3" style="width: 26px;" /></td>
<td><input id="a6x4" style="width: 26px;" /></td>
<td><input id="a6x5" style="width: 26px;" /></td>
<td><input id="a6x6" style="width: 26px;" /></td>
<td><input id="a6x7" style="width: 26px;" /></td>
<td><input id="a6x8" style="width: 26px;" /></td>
</tr>
<tr>
<td><input id="a7x0" style="width: 26px;" /></td>
<td><input id="a7x1" style="width: 26px;" /></td>
<td><input id="a7x2" style="width: 26px;" /></td>
<td><input id="a7x3" style="width: 26px;" /></td>
<td><input id="a7x4" style="width: 26px;" /></td>
<td><input id="a7x5" style="width: 26px;" /></td>
<td><input id="a7x6" style="width: 26px;" /></td>
<td><input id="a7x7" style="width: 26px;" /></td>
<td><input id="a7x8" style="width: 26px;" /></td>
</tr>
<tr>
<td><input id="a8x0" style="width: 26px;" /></td>
<td><input id="a8x1" style="width: 26px;" /></td>
<td><input id="a8x2" style="width: 26px;" /></td>
<td><input id="a8x3" style="width: 26px;" /></td>
<td><input id="a8x4" style="width: 26px;" /></td>
<td><input id="a8x5" style="width: 26px;" /></td>
<td><input id="a8x6" style="width: 26px;" /></td>
<td><input id="a8x7" style="width: 26px;" /></td>
<td><input id="a8x8" style="width: 26px;" /></td>
</tr>
</tbody>
</table>
<p><button id="doGo" onclick="doGo()">Try!</button><button id="showPossibles" onclick="displayPossibilities()">Show Possibilities</button></p>
<div id="possibilities">&nbsp;</div>
<p>&nbsp;</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/Google_Chrome_and_my_past_predic/</id>
    <title>Google Chrome and my past prediction</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/Google_Chrome_and_my_past_predic/"/>
    
    <updated>2009-01-21T13:04:33Z</updated>
    <published>2009-01-11T20:10:15Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Google's announcement of <a href="http://blogoscoped.com/google-chrome/" target="_blank">a new browser</a> is not suprising in the least.</p>
<p>It fits directly in line with <a href="/Blog/entry/what_google_is_doing/" target="_blank">what I said while at Google-IO 2008</a>.</p>
<p>Google is commodizing the desktop.&nbsp; Everything will be online, and when you're not online, you might as well be with tight gears integration.</p>
<p>Making the browser faster, and more bullet proof will take away (over time) security and performance concerns of web apps a thing of the past.</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/Simple_JQuery_Mortgage_Calculato/</id>
    <title>Simple JQuery Mortgage Calculator</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/Simple_JQuery_Mortgage_Calculato/"/>
    
    <updated>2009-01-11T20:09:02Z</updated>
    <published>2009-01-11T20:10:14Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p><a title="Servee" href="http://www.servee.com" target="_blank">Servee</a> is moving into real estate territory, more details to come, but I've made this simple mortgage calculator.&nbsp; Free to use, no warranty, etc.</p>
<p>Here is the code for your copy and paste, check the example below.&nbsp; It requires Jquery to function.&nbsp; My styles also may mess up the line breaks in the HTML, but the JS is all pretty short, so it's not a big deal.</p>
<blockquote>
<p>&lt;!-- if you don't have jquery --&gt;<br /> &lt;script type='text/javascript' src='http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js'&gt;&lt;/script&gt;</p>
<p>&lt;!--The&nbsp;following&nbsp;formula&nbsp;is&nbsp;used&nbsp;to&nbsp;calculate&nbsp;the&nbsp;fixed&nbsp;monthly&nbsp;payment&nbsp;(P)&nbsp;required&nbsp;to&nbsp;fully&nbsp;amortize&nbsp;a&nbsp;loan&nbsp;of&nbsp;L&nbsp;dollars&nbsp;over&nbsp;a&nbsp;term&nbsp;of&nbsp;n&nbsp;months&nbsp;at&nbsp;a&nbsp;monthly&nbsp;interest&nbsp;rate&nbsp;of&nbsp;c.&nbsp;[If&nbsp;the&nbsp;quoted&nbsp;rate&nbsp;is&nbsp;6%,&nbsp;for&nbsp;example,&nbsp;c&nbsp;is&nbsp;.06/12&nbsp;or&nbsp;.005].&nbsp; <br /> <br />P&nbsp;=&nbsp;L[c(1&nbsp;+&nbsp;c)^n]/[(1&nbsp;+&nbsp;c)^n&nbsp;-&nbsp;1]--&gt; <br />&lt;h3&gt;Mortgage&nbsp;Calculator&lt;/h3&gt; <br />&nbsp;&nbsp;&nbsp;&lt;form&nbsp;&gt; <br />&lt;p&gt;&nbsp;&nbsp;&lt;input&nbsp;type="text"&nbsp;name="mcPrice"&nbsp;id="mcPrice"&nbsp;class="mortgageField"&nbsp;/&gt; <br />Sale&nbsp;price&nbsp;($)&nbsp; <br />&lt;/p&gt; <br />&lt;p&gt;&nbsp;&nbsp;&lt;input&nbsp;type="text"&nbsp;name="mcDown"&nbsp;id="mcDown"&nbsp;class="mortgageField"&nbsp;/&gt; <br />Down&nbsp;payment&nbsp;(%)&lt;/p&gt; <br />&lt;p&gt;&nbsp;&nbsp;&lt;input&nbsp;type="text"&nbsp;name="mcRate"&nbsp;id="mcRate"&nbsp;class="mortgageField"&nbsp;/&gt; <br />Interest&nbsp;Rate&nbsp;(%)&lt;/p&gt; <br />&lt;p&gt;&nbsp;&nbsp;&lt;input&nbsp;type="text"&nbsp;name="mcTerm"&nbsp;id="mcTerm"&nbsp;class="mortgageField"&nbsp;/&gt; <br />Term&nbsp;(years)&lt;/p&gt; <br />&lt;button&nbsp;class="smallButton"&nbsp;id="mortgageCalc"&nbsp;onclick="return&nbsp;false"&gt;Calculate&nbsp;Monthly&nbsp;Payment&lt;/button&gt; <br />&nbsp;&nbsp;&lt;input&nbsp;type="text"&nbsp;name="mcPayment"&nbsp;id="mcPayment"&nbsp;class="mortgageAnswer"&nbsp;/&gt; <br />&lt;/form&gt; <br />&lt;script&nbsp;type="text/javascript"&gt; <br /> $("#mortgageCalc").click(function(){ <br /> var&nbsp;L,P,n,c,dp; <br /> L&nbsp;=&nbsp;parseInt($("#mcPrice").val()); <br /> n&nbsp;=&nbsp;parseInt($("#mcTerm").val())&nbsp;*&nbsp;12; <br /> c&nbsp;=&nbsp;parseFloat($("#mcRate").val())/1200; <br /> dp&nbsp;=&nbsp;1&nbsp;-&nbsp;parseFloat($("#mcDown").val())/100; <br /> L&nbsp;=&nbsp;L&nbsp;*&nbsp;dp; <br /> P&nbsp;=&nbsp;(L*(c*Math.pow(1+c,n)))/(Math.pow(1+c,n)-1); <br /> if(!isNaN(P)) <br /> { <br /> $("#mcPayment").val(P.toFixed(2)); <br /> } <br /> else <br /> { <br /> $("#mcPayment").val('There&nbsp;was&nbsp;an&nbsp;error'); <br /> } <br /> return&nbsp;false; <br /> }); <br />&lt;/script&gt;</p>
</blockquote>
<p>&nbsp;</p>
<!--The following formula is used to calculate the fixed monthly payment (P) required to fully amortize a loan of L dollars over a term of n months at a monthly interest rate of c. [If the quoted rate is 6%, for example, c is .06/12 or .005].   P = L[c(1 + c)^n]/[(1 + c)^n - 1]-->
<h3>Mortgage Calculator Example<br /></h3>
<form>
<p><input id="mcPrice" class="mortgageField" name="mcPrice" type="text" /> Sale price ($)</p>
<p><input id="mcDown" class="mortgageField" name="mcDown" type="text" /> Down payment (%)</p>
<p><input id="mcRate" class="mortgageField" name="mcRate" type="text" /> Interest Rate (%)</p>
<p><input id="mcTerm" class="mortgageField" name="mcTerm" type="text" /> Term (years)</p>
<button id="mortgageCalc" class="smallButton" onclick="return false">Calculate Monthly Payment</button> <br /><input id="mcPayment" class="mortgageAnswer" name="mcPayment" type="text" /> </form>
<p>
<script type="text/javascript">&lt;!--
	$("#mortgageCalc").click(function(){
		var L,P,n,c,dp;
		L = parseInt($("#mcPrice").val());
		n = parseInt($("#mcTerm").val()) * 12;
		c = parseFloat($("#mcRate").val())/1200;
		dp = 1 - parseFloat($("#mcDown").val())/100;
		L = L * dp;
		P = (L*(c*Math.pow(1+c,n)))/(Math.pow(1+c,n)-1);
		if(!isNaN(P))
		{
			$("#mcPayment").val(P.toFixed(2));
		}
		else
		{
			$("#mcPayment").val('There was an error');
		}
		return false;
	});
// --&gt;</script>
</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/My_arcade_Cabinet/</id>
    <title>My arcade Cabinet</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/My_arcade_Cabinet/"/>
    
    <updated>2009-01-11T20:09:00Z</updated>
    <published>2009-01-11T20:10:12Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>This is still available!</p>
<p>Works Beautifully, USB arcade controllers for your PC/Mac/*nix/Console (with adapter). &nbsp;I've been using this for the last 6 months and it works beautifully. &nbsp;It stands 5 feet tall, and 3 feet wide. &nbsp;Lots of shelve space. &nbsp;It makes a great arcade cabinet/entertainment center. &nbsp;I'm moving to a smaller place, or else I'd take it with me. &nbsp;</p>
<p>It packs flat, pieces slide together, with the exception of the control top, that has 6 screws for stability. &nbsp;It can store in a 5'x3' area.&nbsp;</p>
<p>I also have a small desk, technical and college text books, various IT/Computer equipt and a lot of clothes I'm trying to get rid of before I move.</p>
<p>$250</p>
<p><img src="/resources/userUploads/IMG_2000.jpg" alt="" /></p>
<p><img src="/resources/userUploads/IMG_2002.jpg" alt="" /></p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/craigslist_is_fail/</id>
    <title>craigslist is fail</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/craigslist_is_fail/"/>
    
    <updated>2009-01-11T20:08:59Z</updated>
    <published>2009-01-11T20:10:11Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p></p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/For_Sale_in_Columbus/</id>
    <title>For Sale in Columbus</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/For_Sale_in_Columbus/"/>
    
    <updated>2009-01-11T20:08:58Z</updated>
    <published>2009-01-11T20:10:10Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I'm moving into a small place (in Charleston SC) when I get married at the end of the summer, and I have a lot of things on Craigslist that i'm trying to get rid of in the short order.</p>
<p><a href="http://columbus.craigslist.org/sys/732112237.html">Arcade Cabinet</a></p>
<p><a href="http://columbus.craigslist.org/sys/732106744.html">Box of Tech Stuff</a></p>
<p><a href="http://columbus.craigslist.org/fur/732132139.html">Desk</a></p>
<p><a href="http://columbus.craigslist.org/hsh/732121600.html">Unworking washer</a></p>
<p><a href="http://columbus.craigslist.org/clo/732139039.html">Mens Clothes</a></p>
<p><a href="http://columbus.craigslist.org/sys/732146136.html">Cannon Photo Printer (takes direct usb from camera)</a></p>
<p><a href="http://columbus.craigslist.org/sys/732148492.html">Lexmark Printer/Scanner/Copier</a></p>
<p>&nbsp;</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/what_google_is_doing/</id>
    <title>What Google Is Doing</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/what_google_is_doing/"/>
    
    <updated>2009-01-11T20:08:57Z</updated>
    <published>2009-01-11T20:10:09Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Spending the day at google makes for a great mind-bending exercise on where they see the future of computing.<br /><br />Here is what I see coming down the oo's tubes.<br /><br />Google has denied that they are making an OS.&nbsp; I 100% believe them.&nbsp; They don't care.&nbsp; Especially about the desktop.<br />The desktop is dying.&nbsp; In the future we will have two types of machines: Mobile devices, and 'smart-dumb terminals'. The smart-dumb terminals, as I am henceforth dubbing them, will have some OS, and a moderate (probably still high by today's standards) ammt of computing power and a trivial ammt of disk space.<br /><br />Google is feverishly investing in both of these areas, with AppEngine, Android, gears, local, social, gwt (for 'enterprise') etc, etc, etc.&nbsp; They are creating the tools to take computing in this direction.<br /><br />They have perfected the art of web scale, and that will make prove to be their most valuable asset in this new computing world. With this, they get developers everywhere to lock-in to their (admittedly wonderful) tools.&nbsp; What they do is create the base for all of these tools, and let great developers show them off, which creates Google's user base for them.&nbsp; <br /><br />It's a very impressive plan for a company who says "don't be evil".&nbsp; Quite subversive compared to most other models that other (non-named) companies have taken to get developers to buy-in (quite literally) to their product.&nbsp; <br /><br />How do you get developers? Make the tools better than the current tools.&nbsp; Give the tools away for free.<br /><br />Happy googling everyone.<br /><br />#io2008 *(just a tag for searches, until keywords are fully supported in <a href="http://www.servee.com">Servee</a>).</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/Columbus_is_not_just_a_spaniard_/</id>
    <title>Columbus is not just a spaniard from the 15th century</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/Columbus_is_not_just_a_spaniard_/"/>
    
    <updated>2009-01-11T20:08:56Z</updated>
    <published>2009-01-11T20:10:08Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            it's still more than alive

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>There is a lot of crap about startups NEEDING to be in the valley.&nbsp;
Most there say you have to be there, and many outside say 'but why?'.&nbsp;
I'm in the second camp for sure.</p><p>I like starting my business in the middle of Ohio. I market <a target="_blank" title="" href="http://www.servee.com/">Servee</a> directly to businesses.&nbsp; My stats show 397 new businesses in the Central Ohio area in the last four weeks. Not bad at all for this economy.</p>
<p>I also market to designers.&nbsp; Columbus is not lacking at all when it
comes to designers.&nbsp; There is most certainly a vibrant creative
community here.* The rest of Ohio doesn't suck either.&nbsp; I can daytrip
to no less than four other major metropolitan areas, and three of them
are in the top 100 most populous cities in the country (Columbus is
15...and I'm sure it creeps near 6 or 7 on Gameday).&nbsp; Not to mention
CMH is the most pleasant airport out of every Intl Airport I have ever
been in.</p>
<p>The independent programmers here are doing interesting things.&nbsp; The
designers I know aren't stuck in 'copy apple' mode.&nbsp; The business
people are down-to-earth and not looking for a gold rush.&nbsp; Life is good
in Columbus, OH, and there is plenty of life to be had.</p>
<p>Things like the momentum around <a target="_blank" title="" href="http://startupweekend.com/columbus-startup-weekend/">startup weekend</a> and the buzz about <a target="_blank" title="" href="http://www.podcampohio.com/">podcamp ohio</a> just go to show that plenty is going on.&nbsp; <a target="_blank" title="" href="http://soldierant.net/">Bryce</a> is seriously trying to get some <a target="_blank" title="" href="http://groups.google.com/group/columbus-coworking">coworking</a> started (we've been meeting on Fridays). Today I heard that Columbus had the 8th most active blogging community.</p>
<p>This turned into a 'Columbus in general is pretty great' and not a
'Servee&nbsp; is working out well in Columbus' but whatever, it's worth it.&nbsp;
What do you like about being in Columbus?</p>
<p><br /></p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/Running_Your_Website_Should_Be_E/</id>
    <title>Running Your Website Should Be Easier</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/Running_Your_Website_Should_Be_E/"/>
    
    <updated>2009-01-11T20:08:55Z</updated>
    <published>2009-01-11T20:10:07Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I recently posted about how setting up and managing a web-site
doesn't have to feel like you're buying a used car from a traveling
salesman.&nbsp; There is another way.</p><p>It's the 21st century, and managing your web site does not have to be a task for the super-geek elite.</p><p>You can do this, and you can maintain good design and practical, powerful, easy to use tools. </p><p>On the web separating design, functionality, and content has emerged as an important idea.&nbsp; This makes all parties in the chain <strong>much</strong>
happier.&nbsp; Content creators and site managers no longer have to worry
about 'what if this makes my site look bad?'.&nbsp; Designers don't have to
worry about 'how do I get the navigation to drop down horizontally?'.&nbsp;
Developers don't have to worry about 'How in the world do I get these
margins to fit?'.&nbsp; Separating these ideas makes the process of running
your website painless for all parties, and the bottom line of that is
cost-reduction.</p><p>Like I've said before, we call it <a target="_blank" title="Servee" href="http://www.servee.com/">Servee</a>.
Servee gives you powerful tools like a calendar, podcast, and a blog
(and many more).&nbsp; They are easy to use, and work with whatever design
that your artist can come up with.&nbsp; Servee means that you don't need to
pay for custom solutions for every problem.&nbsp; They mean that there are <strong>standards</strong> and you don't have to worry that somebody is taking you for a ride.</p><p><br /></p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/Twitter_me_this/</id>
    <title>Twitter me this</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/Twitter_me_this/"/>
    
    <updated>2009-01-11T20:08:54Z</updated>
    <published>2009-01-11T20:10:06Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            Free Idea for the masses...

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Today on Twitter I had an exchange with a guy who I have yet to meet in real life (but we're at least from the same town, thanks <a target="_blank" title="" href="http://www.twitter.com/genuinechris">@genuinechris</a>.&nbsp; His name as far as I know is just <a target="_blank" title="" href="http://ikeif.net">ikeif</a>.&nbsp; He was a bit annoyed at all of the twitter apps that have yet to inevitably pop up (tweet these shoelaces or some-such).&nbsp; It did get me thinking however, and the idea was developed, in about 4 exchanges between he and I.</p><p>Here it is (ikeif...I developed it further in my own head).&nbsp; You're driving down the road, or otherwise somewhere where you aren't listening to your iPod.&nbsp; You hear a song, and like it, but you don't know what it is.&nbsp; OH. NO.&nbsp; You don't even have friends that you can ask, because you're too embarrassed to tell them that you listen to the actual radio.</p><p>What do you do? you tweet the call letters of the station, to, I don't know, say '@radioindex'&nbsp; if it finds it, and if the station is good enough, radioindex will pull their playlist and cross-reference it with the time you tweeted (twat??) and it will tell you what the song was.&nbsp; Not only that, but it will put, in your twitter profile, a link to the radio station's stream.&nbsp; That way, instead of telling your friends about your embarassing radio habit, you tell them about this great new song you discovered. </p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/Image_Processing_with_free_tools/</id>
    <title>Image Processing with free tools.</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/Image_Processing_with_free_tools/"/>
    
    <updated>2009-01-11T20:08:53Z</updated>
    <published>2009-01-11T20:10:05Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            Don't even bother if you are on IE 6, go out and get a modern browser.

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>I'm not a signals guy, so digital image processing isn't something I normally do.&nbsp; I'm just going to make some notes.&nbsp; Free Image processors (Looking at you GD tools) Don't take good care of PNGs.</p>
<p>Exhibit A: Uploaded via FTP</p>
<p><img title="issac-.png" src="../../../resources/userUploads/issac-.png" alt="" width="384" height="279" /></p>
<p>Beautiful.&nbsp; Thank you <a href="http://kkellydesign.com" target="_blank">Kasey.</a> What a nice avatar to post to places like <a href="http://www.twitter.com/issackelly" target="_blank">Twitter</a> and <a href="http://www.disqus.com/people/issackelly/" target="_blank">Disqus</a>.</p>
<p>&nbsp;</p>
<p>But Wait! Exhibit B:</p>
<p><img title="Me weird backgrounds" src="../../../resources/userUploads/issac.png" alt="" /></p>
<p>What happens!? When you run it through GD tools to do a simple shrink, the filesize gets bigger, the colors are distorted, and it adds all that black shit to the background. (as you can see on my twitter and disqus avatars as well).&nbsp; This was run through a script that fits the image to the width of my content window (a la <a href="http://www.servee.com" target="_blank">Servee</a>)</p>
<p>If I'm missing something, please let me know.</p>
<p>Anybody else had these problems?</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/The_Internet_is_not_a_used-car_l/</id>
    <title>The Internet is not a used-car lot</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/The_Internet_is_not_a_used-car_l/"/>
    
    <updated>2009-01-11T20:08:52Z</updated>
    <published>2009-01-11T20:10:04Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Gutenberg invented the printing press 6 centuries ago.&nbsp; By today's standards, using a printing press is a very grueling process.
The problem is that business on the internet grew up around the same
processes that were used to print the King James Bible in 1611.</p>
<p>â€¦</p>
<p>When you set up your website, from my experience, chances are that you: <br />
</p>
<p>1) Found somebody you knew who makes websites, or knows how to use dreamweaver.</p>
<p>2) Went to craigslist.</p>
<p>3) Hired an ad agency or a or a designer to make you a website.</p>
<p>What happens next? You go back and forth on how it gets set up, and
what you want it to say.&nbsp; No matter how much time they spend with your
business, they don't know it like you do, they don't know what strikes
your customers, or how to reach your audience like you do.</p>
<p>When your site is finally online, you get mediocre tools, at best, to manage your site. When you want updates, you are back to some archaic process, like this was 1987 and you were writing a newspaper column. </p>
<p>1) Call/E-mail your web guru.</p>
<p>2) Wait;</p>
<p>3) Read it, they missed two main points, Call/E-mail your web guru.</p><p>4) Back online in the correct form.</p>
<p>5) Wait three days -- You want something else up -- Go to step one.</p>
<p>â€¦</p>
<p>That's the problem, there in the "wait".&nbsp; This is the internet, and
we have tools to do this so you don't have to wait, and so you don't
have to rely on your web guru; You don't have to pay their hourly
rates, and you don't have to settle for mediocre.</p>
<p>â€¦</p>
<p>Like I said, the internet, as far as business is concerned, grew up around the advertising and the PR industry. <br />
</p>
<p>I grew up around the internet, and there is a better way than the used car, nickel-and-dime model of website creation and I'll be addressing that later this week in another post. </p><p>For now, subscribe to my RSS for updates.<br />
</p>
<p>â€¦</p>
<p>What do you think? Let me know in the comments.</p>
<p><br /></p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/Why_comments_should_be_normalize/</id>
    <title>Why comments should be normalized</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/Why_comments_should_be_normalize/"/>
    
    <updated>2009-01-11T20:08:51Z</updated>
    <published>2009-01-11T20:10:03Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            I use Disqus

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>1) I only comment on things that you have to register for on VERY rare occasion.</p><p>2) If I have to register, and I comment, I won't come back (unless you are <a title="" href="http://lifehacker.com">Lifehacker</a>, chances are, you aren't)</p><p>3)If you use disqus, I get an e-mail that says I got replied to.&nbsp; That is crucial to me coming back to your site.</p><p>4) Easier to spot/find trolls.</p><p>Do all of us a favor, and use <a title="" href="http://disqus.com">Disqus</a> or something similar, it's easy to integrate, <br />and it will help out your return rate on the chance that you write something that I want to comment on in the first place.&nbsp; </p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/How_I_got_Ubuntu_Working_for_me/</id>
    <title>How I got Ubuntu Working for me</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/How_I_got_Ubuntu_Working_for_me/"/>
    
    <updated>2009-01-11T20:08:50Z</updated>
    <published>2009-01-11T20:10:02Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            ..or not, who knows at this point.

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Ok, I'm just going to go through the steps that I went through to get my ubuntu desktop up and running with the environment that I like::</p><p>First: I went through and selected (via synaptic) all the things I needed to make my desktop a viable testing-server for my code:</p><p>git</p><p>mysql5</p><p>php5</p><p>apache2</p><p>phpmyadmin</p><p>tons of php5 modules (IMAP, GD, XML, MYSQL, PEAR...)</p><p>gedit-plugins</p><p>filezilla</p><blockquote><p>
sudo apt-get install build-essential automake libtools<br /></p></blockquote><p>Those are the easy parts; Now I want TV out on my Radeon 8500+ (autoconfiged to be R200, or 8500 [LE]) Turns out that's a major pain; no suprise, it's probably the third or fourth time I've tried with this video card.</p><p>In short, not happening.&nbsp; Maybe an Nvidia card will help. :-/ Won't do anything until I'm sure though.&nbsp; </p><p><br /></p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/Dan_Fog_Creek_Software/</id>
    <title>Dan! Fog Creek Software!</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/Dan_Fog_Creek_Software/"/>
    
    <updated>2009-01-11T20:08:48Z</updated>
    <published>2009-01-11T20:10:00Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            Finally, a really positive customer service experience.

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Customer Service success story:</p><p>I'm running a <a title="" href="http://www.servee.com">startup </a>with one other guy.</p><p>Currently I'm making most of the day-to-day decisions of how it's going to be run, Version Control, Bug Tracking, Documentation Styles, Accounting, Sales Directions, Contact Management, Etc.</p><p>Recently I've been working on bug tracking and project management, and I tried a number of different apps. Which I won't go into; This is about a great customer-service experience I had with <a title="" href="http://fogcreek.com">Fog Creek Software</a>.</p><p>â€¦</p><table class="BwDhwd"><tbody><tr><td class="zyVlgb XZlFIc"><table class="O5Harb"><tbody><tr><td><div class="xUReW"><span email="joel.spolsky@fogcreek.com" class="EP8xU">Joel Spolsky</span> <span class="tQWRdd">to <span email="issac.kelly@gmail.com" class="Zv5tZd">me</span> </span></div></td></tr></tbody></table></td><td class="i8p5Ld"><div class="XZlFIc"><span class="D05ws" idlink=""></span>&nbsp;<span id="1fka" class="rziBod" title="Sat, Mar 1, 2008 at 11:03 AM" alt="Sat, Mar 1, 2008 at 11:03 AM">Mar 1 (3 days ago)</span> <span class="KaaYad"></span></div></td><td class="i8p5Ld"><div class="JbJ6Ye"><table class="gQ8wIf" id="1fk8"><tbody><tr><td class="cTzXV LtBCcf t9K9Me" idlink=""><img class="eChx3e DC6qBf" src="https://mail.google.com/mail/images/cleardot.gif" /></td><td class="cTzXV t9K9Me" idlink=""><div class="SvrlRe"><br /></div></td><td class="t9K9Me"><br /></td><td class="wtnCQd tP6gIf t9K9Me"><img class="eChx3e S1nudd" src="https://mail.google.com/mail/images/cleardot.gif" /></td></tr></tbody></table></div></td></tr></tbody></table>
<p>Hi!

Thank you again for trying FogBugz On Demand. I just wanted to drop you
a note to see if everything was OK and if you have any questions about
how FogBugz works.
Have you found the wiki yet? It is one of the many new features in
FogBugz 6.0 -- you can use the wiki for any team documentation:
specifications, requirements documents, knowledge base articles, status
reports, internal technical documentation, or external end-user
documentation!

When you subscribe to FogBugz On Demand, you can continue bug tracking
uninterrupted. You can subscribe by logging on to your account and
clicking on the "Your Account" link:&nbsp;[edited]


Best wishes,</p>
<p><span class="nfakPe">Joel</span> Spolsky, Founder</p><p>â€¦</p><p>So, I got a canned e-mail from Joel.&nbsp; Yes _THE_ Joel.&nbsp; I was more suprised that it contained an e-mail address with his name in it, then the fact that it was his signature at the bottom.&nbsp; With this in mind, I eagerly clicked "Reply"</p><p>â€¦</p><p><span class="nfakPe">Joel</span>,<br /><br />I love FogBugz and I'll most likely be purchasing a few licenses soon; but here is my issue:<br /><br />I have a shared hosting acct with mosso that I run my operations on (Nearly every platform imaginable, php4-5, asp, IIS 6 and 7)<br />
BUT they are pretty strict on what you can install, Do you know if FogBugz works with Mosso?<br /><br />If
not, I have a crappy little linux box in my basement that I use as a
testing server (Apache2 php5 mysql 4) If I purchased two licenses for
that, and I upgraded my testing server, would I be able to migrate w/o
another fee?<br />
<br />ALSO!<br /><br />I read your article on why you write FogBugz in your
own language, and I was wondering if you've ever licensed that one
out....long shot I know...but it may work for a project of mine if so.<span id="q_1187564676abcfea_1" class="WQ9l9c"></span></p><font>-- <br />-------<br />Issac Kelly<br /><a href="http://issackelly.com/" target="_blank">issackelly.com</a><br />--------------------------<br /><br />â€¦<br /><br />So, I knew it was a long shot on everything that I was asking about (esp <a title="" href="http://www.joelonsoftware.com/items/2006/09/01b.html">wasabi</a>), but, eh, why not; Here comes the kicker:<br /><br />â€¦<br /><br /></font><table class="BwDhwd"><tbody><tr><td class="zyVlgb XZlFIc"><table class="O5Harb"><tbody><tr><td><div class="xUReW"><span email="customer-service@fogcreek.com" class="EP8xU">Fog Creek Customer Service</span> <span class="tQWRdd">to <span email="issac.kelly@gmail.com" class="Zv5tZd">me</span> </span></div></td></tr></tbody></table></td><td class="i8p5Ld"><div class="XZlFIc"><span class="D05ws" idlink=""></span><span id="1fl7" class="rziBod" title="Mon, Mar 3, 2008 at 2:13 PM" alt="Mon, Mar 3, 2008 at 2:13 PM">2:13 PM (19 hours ago)</span> <span class="KaaYad"></span></div></td><td class="i8p5Ld"><div class="JbJ6Ye"><br /></div></td></tr></tbody></table><p>Hi! </p><p>
Joel passed along your email and asked me to get back to you.

Thanks for your email. &nbsp;I don't have any direct knowledge of mosso, but I can tell you from experience that running <span class="nfakPe">FogBugz</span>
on a shared server is generally a hassle, for the exact reason you
mention. &nbsp;You can always look at this list, though to see if they would
go for it (for Unix): <a href="http://www.fogcreek.com/FogBugz/docs/60/topics/setup/UnixSystemRequirements.html" target="_blank">http://www.fogcreek.com<br />/<span class="nfakPe">FogBugz</span>/docs/60/topics/setup<br />/UnixSystemRequirements.html</a>

You can move this to as many different installs as you like, but I'm a
little nervous about an "old server," simply because our memory
minimums for <span class="nfakPe">FogBugz</span> 6 are now 2 Gb. &nbsp;I just don't want you to install it there and have it be painfully slow.

We do not license out Wasabi, I'm afraid.
</p><strong><br />If you only need two licenses, why not take advantage of the Student
and Startup Edition? &nbsp;As long as you have two or fewer users, it is
completely free with our On Demand system. &nbsp;Just sign up for a trial
and then go to Settings -&gt; Your <span class="nfakPe">FogBugz</span> On Demand Account to chaneg to the Student and Startup Edition edition.<br /><br /></strong>&nbsp;Let me know if you have any other questions.

Regards,

<p>
Dan</p><font><br />â€¦<br /><br />Dan! Thank you Dan! Not only did he give me a VERY thorough answer to my question.&nbsp; He saved me $400(+ server upgrades), and got his company (not much) in the process.&nbsp; Now I understand that they do this in hopes that I will one day have more than two users at my startup, and I suppose I'll never know, but I was ready to spend that money.<br /><br />â€¦ <br /><br />Here's to you fog creek software. <br /><br /></font>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/Switching_Text_Editors_-_The_Beg/</id>
    <title>Switching Text Editors - The Beginning</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/Switching_Text_Editors_-_The_Beg/"/>
    
    <updated>2009-01-11T20:08:47Z</updated>
    <published>2009-01-11T20:09:59Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            ..just read that it's like learning a new language, so I'll document it here.

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Ok, so I've <a title="" href="http://codeulate.com/?p=12">heard recently that switching</a> editors is like learning a new programming language.&nbsp; Not that THAT's hard, but it's time consuming.&nbsp; So, I'm switching from free ForgEdit to not free Textmate.&nbsp; They're giving me 30 days to decide if I want it, and I'll write one post a week about this for march.</p><p><br /></p><p>Edit 4/23:&nbsp; So I didn't write one a week about this.&nbsp; turns out it was completely uneventful.&nbsp; Textmate is great, and the file browser integrated with it that makes it work like a project view is very cool, but that's about all I've gotten into so far.</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/2009/01/11/First_post/</id>
    <title>Testing Podcasting</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/2009/01/11/First_post/"/>
    
    <updated>2009-01-11T20:08:45Z</updated>
    <published>2009-01-11T20:09:57Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            

        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p><a href="http://www.issackelly.com/resources/userUploads/024.mp3" class="media"> Link to an mp3</a>link</p>
        </div>
    </content>
</entry>
    
        
<entry xml:base="http://issackelly.com/">
    <id>http://issackelly.com/blog/1987/06/20/seekret/</id>
    <title>seekret</title>
    <link rel="alternate" type="text/html" href="http://issackelly.com/blog/1987/06/20/seekret/"/>
    
    <updated></updated>
    <published>1987-06-20T17:18:47Z</published>
    
    <author>
         <name></name>
    </author>
    
    <summary type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Drag this link to your toolbar, click it to decypher stuff! <a href="javascript:(function()%7Bvar%20encode_map%3D%7B%22a%22:%22%C3%A5%22,%22b%22:%22%E2%88%AB%22,%22c%22:%22%C3%A7%22,%22d%22:%22%E2%88%82%22,%22e%22:%22%C2%B4%22,%22f%22:%22%C6%92%22,%22g%22:%22%C2%A9%22,%22h%22:%22%CB%99%22,%22i%22:%22%CB%86%22,%22j%22:%22%E2%88%86%22,%22k%22:%22%CB%9A%22,%22l%22:%22%C2%AC%22,%22m%22:%22%C2%B5%22,%22n%22:%22%CB%9C%22,%22o%22:%22%C3%B8%22,%22p%22:%22%CF%80%22,%22q%22:%22%C5%93%22,%22r%22:%22%C2%AE%22,%22s%22:%22%C3%9F%22,%22t%22:%22%E2%80%A0%22,%22u%22:%22%C2%A8%22,%22v%22:%22%E2%88%9A%22,%22w%22:%22%E2%88%91%22,%22x%22:%22%E2%89%88%22,%22y%22:%22%C2%A5%22,%22z%22:%22%CE%A9%22%7D%3Bvar%20decode_map%3D%7B%22%C3%A5%22:%22a%22,%22%E2%88%AB%22:%22b%22,%22%C3%A7%22:%22c%22,%22%E2%88%82%22:%22d%22,%22%C2%B4%22:%22e%22,%22%C6%92%22:%22f%22,%22%C2%A9%22:%22g%22,%22%CB%99%22:%22h%22,%22%CB%86%22:%22i%22,%22%E2%88%86%22:%22j%22,%22%CB%9A%22:%22k%22,%22%C2%AC%22:%22l%22,%22%C2%B5%22:%22m%22,%22%CB%9C%22:%22n%22,%22%C3%B8%22:%22o%22,%22%CF%80%22:%22p%22,%22%C5%93%22:%22q%22,%22%C2%AE%22:%22r%22,%22%C3%9F%22:%22s%22,%22%E2%80%A0%22:%22t%22,%22%C2%A8%22:%22u%22,%22%E2%88%9A%22:%22v%22,%22%E2%88%91%22:%22w%22,%22%E2%89%88%22:%22x%22,%22%C2%A5%22:%22y%22,%22%CE%A9%22:%22z%22%7D%3Bvar%20decode%3Dfunction(s)%7Bns%3D%5B%5D%3Bfor(a%20in%20s)%7Bns.push(decode_map%5Bs%5Ba%5D%5D%7C%7Cs%5Ba%5D)%3B%7Dreturn%20ns.join(%27%27)%3B%7D%3Bvar%20encode%3Dfunction(s)%7Bns%3D%5B%5D%3Bfor(a%20in%20s)%7Bns.push(encode_map%5Bs%5Ba%5D%5D%7C%7Cs%5Ba%5D)%3B%7Dreturn%20ns.join(%27%27)%3B%7D%3B%24(%22.post-content%22).each(function()%7B%24(this).html(decode(%24(this).html()))%3B%7D)%3B%7D)()%3B">Decypher</a></p>
        </div>
    </summary>
    
    <content type="xhtml" xml:lang="en">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>Drag this link to your toolbar, click it to decypher stuff! <a href="javascript:(function()%7Bvar%20encode_map%3D%7B%22a%22:%22%C3%A5%22,%22b%22:%22%E2%88%AB%22,%22c%22:%22%C3%A7%22,%22d%22:%22%E2%88%82%22,%22e%22:%22%C2%B4%22,%22f%22:%22%C6%92%22,%22g%22:%22%C2%A9%22,%22h%22:%22%CB%99%22,%22i%22:%22%CB%86%22,%22j%22:%22%E2%88%86%22,%22k%22:%22%CB%9A%22,%22l%22:%22%C2%AC%22,%22m%22:%22%C2%B5%22,%22n%22:%22%CB%9C%22,%22o%22:%22%C3%B8%22,%22p%22:%22%CF%80%22,%22q%22:%22%C5%93%22,%22r%22:%22%C2%AE%22,%22s%22:%22%C3%9F%22,%22t%22:%22%E2%80%A0%22,%22u%22:%22%C2%A8%22,%22v%22:%22%E2%88%9A%22,%22w%22:%22%E2%88%91%22,%22x%22:%22%E2%89%88%22,%22y%22:%22%C2%A5%22,%22z%22:%22%CE%A9%22%7D%3Bvar%20decode_map%3D%7B%22%C3%A5%22:%22a%22,%22%E2%88%AB%22:%22b%22,%22%C3%A7%22:%22c%22,%22%E2%88%82%22:%22d%22,%22%C2%B4%22:%22e%22,%22%C6%92%22:%22f%22,%22%C2%A9%22:%22g%22,%22%CB%99%22:%22h%22,%22%CB%86%22:%22i%22,%22%E2%88%86%22:%22j%22,%22%CB%9A%22:%22k%22,%22%C2%AC%22:%22l%22,%22%C2%B5%22:%22m%22,%22%CB%9C%22:%22n%22,%22%C3%B8%22:%22o%22,%22%CF%80%22:%22p%22,%22%C5%93%22:%22q%22,%22%C2%AE%22:%22r%22,%22%C3%9F%22:%22s%22,%22%E2%80%A0%22:%22t%22,%22%C2%A8%22:%22u%22,%22%E2%88%9A%22:%22v%22,%22%E2%88%91%22:%22w%22,%22%E2%89%88%22:%22x%22,%22%C2%A5%22:%22y%22,%22%CE%A9%22:%22z%22%7D%3Bvar%20decode%3Dfunction(s)%7Bns%3D%5B%5D%3Bfor(a%20in%20s)%7Bns.push(decode_map%5Bs%5Ba%5D%5D%7C%7Cs%5Ba%5D)%3B%7Dreturn%20ns.join(%27%27)%3B%7D%3Bvar%20encode%3Dfunction(s)%7Bns%3D%5B%5D%3Bfor(a%20in%20s)%7Bns.push(encode_map%5Bs%5Ba%5D%5D%7C%7Cs%5Ba%5D)%3B%7Dreturn%20ns.join(%27%27)%3B%7D%3B%24(%22.post-content%22).each(function()%7B%24(this).html(decode(%24(this).html()))%3B%7D)%3B%7D)()%3B">Decypher</a></p>
        </div>
    </content>
</entry>
    
</feed>
