Wednesday, April 11, 2012

dev=1

Sometimes you want to be able to toggle dev=1 on a url. This can easily be done with javascript. You can create a link on a page with href="javascript:..." then right-click->save this link as a bookmark in your bookmark toolbar.

The following link is my attempt to write this, you can click it now, or bookmark it --> Toggle Dev

Let's read it line by line:
var alocation = window.location.search.toString(); // save the ?query string

// determine if when we add dev=1 if we need a ? or an &
var questoramp = alocation.indexOf('?') != -1 ? '&' : '?'; 

// if dev=1 exists, remove it, otherwise add it
var next = alocation.match(/[\?&]dev=1/) ? alocation.replace(/[\?&]dev=1/,'') : alocation + questoramp + 'dev=1'; 

// handle special case where dev=1 is at the beginning of the url
next = alocation.match(/\?dev=1&/) ? alocation.replace(/dev=1&/,'') : next; 

// update the window location
window.location.href=window.location.pathname + next + window.location.hash;

You have to make sure you don't forget the window.location.hash, or else you will get the dev=1 in the wrong part of the url.

=====================

I also wanted a way to toggle my web server from live apache(https) to a single threaded dev server (8080)

Here is my attempt: Toggle 8080

Again, here it is line by line
// save the whole url
var alocation = window.location.href.toString(); 

// if you see 8080 in the url, remove it and change the protocol to https, otherwise add it
var next = window.location.port == '8080' ? alocation.replace(/:8080/,'').replace(/http/,'https') : 'http://' + window.location.host + ':8080' + window.location.pathname + window.location.search + window.location.hash; 

// update the window location
window.location = next;

Hope this helps.

Friday, March 9, 2012

Logic chains in javascript and python

Let's talk about javascript.  What happens when you have a function like this:

function(x) {
    x = x || 'default'
    ...
}

This is useful when you want to have a function where x is optional.  When you don't pass a value to your function x is treated as undefined and the statement is read as x = undefined || 'default'.  Whenever you have:

somevariable = statement || statement || statement ... || statement

the variable will get assigned the first true value from left to right or the last false value.

But what happens when you do this?
x = [] || 'kittens'
you would think that [] evaluates as a false value, but in javascript an empty list is true so x becomes []

lets try this in python
x = [] or 'kittens'
This evaluates the way you think, x becomes 'kittens'.

Now, I'm not saying anyone would have statements like this, but I just wanted you to think about the little differences that languages have and how they can cause unforeseen bugs.

The same thing applies to empty objects:
in javascript:
x = {} || 'yarg' /* yields {} */
in python
x = {} or 'yarg' /* yields yarg */
Complimentary to the 'or' examples, 'and's behave the opposite.  If you have:
somevariable = statement && statement && ... && statement
your variable will get the first false statement or the last true statement.

This works pretty well in javascript/python

x = 'lol' and 'heh' and 'doh'
x = 'lol' && 'heh' && 'doh'
/* x has doh */
but again, try this:
// javascript
x = 'lol' && [] && 'doh' /* yields 'doh' */

# python
x = 'lol' and [] and 'doh' /* yields [] */
Now you know; and knowing is half the battle.


Thursday, March 1, 2012

Fun Emacs Prank

I noticed while using emacs you can use this handy program called emacsclient to perhaps open a file or run a command on emacs. I took this as an opportunity to have fun with my co-workers.

They like to run emacs with X-Forwarding on remote hosts that are the development hosts. Its easy to log into their remote host and do something like this:
emacsclient --no-wait ~/prank-file

This would open the file on their currently running emacs. Sounds great right? You could make some ascii picture of something nsfw and then just run good old emacsclient to turn their day around!

Anywho, this wasn't enough for me. I wanted to make it so the file would change and maybe scroll across the screen saying something like "LOL Kittens!". Or even you could try and make it invert the ascii art and then invert it back. Somewhat like you are flashing the text.

I first tried to get it so you could scroll the art across the screen (from left to right)
Example:
first iteration
LOL
CAT

second iteration
OL
AT

final iteration
L
T

I started out trying this:
columns=`head -n 1 /tmp/ascii-art-file | wc -c`; # get the number of columns in the text file

for x in seq 1 $columns; do
    cut -c $x-$columns /tmp/ascii-art-file > /tmp/scroll;
    emacsclient --no-wait /tmp/scroll; 
    sleep 5;
done;

This didn't work as expected. Emacs kept asking if I wanted to refresh the modified buffers.
I did some digging and it didn't seem like an easy solution. I wanted this to be something that would just appear on my co-worker's screen and cause mayhem.

After some more digging I found the handy emacs command: zone.
It does all fun stuff like scrolling your current buffer, or even dripping the text like the movie The Matrix.

I couldn't wait to find out that emacsclient came with --eval as an option. This allows you to run lisp on your emacs server. Checkmate.
I created this script:
/tmp/zone
#!/bin/sh

emacsclient --no-wait $1
emacsclient -e '(with-current-buffer "'`basename $1`'" (zone))'
sleep 5

This script ran fine. But sometimes emacsclient blocked when you ran zone. This wasn't ideal. So I added this to the beginning to kill the emacsclient every time you run zone:
ps -ef | grep emacsclient | grep -v grep | awk '{print $2}' | xargs --no-run-if-empty kill -9
Finally, to get this to run over and over, just put zone in a while loop:

while true; do /tmp/zone /tmp/ascii-art-file; done;
Happy pranking!

Friday, July 8, 2011

Code Review and Pair Programming

I was recently reading comments on Slashdot

While most developers agree that code reviews are a good thing, the people that don't like code review seem to think of it as a matter of the developer's skill level. If you write good code, then you don't need code reviews.

