Wednesday, September 21, 2011

git differences between working copy and stashed copy

Shows the differences between copy and third item in the stash stack...

git diff stash@{3}

Monday, September 12, 2011

Vim search and replace from current location to end of file

Instead of searching and replacing the entire file with...

:s/old/new/g

Try inserting ".," just after the colon. This means "from current position to end of file".


:.,s/old/new/g

The comma actually specifies a range to make the substitution, from left and right of comma. For example...

:5,10s/old/new/g

...makes the substitutions on lines 5 through 10.


Friday, September 09, 2011

Notice to .NET developers

Word is there are about 30 more JAVA positions that need to be filled in the Tulsa area than there are JAVA capable developers. This is driving up the rate that JAVA developers can demand.

Meanwhile, Tulsa is flooded with .NET developers, which drives the rate .NET developers demand, downward.

So a word to the wise: don't get married to one vendor's technology. Any software engineer worth his salt can switch from .NET to JAVA or visa-versa without much pain.

Wednesday, August 31, 2011

Vim tags

Continuing on with my exploration of Vim features I've yet to use, let's explore tags.

Tags are like bookmarks. They let you jump around to different places in your file that you might want to reference, like a class definition for example.

Create a tag like so: ":tag tagname". This tags the current line number with the name you provide. Alternatively, you can use the shortcut CTRL + ]. The tag name will be taken from either the character under your cursor, or if you've highlighted a word or phrase, it will be used.

":tags" shows you your list of tags.

:tags
# TO tag FROM line in file/text
> 1 1 LongTextAnswer 8 q = LongTextAnswer()

Each time I show my :tags I get this error:

E433: No tags file.

This may also explain why my tags queue only contains the most recent tag I create. Further reading reveals that the tags file is created by the program ctags. I'll try installing exuberant-ctags and see what affect that has on my operation.

sudo apt-get install exuberant-ctags

Restarting vim and trying the :tags command again showed that my tags file could still not be found. I found a nice little page that describes the rest of the process that one must go through to get your tags file set up. Follow the link to learn more.


On a related note, you can read ctags in python:






Vim Execute Mode

I use vim and gvim every day. I'm so productive using the small subset of available commands that I know that I tend not to explore the question, "what else can I do with Vim?"

Take Execute Mode for example. In 10 years of Vim use, I've never tried it. Let's fix that now.

You enter Execute Mode by pressing capital Q (shift + q) when in normal mode. You'll see this at the bottom of your window.

Entering Ex mode. Type "visual" to go to Normal mode.
:

This seems familiar enough, but this is different than when you simply type ":" to enter a command at the bottom of the screen in normal mode. In normal mode, typing ":10 " + enter takes you to the tenth line in the document. In Execute Mode, ":10" + enter displays the tenth line just below your cursor. Hitting return again shows the eleventh line, and so on. You are not editing the document in this mode, simply accessing it. Interesting, but not yet terribly useful. Let's see what else you can do.

:w filename

This writes the file, just as it would if you had typed :w filename in normal mode, except again, instead of returning you to editing the document, you remain in Execute mode, meaning that the ":" appears again, awaiting your next command.

I'm afraid I can't imagine too many good reasons to use Execute Mode. The best use-case I can find is that you could use the :n, where n is a line number, feature view a section of the document you are not working on without leaving the section you are working on. If you have any tips on how Execute Mode makes your life easier, please leave a comment.


Monday, August 08, 2011

Safari URL opens new window

Here's a strange quirk I encountered while working with Safari mobile: HTML anchors (<a href="http://www.blogger.com/something.html">click</a>) open a new Safari browser instance---every time.

Now that can't be right. As it turns out, this is indeed the standard behavior when the target attribute is not explicitly set in the anchor. Apple does provide a work around setting:

http://www.naquah.net/blog/dennis/2008/03/21/how-to-enable-single-window-mode-in-safari

There are many instances when web designers don't need targets, and they are omitted. For most browsers, when the target is not explicitly set, the browser default behavior is _self. See the table from w3cschool:

http://www.w3schools.com/tags/att_a_target.asp

Attribute Values
ValueDescription
_blankOpen the linked document in a new window or tab
_selfOpen the linked document in the same frame as it was clicked (this is default)
_parentOpen the linked document in the parent frameset
_topOpen the linked document in the full body of the window
framenameOpen the linked document in a named frame


The kicker is that Safari uses _blank as the default instead of self. The solution for web designers? Explicitly set the target attribute to _self for every anchor. A bit of a hassle, but the best way to ensure that a new window does not open up with each hyperlink click.


Wednesday, July 13, 2011

Huge gvim annoyance

