You can kill the background for speed, if you wish.[x]

Monday, December 19, 2011

Disabling the Caps Lock key in Linux

My personal laptop has had its Caps Lock key disabled for a while, because I find the Caps Lock key largely useless, and since I've been using Vim regularly at work, I've found it worse than useless - it's been counterproductive. Because when you're typing in the normal world and you accidentally have Caps Lock on, you realize that all your letters are coming out capitalized, and you backspace them and move on. But in Vim, if you accidentally bump the Caps Lock key, you're just trying to move around and all of a sudden your lines are disappearing, help starts popping up, it won't let you save or undo, and you start jumping all over the screen. Every time my screen stops doing what my fingers are telling it to do, it takes me a few (often destructive) seconds to figure out what the hell is going on, and it's usually the Caps Lock key.

So, to that end, I need to once again remap my Caps Lock key, but don't remember how to do it, and have to go back to my own more informative but longer blog post from a while back about remapping keys.  But I figured it'd be a lot easier in the future (and possibly helpful to others) to write a post dedicated to disabling the Caps Lock key, and since a quick Google turned up wrongdumb or temporary ways to do it, I will be doing myself, and perhaps you, a favor.  I also thought it'd be good to have a post without all the blathering, but you see how well that worked out.

So, how to disable your Caps Lock key in Linux, the Right WayTM:
  1. Open (or more likely create) an .xmodmap file in your home directory (vi ~/.xmodmap)
  2. Add the line remove lock = Caps_Lock to it
  3. Save and close
Changes here will take effect on an X restart - if you want to disable it right now, you can run xmodmap -e "remove lock = Caps_Lock" in a terminal, and it will take effect for your current session.  If this doesn't work, try also running xmodmap -e "keycode 66 =" to unmap the Caps Lock key completely - I had to do this on my work comptuer for some reason, despite all the "helpful" tutorials elsewhere on the internet.  If you also find this to be the case, add keycode 66 = to your ~/.xmodmap as well.  It's worth noting that the spaces around the equals sign are important in all of these commands.  If for some really strange reason you don't have xmodmap installed, you'll have to do that first, of course, but it should come with just about any distro.

If you want to, like I did in my original post, remap Caps Lock to a more useful key (say, Esc, vim users?), you can do so by adding the following lines instead. Something like this is actually what I have in place on my personal laptop, as it's remapped to mod5, which gives me an extra key to use for things like Compiz mappings.
remove lock = Caps_Lock
keycode 66 = {target keysym} {target keysym}
The first is what to replace Caps Lock, the second is an optional key for when you hit Shift+Caps Lock.  {target keysym} is a semi-friendly name like "Escape" or "k", and is obtained from pulling up a terminal and either running xmodmap -pke and scanning/grepping through the resulting list or, my favorite, running xev and mashing they keys you want to remap to find the "(keysym 0x##, [keysym name])" in the output.  A nifty way to do the latter is running xev | grep keysym - that will just spit out the needed line.  With xev, just close the white box that comes up to stop things.

If you do want to know about xmodmap and the wonders it can work in rearranging your keyboard to your satisfaction, or you want to move your Caps Lock key, by all means check out my original blog post, which goes into things in more depth.

Thursday, August 25, 2011

strtotime() weirdness

