CAT | Code
Last weekend I biked my first century. It was an “easy” course and was supposed to be a beautiful day. I wasn’t expecting anything to go wrong, but as luck would have it, a lot did. I struggled to finish.
Looking back, I think there are a few reasons why it wasn’t as easy as I had hoped:
- I got 5 hours of sleep the night before
- I didn’t train much
- I didn’t drink enough water the night/week before
- I got lost, and ended up biking an extra six miles
Whoa, back up… what was that last one?
“I ended up biking an extra six miles”
I’d like to call these my “bonus miles”. Even though I went off-course at the time, lost a few minutes off my time, and made the rest of the race a little harder… it forced me to push myself a further, get a better workout, and gave me the confidence that if needed, I can go even further. It also taught me a valuable lesson — don’t get lost. So even though it was a short-term loss, it ended up being a long-term gain.
So how does this relate to programming?
Bonus coding. Sometimes we get lost in what we are programming. Sometimes it’s a miscommunication. Sometimes it’s a false assumption. But often times we find ourselves in a place where we’ve coded for a long amount of time and end up having to throw it all away. It’s not the best feeling in the world — it actually makes you feel like you’ve just wasted valuable time from your life. But it’s more than that. You’ve gained more experience in the wrong way to code. Like biking, it’s a short-term loss, but a long-term gain. Just learn from it and try not to repeat the same mistakes.
Just remember in your coding that your career isn’t a sprint, it’s a century — a marathon. Go at a steady pace, learn from your mistakes, and don’t get yourself down at short-term losses.
A coworker of mine, Dustin McQuay, released the YUI Magnifier, a YUI implementation of other popular image zoom utilities. We were actually surprised to see that nothing else like it already existed for YUI, so Dustin took the challenge of building his own, with the hopes that it might be included in other larger YUI libraries.
It boasts the features:
- Display a magnified portion of an image, which is controlled by where the mouse is hovering over the image
- Control over styling
- Control over location of magnification lens
- Magnified image can be wrapped by a larger element
Though the release wasn’t very public, it was still quite an accomplishment. It happens to be one of the first open-source releases from Backcountry.com (preceded to my knowledge by only Bucardo, a Postgres replication application written for Backcountry.com by Endpoint). It was originally designed to be used for our 900×900 images, but got cut after development has essentially finished due to changed requirements.
It’s a pretty solid application, and hopefully the start of more open source to be coming out of Backcountry.com
This was a python script created by me a while ago to automate voting for a particular user. It may not work anymore, as this script was written quite a while ago. It’s not commented or anything. Here is the original post:
I created a small script to do the clearing of the cookies for you and everything. I tried to have it solve the captcha for you automagically, but it just wasn’t happening (I used ocrad and tesseract, and cleaning the image using imagemagick first). Anyways, you can sit there all day and enter the captchas to keep voting.
A few requirements:
* I wrote it using python 2.5.1. Not sure what other version it will work on.
* PIL required
* mechanize required
both of the required modules are available in the ubuntu repositories. I think that’s all you need, let me know if you run into any troubles.
sudo apt-get install python-imaging python-mechanize
A couple notes about it:
* You don’t have to hit “submit”, you can just press enter
* check the console for updates on whether it was submitted ok or not
Let me know if you want help learning how to set it up.
#!/usr/bin/python # Displays the Captcha from http://basketball.seniorclassaward.com/public/men/vote.aspx?usr=public&gen=M # so that you can enter it so that Jacee Carroll will win. It automagically keeps track/clears cookies (via mechanize) # so you can submit more than once every 24 hours # Written by Josh import pygtk, gtk import StringIO import ImageFile import re from mechanize import Browser pygtk.require('2.0') # taken from http://www.daa.com.au/pipermail/pygtk/2003-June/005268.html def image_to_gtkpixbuf(image): file = StringIO.StringIO () image.save (file, 'ppm') contents = file.getvalue() file.close () loader = gtk.gdk.PixbufLoader ('pnm') loader.write (contents, len (contents)) pixbuf = loader.get_pixbuf () loader.close () return pixbuf class Submitter: def get_image(self): # Get the image image_url = 'http://basketball.seniorclassaward.com/Captcha.aspx' image_response = self.br.open_novisit(image_url) p = ImageFile.Parser() while 1: data = image_response.read(1024) if not data: break p.feed(data) image_response.close() return p.image def __init__(self): self.br = Browser() self.br.set_handle_robots(False) self.url = 'http://basketball.seniorclassaward.com/public/men/vote.aspx?usr=public&gen=M' self.br.open(self.url) self.captcha = self.get_image() def submit(self, captcha_text): captcha_textbox = 'ctl00$DefaultContentPlaceholder$PublicBallot$CaptchaTextBox' jaycee_checkbox = 'ctl00$DefaultContentPlaceholder$PublicBallot$BallotCheckBoxList$0' br = self.br br.select_form( name='aspnetForm' ) br[captcha_textbox] = captcha_text br[jaycee_checkbox] = ['on'] response = br.submit() r = response.read() if re.search(r"ATTENTION:\\n([^']+)'", r): res = re.search(r"ATTENTION:\\n([^']+)'", r) print "Error submitting: " + res.groups()[0] return False elif re.search(r"COMPLETE:\\n([^']+)'", r): res = re.search(r"COMPLETE:\\n([^']+)'", r) print "SUCCESS! " + res.groups()[0] return True class Control: def __init__(self): self.window = gtk.Window() self.window.connect("destroy", gtk.main_quit) self.submitter = Submitter() self.box = gtk.HBox(False, 0) self.window.add(self.box) self.submitButton = gtk.Button("Submit") self.submitButton.connect('clicked', self.submit) self.box.pack_start(self.submitButton, True, True, 0) self.submitButton.show() self.text = gtk.Entry() self.text.connect("activate", self.submit) self.box.pack_start(self.text, True, True, 0) self.text.show() self.set_image(self.submitter.captcha) self.box.pack_start(self.image, True, True, 0) self.image.show() self.box.show() self.window.show() self.text.grab_focus() def set_image(self, image): self.image = gtk.Image() self.image.set_from_pixbuf( image_to_gtkpixbuf(image)) def change_image(self): self.box.remove( self.image ) self.set_image( self.submitter.get_image() ) self.box.pack_start(self.image, True, True, 0) self.image.show() return True def submit(self, evt): if self.submitter.submit( self.text.get_text().upper() ): # reset the submitter self.submitter = Submitter() self.change_image() self.text.set_text('') self.text.grab_focus() def main(): gtk.main() return 0 if __name__ == "__main__": Control() main()
This was a just-for-fun thing for me, so I could test out some various web tools for python. I tried simple urllib/urllib2, ClientForm, ClientCookies, and mechanize, and found mechanize to be the most robust and easiest to use, although it was missing out on some features that I thought may be useful (as higher-level modules normally do).
Also, I didn’t like this:
if re.search(r"ATTENTION:\\n([^']+)'", r): res = re.search(r"ATTENTION:\\n([^']+)'", r)