Since upgrading to Ubuntu 11.01, when I open a document using gvim, I get a very unresponsive file browser window. In the past, I would double click a folder and it would quickly open. Using gvim, when I double-click, I get a wait cursor. I often have to click four or five times before the folder opens. Very irritating. Anyone else have this problem?

Same thing happens whether using vim-gnome or vim-gtk package.

Other programs do not share this quirk. For example, the text editor program behaves as expected when opening the files.

Tuesday, May 24, 2011

Can't ignore IE

I've been using Ubuntu as my operating system for the past five years. So long that I almost forgot that you must always check your web site for IE compliance. Well, I didn't forget so much as I wasn't concerned.

So since I've been shopping for contracts---I decided to return to consulting if I can line up the right opportunities--I thought it would be wise to review the user experience of my site, devinvenable.com, using IE. I fired up a virtual machine running Windows XP, opened up IE 8, and was hit with Javascript errors. Doh!

It's simple enough to conditionally remove code from your page that won't run on IE, or conditionally include code that does. Even if you use cross-platform javascript libraries like jQuery, as I do, you are still bound to run into issues from time to time.


<!--[if IE]>
You are using IE (IE5+ and above), so include include script that is specific for IE here.
<![endif]-->

<![if !IE]>
You are NOT using IE, so feel free to use HTML 5 features.
<![endif]>


So don't get lazy and assume that IE is history. While it's true that many savvy technical users have ditched IE for Chrome or Firefox, there are always users who will use IE because it is installed by default on their Windows OS.

Writing this entry made me curious about the current browser usage statistics. Amazingly, Firefox is way out in front with 42.9% this month, followed by Chrome at 25.6%. Microsoft's IE is still hanging in there with a respectable 24.3%. Still a contender but far from being the market leader in 2011.

http://www.w3schools.com/browsers/browsers_stats.asp

Friday, May 20, 2011

Job search fun!

I've decided to make a transition. New opportunity, here I come!

Looking for a new gig is always a lot of hard work. One must find the right fit: good people, exciting technology, and room for growth. I've talked to one prospective employer already and was asked, "What would be your ideal job if you could have anything you dream of, the perfect environment?"


It's a tough question. As a technologist, I'm probably at the top of my game. With 14 years of software development, I've dappled in just about everything. I don't encounter new technologies or languages often for which I've not already built products. Because of this, I tend to stay in the trenches---doing hands on technical work.

I'm 42. At my age, some get out of the trenches and into management. I'm afraid I would be bored silly if my primary work tool was Microsoft Project. That said, I am a people person, and often find myself wishing for more socialization when working with other developers, as so often they are introverts.

I like building new products versus extending the work others did before me. Who wouldn't? So often you inherit a bug infested mess. Building systems from scratch is fun for me.

I love brainstorming and sharing ideas. I'm a dreamer and I always have been, and this tends to work for me in the creativity department.

I love open source projects and all things Linux. This doesn't always work to my benefit in the Tulsa market where many mid-sized corporations go with Microsoft solutions. Perhaps I ought to go after these markets, selling CTO's on the joy of open source and living in a license free world. For a fraction of what companies pay for licensing fees I could switch them over to free solutions. That's a gift that would keep on giving. Many mid-sized corporations would be well served ditching Oracle, for example, as the scalability and reliability of open source alternatives is easily demonstrable. And what about the hundreds of thousands they spend on DBA's? Database administration doesn't have to be this hard, folks.

I'm no closer now than when I started writing this blog entry to knowing what my ideal job would be. But at least the creative juices are flowing. :)

Tuesday, April 26, 2011

Adding information to Django's default error page

Django's default error page is a handy way find out what went wrong when your view code runs into an exception that is not explicitly handled. But sometimes you don't get the info you really want to see. For instance, today I kept running into sql errors, something I don't see too much of using Django because they are normally abstracted away by the model framework.

In my case I needed to resort to using raw sql. The query was complex and the variables many, and thus I encountered a number of different database (cx_oracle) errors while working on the view and I didn't have a quick and dirty way to see the sql that was generated.

Getting the most recently generated sql is possible by importing django.db.connections. You can then tack it into your exception and see it on the default error page using the following technique.



try:

"""
This is where you build your view. Do whatever you need to do. In my case
I was inserting a row into the database here.
"""
except Exception as inst:

"""
inst.args is a tuple of arguments that were passed when the exception
was raised. Django will turn this variable into the main error message
you see atop the default error page. It's a tuple, so you can't append
to it, but you can replace it with another tuple and add any information
that would serve you well.
"""

inst.args = ("%s sql:%s" % (inst.args[0], " ".join(connections[db].queries.pop()['sql'].split())),)