So today at work I found a bug in my (or possibly one of my coworkers') PHP code where strtotime() was being called without a unit - in this case it was strtotime("-91"). strtotime didn't, as I had hoped, assume I meant days, so I investigated as to what it did assume. Poking around the source proved a task that outlasted my curiosity, since I had no clue where the entry and exit to the code was, and it was a pretty complex bit of code. So instead I plugged in some numbers to the PHP command line. I subtracted the output of strtotime from time() to get the difference, and divided by 24*60*60 to get it in days, and got some very odd numbers indeed:
php> print (time() - strtotime("+91"))/24/60/60;
4.0833333333333
php> print (time() - strtotime("+1"))/24/60/60;
0.33333333333333
php> print (time() - strtotime("-1"))/24/60/60;
0.25
php> print (time() - strtotime("-2"))/24/60/60;
0.20833333333333
php> print (time() - strtotime("-2"))/24/60/60;
0.20833333333333
php> print (time() - strtotime("+2"))/24/60/60;
0.375
Interesting. So I decided to make some graphs, of course. I eventually came up with this bit of code:

php -r '$range = 5000; function doit($i, $posneg) { $diff = (time() - strtotime("$posneg$i"))/24/60/60; if($diff > 10000) { $diff -= 15207; } print "$posneg$i,$diff\n"; } for($i=-$range;$i<=$range;$i++) { $posneg = ($i <= 0 ? "" : "+"); if($i == 0) { doit(0,"-"); } doit($i,$posneg); if($i == 0) { doit(0,"+"); } }' > phpstrtotime5000.csv

The $diff adjustment bit is because I was getting a lot of numbers that were waaaaay up around 15212, and a bunch around 1, but nothing in between, so I adjusted the big nubmers so they could be seen on the vertical scale. This is what I ended up with - the whole range, then zoomed in from -500 to 500: As I was putting this blog post together, I realized I could have done strtotime("-91",0) to just calculate from a timestamp of zero, so I tried that out:

php -r '$range = 5000; function doit($i, $posneg) { $diff = strtotime("$posneg$i",0)/24/60/60; if($diff > 10000) { $diff -= 15207; } print "$posneg$i,$diff\n"; } for($i=-$range;$i<=$range;$i++) { $posneg = ($i <= 0 ? "" : "+"); if($i == 0) { doit(0,"-"); } doit($i,$posneg); if($i == 0) { doit(0,"+"); } }' > phpstrtotime5000_2.csv

This had the apparent effect of getting rid of all those weird outliers and replacing them with zeroes. That, combined with the number, made me realize that the 15212 number was in fact time()/24/60/60 - meaning that strtotime() probably returns zero regardless of the base time provided for those ranges. Here are my graphs from that run:

Now, I have no clue why strtotime() behaves like this. I know it's not defined how it should respond, but these numbers obviously have some kind of pattern, but I'm not sure what it is.

Some other tidbits: the last numbers that don't return zero are +/-2459, and the slope of the line is approximately -36.57 seconds with a y-intercept of precisely -8 hours. The little slope in the middle is in the range (-100,100), with a slope of exactly -1 hour, and a y-intercept of exactly -8 hours again. The zero sections occur every 100 values - the function is zero from [100n+60,100n+99] for positive numbers, [100n-60,100n-99] for negative numbers, |n| > 1. For |n| <=1 - (-200,200) - there is the aforementioned discontinuity, plus a slight change in slope outside the (-100,100) range. Outside that range - in the ranges (-200,-100] and [100,200) - the slope is -47.94 seconds, again with that y-intercept of -8 hours. "+0" and "-0" are both 0.33333 days, but "0" returns 0 days.

I can guess that the zeroes are related to minutes in an hour or seconds in a minute, with 60 being a factor there - something is defined for 0-59, but not for 60-99. The y-intercept appears to be related to the current hour/time of day - my first sampling was taken at 1:XX UTC (6:XX local time) and the second at 2:XX UTC (7:XX local time), and the y-intercept changed from -7 to -8.

For reference, I was running the first set of stats at approximately 1:49:30am UTC, Friday, August 26, and the second stats some time afterwards. I'm in Pacific time, currently GMT-7.

I'm not sure is the cause of all this weirdness, and I know it doesn't matter at all, but it is really interesting - maybe sometime I'll have the time to plumb through the code and figure it out. If anyone else wants to play with it, I've put my numbers in a Google Spreadsheet that you can check out and download if you want.

P.S. I had formerly run the numbers with the upper graph, and the results were the exact same slopes (36.57 seconds, 1 hour, just y-mirrored, but with a y-intercept of 7 hours. Odd, but probably significant.

Friday, April 1, 2011

Hey look, I made some xk3d!

So last night someone on Facebook linked to xkcd, which for April Fools' day converted several of their comics to 3D with some clever Javascript and image slicing. In typical xkcd style, Randall also posted a link with instructions about how the system worked, and importantly, how you could convert older comics to 3D yourself if you wanted. If you did so and sent them in, they may put them on the site.

So I, of course, immediately checked my all-time-favorite xkcd comics - the five-part barrel series. None of them had been done, so I decided to tackle my favorite, the culmination. It was a lot of fun - slicing, cloning, sorting, all of course in GIMP, and by the end I had a nice 3D version of the comic, so I sent it in, figuring that a million other geeks also held these comics near and dear, and at least a bunch of those had gotten around to it before me.

But this morning, I checked my email, and what do you know, I had a email that said "Thanks!" in reply to my submission, and sure enough, there was my 3D conversion, with my name at the bottom and everything! How cool is that?

So of course, I had to go through and convert the rest of the barrel series - If it's still April Fools', you may notice that all of them are now 3D. I sent them in about half an hour ago, and got a prompt reply saying they'd all been put up, and complementing me on dealing with the "slice-orthogonal plane". Awesome, and totally worth being a few minutes late to Engineering Probability and Stats for.

I also had to hack together a version of the webpage to test these guys with - fortunately, since it was all Javascript magic, that was as easy as saving and modifying a copy of the homepage. It was as easy as adding a parameter to the omgitsin3d initialization function for the comic num, and have it use that as the folder to take the images from in the script, which let me throw each set into its own folder, modify the JSON in the HTML file, and adjust as necessary. Then it was just a copy/paste of the JSON into the comics.json file and they were done. In case anyone else wants to do some conversions but doesn't want to go through the trouble of building a testing thing, I zipped this guy up with the original comic I did, and you can download it if you like. You'll still have to read up on how it all works, but this should help testing it out. And of course, xkcd is CC-noncom-by-attrib, so this all, of course, is thanks to Randall and xkcd, and is based off of his comics.

Thursday, March 3, 2011

Connecting my w385 to Ubuntu Linux

So I have a trusty old Motorola w385, which has a USB-mini port on it, so I can connect it to my computer. Trouble is getting it to actually do anything. I did it a long time ago, to back up my text messages, and remembered having a lot of trouble to do so. But I went to try it again, with my computer set up, and still had trouble, unless I came across the dead-simple method in this thread - grabbing the ids from lsusb, and plugging them into modprobe usbserial. That set up the /dev/ttyUSB0, which allowed me to use KMobileTools to backup my texts. This is mostly for my reference, but if it manages to help someone else (I'm lazy halfway through a beer, so that's unlikely), good for you.

Monday, August 9, 2010

More Stupid Vim Tricks

Today I had an SVN log that was in descending order by date (most recent at the top), and I wanted it in ascending order (most recent at the bottom). Now there may be a flag on the svn log command to do this, but I thought I'd see what I could do with Vim. One of the most useful tools for doing such things is macros. I read this article a while back about using macros over regexes for many situations, and it's proved to be a very useful technique, and one that looked to be of use here, too. Here's what the svn log looks like:

------------------------------------------------------------------------
r21783 | jbradsha | 2010-08-04 14:41:02 -0700 (Wed, 04 Aug 2010) | 2 lines

Log notes

------------------------------------------------------------------------
r21765 | jbradsha | 2010-08-03 16:09:05 -0700 (Tue, 03 Aug 2010) | 2 lines

Log notes

------------------------------------------------------------------------
r21519 | jbradsha | 2010-07-22 16:51:04 -0700 (Thu, 22 Jul 2010) | 4 lines

Log notes

And so on.

The log notes can be of any length and number of lines, so obviously this wasn't going to be a straightforward task. But it ended up being pretty easy with macros. What I wanted to do was sort those blocks by revision number. To do that, I figured the easiest way is to get each block on one line in a way that I could revert, sort the lines, and then put them back. So I put my cursor on the first character of the first line and did this:

qj 
v
/\n\n---- 
:'<,'> s/[\r\n]/#!#/g
j
q
100@j
:% sort
:% s/#!#/\r/g

Which quite nicely did the trick. Here's what each bit did:
  1. Started recording a macro labelled "j" (for "join")
  2. Started visual selection mode
  3. Searched for two newlines followed by ----: this selects up to the end of the line before the end of the current block (by going two lines before the beginning of the next)
  4. Within that selection, replace all newlines with a unique symbol (#!#), making it all one line ready to be re-exploded afterwards
  5. Move down one line to the beginning of the next block
  6. Stop recording the macro
  7. Run the macro 100 times (I had less than 100 commits to sort)
  8. Sort the now-one-line commits, increasing in number (sort! would reverse the sort)
  9. Replace my delimiters with newlines, restoring the original format
It may sound and look horrendous, but it was pretty straighforward, and macros are a lot easier when you're actually doing them. I just love the power and flexibility you have to do such things in Vim - I can't compare it to emacs, but no other editor allows you nearly this amount of power or flexibility. And if I had wanted to do an even more complex sort, I could have easily piped it out to a command line utility instead of using Vim's built-in sort. But for my purposes, this was plenty.

Thursday, August 5, 2010

Presenting: Wreck's This?

Woo hoo! Jen featured this in her Saturday post this week. It's awesome that so many people have enjoyed this crazy thing! Downloads/ringtones are available down below the video.

Among my blogs that I read sometimes sporadically are Cake Wrecks, a wonderful project by a woman named Jen (with frequent contributions from her husband John) dedicated to sharing the results when, as the motto goes, "professional cakes go horribly, hilariously wrong." It's always entertaining, and I've been especially amused by the occasional geeky and/or childhood references that make their way into her posts - a quick, subtle Veggie Tales reference, the inevitable display of Star Wars butchery - as well as classic and fantastic word journeys that are inexplicable in their hilarity.

But all of this reached a fantastic new height, when a whole post was set to the tune of one of my favorite songs from one of my favorite movies - What's This? from Nightmare Before Christmas - I was delighted. I have both of the awesome cover albums from Nightmare Before Christmas, and both the original and Fall Out Boy's cover are fantastic* - if you haven't heard the latter, do yourself a favor and check it out. Suffice it to say, I loved this post already. But then, at the bottom, was a fantastic and hilarious video of John and one of their friends SINGING the blog post, and doing a pretty decent job of it!

I couldn't help but imagine how awesome it would be to back this terrific effort with some music - and fortunately, I've done enough twiddling with Audacity that it was quite possible to try, anyway. So try I did, and this was the result. Before listening, you should probably read the original post if you haven't already. Read it? Okay, I call this...

Wreck's This?: A Parody:

But of course, I couldn't stop there. I e-mailed Jen and John, and they loved it, and agreed that it was simply begging for a video/slideshow to go with it. And who am I to keep such a thing from being in existence? So I fired up Openoffice Impress to get a slideshow up and running, recorded my clicking through it to the music with xvidcap, and then hopped over to Blender (which is fantastic as a video editor, by the way) to edit and put everything together. And yes, I'm a Linux man, through and through. Anyway, after all that, I came out with this:

...and now my work is done. Hopefully.

Update: Thanks for all the comments, here and over on Cake Wrecks. It's great to see my augmentation of the original Cake Wrecks genius bring a bit of joy and laughter to so many people! For you crazies that want to download it, here's a Normal-quality (~128k, 3.7MB) and High-quality (256k, 6.3MB) version.

And for those of you who are even more crazy, and want ringones, I made a few:
"Popular" by John
Donkey Tank Surprise!
Dumpa dumpa dumpa dumpa whee-you whee-you
Meteorite-bird Fiiiiish (with subsequent ring!)
Rappiness
Can we wrap this up?
If you have Bluetooth on your phone and computer, you can send them to your phone that way. Otherwise, there are internet sites that should be able to do so. From some brief looking, Myxer looks like the most legit/easy way to do this (you can even upload the full song above and chop to make custom ones!). The file it sent to my phone didn't play, but sometimes my phone is weird like that. So good luck?
If you want to chop them up without Myxer (like for Bluetooth), the tool I used is Audacity, which is really easy, I promise - just open one of the full songs above in it, select the portion you want, and hit File->Export Selection. Done!

My favorite part of this whole thing is still "I'm with Jen and John and we're doing this thing... but it's dumb." Cracks me up every time. I still kind of want to put it in a video with the pictures being sung about, but for now this will suffice. Hey, look! I did! The song was surprisingly easy to put together - my compliments on the singers for being remarkably on tempo. The middle was a little iffy, as the tune didn't exactly line up to anything actually in the song as far as I could tell, and the "rappy" part at the end gets a little muddled, but it works, and finishes strong. My favorite part is that the timing of the phone call works perfectly in the space that's not filled by actual lyrics. Thank you, Jen, John, and "the other Jen", for an awesome blog, post, and song.

I think this all should be good, being a parody and all, and I doubt anyone will get riled about it anyway. Jen and John loved it, and agreed that it was begging for a video - hence the addition.

*While many of the other additional covers on Nightmare Revisited are fantastic (Rodrigo y Gabriela, Korn, and even All-American Rejects and Plain White T's are all wonderful), Flyleaf's version of What's This? just made me very sad.

Monday, May 3, 2010

CakePHP, cakephp-instaweb, and PHP 5.3

Today I tried to get a CakePHP app up and running on my home computer, with the excellent cakephp-instaweb, a nifty little Python script that lets you run any CakePHP app from anywhere on your computer. Unfortunately, it didn't work, and was giving me a HTTP 500 CGI Script Error: Premature End of Script Headers error. From looking around the internet, this basically means "Ahh! Something went wrong," which isn't terribly helpful. My first guess* was that my .htaccess files got messed up, which is a good first guess when such things go wrong, but everything was as it should be.

After some more digging, I found out that PHP 5.3 by default flipped a switch (cgi-bin.force-redirect) that previously had been defaulted to off. This issue, I suspect, cropped up because I just recently upgraded to Ubuntu 10.04 Lucid Lynx, and I'm assuming my PHP was upgraded in the process - it is indeed now at 5.3.

From what I can tell, it's a security measure that makes sure scripts are running from where they're supposed to be - which is great, except that that's exactly what CakePHP doesn't do. Fortunately, the solution was as simple as turning this off in my php.ini. A quick locate revealed three of those, in three subfolders of /etc/php5: /cgi, /apache2, and /cli. I initially turned them all off, but only the CGI version ended up needing it. Where exactly your php.ini is depends on your operating system, configuration, and all kinds of things. But if you run into an error like this, try un-commenting and changing the section in your php.ini to look like this:

; cgi.force_redirect is necessary to provide security running PHP as a CGI under
; most web servers.  Left undefined, PHP turns this on by default.  You can
; turn it off here AT YOUR OWN RISK
; **You CAN safely turn this off for IIS, in fact, you MUST.**
; http://php.net/cgi.force-redirect
cgi.force_redirect = 0
Things should start working better, or at least they did for me.

*For general Cake debugging reference, the first thing you should suspect is your cache. If debug is set to 0, it doesn't recreate the cached models and such, so many modifications you make won't actually take effect. Setting debug to 1 or 2, in your core.php, or just clearing your app/tmp/cache folder (only the files inside it though, leave the folder there!) will often resolve some unexpected behaviors.