tag:blogger.com,1999:blog-89165454478034726592024-03-18T21:30:38.115-07:00Illicit TechnologyJustin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.comBlogger32125tag:blogger.com,1999:blog-8916545447803472659.post-3727095383087756172009-01-04T02:26:00.000-08:002009-01-04T02:43:29.079-08:00Pretty (or ugly, depending on your outlook) pictures of the current state of unemployment in the US<p>Combined 3-colors: Lighter is higher unemployment (i.e. dark is good) Red is change, Green is current, Blue is old:</p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLScTYXoROfzyReh4_0S-4N4ceBfYy6X-iusmv2_aP5pxUbdfgSYLlfiXvCgo9Hv6k__xR__Rix3FSRJpGiUWWgqvdh4_Q4D1ra29thF9yvYQ5KIImoHelPb1DVtq0N1mDWu1F2tAgpbM/s1600-h/color.png"><img style="cursor: pointer; width: 400px; height: 253px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLScTYXoROfzyReh4_0S-4N4ceBfYy6X-iusmv2_aP5pxUbdfgSYLlfiXvCgo9Hv6k__xR__Rix3FSRJpGiUWWgqvdh4_Q4D1ra29thF9yvYQ5KIImoHelPb1DVtq0N1mDWu1F2tAgpbM/s400/color.png" alt="" id="BLOGGER_PHOTO_ID_5287383231832018034" border="0" /></a><p>Old (lighter = worse):</p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAneH-kj348unBBu0xI_w08ipJOfsTPqIuFrtHtQ52p_0WOZ_ocIF8-D6WBLldu1WkRFrB7ECu3JUbzBI19faHQSlX5XqQk0DVts1Ryp2eHqfL95bwt6f64o8Va9MADtuQhEufMG8riQU/s1600-h/old.png"><img style="cursor:pointer; cursor:hand;width: 400px; height: 253px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAneH-kj348unBBu0xI_w08ipJOfsTPqIuFrtHtQ52p_0WOZ_ocIF8-D6WBLldu1WkRFrB7ECu3JUbzBI19faHQSlX5XqQk0DVts1Ryp2eHqfL95bwt6f64o8Va9MADtuQhEufMG8riQU/s400/old.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5287383596684705570" /></a><p>Change (lighter = worse):</p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj67rktFFWOxHQobkgDENAsNmPl93Ei-aHCHg_R-KSDPkbrl7C1HcDFr5wGEkeWYuVbQi76CC37nv3FNPOv59TGs_cS7oC5ZsKBvHUPcQTIqmEoBFFFXPnCY0hOYr1wZgUykEQKwnrpp_s/s1600-h/change.png"><img style="cursor:pointer; cursor:hand;width: 400px; height: 253px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj67rktFFWOxHQobkgDENAsNmPl93Ei-aHCHg_R-KSDPkbrl7C1HcDFr5wGEkeWYuVbQi76CC37nv3FNPOv59TGs_cS7oC5ZsKBvHUPcQTIqmEoBFFFXPnCY0hOYr1wZgUykEQKwnrpp_s/s400/change.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5287383588030197042" /></a></p><p>Now (lighter = worse, and note Michegan and Rhode Island are light enough they have to be bordered to be visible):</p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAJaZKAUDCknoEQ862f2uNscJCgRGzj1I9m1OjJlpBaByRSEF-z_WxTieJn2yBwlevLmNnZolP2CrzV3Tm4HSsbWUaMjI4uV02nKDjUx9kON4FQPfJirMM1MUu-rTu186_clvEAD4r9LI/s1600-h/total.png"><img style="cursor:pointer; cursor:hand;width: 400px; height: 253px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAJaZKAUDCknoEQ862f2uNscJCgRGzj1I9m1OjJlpBaByRSEF-z_WxTieJn2yBwlevLmNnZolP2CrzV3Tm4HSsbWUaMjI4uV02nKDjUx9kON4FQPfJirMM1MUu-rTu186_clvEAD4r9LI/s400/total.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5287383605591916722" /></a><p>Data from <a href="http://www.bls.gov/web/laumstch.htm">Bureau of Labor Statistics</a>, blank map from <a href="http://commons.wikimedia.org/wiki/File:Blank_US_Map.svg">Wikimedia Commons - Blank US Map.svg</a>, shading/edits by <a href="http://www.jaggederest.com/">Justin George</a>(me). Images <a href="http://commons.wikimedia.org/wiki/Commons:GNU_Free_Documentation_License">GFDL licensed</a>.</p>Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com0tag:blogger.com,1999:blog-8916545447803472659.post-6697959782784072162008-07-23T23:26:00.001-07:002008-07-23T23:27:11.782-07:00Amusing side effects of popular cultureAs a result of Dark Knight, I'm now getting 40-50 hits a day to my personal site, featuring the joker cheesehead down on the left side there.<br /><br />I was very confused as I watched the traffic spike, then I realized the movie came out.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com0tag:blogger.com,1999:blog-8916545447803472659.post-18232565365164003682008-07-22T10:23:00.001-07:002008-07-22T10:24:31.953-07:00Real-life Superpowers, part 1Horses store up to 50% of their red blood cells and can release them during endurance running. Self-doping, with the larger hearts needed to deal with the thicker blood that results.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com0tag:blogger.com,1999:blog-8916545447803472659.post-31163733893221455142008-07-18T01:05:00.000-07:002008-07-18T01:06:22.135-07:00Ubiquitous call recording, finally.https://www.speechtrack.com<br /><br />I've been wanting a service like this for as long as I can remember. Now they just need to offer inbound phone numbers that auto-record, and maybe a transcription service or speech-to-text.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com0tag:blogger.com,1999:blog-8916545447803472659.post-10719032675705121202008-06-28T01:17:00.000-07:002008-06-28T01:41:15.577-07:00Git tricks I've been using a lot<ul><li><h3><code>git add --patch</code></h3><p>Incredibly helpful for splitting up your patches into atomic commits.</p><p> I use this like mad when I've made a few different types of changes between committing. <small>(e.g. I find something that needs refactoring in the middle of adding a feature)</small></p><p>For hairier tasks, don't forget it's older brother, <code>git add --interactive</code>, which launches a file manager shell with more options and better status info</p></li><li><h3><code>git stash apply</code></h3><p>Git stash is a wonderful thing, but people often don't realize that the stash is a stack, not just a single object.</p><p>Using apply with an optional ref argument, you can pop things off the stack that date from before the most recent stash.</p><p> I use this as a whole project undo/redo for things not worth creating a branch for</p></li><li><h3><code>git rebase --interactive</code></h3><p>Oh the power. If you pass the right revisions into git rebase --interactive, you can essentially go back and edit every single commit made in the repo.</p><p> For extra fun, try nonlinear editing or cross-branch interactive rebasing.</p><p>My primary use for this is to squash commits into useful units of functionality, particularly when updating a production branch or the equivalent.</p><p>Caution: if you're publishing your changes to other people, using this can really piss them off. You can also drastically break your repo, so make sure you know what you're doing, or try it on a fresh clone</p></li><li><h3><code>git checkout -b branch_name remote/branch</code></h3><p>This is an interesting trick: you can create a local branch named something different than a remote branch, and set it to track the remote. Makes git pull work without having to specify a remote and branch to merge.</p></li><li><h3><code>git diff -Sstr</code></h3><p>This lets you pull out a change that relates to the string. If you want to see whole patches, play with <code>--pickaxe-all</code>, and for POSIX regex support use <code>--pickaxe-regex</code>.</p><p>Useful if you ever want to see who's using that bad idiom that you want to crush out of existence, or if you need to go back and find a chunk of lost code.</p></li></ul>Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com0tag:blogger.com,1999:blog-8916545447803472659.post-47693329508617648412008-06-05T12:35:00.000-07:002008-06-05T12:42:54.134-07:00Why you should always use SSH keys, not passwordsThere are three main reasons for using SSH keys over passwords:<br /><ul><li><h2>Security</h2><p>Since SSH keys are stored on your computer and never go over the wire, they are inherently more secure than passwords. Even if you pick a terrible passphrase for your SSH keys (or none at all), an attacker still has to get ahold of that key <span style="font-size: small">(barring someone patching your random number generator to return one of 2^10 numbers...)</span></p></li><li><h2>Segmentation</h2><p>With passwords, if everyone needs access to an account on one of your servers, then everyone has to know the same password. If one of your coworkers goes insane, you have to change the password (and probably a lot more than one) whereas with SSH keys, you just remove their key from the authorized_keys file and they're gone, nobody else has to worry about it.</p><p>Similarly, if people need access to some accounts and not others, you can segment access with keys much more easily than with passwords</p></li><li><h2>Speed</h2><p>Entering passwords gets old really quick. With the superb ssh-agent in use, you shouldn't ever have to do that, and as long as you remember to lock your computer when you leave it, you're as secure as if you were typing your password in every time</p></li></ul>Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com2tag:blogger.com,1999:blog-8916545447803472659.post-69441123512291440492008-05-28T23:19:00.000-07:002008-05-29T00:19:49.202-07:00Recommendation Letter redux: how to write a letter of recommendation for a friend<p>Since I wrote this short joking post about <a href="http://illicittech.blogspot.com/2007/08/from-friends-recommendation-letter.html">faux pas in a friend's recommendation letter</a>, I've been getting people asking me how to write a good recommendation letter.</p><p>For posterity and the Internet, here you go:</p><div><h2>Content:</h2><ul><li><h3>Above all, be professional.</h3><p>Remember, your friend / colleague / student is submitting this for something that is very important to them. Probably the most important part is making sure that it reads like something you'd submit to a scholarly journal, not something you'd comment on their myspace page with.</p></li><li><h3>Be real.</h3><p>Talk about them as you know them: write about the qualities they've shown through the experiences you've had with them. Don't fluff, bullshit, or otherwise go further than your experiences can warrant.</p></li><li><h3>Advocate</h3><p>Remember, they're trying to get something from someone with this. That job, college admission, or grad school means a lot to your friend, and you have the ability to directly affect their chances. On the other hand, don't advocate so much that you're written off as a cheerleader.</p></li><li><h3>Be specific</h3><p>If prompts are provided, make sure you nail every one of them. If they aren't, think about what you'd want in someone working or studying with you, and nail those points. Particularly, make sure you talk about communication skills, work ethic, and creativity, since those are pretty universally applicable.</p></li><li><h3>Don't just talk about the good things</h3><p>Make sure you discuss ways in which they're not perfect. Talk about how they worked on their problems, how they changed for the better, and how they overcame obstacles.</p></li><li><h3>Get other eyes on it</h3><p>Before you send that make-or-break document off, have other people read it and give you feedback. A fresh set of eyes can catch possibly credibility-damaging errors before you have to apologize for them.</p><p>In a pinch, drop me (<a href="mailto:justin.george@gmail.com?subject=Recommendation Letter Review">Justin George</a>) a note and I'll do a brain-dead check on it for you.</p></li></ul></div><div><h2>Style:</h2><p>Stylistically, there are a couple things you want to make sure you do:</p><ul><li><h3>Succinctness</h3><p>Write in short, complete paragraphs, and make sure each one has a topic. Limit yourself to a few sentences for each, and keep it punchy.</p></li><li><h3>Length</h3><p>Take the space you need, but don't be verbose. Imagine yourself in the shoes of the reviewer: you don't want to waste time, neither do they. I usually suggest that people aim for a page, two or three if you've known them for a long time or in multiple roles.</p></li><li><h3>Quality</h3><p>Sign it with real pen, on real paper, and mail it to them. People are silly creatures, and an authentic signature on good stationery will make it clear that you mean it.</p><p>You do have good stationery, don't you? Everyone should have a few sheets of quality personal stationery for just such an occasion. Rag paper with a heavy feel shows you care enough to spend money on the people you're writing <em>to</em>, as well as the person you're writing <em>for</em>.</p></li></ul></div><p>These are, generally, the same rules you should follow for all good writing. In fact, you'd do well to follow them for all official correspondence, including admissions letters and particularly thank-you letters.</p><p>If you're the one <em>getting</em> a recommendation, remember that it takes a <em>lot</em> of time and effort to write a really stellar one, so make sure you write them two letters: One to ask for a recommendation letter (Even if you're asking for a recommendation letter in person, it's a nice touch to follow up) and a second as a thank-you letter (both on real paper, following the rules above) and <em>mean it</em>. It will make you memorable in the future, and that can mean jobs, referrals, and other benefits, as well as a lasting friendship.</p>Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com0tag:blogger.com,1999:blog-8916545447803472659.post-23079091049270321842008-05-24T23:00:00.000-07:002008-05-25T09:32:06.203-07:00Bouncy visitors<a href="http://www.jaggederest.com"><img src="http://img406.imageshack.us/img406/1940/37022789ue3.png" alt="Ouch! That's a low bounce rate!"></a><br /><br />Most simple websites and blogs have a really high bounce rate. Mine hovers around 95%.<br /><br />So we lost 95% of the folks in the first three words of that sentence. Ouch.<br /><br />Thus, you need to make the first words of the page good ones. One of the Portland bloggers I know just swapped out his <del>Wordpress</del> [Edit: Blogger! my bad.] default title text with a custom image and cut his bounce rate to one-tenth what it was.<br /><br /><a href="http://www.agoodhusband.net/"><img src="http://img149.imageshack.us/img149/4300/goodhusbandheader251508vt0.jpg" alt="The blog header in question"></a><br /><br />So, that being said:<br /><ul><li>If you have a site, think about the first thing people see.</li><li>I'm going to go get myself a custom header</li></ul>Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com2tag:blogger.com,1999:blog-8916545447803472659.post-23353972942437796102008-04-15T10:23:00.001-07:002008-04-15T10:31:06.405-07:00Migraine treatment tips<p>So I've learned (possibly more than I ever wanted to know) about migraines lately. Here's some tips if you're getting them:</p><ol><li>Everyone is different, so this list isn't anywhere near definitive.</li><li>Nasal sprays don't work.</li><li>Neither do (normal) antidepressants. e.g. Prozac, Zoloft, Celexa, etc</li><li>Opiates (vicodin, percocet, oxycontin, etc) don't work. But they do make you <em>not care</em> which can be your last option at times.</li><li>Maxalt (rizatriptan) is pretty effective and works quickly. Maybe 3/4 of the time it can kill a migraine.</li><li>Supplements apparently <em>can</em> help prevent migraines. If you're getting more than eight a month, try petadolex / butterbur, riboflavin, coenzyme Q, or magnesium. Petadolex is sold in approximately the right doses (usually with riboflavin). Riboflavin you want 200mg/day twice a day. Ditto Coenzyme Q. Magnesium I'm not as clear what works.</li></ol>Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com1tag:blogger.com,1999:blog-8916545447803472659.post-58339010105026793562008-04-13T01:11:00.000-07:002008-04-14T10:20:49.250-07:00Efficiency vs Efficacy<ul><li><h2>Efficiency</h2><p>Efficiency is <em>lack of waste</em>. In some cases, it can mean "lack of waste of money" or "lack of waste of energy".</p><p>Example: You're selling widgets, and you want to make the most money possible. This is an efficiency goal. Widget production cost = waste + materials + labor.</p></li><li><h2>Efficacy</h2><p>Efficacy is <em>effectiveness</em>. It can mean "level of coverage" or "level of positive outcome".</p><p>Example: You're making a vaccine, and you want to make sure everyone gets it. Price is no longer particularly important, only the level of coverage. This is an efficacy goal. <code>Number of people dead = ((people in population) / (people covered))^2</code> <small>(since transmission is reduced, it's square-law-type)</small></p></li></ul><h3>For example, you want these to be efficient:</h3><ul><li>Tax collection</li><li>Luxury good distribution</li><li>Financial services</li></ul><h3>You want these to be efficacious:</h3><ul><li>Medical care</li><li>Car safety</li><li>Welfare services</li><li>Fire and police services</li><li>Education</li></ul>Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com3tag:blogger.com,1999:blog-8916545447803472659.post-1031667342071388472008-04-10T00:39:00.000-07:002008-04-10T20:32:49.723-07:00Yahoo Pipes (Dataflow programming, but don't call it that!)Pretty interesting stuff. If you've ever worked with <a href="http://www.ni.com/labview/">LabView</a> or <a href="http://www.vvvv.org/">VVVV</a> <small>(Windows-only, but a toolkit that deserves many posts of its own)</small>, you know how nifty dataflow programming can be.<br /><br />I've just started playing around with Yahoo Pipes, late to the party again by about a year, and it's pretty interesting stuff.<br /><br />As an example, I improved the Craigslist / Zillow mashup that was already on there to do multisegmented feeds (since craigslist limits you to 25 per feed) and to add query, min/max price, and county indicators, since I was interested in those as well.<br /><br />Right now, it's pretty useful for comparing the real value of houses with the listings on Craigslist. If it's significantly different, be on the lookout for a bargain or a ripoff, or at least ask why it's different <small>(remodels often mess up Zestimates)</small>.<br /><br />Here's the link: <a href="http://pipes.yahoo.com/jaggederest/clpricecheckv2">Craigslist / Zillow mashup version 2</a> ( http://pipes.yahoo.com/jaggederest/clpricecheckv2 )<br /><br />It's pretty typical of dataflow: It's easy to toss things together, but to really get into it you need to build new components, and apparently the only way to do that is via importing pipes, which is nice, but doesn't let me build 'if' statements as I'd like.<br /><br />As a side note, dataflow is one of the other ways to achieve low-cost parallelism, and one that's often overlooked, I think. People concentrate on actor-model or locks far too often.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com0tag:blogger.com,1999:blog-8916545447803472659.post-21182028741553752032008-04-08T21:55:00.000-07:002008-04-09T12:45:15.689-07:00Tendency to Hoard stuff? A plan for piles.I know I tend to pack-rat things. I often find it difficult to clear things up or clean an area out, even when I know most of the stuff in it is junk, or even just something I won't need right away.<br />Here's my method:<ol><li> <h3>Clear it all out.</h3> <p>It doesn't matter if it goes in a big pile in the middle of the room, just get it out of there. Put it someplace you can't stop until you're done.</p></li><li> <h3>Sort them out by quality or usefulness</h3> <p>Ambiguous, yes, but it's really up to the person doing the sorting. Whatever criteria you use to decide whether to keep things when it's one-by-one, use it here, to group things into a set of piles.</p> <p>I usually use at least five. The goal is to have <em>equal sized</em> piles. <small>(If you've heard of the bond market, they call this 'tranches', say AAA, AA, A, B, C, etc)</small></p></li><li> <h3>Put the first pile back</h3> <p>Take the pile that is the top shelf stuff, and put it back where you started from. Make it nice, neat, and clean (good time to get dirt off, while it's empty).</p></li><li> <h3>Assess the situation</h3> <p>Don't worry about all the other piles, just honestly assess the situation. Is the space clean? Is it clear? Does it have all the things you'd commonly use there?</p> <p>Sometimes with this part, it helps to get an outside opinion. Have someone you trust tell you whether it looks good, is cluttered, or is empty. If it's cluttered, split the pile.</p></li><li> <h3>If it needs <em>more</em>, go to step 3.</h3> <p>Say you're organizing your drawing desk. Are all your favorite pastels still sitting behind you? Maybe you still need that ruler or the pens that haven't made it in yet. Time to go back, get another pile (the next-best one) and put it away as well.</p></li><li> <h3>Clean up the other piles</h3> <p>Here's the fun part: By process of elimination, you've just decide what to store/give away/recycle without ever having to agonize over your favorite pincushion. You can trick yourself into realizing that you don't need so much stuff.</p></li><li> <h3>You're done.</h3> <p>You've just reclaimed usable space, and, if you're like me, given away quite a bit to charity, which can take a nice bite out of your tax liabilities.</p><p>Do this often enough, you'll realize how many of the things you thought were 'vital' to have out are really once-a-month or once-a-year items, too.</p></li></ol>Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com0tag:blogger.com,1999:blog-8916545447803472659.post-16358936321549495302008-02-25T15:03:00.000-08:002008-02-25T19:18:54.109-08:00Git is amazingSo, today, I'm working on a project, I've got it all mocked out with some sample forms and some throwaway objects to play with.<br /><br />I realize 'Hey, I need an authorization/authentication system', so I have a dilemma.<br /><br />On the one hand, my code is throwaway that I plan to evolve to fit what I end up actually doing with it long term.<br /><br />On the other hand, I really don't want to have to redo it later, since I'll probably want to come back here after I build out the auth/auth system.<br /><br />Git to the rescue.<br /><br />I've been doing all my development on the 'experimental' branch locally, as one ought to do.<br /><br />git commit -m 'End of tinkering, time to get serious'<br /><br />git checkout master #Back to the beginning, <br />#or you can use git checkout HEAD~x where x is how many commits you want to go back<br /><br />#create the new branch and check it out<br />#equivalent of git branch restful_auth; git checkout restful_auth<br />git checkout -b restful_auth #which is a wonderful plugin, btw<br /><br /># do your install here...<br /><br />git commit -m 'All restful, now lets go back to the other'<br /><br />git checkout experimental<br /><br />git rebase restful_auth<br /><br /># fix the conflicts, I had three<br /><br />And you're done. You just saved yourself a couple hours of rewriting throw-away bits of your app. And of course, this is completely doable with pretty much any type of edit. You can go back into the past and effectively 'redo it right' without having to worry about the time it takes up front.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com0tag:blogger.com,1999:blog-8916545447803472659.post-20636305079136608532008-01-17T23:25:00.001-08:002008-06-28T01:16:40.658-07:00Ibuprofen, Naproxsyn/Naproxsen, and Aspirin: Don't overdo it.My girlfriend just got out of the hospital after having a bleeding ulcer as a result of taking ibuprofen, among other stressors.<br /><br />Just a heads up, any of you who read this, go easy on the ibuprofen, because the effects can be <i>very bad</i> if you are unlucky, and it is surprisingly common.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com1tag:blogger.com,1999:blog-8916545447803472659.post-2806423847430429152008-01-11T02:55:00.000-08:002008-01-11T03:29:43.547-08:00multiurllike tinyurl but with multiple pages. Pop page with previews, ask users if they want to open all, one, some, or play slideshow-style in frame?<br /><br />Perhaps a bookmarklet interface, along the standard HTML paste-in-urls.<br /><br />Edit: Already exists, <a href="http://www.manyurl.com/">ManyURL</a>, works nice from what I see. Could use a bit more, though! Too simple, not complicated enough.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com0tag:blogger.com,1999:blog-8916545447803472659.post-88020274144021889012007-12-14T00:09:00.000-08:002008-01-28T11:15:32.852-08:00When you're serving static files...Never link http://yoursite.com/foo/bar/x to: <br /><br />A) plain http://static.yoursite.com/foo_bar_x.ext<br /><br />B) Never use plain hashes of the ID. e.g. .../hash_of_id_here.ext<br /><br />C) Borderline, but even static salts are bad: .../hash_of_id_plus_'foobar'_here.ext<br /><br />Basic is, use a variable salt for every item. It can ever be public info, like the title, creation time, or anything that varies sufficiently per-item. That's the beauty of salts.<br /><br />Or, alternatively, as better people than I have mentioned, use bcrypt with a set difficulty value, and all your rainbow table type fears go away.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com0tag:blogger.com,1999:blog-8916545447803472659.post-87661574828333029392007-10-18T17:17:00.000-07:002007-10-18T17:21:20.611-07:00Emacs...Biggest reason to switch to emacs I've found so far is that the commands work by default in bash, too.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com0tag:blogger.com,1999:blog-8916545447803472659.post-81339034316065716402007-09-07T11:31:00.000-07:002007-09-07T11:41:31.478-07:00Code on the Road: Navigating The Minefield that is Visual Source Safe<a href="http://www.expatsoftware.com/articles/2007/09/minefield-that-is-visual-source-safe.html">Code on the Road: Navigating The Minefield that is Visual Source Safe</a><br /><br />Such a no-brainer. Why do you even try VSS to begin with? Get the Subversion plugin, grab SVN, and 99% of these things go away.<br /><br />If that's not enough, <a href="http://git.or.cz/">git</a>, <a href="http://darcs.net/">darcs</a>, <a href="http://bazaar-vcs.org/">bzr</a>, and <a href="http://www.selenic.com/mercurial/wiki/">mercurial</a> provide reasonable distributed solutions. Miles ahead of VSS (Actually, three generations, but who's counting.)<br /><br />Seems to me, if you're really running an 'ex-pat' office, you'd want distributed. That way you can all trade changes around without having to fight conflicts. Best part is, you can stage to production without branch/tag.<br /><br />Basically, there's no excuse these days for using an old VCS. Or, dare I say, a Microsoft VCS.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com2tag:blogger.com,1999:blog-8916545447803472659.post-37096332626279916302007-09-06T15:55:00.001-07:002007-09-06T22:55:39.151-07:00On convergent evolution, and the invocation of holy wars.Python and Ruby are the same thing.<br /><br />There, with that out of the way, let me explain myself.<br /><br />I was looking at <a href="http://blog.eikke.com/index.php/ikke/2007/09/02/seam_carving_content_aware_image_resizin">a post about scene carving image retargeting</a> which thoughtfully includes a link to <a href="http://git.nicolast.be/?p=scarving.git;a=summary">his python implementation of scene carving</a> all nicely packaged into git.<br /><br />So I grabbed it, used emacs to import it into a new file, and started converting it to Ruby, since that's the language which is hitting my happy button right now (<a href="http://www.haskell.org/">Haskell</a> is for when I want to hurt myself). (NB said conversion I plan to post here, or at least, link to SVN for it.)<br /><br />Take a look at an excerpt:<br /><blockquote><pre><br />class CostMatrix(ndarray):<br /> def calculate(self, energy_map):<br /> if not energy_map.shape == self.shape:<br /> raise Exception, "Wrong shape"<br /> (h, w) = self.shape<br /> self[0] = energy_map[0].copy()<br /> self[0] = self[0]<br /> for y in range(1, h):<br /> for x in range(0, w):<br /> bestcost = inf<br /> bestx = x<br /> for dx in range(x - 1, x + 2):<br /> if dx >= 0 and dx < w:<br /> if self[y - 1, dx] < bestcost:<br /> bestcost = self[y - 1, dx]<br /> bestx = dx<br /> self[y, x] = self[y - 1, bestx] + energy_map[y, x]<br /> self._calculated = True<br /><br /> def _get_max_index(self, row, startcol = 0):<br /> maxx = startcol<br /> maxval = self[row, maxx]<br /> <br /> for x in range(0, len(self[row])):<br /> if self[row, x] > maxval:<br /> maxx = x<br /> maxval = self[row, x]<br /><br /> return maxx<br /><br /> def find_shortest_path(self):<br /> (h, w) = self.shape<br /> <br /> x = self._get_max_index(-1)<br /> path = [x]<br /> for y in range(h - 2, -1, -1):<br /> bestcost = inf<br /> for dx in range(x - 1, x + 2):<br /> if dx >= 0 and dx < w:<br /> if self[y, dx] < bestcost:<br /> bestcost = self[y, dx]<br /> x = dx<br /> path.append(x)<br /><br /> path.reverse()<br /> return path<br /><br /><br /> def get_image(self):<br /> scaling = 0.03<br /> (h, w) = self.shape<br /> im = Image.new("L", (w, h))<br /> im.putdata(self.flatten() * scaling)<br /> return im<br /></pre></blockquote><br /><br />Now, if you're a python person, that should be fine. But what if you're a ruby person? That looks like ruby, where someone added in a lot of colons, and didn't remember their end tags. Oh, and someone's using paretheses oddly.<br /><br />So, having converted those things, I'm confronted with a syntactically valid chunk of ruby code. It no longer throws parse errors.<br /><br />This is pretty mindblowing, to me. Maybe it's something that's long since been obvious to the old hands...<br /><br />Anyway, this makes me wonder why Python and Ruby aren't implemented on the same core compiler/interpreter. I know Microsoft is doing something akin to this with their <a href="http://en.wikipedia.org/wiki/Dynamic_Language_Runtime">Dynamic Language Runtime</a>, but why aren't the <a href="http://www.ruby-lang.org/en/">Ruby</a> people stealing like mad from the <a href="http://python.org/">Python</a> people, and vice versa? <br /><br />That said, this, to me, is only the midway step between Python and Haskell. Ruby will probably take a week to do anything fun with it, so, much as I might like to throw up a free image resizing service, I'm thinking I'd rather do it in HAppS, where at least it will be fast.<br /><br />Any thoughts? Am I an idiot for not seeing this already?<br /><br />PS there's also <a href="http://www.thegedanken.com/retarget/">another implementation of scene carving based resizing</a> that I've been looking at.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com8tag:blogger.com,1999:blog-8916545447803472659.post-14416757457573443352007-08-28T09:55:00.000-07:002007-08-28T09:59:27.058-07:00Lunar Eclipse<img src="http://img209.imageshack.us/img209/7582/moonzj4.jpg" border="0" alt="Total Eclipse" title="Partial Eclipse" /><br /><img src="http://img515.imageshack.us/img515/7538/totalmc5.jpg" border="0" alt="Total Eclipse" title="Total Eclipse" /><br /><br />Taken last night. If I had a better camera, I'd have taken Mars during the eclipse too.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com1tag:blogger.com,1999:blog-8916545447803472659.post-62623719848305643222007-08-10T00:16:00.000-07:002007-08-10T00:48:17.319-07:00Eliciting rational thought on the internet<span style="font-size:130%;">Ok, this is very much a work in progress at the moment, I'd appreciate feedback a lot.</span><br /><br />I'd like to take some time today to write about the way I <a href="http://slashdot.org/~Baddas/">interact</a> on <a href="http://news.ycombinator.com/user?id=jaggederest">the</a> <a href="http://reddit.com/user/jaggederest">internet</a>. I'm doing this partly as a way of clarifying to myself the goals that I'm pursuing. Another part is, when people accuse me of being deliberately obtuse, argumentative, or 'debating unfairly', I can point them here, as not a means of excusing myself, but rather a means of explaining the reasons. Finally, I think the world would be a better place if people examined the way they interact with others more often, so I'd like to be less of a hypocrite by spending some time in the pursuit of that goal.<br /><br /><span style="font-size:130%;">Firstly, let me lay out my goals:</span><br /><dl><br /><dt> Learning.</dt><br /><dd>This is always high on the list. Everyone teaches you things.</dd><br /><dt>Teaching others.</dt><br /><dd>Again, I'm not sure this is as noble as all that, given that most people don't like to be taught a lesson even if it's good for them.</dd><br /><dt>Developing communication skills.</dt><br /><dd>This is something that I, as with, I think, most technical people, have problems with.</dd><br /><dt>Getting others to think before they comment.</dt><br /><dd>I'd like to see more people think to themselves 'No, that's silly, I shouldn't say that' or 'Hmm, is that really true?' before they spout off about the topic du jour.</dd><br /></dl><br />So in pursuit of these, I do a few 'not so nice' things, though I believe, as is the call of petty tyrants throughout the ages, 'the ends justify the means'.<br /><dl><br /><dt>Feigned ignorance.</dt><br /><dd>This is probably my favorite thing to do. Most people, in the course of explaining what 'everybody knows' will end up realizing that they don't have a firm grasp on the topic at hand. I end up doing more research myself this way...</dd><br /><dt>Questioning of basis.</dt><br /><dd>I've been accused of being a dirty debater for asking people a pretty simple question: "Why do you think that? Do you have any evidence or proof?" People come up with the most marvelous sources when you ask them this, especially when they're experts in the field.</dd><br /><dt>Employing logical fallacies.</dt><br /><dd>This is almost a test: Do you recognize when someone is using these? I wrote about one that always bothers me in <a href="http://illicittech.blogspot.com/2007/05/sunk-cost-fallacy-and-dilemma.html">Sunk Cost: Fallacy and Dilemma</a>, but there are <a href="http://en.wikipedia.org/wiki/Category:Logical_fallacies">many more</a>. People don't seem to realize that this is one of the key tools of a demagogue. Immunizing people against them should be one of the key tasks of education, but I'm fairly sure my school didn't even mention them once.</dd><br /><dt>Playing Devil's Advocate.</dt><br /><dd>This is the classic trick of the <a href="http://www.gnaa.us/">troll</a>. Take a deliberately extreme position, and defend it well. In doing so, you're far more likely to solidify people's current beliefs than change minds. In a lively debate, often both sides come away better educated, perhaps having gained a modicum of respect for their opponents. <br /><br />(This is one of the key problems with politics now: nobody can put themselves in the other person's shoes, everything is a life or death issue)</dd><br /></dl><br />Anyway, I've got to sleep now, but there it is: When I talk to people on the internet, it's often with goals in mind.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com3tag:blogger.com,1999:blog-8916545447803472659.post-38708811984491430532007-08-07T18:57:00.000-07:002008-06-18T17:55:56.700-07:00From a friend's recommendation letter...<h3>New post on this subject: <a href="http://illicittech.blogspot.com/2008/05/recommendation-letter-redux-how-to.html">How to write a letter of recommendation</a></h3><br /><br /><hr><br /><br />I was helping a friend write a recommendation letter and came across these gems:<br /><br />- "Self Goal Oriented"<br /><br />- "Most plausible vehicle for my goals"<br /><br />- "Practice my compassion"<br /><br />Yep, lessons in what to avoid when talking to literate people.<br /><br />Also, I'm still alive out here and plan to have another post up with real content soon.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com0tag:blogger.com,1999:blog-8916545447803472659.post-77703378155895362432007-06-08T11:45:00.000-07:002007-06-08T14:00:51.057-07:00Trendlines and MusingsIt seems that there have been several general and successive <span style="font-weight: bold;">trends online</span> over the last few years, each driving a certain type of success story (and yes, some overlap exists):<br /><ol><li>Search (Google, Ask.com, Y!, tagging on Flickr, etc)</li><li>Share (del.icio.us, Digg, YouTube, Reddit, etc)</li><li>Create ... this one is still in its nascent phase, but is cropping up more and more, often in conjunction with the first two</li><li>???</li></ol>My lines of inquiry here are: what is the eventual trajectory for the "create" modality, what comes after it, how can these work together, and what technologies/techniques might offer the best fit in pursuing these new projects?<br /><br /><span style="font-weight: bold;">Create</span><br />The creation modality of the net is nothing truly new. We've long seen services that allow users to create and customize their own home pages, and blog services that allow people to post and host their own content.<br /><br />This creation trend has been expanding into other areas more recently, pulling more varied media types and methods into the fray. <a href="http://www.deliciousdesigner.com/">Delicious:designer</a>, for example, is an intriguing new tool that gives a pretty slick graphic design interface to its users. There have been spin offs of the "picture a day" internet meme that use Flash to pull images directly from connected web cams into the internet application, automating the creation of an image stream. There are similar services available for creating music mashups or playlists to share with friends (both through links and via p2p, but the discussion of technology will come later).<br /><br />There have also been some pushes to create services that allow people to create dynamic content, like <a href="http://www.sploder.com/">web games</a> and other small apps, all through simple interfaces. I know that HAppS has some interesting potential here, as do things like Flash, Flex and possibly even Laszlo.<br /><br />Looking at the progression of create-style web apps, we see a trend of offering more and more control in creating more rich content. The examples that seem to be most successful, in my experience, are those that offer the simplest interfaces, and the simplest hooks to allow people to integrate their creations into the search/share spaces.<br /><br /><span style="font-weight: bold;">Search/Share</span><br />Uptake of content is the name of the game. Anyone can "publish" these days. Getting content online takes about half a moment, and even less thought. Getting that content into the hands/eyes/minds of others is the trick. Getting that same content to your <span style="font-style: italic;">desired</span> audience is the holy grail of search/share, and it's why companies have been able to pull in hundreds of millions of dollars in that space.<br /><br />As more dynamic content is created, there is more noise added to the search/share channels for those media types. Let's face it - it's not all good content that's being produced. So how do end users find good content - and the converse - how do content producers get their content into the channels that will get to good audiences? Well, most of that discussion is for another time and place, but from a create-mode product view, there are several emerging strategies that seem to be doing well:<br /><ul><li>the aggregate and vote system (ie, Digg and Reddit) allows a wide pool of users to filter material, giving exposure to a lot of content, but pushing a certain amount to the top<br /></li><li>the "email to share" system allows people to push interesting content directly to their friends (making this *easy* and non-intrusive is key, though)</li><li>social network messaging systems allow people to post to a focused group of consumers, who can then propagate the message further through their networks if they find the content appealing</li></ul>There are more methods, to be certain, and it will be interesting to watch them as they continue to evolve.<br /><br /><span style="font-weight: bold;">Technologies/Techniques<br /></span>Speed. Simplicity. Engaging.<br /><br />These concepts have really been at the forefront of the current trend cycle. Agile development and rapid application development help get things from concept to reality in short, repeatable cycles, allowing things to grow organically and respond to feedback quickly. Simple focus - doing one thing really well - has made the use cases for products really clear. This lets their utility shine through, promotes ease of use, and keeps things focused on what works and what's needed. Finally, keeping people <span style="font-style: italic;">engaged </span>has been critical. This is no longer a broadcast world. Commentary, dialogue, edits, versions, iterations - these all form the critical feedback that keeps the system evolving.<br /><br />The tool sets and technologies that really respond to these things have definitely seen a lot of attention in recent years. Agile has taken off like a rocket. Rails has been going gangbusters, maturing by leaps and bounds. Languages with high ability for concurrent execution have been getting more attention. Tool sets that allow for mixed online/offline utility have been popping up like mushrooms.<br /><br />... to be concluded in next post.<br /><span style="font-weight: bold;"></span>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-8916545447803472659.post-54862164349072865722007-06-05T22:38:00.000-07:002007-06-07T11:16:29.908-07:00Travelling Salesman Problem: Introduction (in Haskell)<a href="http://psychicorigami.com/2007/04/17/tackling-the-travelling-salesman-problem-part-one/">Here's</a> the original link.<br /><br />The task here is a setup for some stochastic methods of solving the <a href="http://en.wikipedia.org/wiki/Traveling_Salesman_Problem">Travelling Salesman Problem</a>. I'm doing it in <a href="http://haskell.org">Haskell</a> since my skills here need work.<br /><br />basic.lhs:<br /><br />Set up a coordinate string. These are the cities in our routes.<br /><pre><br />> coordinates :: [(Float,Float)]<br />> coordinates = [(0,1),(1,2),(2,3),(2,4),(0,6)]<br /></pre><br /><br /><br />This is a simple function that takes two 'cities' and returns the floating-point distance between them using the <a href="http://en.wikipedia.org/wiki/Pythagorean_Theorem">Pythagorean Theorem</a><br /><pre><br />> distance :: (Float, Float) -> (Float, Float) -> Float<br />> distance (x1,y1) (x2,y2) = sqrt ((x1-x2)^2 + (y1-y2)^2)<br /></pre><br /><br /><br />This allows us to determine the actual length of a list of cities ('tour'). Note that it's not circular, unlike in the linked article. <br /><br />The 'let' statement looks up the city in question from the list above and inserts it into an equivalent list.<br /><br />zipWith is like map, except it takes a two-argument function, and two lists of arguments which are 'zipped' together into a result list.<br /><pre><br />> tourLength :: [(Float, Float)] -> [Int] -> Float<br />> tourLength pairs tour = let coords = map (pairs !!) tour <br />> in sum $ zipWith distance coords (tail coords)<br /></pre><br /><br /><br />A wrapper, if you'd like to have all tours be circular.<br /><pre><br />> tourLength' :: [(Float, Float)] -> [Int] -> Float<br />> tourLength' pairs tour = tourLength pairs (tour ++ (head tour))<br /></pre><br /><br /><br />The main testing function, which prints the specified tour's length<br /><pre><br />> main :: IO ()<br />> main = print $ tourLength' coordinates [2,1,0,3,4]<br /></pre><br /><br /><br />One thing you'll notice here, is that I'm eliding the matrix calculation in the original source. One of the nice things about Haskell is that a later date, should I choose to do some <a href="http://en.wikipedia.org/wiki/memoization">memoization</a>, there's very little work to be done. Only one of these functions would need to change. <br /><br />Another nice thing is that if a given pair of cities is not ever used, Haskell (due to it's <a href="http://en.wikipedia.org/wiki/Lazy_evaluation">laziness</a>) won't ever bother to actually calculate the value, even if I do go back and add memoization.<br /><br />There's more to this, especially the shuffling functions (I'll get to introduce Monads!). That'll have to wait for another day soon.Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com3tag:blogger.com,1999:blog-8916545447803472659.post-44194168077881849832007-06-04T22:32:00.000-07:002007-06-04T22:33:45.862-07:00mimes.<a href="http://www.jaggederest.com/mime.html">Mime shouldn't be a capital crime. The first time.</a>Justin Georgehttp://www.blogger.com/profile/00841137599327072247noreply@blogger.com0