"""
Sure that's ugly, but it served my debugging purpose. Use pop to get the most
recent query from the queries list. I wanted to get rid of the while space and
newline characters, which is the reason for the split and join. Now you just
raise the exception.
"""
raise



If you are going to do this kind of thing frequently you should probably explore the process-exception middleware API.

http://docs.djangoproject.com/en/dev/topics/http/middleware/?from=olddocs#process-exception

Monday, April 25, 2011

Best Django debugging technique ever

Start up your test app using the Development Server. Then inject the following into your code where you want to examine everything, perhaps in an exception handler.


import pdb
pdb.set_trace


Now when you hit the exception, pdb will take over the console window you started the test app. Type help if you are unfamiliar with pdb. All of your variables are available for review!

Sweet! I can't believe I didn't know about this technique before.

Monday, March 28, 2011

Dansguardian and Youtube on Ubuntu 10.10

If you want content filtering for your kids on Ubuntu 10.10, Dansguardian does the trick, but be prepared to do some tweaking.

Installation is not difficult. Follow this recipe:

https://help.ubuntu.com/community/Servers/DansGuardian

My kids love youtube but the default configuration renders it useless. Locate the configuration files in /etc/dansguardian. You'll primarily be interested in the content under the "lists" directory.

I added the following file extensions to exceptionextensionlist:


.js
.flv
.mp3
.ico


From bannedregexpurllist, I removed the keyword "naked", which seemed a bit over the top to me.

For video playback, add this line to exceptionurllist:


youtube.com/videoplayback


In exceptionsitelist, add the following. What the heck is ytimg.com? Well apparently it serves the main static css off youtube. I don't know if this changes and if it does how often, but I do know that the addition of this line alone had the most positive change on the overall youtube experience under Dansguardian.


ytimg.com


Similar steps may need to be repeated for other sites that fail to render properly. Watch the log at /var/log/dansguardian/access.log to see what's getting blocked, as that will provide the clues as to what you need to make exception for.

Thursday, March 17, 2011

Color highlight columns in Vim

Vim 7.3 has a new, useful feature that allows you to highlight (set the background color) of one or more columns of the document you are working on. This comes in handy if you are working with a file that uses a fixed width format. For example, if you want to quickly see the 44th column for every row as you scan through a file, this might assist in the task.

Vim 7.3 is not yet in the Ubuntu repositories officially, but a PPM is available here:

http://askubuntu.com/questions/7283/where-can-i-find-vim-7-3

Once installed, use vim help to get details about colorcolumn.


:help colorcolumn


This will show you:


'colorcolumn' 'cc' string (default "")
local to window
{not in Vi}
{not available when compiled without the |+syntax|
feature}
'colorcolumn' is a comma separated list of screen columns that are
highlighted with ColorColumn |hl-ColorColumn|. Useful to align
text. Will make screen redrawing slower.
The screen column can be an absolute number, or a number preceded with
'+' or '-', which is added to or subtracted from 'textwidth'.

:set cc=+1 " highlight column after 'textwidth'
:set cc=+1,+2,+3 " highlight three columns after 'textwidth'
:hi ColorColumn ctermbg=lightgrey guibg=lightgrey

When 'textwidth' is zero then the items with '-' and '+' are not used.
A maximum of 256 columns are highlighted.




In practice you only need to :set cc=n, as there are default colors.

Thursday, March 03, 2011

History in Python shell

I never could get used to ipython, but still wish for command history in my shell. You too? I'm reposting this solution here that not only saves your command history between sessions but also gives you auto-completion.

Here's what you do. Store the following file in ~/.pystartup

Don't forget to export PYTHONSTARTUP as noted in the comments.


# Add auto-completion and a stored history file of commands to your Python
# interactive interpreter. Requires Python 2.0+, readline. Autocomplete is
# bound to the Esc key by default (you can change it - see readline docs).
#
# Store the file in ~/.pystartup, and set an environment variable to point
# to it: "export PYTHONSTARTUP=/home/user/.pystartup" in bash.
#
# Note that PYTHONSTARTUP does *not* expand "~", so you have to put in the
# full path to your home directory.

import atexit
import os
import readline
import rlcompleter

readline.parse_and_bind('tab: complete')
historyPath = os.path.expanduser("~/.pyhistory")

def save_history(historyPath=historyPath):
import readline
readline.write_history_file(historyPath)

if os.path.exists(historyPath):
readline.read_history_file(historyPath)

atexit.register(save_history)
del os, atexit, readline, rlcompleter, save_history, historyPath




Please note that this will only work on *nix systems. As readline is only available in Unix platform.