I don't believe this is right. At a big giant newspaper, or even for a book publisher, there are professionals that are really good writers. But this doesn't stop the publishers from hiring editors to review what they are writing. This is an example of feedback that ensures a high quality product. Even in school you can always agree that any paper you write is a better quality if you have at least one person proofread it first. I know I've gotten A's from papers that went through this process.

At my current job we do pair programming. I was skeptical at first, but this process ensures that every line of code checked in has been reviewed by a peer. I know this is not for everyone. It's an extreme diversion from the school of thought that programmers are best left alone in a cave.

Not only is code review built into pair programming, but it almost feels like an apprenticeship to new hires. It helps get them up to speed a lot faster than the old way where the new developer would bang their heads on code and then come ask a bunch of whiny questions to the more experienced developers. And usually the more experienced developers always give an indication that they don't have time to answer questions. When you pair, asking questions is part of your job and the more experienced person encourages you to stop them and explain what they are working on.

The final thing I like about pair programming is that it actually focuses you better. Let's say you are by yourself and feeling tired. You might want to goof off and go on Facebook or surf the web. When you are pairing, the other developer can help pick up slack, or you might help them. This is especially helpful during the after-lunch food coma.

Wednesday, March 17, 2010

Use data to do the work for you

When trying to use complex objects in with a remote API, I've noticed that there is a slow way to use the objects and a fast way. If you wanted to create one of these objects, you might not know the exact construction of this object. It might help to have an example of the object. Let's say the API gives you the ability to Read, Create, and Update these objects. You yourself only have client access to the api through python.

What you could do is try inspecting the object:
>>> obj = myApiAccess.getFoo(id=123)
>>> print dir(obj)
['__doc__', '__module__', 'id', 'name', 'description']

Let's try constructing the object and use the create method of the API since you want to create your own object without the UI:
>>> nextObj = Foo()
>>> nextObj.id = 123
>>> nextObj.name = "super cool object"
>>> nextObj.description = "created the slow way"
>>> myApiAccess.createFoo(nextObj)

This is fine for simple objects. But when you have complex nested objects, you will not be able to manually construct objects like this without getting frustrated and use slightly duplicated work. Let's say Foo objects now have a list of Bar objects. You would need to go construct each Bar object, then insert the bar object into Foo update Foo's fields, then run the create method.

>>> nextObj = Foo()
>>> nextObj.id = 123
>>> nextObj.name = "super cool object"
>>> nextObj.description = "created the slow way"
>>> barData = ['a','b','c']
>>> barList = []
>>> for b in barData:
barObj = Bar()
barObj.val = b
barList.append(barObj)
>>> nextObj.bars = barList
>>> myApiAccess.createFoo(nextObj)

A better way of doing this is by creating a mechanism to allow you to dump an object from the api to a json-like format and load it back.

You can then use the UI for your product to create example objects of how you want to construct your object. Then get the object and dump it to a file. Edit the field you want to change, then update or create an object based on this template.

When you dump the object it could look something like this:
{"api_class": "Foo",
"id": 123,
"name" : "super cool object",
"description" : "created the fast way",
"bars" : [
{"api_class": "Bar",
"val":"a"
},
{"api_class": "Bar",
"val":"b"
},
{"api_class": "Bar",
"val":"c"
}
]
}

Great! We have abstracted the blueprints of how to construct API objects. Dumping objects like this will involve 2 steps. First you turn the object into a python dictionary. Then you use simplejson to dump the object. Loading the object requires using simplejson to load the object, then you have a reverse parser that recursively creates objects. With this abstract construction module we can do the real work that we care about: interact with the API and create/update objects.

# this is an example creating an object by template

# a module you created to abstract object construction
import objectConstructionModule
# your client module
import clientApi

#initialize api access around here
# ...

fp = open('./FooTemplate')
jsonStr = fp.read()
fp.close()
pythonObj = simplejson.loads(jsonStr)
apiObj = objectConstructionModule.parseObj(pythonObj)
myApiAccess.createFoo(apiObj)

This method alone is useful for testing. You could have a file for each way you want the object to look before running some other test that uses the object.

We can even extend this to large scale testing. What if you wanted to create 1000 Foo objects? You could read in the template and try creating the object over and over. But this could run into constraints like unique names for the object.

To accomplish this, you could alter the json behavior to use a function that randomizes a part of the object that needs to be unique when you parse the object. What you need to do is make your parser understand that a list object could be a hidden function with parameters:

{
"api_class": "Foo",
"id": 123,
"name" : ["< function randName >", 10, "Rand"],
"description" : "created the fast way",
"bars" : []
}

Then in the module the loads the file could have a function randName:


import random
import simplejson
#letters and numbers
alphabet = map(chr,range(48,58))+map(chr,range(65,91))+map(chr,range(97,123))
def randName(length=10, prefix = ""):
global alphabet
retstr = ""
lenAlphabet = len(alphabet)
for x in range(0,length):
retstr = retstr + alphabet[int(random.random()*lenAlphabet)]
return prefix + retstr

fp = open('./FooTemplate')
jsonStr = fp.read()
pythonObj = simplejson.loads(jsonStr)
fp.close()
for x in range(0,1000):
# parseObj calls the randName function each parse
apiObj = objectConstructionModule.parseObj(pythonObj)
myApiAccess.createFoo(apiObj)

Of course this all depends upon your implementation of the json dumper/parser module as well as your API's behavior. But I just thought it was interesting how you can use data and functions to do more work for you. Also its always nice to have a way to inspect objects at a high level. That way the API client user doesn't have to know too much about how the objects are constructed to get started fast.