<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-35024663</id><updated>2012-02-16T07:16:15.436-08:00</updated><category term='Programs'/><category term='Interview'/><category term='Hacks'/><category term='Tweaks'/><category term='Funny'/><category term='Reads'/><category term='Programming'/><category term='Links'/><title type='text'>Code, Links, Programs, and Stuff.</title><subtitle type='html'>The Unfocused, but mostly technical, Blog of Jonathan Discar</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>75</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-35024663.post-1843826701854028470</id><published>2012-01-23T10:09:00.000-08:00</published><updated>2012-01-23T10:09:00.928-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Extended Cron</title><content type='html'>I wrote a Reminder/Notification program for Windows called Reminder 19 (you can check it out at &lt;a href="http://reminder.relic19.net/"&gt;http://reminder.relic19.net&lt;/a&gt;.) &amp;nbsp;I wanted to be able to cleanly define many different kinds of alert schedules and decided to use cron as my starting point. &amp;nbsp;I ended up extending the format because I wanted to have things like time delayed alerts and a year field. &amp;nbsp;This is the format I came up with... I think it's pretty expressive. &amp;nbsp;The only way I think it would be more expressive is if I added conditional alerts (for example, an alert should be shown on the 31st if the month has 31 days, otherwise it should be shown on the 28th).&lt;br /&gt;&lt;br /&gt;Format 1: Advanced Schedule By Dates and Times&lt;br /&gt;&amp;nbsp; +------------------ minute (0 - 59)&lt;br /&gt;&amp;nbsp; | &amp;nbsp;+--------------- hour (0 - 23)&lt;br /&gt;&amp;nbsp; | &amp;nbsp;| &amp;nbsp;+------------ day of month (0 - 31)&lt;br /&gt;&amp;nbsp; | &amp;nbsp;| &amp;nbsp;| &amp;nbsp;+--------- month (1 - 12)&lt;br /&gt;&amp;nbsp; | &amp;nbsp;| &amp;nbsp;| &amp;nbsp;| &amp;nbsp;+------ year (number between 1700 and 9999)&lt;br /&gt;&amp;nbsp; | &amp;nbsp;| &amp;nbsp;| &amp;nbsp;| &amp;nbsp;| &amp;nbsp;+--- dayOfWeek (0 - 7, 10-17, 20-27, 30-37, 40-47)&lt;br /&gt;&amp;nbsp; | &amp;nbsp;| &amp;nbsp;| &amp;nbsp;| &amp;nbsp;| &amp;nbsp;| &amp;nbsp;+ optional command and parameters&lt;br /&gt;&amp;nbsp; * &amp;nbsp;* &amp;nbsp;* &amp;nbsp;* &amp;nbsp;* &amp;nbsp;* &amp;nbsp;*&lt;br /&gt;&lt;br /&gt;Each of the patterns from the first six fields may be either a single in range number, * (the asterisk character, which means the field matches all legal values), or a list of in range numbers separated by commas (such as 2,3). There may be no spaces following commas and fields may not end with a comma. &amp;nbsp;There is also an optional special seventh field.&lt;br /&gt;&lt;br /&gt;The hour field (field 1) is specified using the 24-hour format. &amp;nbsp;0 is 12 AM, 4 is 4 AM, and 15 is 3 PM.&lt;br /&gt;&lt;br /&gt;The month field (field 4) is defined as a number, where 1 is January and 11 is November. &amp;nbsp;Alerts will not be shown for non existent days, such as September 31. &amp;nbsp;Please note that an alert will not show on September 30 instead.&lt;br /&gt;&lt;br /&gt;For the day of the week field (field 6), both 0 and 7 are considered Sunday. &amp;nbsp;The dayOfWeek field can be two digits, where the first digit represents its position in the month and the second digit is the day of the week. &amp;nbsp;For example, 31 would mean the third Monday of every month. &amp;nbsp;A position of 0 means every postion, so 03 means every Wednesday. &amp;nbsp;In deciding the next wake up time between, for example, the 1st and 31st, the soonest wake up date is chosen.&lt;br /&gt;&lt;br /&gt;An alert is shown when the time/date specification fields all match the current time and date. There is one exception: if both "day of month" and "day of week" are restricted (not "*"), then either the "day of month" field (field 3) or the "day of week" field (field 6) must match the current day (even though the other of the two fields need not match the current day).&lt;br /&gt;&lt;br /&gt;The command field (field 7) is completely optional. &amp;nbsp;If it is present, then an attempt will be made to execute the command.&lt;br /&gt;&lt;br /&gt;Example 1:&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;00 16 1,2,31 2,3 2008 1,45&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;This alert specifies the following date and times:&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;February 1, 2008 at 4:00 PM&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;February 2, 2008 at 4:00 PM&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;February 4, 2008 at 4:00 PM (A Monday)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;February 11, 2008 at 4:00 PM (A Monday)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;February 18, 2008 at 4:00 PM (A Monday)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;February 22, 2008 at 4:00 PM (The fourth Friday)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;February 25, 2008 at 4:00 PM (A Monday)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;March 1, 2008 at 4:00 PM&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;March 2, 2008 at 4:00 PM&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;March 3, 2008 at 4:00 PM (A Monday)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;March 10, 2008 at 4:00 PM (A Monday)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;March 17, 2008 at 4:00 PM (A Monday)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;March 24, 2008 at 4:00 PM (A Monday)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;March 28, 2008 at 4:00 PM (The fourth Friday)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;March 31, 2008 at 4:00 PM (The 31st and a Monday)&lt;br /&gt;&lt;br /&gt;Example 2:&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;00 4,16 * * * * "C:\Program Files\Internet Explorer\IEXPLORE.EXE" ? http://www.google.com&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Every day at 4 AM and 4 PM, an instance of Internet Explorer will be launched that navigates to http://www.google.com.&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;Format 2: Advanced Schedules by Time Delays&lt;br /&gt;&amp;nbsp; +------------------ the start minute (0 - 59)&lt;br /&gt;&amp;nbsp; | &amp;nbsp;+--------------- the start hour (0 - 23)&lt;br /&gt;&amp;nbsp; | &amp;nbsp;| &amp;nbsp;+------------ the start day of month (0 - 31)&lt;br /&gt;&amp;nbsp; | &amp;nbsp;| &amp;nbsp;| &amp;nbsp;+--------- the start month (1 - 12)&lt;br /&gt;&amp;nbsp; | &amp;nbsp;| &amp;nbsp;| &amp;nbsp;| &amp;nbsp;+------ the start year (number between 1700 and 9999)&lt;br /&gt;&amp;nbsp; | &amp;nbsp;| &amp;nbsp;| &amp;nbsp;| &amp;nbsp;| &amp;nbsp;+--- increment in minutes (+[number of minutes to delay])&lt;br /&gt;&amp;nbsp; | &amp;nbsp;| &amp;nbsp;| &amp;nbsp;| &amp;nbsp;| &amp;nbsp;| &amp;nbsp;+ optional command and parameters&lt;br /&gt;&amp;nbsp; * * * * * &amp;nbsp;* &amp;nbsp;*&lt;br /&gt;&lt;br /&gt;No field in this format may be * (an asterisk character.) &amp;nbsp;Field 7 (the command field) is optional, but all other fields must be defined.&lt;br /&gt;&lt;br /&gt;Each of the first 5 fields must be a single number in the specified ranges. &amp;nbsp;They will be used to define the start date.&lt;br /&gt;&lt;br /&gt;The hour field is specified using the 24-hour format. &amp;nbsp;0 is 12 AM, 4 is 4 AM, and 15 is 3 PM.&lt;br /&gt;&lt;br /&gt;The months are defined as number, where 1 is January and 11 is November.&lt;br /&gt;&lt;br /&gt;For "increment in minutes" field (field 6), a non-negative number must be specified, prefixed by a '+' character. &amp;nbsp;The number represents the number of minutes to wait between alerts. &amp;nbsp;For example, +59 means that the alert will be triggered every 59 minutes after the start date.&lt;br /&gt;&lt;br /&gt;The command field (field 7) is completely optional. &amp;nbsp;If it is present, then an attempt will be made to execute the command.&lt;br /&gt;&lt;br /&gt;Example 1:&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;00 00 31 3 2008 +30&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;This alert will be shown every 30 minutes after March 31, 2008 at 12:00 AM. &amp;nbsp;So the first alert will go off at March 31, 2008 at 12:30 AM, the next alert will go off at March 31, 2008 at 1:00 AM, and so on.&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;Example 2:&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;00 00 31 3 2008 +60 "C:\Program Files\Internet Explorer\IEXPLORE.EXE" ? http://www.google.com&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;This alert will be shown every 60 minutes (one hour) after March 31, 2008 at 12:00 AM. &amp;nbsp;So the first alert will go off at March 31, 2008 at 1:00 AM, the next alert will go off at March 31, 2008 at 2:00 AM, and so on. &amp;nbsp;Whenever an alert goes off, http://www.google.com will be launched in Internet Explorer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-1843826701854028470?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/1843826701854028470/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=1843826701854028470' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/1843826701854028470'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/1843826701854028470'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2012/01/extended-cron.html' title='Extended Cron'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-3104434830598446687</id><published>2012-01-18T14:37:00.000-08:00</published><updated>2012-01-18T14:37:00.236-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Decoding Text Formats</title><content type='html'>Occasionally, you're get text documents in different formats.&amp;nbsp; I'm a plain text kinda guy.&amp;nbsp; I like that it's really flexible.&amp;nbsp; Anyway, here's a list of decoders I used.&amp;nbsp; These have been virus and functionally tested.&lt;br /&gt;&lt;br /&gt;CHM Decoder (CHM to HTML) - It's useful to me because sometimes the text is too small to read on a CHM and there's no nice way I know of to increase the font size.&amp;nbsp; You can download it at: &lt;a href="http://www.shareup.com/CHM_Encoder-download-26404.html"&gt;http://www.shareup.com/CHM_Encoder-download-26404.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;CLIT (LIT to HTML) - I found a similar program to convert LIT files to HTML.&amp;nbsp; Although it has a slightly unfortunate name, it works really well.&amp;nbsp; You can download it at: &lt;a href="http://www.convertlit.com/download.php"&gt;http://www.convertlit.com/download.php&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-3104434830598446687?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/3104434830598446687/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=3104434830598446687' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3104434830598446687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3104434830598446687'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2012/01/decoding-text-formats.html' title='Decoding Text Formats'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-3205392814661936135</id><published>2011-09-11T09:45:00.001-07:00</published><updated>2011-09-11T09:50:56.326-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>ReNamer</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-yq0B0_UNj0w/Tmzm42zSJ4I/AAAAAAAAACA/Dir-vqw1DEE/s1600/renamer.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="326" src="http://3.bp.blogspot.com/-yq0B0_UNj0w/Tmzm42zSJ4I/AAAAAAAAACA/Dir-vqw1DEE/s400/renamer.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;I wanted to replace a lot of text in filenames without any hassle, so I quickly looked for a program to do it for me. &amp;nbsp;The first program I tried worked perfectly, had no installation process, and had a "no install" version (the archive version.) &amp;nbsp;So, if you need to rename files easily, I suggest giving this a program a try.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.den4b.com/?x=downloads&amp;amp;product=renamer"&gt;Try out ReNamer&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-3205392814661936135?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/3205392814661936135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=3205392814661936135' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3205392814661936135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3205392814661936135'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2011/09/renamer.html' title='ReNamer'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-yq0B0_UNj0w/Tmzm42zSJ4I/AAAAAAAAACA/Dir-vqw1DEE/s72-c/renamer.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-8072378027590754922</id><published>2011-05-16T12:51:00.000-07:00</published><updated>2011-05-16T12:51:07.906-07:00</updated><title type='text'>C# Notes</title><content type='html'>I made a stupid C# mistake today.  In the constructor of my form, I had an OpenFileDialog.Show() call (to get the name of a file to operate on.)  When I ran the program, the OpenFileDialog would show as expected.  But after I pressed okay, the main application would not be the focused window.&lt;br /&gt;&lt;br /&gt;It took me too long to figure out that since I was calling OpenFileDialog in the constructor, the Application wasn't initialized yet and so the OpenFileDialog.ShowDialog() was using another window as its parent.  Using the call OpenFileDialog.ShowDialog(this), where this is the current form, made everything work as expected.&lt;br /&gt;&lt;br /&gt;Another problem I had was not being able to exit the program by calling Application.Exit() in the constructor.  Apparently, the Application isn't initialized before the constructor returns.  So I'd either have to throw an exception for whoever is calling Application.Run() or else use the Environment.Exit().  I went with Environment.Exit()... not sure if there's any reason not to.&lt;br /&gt;&lt;br /&gt;I spent a long time trying to figure out why I couldn't set an item as selected for a ListView by setting the Select property to true.  Apparently, you're supposed to call ListView's Select method.  I should look into this more.&lt;br /&gt;&lt;br /&gt;More:&lt;br /&gt;&lt;br /&gt;Use the Shown Callback in forms if you want to do stuff to controls outside of the contstructor but before things really start running.  In the constructor, there are no event handlers and you can't exit the application without using Environment.Exit.&lt;br /&gt;&lt;br /&gt;If you want to use a checkbox in a list view, that is built in.  If you're listening for items checked, make sure you don't add the ListViewItem to the list until the checked value is correctly set.&lt;br /&gt;&lt;br /&gt;When I first started .Net development, I couldn't get the KeyDownEvent listener to work for my form.  It turns out I forgot to change the form's KeyPreviewProperty to true.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-8072378027590754922?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/8072378027590754922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=8072378027590754922' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8072378027590754922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8072378027590754922'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2011/05/c-notes.html' title='C# Notes'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-4466166627332543578</id><published>2011-05-09T10:49:00.001-07:00</published><updated>2011-05-09T10:49:43.554-07:00</updated><title type='text'>iPhone Pains</title><content type='html'>Man, at this point I wish I had gone with an Android phone instead of an iPhone. But I have too much time and money burned (NOT INVESTED) on the iPhone to make it worthwhile. My laptop died last month (I think Taiwan's summer destroyed its ability to stay cool.) I used that laptop to sync with my iPhone and because of the way the iPhone is designed, I needed to resync with iTunes on a new computer, which would delete all my music and playlists. Luckily, the hard drive from my busted laptop was still good so I could get my music. Otherwise, I would need to spend A LOT of time looking for safe, trustworthy programs to get my music off my iPhone. I've heard they exist, I just don't want to spend the time figuring out what they are and how to use them safely.&lt;br /&gt;&lt;br /&gt;So I needed to copy all the music from the laptop onto a new computer. I ended up using an old Mac Mini I had lying around, (might as well find a use for that expensive lesson on how I do not enjoy developing iPhone software in my freetime.) I needed to figure out how to copy all my playlists (hint: figure out where your iTune's library.xml file is and import it. Use some text editing software and do a "replace all" on your music directories from your old computer to where they live on the new computer.)&lt;br /&gt;&lt;br /&gt;I spent an entire evening doing all of this, which was really annoying. I really, really wish I didn't have to jump through all these hoops to add new music or to sync other items with my iPhone. While the iPhone is pretty, using it requires so much awkward hoop jumping that one day, I know I'm just going to give up on it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-4466166627332543578?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/4466166627332543578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=4466166627332543578' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4466166627332543578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4466166627332543578'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2011/05/iphone-pains.html' title='iPhone Pains'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-4653709322495846161</id><published>2011-05-09T10:48:00.001-07:00</published><updated>2011-05-09T10:49:18.340-07:00</updated><title type='text'>Advice to a man for a successful marriage</title><content type='html'>Okay, today I'm going to share one of the secrets to a successful marriage (for the husband.)  This secret was passed down to me by a wise former boss of mine.  Here's what he told me:&lt;br /&gt;&lt;br /&gt;"At some point, especially in the beginning of marriage before she learns better, she will inevitably ask you to make a choice.  This should be your most frequent response:&lt;br /&gt;&lt;br /&gt;1. Slowly look over each choice.  You don't have to really care, but it needs to appear like your thinking about them.&lt;br /&gt;2. Pause until the count of 3.&lt;br /&gt;3. Ask her what she thinks.  She will have an opinion. You must make her voice it.&lt;br /&gt;4. Reply: Y'know, that's what I was leaning for too.  Let's go with that one."&lt;br /&gt;&lt;br /&gt;This works very well, just don't be too obvious.  And remember, in an argument, it's not a question about who is right or who is wrong.  It's just about who cares more.  I read that from Scott Adam's blog, and although I don't always agree with him, I agree with him in that.&lt;br /&gt;&lt;br /&gt;(Yes, in case you're worried, there's loads of sarcasm in this entire post, Maybe. Ha ha.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-4653709322495846161?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/4653709322495846161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=4653709322495846161' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4653709322495846161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4653709322495846161'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2011/05/advice-to-man-for-successful-marriage.html' title='Advice to a man for a successful marriage'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-8792541376365230343</id><published>2011-05-04T14:39:00.000-07:00</published><updated>2011-05-04T14:54:13.826-07:00</updated><title type='text'>Subversion</title><content type='html'>&lt;i&gt;&lt;span style="font-style: italic;"&gt;Notes I wrote up in 2006 regarding subversion. It functions as &lt;/span&gt;an intro guide to subversion, both as a client and as an administrator.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;I've been using subversion (nope, not a git guy yet) for most of my own work, I even got our projects at my current job onto subversion.  It's much better than source safe/offsite (which I used at a previous job) and I even prefer it to CVS.  Subversion is designed specifically to be a modern replacement for CVS and shares a number of the same key developers. It uses a copy-modify-merge for file sharing. To read more about subversion, you can read their very good documentation at &lt;a href="http://svnbook.red-bean.com/"&gt;http://svnbook.red-bean.com/&lt;/a&gt;. The following is a link to an appendix from the svnbook that introduces subversion for cvs users. I think that it will be a very helpful and painless way to quickly understand subversion with a cvs background. You can read it starting at &lt;a href="http://svnbook.red-bean.com/en/1.2/svn.forcvs.html"&gt;http://svnbook.red-bean.com/en/1.2/svn.forcvs.html&lt;/a&gt;. &lt;br /&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;Subversion’s homepage is &lt;a href="http://subversion.tigris.org/"&gt;http://subversion.tigris.org/&lt;/a&gt;. I install it using the instructions found on &lt;a href="http://www.excastle.com/blog/archive/2005/05/31/1048.aspx"&gt;http://www.excastle.com/blog/archive/2005/05/31/1048.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The most direct way of using subversion is through the subversion client tool called svn. You can download the tool from subversion’s site, &lt;a href="http://subversion.tigris.org/"&gt;http://subversion.tigris.org/&lt;/a&gt;. For directions on using the tool, refer to the appropriate section at &lt;a href="http://svnbook.red-bean.com/"&gt;http://svnbook.red-bean.com/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Another subversion client option for Win32 users is TortoiseSVN, which is implemented as a Windows shell extension. TortoiseSVN can be downloaded from &lt;a href="http://tortoisesvn.tigris.org/"&gt;http://tortoisesvn.tigris.org/&lt;/a&gt;. It is very simple and intuitive to use as all commands are added to the right click context menu when using windows explorer. Special icons are used to show which files and folders are under revision control.&lt;br /&gt;&lt;br /&gt;If you're using Eclipse, there is a plugin called SubClipse that will integrate Eclipse and Subversion. You can download the plug-in from &lt;a href="http://subclipse.tigris.org/"&gt;http://subclipse.tigris.org/&lt;/a&gt;. A good guide to installation and usage for the plug-in can be found at &lt;a href="http://dev2dev.bea.com/pub/a/2005/11/subclipse.html?page=1"&gt;http://dev2dev.bea.com/pub/a/2005/11/subclipse.html?page=1&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The goal of the following sections is to explain how to use the subversion repository I'm administering from a Windows 2000 machine, a Trusted Solaris 8 machine, and a Solaris 10 machine.  Solaris instructions should be pretty similar for any UNIX and Windows 2000 should be pretty similar to any Windows in general &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 130%;"&gt;&lt;span style="font-weight: bold;"&gt;Brief Intro to Using Subversion as a Client&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The true guide to subversion is &lt;a href="http://svnbook.red-bean.com/"&gt;http://svnbook.red-bean.com/&lt;/a&gt;.  It’s somewhat long, so I’ve created a short document to help get you started using it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Basics&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Subversion is a version control system.  It is primarily a "copy-modify-merge" system as opposed to a "lock-modify-unlock" system, although it has optional features to do the latter.  Subversion works on the client by using hidden ".svn" folders in the directory you checkout to that you must not remove.  Subversion repositories generally have top-level folders of trunk, branches, and tags.  Trunk contains the working data, branches hold code branches, and tags allow you to store named "snapshots" of the project.  Subversion uses only one revision number for the entire project: anytime anything is changed, the revision number goes up.  For features and general information, you can look at the wikipedia page: &lt;a href="http://en.wikipedia.org/wiki/Subversion_%28software%29"&gt;http://en.wikipedia.org/wiki/Subversion_%28software%29&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Here’s a list of important action words:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #006600;"&gt;Checkout&lt;/span&gt; - Get the files from the repository for the first time.&lt;br /&gt;&lt;span style="color: #006600;"&gt;Update&lt;/span&gt; - Get a version of the project, HEAD is the most recent version.&lt;br /&gt;&lt;span style="color: #006600;"&gt;Commit&lt;/span&gt; - Make your changes happen in the repository; basically "check-in."&lt;br /&gt;&lt;span style="color: #006600;"&gt;Add&lt;/span&gt; - Add a file to the repository.  This won’t actually happen until you commit.&lt;br /&gt;&lt;span style="color: #006600;"&gt;Delete&lt;/span&gt; - Delete a file from the repository.  This won’t actually happen until you commit.&lt;br /&gt;&lt;span style="color: #006600;"&gt;Export &lt;/span&gt;- Copy the files from the repository without the hidden .svn files.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Getting Set Up&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Each repository has a separate list of users and passwords.  If you don’t have access to a certain repository, talk to the subversion administrator.  Right now, there is no way to set up a user or change a password without a subversion administrator being in the room with you.  If it’s a big enough deal, this can be changed, but it might take up to a week to set up correctly.&lt;br /&gt;&lt;br /&gt;Once you have access to the repository, you will need the url to the repository and a subversion client (see the following two sections.)  Once you have both, you will need to give the client the url to the repository, your username, and your password to do your initial checkout.  You can checkout starting from a subfolder (say /trunk) instead of the top level if you’d like.  And then you’re all set up.&lt;br /&gt;&lt;br /&gt;Please remember to make a log message whenever you do a commit to explain what you’re committing.  Also, remember that the permissions for files are not checked in with a file.  To make sure it's executable, you need to set a special permission, the svn-executable flag.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Subversion Clients&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I’m going to list the subversion clients I know about and how to start using them.  If you know the basics behind subversion, all these clients should be pretty intuitive to use once you’ve got them running.  If you don’t know the basics of subversion, read the intro to &lt;a href="http://svnbook.red-bean.com/"&gt;http://svnbook.red-bean.com/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Subversion Client: &lt;a href="http://subversion.tigris.org/"&gt;http://subversion.tigris.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is the command line subversion client.  To install it for Solaris, visit &lt;a href="http://www.sunfreeware.com/"&gt;http://www.sunfreeware.com&lt;/a&gt; and get/install the subversion package for your version of Solaris.  The utility will be located at /usr/local/bin/svn.  To use this client, read the very easy to follow &lt;a href="http://svnbook.red-bean.com/"&gt;http://svnbook.red-bean.com/&lt;/a&gt;.  If you only read the subversion client section (&lt;a href="http://svnbook.red-bean.com/en/1.4/svn-book.html#svn.ref.svn"&gt;http://svnbook.red-bean.com/en/1.4/svn-book.html#svn.ref.svn&lt;/a&gt;), it should be enough.  I think this is the best client for UNIX systems.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Sample Commands:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Since you’ll be using the SVN Command line tool for now, here’s some samples on how to do things.  I’ll assume /usr/local/bin/svn is on your path.&lt;br /&gt;&lt;br /&gt;&amp;gt; mkdir /opt/repositoryName&lt;br /&gt;&amp;gt; cd /opt/repositoryName&lt;br /&gt;&amp;gt; svn checkout [repository url] .&lt;br /&gt;&amp;gt; (possibly enter your username and password)&lt;br /&gt;&lt;br /&gt;To do an update:&lt;br /&gt;&amp;gt; cd /opt/repositoryName&lt;br /&gt;&amp;gt; svn update&lt;br /&gt;&lt;br /&gt;To do a commit:&lt;br /&gt;&amp;gt; cd /opt/repositoryName&lt;br /&gt;&amp;gt; svn commit&lt;br /&gt;&lt;br /&gt;This will open an editor.  Above the line is the log message.  Below the line are the changes that will be committed.  You can delete the lines you don’t want to be commited.  To commit, do a :wq.  To cancel, do a :q, and then specify abort.&lt;br /&gt;&lt;br /&gt;To add a file:&lt;br /&gt;&amp;gt; cd /opt/repositoryName&lt;br /&gt;&amp;gt; svn add [filename]&lt;br /&gt;&amp;gt; svn commit&lt;br /&gt;&lt;br /&gt;To delete a file:&lt;br /&gt;&amp;gt; cd /opt/repositoryName&lt;br /&gt;&amp;gt; svn delete [filename]&lt;br /&gt;&amp;gt; svn commit&lt;br /&gt;&lt;br /&gt;Tortoise SVN (windows only): &lt;a href="http://tortoisesvn.tigris.org/"&gt;http://tortoisesvn.tigris.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In my opinion, this is the best subversion client on the windows side.  It’s a simple, one click install.  To use it, create a folder and then right click on it.  Go to &lt;i&gt;SVN Checkout&lt;/i&gt; and provide the repository information.  All subversion operations will be available from the windows right click menu.&lt;br /&gt;&lt;br /&gt;SmartSvn: &lt;a href="http://www.syntevo.com/smartsvn/index.html"&gt;http://www.syntevo.com/smartsvn/index.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is the easiest to install graphical svn client on the Solaris side.  That is because it is a java program.  This also means it’s probably the slowest of the graphical svn clients, but I’d say the easy install is worth it.  To run it, run "[SmartSvnHome]/bin/smartsvn.sh."  Please note you need java 1.4 to run it (which you should already have if you’ve installed NetBeans.)  If your OS isn’t pointing to java 1.4 by default, edit the seventh line of [SmartSvnHome]/bin/smartsvn.sh.&lt;br /&gt;&lt;br /&gt;RapidSvn: &lt;a href="http://rapidsvn.tigris.org/"&gt;http://rapidsvn.tigris.org&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is another subversion client.  It’s faster than smartsvn, but you’ll need to build it from source if you want to use if on Solaris.  I like this graphical client the best on the Solaris side.&lt;br /&gt;&lt;br /&gt;Tips for building RapidSvn:&lt;br /&gt;&lt;br /&gt;1. A lot of compilation errors are probably due to your path.  I needed to add /usr/local/bin:/usr/local/lib/:/usr/ccs/bin to my Path.&lt;br /&gt;2. You’ll need to use the gnu make (which will install to /usr/local/bin) to make wxWidgets and Rapidsvn.  Their make files are too big for Solaris’s preinstalled make.&lt;br /&gt;3. You’ll need gtk 2 and glib 2 to compile wxWidgets.  You might have to remove old packages (using pkginfo and pkgrm) to add them.&lt;br /&gt;4. sunfreeware.com will list other dependencies the subversion package might need, so make sure those are installed if you’re having problems.&lt;br /&gt;6.   Basic Instructions for building RapidSvn:&lt;br /&gt;a. Ensure /usr/local/bin:/usr/local/lib/:/usr/ccs/ are on your path.&lt;br /&gt;b. Install all the necessary packages.&lt;br /&gt;c. Untar wxWidgets and go into its folder, then type the following:&lt;br /&gt;- ./configure -with-gtk&lt;br /&gt;- /usr/local/bin/make (this will take about 2 hours full CPU)&lt;br /&gt;- /usr/local/bin/make install&lt;br /&gt;d. Untar rapidsvn and go into its folder, then type the following:&lt;br /&gt;- ./configure&lt;br /&gt;- /usr/local/bin/make (this will take about 1 hour full CPU)&lt;br /&gt;- /usr/local/bin/make install&lt;br /&gt;e. Try rapidsvn (/usr/local/bin/rapidsvn)&lt;br /&gt;&lt;br /&gt;Subcommander: &lt;a href="http://subcommander.tigris.org/"&gt;http://subcommander.tigris.org/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is a pretty good graphical svn client, although it looks a bit ugly.  It should already be installed on the windows side.  This is a very difficult install for the Solaris side because you will need to build it from source.  It has a lot of very huge dependencies so I eventually gave up trying to build it.  You’re free to give it a try though.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 130%;"&gt;&lt;span style="font-weight: bold;"&gt;For Would-be Subversion Administrators, a very brief guide&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To complement the Subversion Client guide, I wrote this up.  I probably shouldn't have because it's really, really brief and vague.  But maybe it'll be helpful.&lt;br /&gt;&lt;br /&gt;You will need to download and install subversion from &lt;a href="http://subversion.apache.org/"&gt;http://subversion.apache.org&lt;/a&gt;.  It is very likely that it's available for the platform you're using.  If you're using Solaris, you can get the necessary packages from &lt;a href="http://sunfreeware.com/"&gt;http://sunfreeware.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So follow the instructions and install subversion.  Now I'm going into my personal preferences.  I like to use apache as my subversion server, so make sure you've got that.  Apache is easy to use, performs well, is easy to modify, and allows people to view your source without a subversion client on their machine.  Now here's instructions on how I do my subversion set ups.&lt;br /&gt;&lt;br /&gt;Create the directories [some path]/svn/users and [some path]/svn/repos.&lt;br /&gt;&lt;br /&gt;All the repositories will be stored in [root]/svn/repos.  To create a new subversion repository, open a command line prompt, go to [root]/svn/repos, and type the following commands:&lt;br /&gt;&lt;br /&gt;&amp;gt; svnadmin create [name_of_new_repository]&lt;br /&gt;&amp;gt; [path to apache's htpasswd]/htpasswd -c /svn/users/[password name] [firstuser]&lt;br /&gt;&amp;gt; [Enter Password]&lt;br /&gt;&amp;gt; [Create the initial layout of trunk, branches, and tags folders]&lt;br /&gt;&lt;br /&gt;Now that the new repository is created, you will need to serve it.  To make the new repository available, you will need to edit httpd.conf and then restart the Apache (you can use the apache monitor in the taskbar to restart.)  The configuration for the new repository in the httpd.conf file should look something like this:&lt;br /&gt;&lt;location repository="" svn=""&gt;&lt;br /&gt;DAV svn&lt;br /&gt;SVNPath /svn/repos/[repository name]&lt;br /&gt;AuthType Basic&lt;br /&gt;AuthName "[repository name]"&lt;br /&gt;AuthUserFile [root]/svn/users/[passwords file]&lt;br /&gt;Require valid-user&lt;br /&gt;&lt;/location&gt;&lt;br /&gt;The password files for the repositories will all be stored in /svn/users.  Each repository has its own password file.  Look into the httpd.conf file to figure out which repository uses which password file, but the file names should make it fairly obvious.  To create or edit a user’s password, open a command line prompt, go to /svn/users, and type the following commands:&lt;br /&gt;&lt;br /&gt;&amp;gt; [path to apache's htpasswd]/htpasswd [password file name] [username to edit/create]&lt;br /&gt;&amp;gt; [enter password]&lt;br /&gt;&amp;gt; [verify password]&lt;br /&gt;&lt;br /&gt;Unfortunately, there is currently no way easily change passwords remotely.  Password management can be done in many ways, like through Apache features or through a Web Application, but doing it would be a fair amount of effort to set up without any previous experience.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-8792541376365230343?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/8792541376365230343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=8792541376365230343' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8792541376365230343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8792541376365230343'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2011/05/subversion.html' title='Subversion'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-8568155497910785767</id><published>2011-05-02T18:26:00.001-07:00</published><updated>2011-05-02T18:26:40.271-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Executing Java from VBScript</title><content type='html'>This post is simple, it's just some Visual Basic Script for executing a jar and keeping the text output in a variable:&lt;br /&gt;&lt;br /&gt;&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;"&gt;view plain&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;"&gt;copy to clipboard&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;"&gt;print&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('About',this);return false;"&gt;?&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-c" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;Set&amp;nbsp;objShell&amp;nbsp;=&amp;nbsp;WScript.CreateObject(&lt;/span&gt;&lt;span class="string"&gt;"WScript.Shell"&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;Set&amp;nbsp;objExecObject&amp;nbsp;=&amp;nbsp;objShell.Exec(&lt;span class="string"&gt;"java&amp;nbsp;-classpath&amp;nbsp;JavaCode.jar&amp;nbsp;JavaClassName"&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;Do&amp;nbsp;Until&amp;nbsp;objExecObject.StdOut.AtEndOfStream&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;Results&amp;nbsp;=&amp;nbsp;Results&amp;nbsp;+&amp;nbsp;&lt;span class="string"&gt;"&amp;nbsp;"&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;objExecObject.StdOut.ReadLine()&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;Loop&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;Set objShell = WScript.CreateObject("WScript.Shell")&lt;br /&gt;Set objExecObject = objShell.Exec("java -classpath JavaCode.jar JavaClassName")&lt;br /&gt;&lt;br /&gt;Do Until objExecObject.StdOut.AtEndOfStream&lt;br /&gt; Results = Results + " " + objExecObject.StdOut.ReadLine() &lt;br /&gt;Loop&lt;/textarea&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-8568155497910785767?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/8568155497910785767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=8568155497910785767' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8568155497910785767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8568155497910785767'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2011/05/executing-java-from-vbscript.html' title='Executing Java from VBScript'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-202799979820830748</id><published>2011-04-27T09:54:00.000-07:00</published><updated>2011-04-28T08:05:03.308-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tweaks'/><title type='text'>Copy Your Hard Drive with Windows 7</title><content type='html'>I got a new SATA hard drive and decided to make it my primary drive. My current hard disk was IDE and was pretty old, so the decision made sense. But I really didn't want to reinstall everything, so I looked into copying the old hard disk into the new one. This is called Disk Cloning and there are lots of programs that do this. I just wanted the easiest way.&lt;br /&gt;&lt;br /&gt;I first looked into Hiren's Boot CD because I had used Hiren's Recovery Tools before. You burn a CD, boot from it, and one of its tools clones the hard drive. I was too lazy to create a boot CD, so I read on. I read about Clonezilla, Aconis (not free), and Paradigm (maybe free?), which all required you to make a system image (a file that's a snapshot of a hard disk), but ultimately decided I didn't want to look into third party software if possible. (It takes me a while to read enough to convince myself that third-party software isn't going to mess up my computer and is going to be user friendly enough to use.) I'm using Windows 7 and read that the built in Backup and Restore program worked well. I didn't have to download anything or burn anything, so I decided to try that first.&lt;br /&gt;&lt;br /&gt;To use it, you need:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The Windows 7 Installation CD (or you'll need to create a system repair CD)&lt;/li&gt;&lt;li&gt;Your original hard drive&lt;/li&gt;&lt;li&gt;Your new hard drive &lt;/li&gt;&lt;li&gt;And some other storage system (DVDs/External Hard Drive/Internal Hard Drive) to store the image of your original hard drive. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;WARNING: The new hard drive and other storage system must be at least the size of your original hard drive. The other storage system CAN NOT be the new hard drive.&lt;br /&gt;&lt;br /&gt;To use Windows 7's backup and restore tool:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Go to Start Bar -&amp;gt; Control Panel -&amp;gt; Backup and Restore -&amp;gt; Create a System Image&lt;/li&gt;&lt;li&gt;Choose where you want to store the image and press next&lt;/li&gt;&lt;li&gt;Choose the drive (the other storage system) you want to back up and press "Start Backup"&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;It took about an hour and a half to create a backup image for a 200GB system.  When the backup is done, shut down your machine.&lt;br /&gt;&lt;br /&gt;THIS IS IMPORTANT: You now need to unplug the power to your original hard drive (or otherwise remove it from your system.)  Your new hard drive and other storage system must remain accessible.&lt;br /&gt;&lt;br /&gt;Then boot from your Windows 7 Installation CD (or a system repair disk.) You'll get the Windows 7 Installation Menu.  Choose your language, then choose "Restore from System Image."&lt;br /&gt;&lt;br /&gt;The system image you just made should already be selected. Choose it and press next.&lt;br /&gt;&lt;br /&gt;By default, the system restore program will take every hard disk on your system (except for the one holding the system image), delete it, format it, and restore the system image on it. So make sure to exclude any hard disks you don't want to be replaced on the next screen, then continue.&lt;br /&gt;&lt;br /&gt;When I first tried this, I got an error that said no suitable disks were found. I wasted half an hour trying to figure out what was wrong. I ended up needing to cancel, select "Command Prompt" from the tools menu, and then doing the following:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Type "diskpart"&lt;/li&gt;&lt;li&gt;Type "select disk=disk0"&lt;/li&gt;&lt;li&gt;Type "detail disk"&lt;/li&gt;&lt;li&gt;(Read the output and make sure this disk is the new hard drive)&lt;/li&gt;&lt;li&gt;Type "clean"&lt;/li&gt;&lt;li&gt;Type "exit"&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Select "Restore system from System Image" and this time there hopefully won't be an error.&lt;br /&gt;&lt;br /&gt;Your system should restore and you should boot up into windows (you may need to go into your system BIOS to make sure your new drive is set as a boot device.) You can shut down the computer and plug your old hard disk back in if you'd like to continue using it for storage. Make sure it's not your primary boot device in BIOS! If windows doesn't show the old drive, you may need to right click "My Computer", select "Manage", select "Disk Management", and then right click your old drive and select "Online."&lt;br /&gt;&lt;br /&gt;When I finished switching my primary drive, I brought up my Windows System Rating. Up to a 5.9 ... ... ... ... it makes me want to upgrade my machine more. Microsoft and your achievement points.... *sigh*&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-202799979820830748?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/202799979820830748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=202799979820830748' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/202799979820830748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/202799979820830748'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2011/04/copy-your-hard-drive-with-windows-7.html' title='Copy Your Hard Drive with Windows 7'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-5809088785726807056</id><published>2011-04-27T09:44:00.000-07:00</published><updated>2011-04-27T16:32:46.249-07:00</updated><title type='text'>English Challenge</title><content type='html'>While I was in Taiwan, I would meet with Taiwanese students to exchange language.  I'd help them with their English for an hour, then they would help me with their Chinese for an hour.  It was a lot of fun.&lt;br /&gt;&lt;br /&gt;Before doing it, I didn't fully realize how difficult a language English was.  The grammar has so many special cases and confusing rules.  Just being able to read a word doesn't necessarily help you with its pronunciation, there is a lot of memorization.  Case in point, try reading this poem named Chaos: &lt;a href="http://www.hep.wisc.edu/~jnb/charivarius.html"&gt;http://www.hep.wisc.edu/~jnb/charivarius.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I still think English is easier to communicate in than Chinese.  Even if you mangle the sounds up or use very messy grammar, you're still understandable... you just sound like a foreign speaker.  If you mangle Chinese sounds or grammar, there's a good chance you won't be understood.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-5809088785726807056?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/5809088785726807056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=5809088785726807056' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/5809088785726807056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/5809088785726807056'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2011/04/english-challenge.html' title='English Challenge'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-7159908383571233003</id><published>2011-04-26T09:52:00.000-07:00</published><updated>2011-04-26T09:54:29.152-07:00</updated><title type='text'>Taiwan Visa and Visa Extension</title><content type='html'>So, I went to Taiwan over the summer to study Chinese.  I'm American and I was there for a little more than three months, which means I needed a Vistor Visa and that I needed to extend my Visa while I was there.&lt;br /&gt;&lt;br /&gt;I live in California, San Diego.  The &lt;a href="http://www.taiwanembassy.org/us/lax/mp.asp?mp=52"&gt;nearest Taiwan embassy&lt;/a&gt; was in Los Angeles (which is about a 2 hour drive away) and I didn't have enough time to do my Visa through mail.  The embassy is only open on weekdays, so I chose a day and drove through traffic to get up there.  The office was not too easy to find.  It's on the 4th floor of some huge building with a bank of the first floor.  The visa application process itself was a lot smoother than I expected and the line moved pretty quickly.  As long as you have your passport and proof of a reason to need a Visitor Visa, you're good to go.  You do need Passport Photos, but you can take them once you're there.  You can make free copies of documents there as well.&lt;br /&gt;&lt;br /&gt;I expected them to have to mail the visa back to me, but it actually only takes a few hours to process.  So I went out to lunch and picked up my Vistor Visa before I left LA.  You have the option between a single visit and multiple visit visa. A multiple visit visa allows you to leave the country during your stay without voiding your visa.  I got the single visit visa because it was faster to process and slightly cheaper. In the end, I wish I got a multiple visit visa so I could have taken weekend trips out.&lt;br /&gt;&lt;br /&gt;The Visitor Visa is only valid for about two months, so if you're going to be there for longer than two months, it needs to be renewed from Taiwan.  (Multiple Visit Visa will be renewed automatically if you leave the country and come back.)  Renewal is free and I believe you can keep renewing it for about two years as long as you can prove a need for it.  I think you can renew your Visa as early as a month after arriving in Taiwan, although I waited until the week before expiration.  Renewing your Visa is free, the process is immediate and only takes 10 minutes or so once you make it to the front of the line.  The attendants all speak enough English to get by if your Mandarin is really bad.  The only problem I had was trying to renew my Visa at Taipei City's Office instead of Taipei County's Office; I didn't realize I was living in Taipei County.   The Taipei City office is really easy to find. The Taipei County office is a bit more difficult to find, so leave yourself a lot of time if you have to go there. &lt;br /&gt;&lt;br /&gt;If you have a multiple visit visa, renewal is much easier.  Just leave the country and when you come back, it will be extended for you.  One of my classmates extended his visa this way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-7159908383571233003?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/7159908383571233003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=7159908383571233003' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7159908383571233003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7159908383571233003'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2011/04/taiwan-visa-and-visa-extension.html' title='Taiwan Visa and Visa Extension'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-8190074479272516645</id><published>2011-04-25T10:10:00.000-07:00</published><updated>2011-04-25T10:17:29.341-07:00</updated><title type='text'>CLD Program Impressions</title><content type='html'>I attended the CLD Program at NTU (台大) over summer 2010 and I thought it would be useful for people considering the program if I wrote my impressions about it.  I'll just write about my experiences and you can make of it what you will.&lt;br /&gt;&lt;br /&gt;First, my background.  I'm currently 27 and am studying Mandarin for purely personal reasons.  I basically want basic conversational skills and good listening comprehension.  Although I've previously studied French and Japanese, I'm only fluent in English.  Before going to Taiwan, I self-studied Mandarin college textbooks, listened to audio tapes, and practiced conversational skills with my wife.  I decided to go to Taiwan in order to strengthen my foundational skills so I could study more effectively with my wife at home.  After reading about several programs from forums and other people's reviews, I decided to attend NTU (台大) over &lt;a href="http://web.mtc.ntnu.edu.tw/mtcweb/"&gt;NTNU (師大)&lt;/a&gt;, and then &lt;a href="http://homepage.ntu.edu.tw/~cld222/en/news.htm"&gt;the CLD Program&lt;/a&gt; over &lt;a href="http://iclp.ntu.edu.tw/"&gt;the ICLP Program&lt;/a&gt;.  I'm very happy with my choices.&lt;br /&gt;&lt;br /&gt;The application process was simple.  My application probably didn't get to them until the day before their "deadline", but I got in anyway.  It only left me with a month to prepare for the trip, the main hassle being getting my visa.  CLD doesn't offer any housing, but that wasn't a problem for me because I already had a place to stay.  I had classmates that didn't take care of housing until after they arrived with very little hassle, although their rent tended to be more expensive than those that planned earlier.  &lt;br /&gt;&lt;br /&gt;The CLD is located on the NTU campus on the second floor of the language center (語言中心.)  It was very easy to find, even though I'd never been to the campus before, as there are plenty of campus maps.  NTU itself is very nice.  The campus is beautiful and has a large library that's great for studying in.  The cafeteria near the language center (in the 學生活動中心) is pretty good.  There's a lot of stores, housing, and restaurants within five minute walking distance of the campus... finding things in Taipei in general is really easy.  On the bottom floor of the language center is a bulletin board that makes it very easy to find language exchange partners.  Finding an native speakers to practice with is very, very important if you want to really learn Chinese.&lt;br /&gt;&lt;br /&gt;New students are required to show up at NTU a week before classes start in order to register and take a placement test.  Registration went very smoothly and the staff was very nice.  The optional placement test had no time limit.  The first part was a written test broken into three sections.  The first section was correcting grammar, the second was answering reading comprehension questions, and the third was writing an essay.  The first two sections were graded immediately, after which I was sent to a different room for an oral test.  A teacher looked over my results, read my essay, and then talked with me a bit in Mandarin.  Afterwards, the teacher placed me.  My Mandarin was very limited and although I could read many characters, I could barely write any, so I was just happy to not be placed in the lowest class.  Although I didn't realize it at the time, you can buy your books from the CLD office at this point since you know your class level.&lt;br /&gt;&lt;br /&gt;On the Friday before classes started, we had an orientation.  The orientation was pretty useless, but only took an hour or two.&lt;br /&gt;&lt;br /&gt;I bet the program quality really varies based on your teacher and classmates.  I feel my teacher, 蔡美雲, was excellent.  My classmates were also very good and hard working.  We all refused to speak English to each other, even though we often spent time together outside of class.  Their ages varied between 22 and 37, they came from all over the world.  I had 5 classmates total.  By looking at the class list, it seemed almost all classes had the full 6 students.&lt;br /&gt;&lt;br /&gt;The program itself was basically working through the &lt;a href="http://www.amazon.com/Practical-Audio-Visual-Chinese-Book-Yong/dp/B0043WNUP8/"&gt;Practical Audio and Visual Chinese&lt;/a&gt; textbooks.  (Although the most advanced classes moved on to different texts.)  My class started at Book One Chapter 6 and ended at Book Two Chapter 8.  We covered a chapter every three or four days.  It seems all the classes working on the Practical Audio and Visual Chinese textbooks covered about one book in the three months.&lt;br /&gt;&lt;br /&gt;Each day we had class for three hours.  Only Mandarin was spoken.  Homework takes at least half an hour if you rush through it, but it's much better if you spend more time on it.  My teacher would correct whatever I wrote, no matter if it was assigned or not.  After getting the introductions and review done, classes basically followed a four day loop.&lt;br /&gt;&lt;br /&gt;- First Day -&lt;br /&gt;Give an oral presentation.  Usually this was reciting a memorized essay from the textbook.&lt;br /&gt;Take a test over the previous material.  This usually took one and a half hours.&lt;br /&gt;Begin learning the vocabulary for the next chapter.  The teacher would add many comments and the students were required to form sentences using the vocabulary.&lt;br /&gt;Homework: Practice writing the new vocabulary words.&lt;br /&gt;&lt;br /&gt;- Second Day - &lt;br /&gt;Listening and Writing test.  The teacher would say a sentence twice and the students must write the pinyin and Chinese characters for that sentence.&lt;br /&gt;Finish the vocabulary and begin going over the grammar.&lt;br /&gt;Homework: Write sentences using the vocabulary&lt;br /&gt;&lt;br /&gt;- Third Day -&lt;br /&gt;Listening and Writing test.&lt;br /&gt;Finish going over the grammar.&lt;br /&gt;Homework: Do the Workbook chapter, which is grammar and writing drills.&lt;br /&gt;&lt;br /&gt;- Fourth Day -&lt;br /&gt;Listening and Writing test.&lt;br /&gt;Role Play situations, practice listening to dialogs, and work through more examples.&lt;br /&gt;Homework: Write an essay.&lt;br /&gt;&lt;br /&gt;The main benefit in all this is the teacher's guidance.  In addition to the teacher pointing out gotchas, she also constantly corrected errors, whether in speaking or writing.  I felt she did very well in pointing out problems I hadn't noticed by myself and explaining problems to me my wife was unable to explain clearly.  I felt I learned a lot in the three months I was there.  The program is what you make of it.&lt;br /&gt;&lt;br /&gt;As a side note, to help make the most of my short time in Taiwan, I also had one on one Mandarin lessons on the side.  My teacher was Peter Su and he was really excellent.  His times and lessons were very flexible.  These additional lessons allowed me to learn the subjects I wouldn't be able to cover during my short stay in the CLD program.  I'd definitely suggest looking him up for some one on one lessons, here's his web site: &lt;a href="http://petersonsu.blogspot.com/"&gt;http://petersonsu.blogspot.com/&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-8190074479272516645?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/8190074479272516645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=8190074479272516645' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8190074479272516645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8190074479272516645'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2011/04/cld-program-impressions.html' title='CLD Program Impressions'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-8679592643843263550</id><published>2011-04-21T16:42:00.000-07:00</published><updated>2011-04-21T16:45:07.541-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tweaks'/><title type='text'>PS3 Controller on PC</title><content type='html'>(This was actually a really old post, which I dredged up so I could add a notice mentioning &lt;a href="http://www.motioninjoy.com/"&gt;MotionInJoy&lt;/a&gt;, which I'm currently using.  It has a lot of options and works perfectly on Windows 7 with no problems.  It shows ads, but I'm pretty sure it doesn't install anything nefarious on your system. So... use MotionInJoy instead of whatever I talked about here. MotionInJoy avoided all the annoying driver signing this old post talked about too.)&lt;br /&gt;&lt;br /&gt;I got a Playstation 3 controller to work with windows as a game controller, which is awesome.  I'm not using it over Bluetooth, I have the controller plugged into the USB port.  I've found a lot of fun indie games that I intended to play for the PC (La Mulana, Cave Story, Knytt), but wanted a controller to maximize enjoying them.  &lt;br /&gt;&lt;br /&gt;Besides the hardware, all you need is the driver and setup executable.  You can get these over at &lt;a href="http://ps3-hacks.com"&gt;http://ps3-hacks.com&lt;/a&gt;.  It may not necessarily work very easily... I couldn't get the controller to work on my XP desktop (I'm almost positive it's due to conflicts with other drivers, but don't want to waste anymore time debugging), but it worked immediately without any problems on my Vista laptop.  My suggestion would be to give up (or reinstall your entire system) if you follow the instructions and it still doesn't work.  Make sure to press your PS Home button before complaining that it doesn't work.&lt;br /&gt;&lt;br /&gt;I also have a x64 Windows 7 machine at home.  By following this guide, I've been able to get the PS3 controller working.  The (huge) downside is that the application uses an unsigned driver, which means you have to run Windows 7 in a special mode.  The guide will explain that a little more.  By the way, I do not suggest changing system properties to always allow unsigned drivers.  It just doesn't seem like a good idea, plus, it puts an annoying watermark on your background.&lt;br /&gt;&lt;br /&gt;After getting the controller to work, I had problems with actually using it to play games.  Some of my games didn't give me very good joypad mapping options, mainly in not supporting all of the PS3's 16 buttons.  But then I found XPadder... check out &lt;a href="http://www.xpadder.com"&gt;http://www.xpadder.com&lt;/a&gt;!  (Note that versions 5.3 and below are free (softpedia link), but versions above 5.3 must be purchased.  I suggest supporting the other Jonathan's efforts.)  XPadder easily lets you map keyboard key(s) to any button on any gamepad supported by windows.  It is REALLY awesome.  I can even play Guilty Gear and pull off supers with the press of one button since it lets you map sequences.&lt;br /&gt;&lt;br /&gt;Suddenly, fighting games (Guilty Gear), platformers (Cave Story), and RPGs (Ys) are something I'm willing to play on my PC.&lt;br /&gt;&lt;br /&gt;Also, using &lt;a href="http://pcsx2.net/"&gt;PS2 Emulators&lt;/a&gt; with save states for my old games is pretty awesome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-8679592643843263550?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/8679592643843263550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=8679592643843263550' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8679592643843263550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8679592643843263550'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2011/04/ps3-controller-on-pc.html' title='PS3 Controller on PC'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-7394729455677269623</id><published>2011-04-17T14:39:00.001-07:00</published><updated>2011-04-17T14:39:23.595-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Links'/><title type='text'>Wayback Machine</title><content type='html'>So, the &lt;a href="http://www.archive.org/web/web.php"&gt;internet wayback machine&lt;/a&gt; has proven useful to me time and time again.&lt;br /&gt;&lt;br /&gt;If you don't know, the internet wayback machine makes text backups of... pretty much the entire internet.  Text only... but really, the text is generally the most devastating loss of a missing website.  The site does a really good job of keeping timely backups of changes.&lt;br /&gt;&lt;br /&gt;I've used the wayback machine to recover an old site I had made when I was in middle school.  I thought I had lost all of it forever... granted what I found was very embarassing and much less amazing than I remembered, but I was very happy to find it again.&lt;br /&gt;&lt;br /&gt;I've used the wayback machine to find pages that had been removed, sometimes with information that the webhost was hoping to get off the internet.&lt;br /&gt;&lt;br /&gt;And I've used the wayback machine in my job, to find tutorials that had lost their home.  I'd follow links to dead pages, but be able to read the information anyway thanks to the wayback machine.&lt;br /&gt;&lt;br /&gt;The wayback machine is more than a toy and when you need it, it's definitely nice it's there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-7394729455677269623?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/7394729455677269623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=7394729455677269623' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7394729455677269623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7394729455677269623'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2011/04/wayback-machine.html' title='Wayback Machine'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-744328914440949812</id><published>2010-11-28T17:31:00.000-08:00</published><updated>2010-11-28T17:34:38.837-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Hex Editing Programs</title><content type='html'>So, I got obsessed over the past two weeks or so "solving" archive files.  This involved trying to extract the resources from video game archive files.  Even if I don't care about the result, it was like solving a puzzle to figure out how to get the resources out.  I'll probably write about it sometime.&lt;br /&gt;&lt;br /&gt;What I wanted to point out now is the hex editor I used.  To solve archive formats, you need to open up the archive files as binary.  I started off using Textpad, since it's my text editor of choice on windows.  It's not that convenient though... after reading some tutorials, I settled on Hex Workshop.&lt;br /&gt;&lt;br /&gt;Hex Workshop lets you easily copy and paste binary, allows you to easily set bookmarks to binary fragments, easily lets you color-code the binary, easily lets you jump to specific offsets, lets you have multiple files open simultaneously, and has a hex calculator.  I heartily recommend it.  It is pretty pricey (~$90)... but that's pretty much the price of two video games.  I think it's worth it as I've had so much more fun doing this than playing games recently.  &lt;a href="http://www.hexworkshop.com/"&gt;Hex Workshop&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;On another note, on a slow day, I played around with Cheat Engine.  It was a lot of fun.  Cheat Engine lets you easily mess around with Windows memory.  The most obvious use is changing game memory to give you unlimited whatever.  It's really fun to play with in general and comes with a great tutorial that'll get you started.  If you have some time, give it a try.  &lt;a href="http://www.cheatengine.org/"&gt;http://www.cheatengine.org/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-744328914440949812?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/744328914440949812/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=744328914440949812' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/744328914440949812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/744328914440949812'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2010/11/hex-editing-programs.html' title='Hex Editing Programs'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-8200359281983366570</id><published>2010-10-31T17:45:00.000-07:00</published><updated>2010-10-31T17:50:04.686-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>C# Web Service Plain Text Response</title><content type='html'>It took me far longer than I expected in order to figure out how to return plain text from a C# web service.  I'm not sure why this took so long for me to figure out, but if it wasn't just me, then maybe this post can help other people out.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Problem&lt;/span&gt;: When writing a web service endpoint in C#, if the return type is a String, the result will be an XML formatted string. &lt;br /&gt;&lt;br /&gt;For example, the following web service:&lt;br /&gt;&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-c" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt; String TestServiceA(Stream input)  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;{         &lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;  &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span class="string"&gt;"Some kind of Text"&lt;/span&gt;&lt;span&gt;;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;} &lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;public String TestServiceA(Stream input)&lt;br /&gt;{     &lt;br /&gt;  return "Some kind of Text";&lt;br /&gt;}&lt;/textarea&gt;&lt;/div&gt;returns the following string:&lt;br /&gt;&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-c" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;&amp;gt;Some kind of Text&amp;lt;/&lt;/span&gt;&lt;span class="keyword"&gt;string&lt;/span&gt;&lt;span&gt;&amp;gt; &lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;&amp;lt;string&amp;gt;Some kind of Text&amp;lt;/string&amp;gt;&lt;/textarea&gt;&lt;/div&gt;It isn't that big a deal and the contained text can be easily parsed out, but it wasn't what I wanted and extra parsing code somehow seems wrong.  I wanted the result to simply be the text I set.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Solution&lt;/span&gt;: The return type needs to be a Stream.&lt;br /&gt;&lt;br /&gt;So now the following web service:&lt;br /&gt;&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-c" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt; Stream TestServiceB(Stream input)  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;{         &lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;  MemoryStream ms = &lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; MemoryStream();  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;  StreamWriter sw = &lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt; StreamWriter(ms);  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;  sw.Write(&lt;span class="string"&gt;"Some kind of Text"&lt;/span&gt;&lt;span&gt;);  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;  sw.Flush();  &lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;  ms.Position = 0;  &lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;  &lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt; ms;  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;} &lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;public Stream TestServiceB(Stream input)&lt;br /&gt;{     &lt;br /&gt;  MemoryStream ms = new MemoryStream();&lt;br /&gt;  StreamWriter sw = new StreamWriter(ms);&lt;br /&gt;  sw.Write("Some kind of Text");&lt;br /&gt;  sw.Flush();&lt;br /&gt;  ms.Position = 0;&lt;br /&gt;  return ms;&lt;br /&gt;}&lt;/textarea&gt;&lt;/div&gt;returns the expected result:&lt;br /&gt;&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;/div&gt;&lt;ol class="dp-c" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;Some kind of Text  &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;Some kind of Text&lt;/textarea&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-8200359281983366570?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/8200359281983366570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=8200359281983366570' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8200359281983366570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8200359281983366570'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2010/10/c-web-service-plain-text-response.html' title='C# Web Service Plain Text Response'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-8877999016319809030</id><published>2010-09-30T08:35:00.001-07:00</published><updated>2010-09-30T08:35:31.800-07:00</updated><title type='text'>Router and Bridge</title><content type='html'>Router and Bridge&lt;br /&gt;&lt;br /&gt;At home we're basiscally using five computers, one computer for each one of us.  We all need internet access, we don't want anyone to have to use wireless, and it would be nice if we can all see each other's shared data.  We have two 4 LAN Port routers, a D-Link 624 (wireless) and a D-Link 604.  Those routers have worked very well for us, much better than Linksys routers have worked.  We decided to have one router act as a bridge.  Since one port from 604 would connect to one port from 624 (making them kind of act as a single router) we would have a total of six LAN ports.  I feel it's really common knowledge how to set up a router, but making the other router act as a bridge isn't as clear.  These are the steps to do this and they should be pretty adaptable for any routers.&lt;br /&gt;&lt;br /&gt;   1. Set up the first router as normal.&lt;br /&gt;   2. Connect a PC directly to the second router (and not the first router.)&lt;br /&gt;   3. Reboot the PC.&lt;br /&gt;   4. Log in to the secondrouter (usually defaulted at 192.168.0.1, with User Name = admin and no password).&lt;br /&gt;   5. Go to the DHCP menu and disable DHCP by checking "Disabled" for DHCP Server and Static DHCP.&lt;br /&gt;   6. Go to the LAN menu and change the IP Address to 192.168.0.99.  (It can't conflict with the first router.)&lt;br /&gt;   7. Click Apply to save the settings. (You lose the connection to the second router since its IP address changed.)&lt;br /&gt;   8. Connect one of the second router's Local (LAN) ports to the first router.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-8877999016319809030?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/8877999016319809030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=8877999016319809030' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8877999016319809030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8877999016319809030'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2010/09/router-and-bridge.html' title='Router and Bridge'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-7189330322164884864</id><published>2010-08-31T19:46:00.001-07:00</published><updated>2010-08-31T19:46:50.059-07:00</updated><title type='text'>Free Quality Burning Software</title><content type='html'>&lt;a href="http://www.imgburn.com/"&gt;http://www.imgburn.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This summer I needed to burn an DVD ISO Image, but I was away from home and didn't have any burning software on my laptop.  So I needed something free.  A quick search turned out &lt;a href="http://www.imgburn.com/"&gt;ImgBurn&lt;/a&gt;, which worked for me very well, seemed very well made, and was very simple to use.  So if you need free CD/DVD burning software, I recommend that you try ImgBurn.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-7189330322164884864?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/7189330322164884864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=7189330322164884864' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7189330322164884864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7189330322164884864'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2010/08/free-quality-burning-software.html' title='Free Quality Burning Software'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-5796283040483533407</id><published>2010-08-31T19:45:00.000-07:00</published><updated>2010-08-31T19:46:13.138-07:00</updated><title type='text'>Missed Time</title><content type='html'>Whoops, missed a few months.  I was out of the country and didn't have the time to post anything.  I'm back home now so I'll make up for it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-5796283040483533407?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/5796283040483533407/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=5796283040483533407' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/5796283040483533407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/5796283040483533407'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2010/08/missed-time.html' title='Missed Time'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-4951666173315291592</id><published>2010-07-08T07:41:00.000-07:00</published><updated>2010-07-08T07:44:28.699-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Subversion Intro</title><content type='html'>I've been using subversion (nope, not a git guy yet) for most of my own work, even got our projects at my current job onto subversion.  It's much better than source safe/offsite (which I used at a previous job) and I even prefer it to CVS.  Subversion is designed specifically to be a modern replacement for CVS and shares a number of the same key developers. It uses a copy-modify-merge for file sharing. To read more about subversion, you can read their very good documentation at &lt;a href="http://svnbook.red-bean.com/"&gt;http://svnbook.red-bean.com/&lt;/a&gt;. The following is a link to an appendix from the svnbook that introduces subversion for cvs users. I think that it will be a very helpful and painless way to quickly understand subversion with a cvs background. You can read it starting at &lt;a href="http://svnbook.red-bean.com/en/1.2/svn.forcvs.html"&gt;http://svnbook.red-bean.com/en/1.2/svn.forcvs.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Subversion’s homepage is &lt;a href="http://subversion.tigris.org/"&gt;http://subversion.tigris.org/&lt;/a&gt;. I install it using the instructions found on &lt;a href="http://www.excastle.com/blog/archive/2005/05/31/1048.aspx"&gt;http://www.excastle.com/blog/archive/2005/05/31/1048.aspx&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The most direct way of using subversion is through the subversion client tool called svn. You can download the tool from subversion’s site, &lt;a href="http://subversion.tigris.org/"&gt;http://subversion.tigris.org/&lt;/a&gt;. For directions on using the tool, refer to the appropriate section at &lt;a href="http://svnbook.red-bean.com/"&gt;http://svnbook.red-bean.com/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Another subversion client option for Win32 users is TortoiseSVN, which is implemented as a Windows shell extension. TortoiseSVN can be downloaded from &lt;a href="http://tortoisesvn.tigris.org/"&gt;http://tortoisesvn.tigris.org/&lt;/a&gt;. It is very simple and intuitve to use as all commands are added to the right click context menu when using windows explorer. Special icons are used to show which files and folders are under revision control.&lt;br /&gt;&lt;br /&gt;If you're using Eclipse, there is a plugin called SubClipse that will integrate Eclipse and Subversion. You can download the plug-in from &lt;a href="http://subclipse.tigris.org/"&gt;http://subclipse.tigris.org/&lt;/a&gt;. A good guide to installation and usage for the plug-in can be found at &lt;a href="http://dev2dev.bea.com/pub/a/2005/11/subclipse.html?page=1"&gt;http://dev2dev.bea.com/pub/a/2005/11/subclipse.html?page=1&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-4951666173315291592?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/4951666173315291592/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=4951666173315291592' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4951666173315291592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4951666173315291592'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2010/07/subversion-intro.html' title='Subversion Intro'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-7416525965154198943</id><published>2010-05-31T06:32:00.001-07:00</published><updated>2010-05-31T06:32:44.064-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Hiren Boot CD</title><content type='html'>I'd heard about Hiren's Boot CD before, but I never needed it until last weekend.  There were a few Windows machines that none of us knew the passwords or even account names to anymore.  Using Hiren's Boot CD, we were easily able to get back in.  We could see the accounts on the machine, we could reset the passwords, and we could lock/unlock accounts.  It was very convenient.&lt;br /&gt;&lt;br /&gt;There aren't many times most people would need a tool like this, but it's nice that it's there just in case.  Read more about it (and get links to it) at http://en.wikipedia.org/wiki/Hiren's_BootCD  A mac version of this type of program seems to be Boot-123.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-7416525965154198943?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/7416525965154198943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=7416525965154198943' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7416525965154198943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7416525965154198943'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2010/05/hiren-boot-cd.html' title='Hiren Boot CD'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-513090475541132897</id><published>2010-04-30T21:54:00.000-07:00</published><updated>2010-04-30T21:57:09.010-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Got API</title><content type='html'>I really like the website &lt;a href="http://gotapi.com"&gt;gotapi&lt;/a&gt; while programming.  It provides a quick and easy interface for various APIs for many programming languages.  Wish they included C#.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-513090475541132897?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/513090475541132897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=513090475541132897' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/513090475541132897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/513090475541132897'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2010/04/got-api.html' title='Got API'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-8539934468541642684</id><published>2010-03-31T21:26:00.000-07:00</published><updated>2010-03-31T21:27:30.162-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Sharp Develop</title><content type='html'>Thought I'd point out &lt;a href="http://www.icsharpcode.net/"&gt;Sharp Develop&lt;/a&gt;, a free alternative to Visual Studio.  In some ways, it's much more convenient and friendly.  I'd suggest giving it a try, C# is a pretty good language to work in.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-8539934468541642684?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/8539934468541642684/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=8539934468541642684' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8539934468541642684'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8539934468541642684'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2010/03/sharp-develop.html' title='Sharp Develop'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-403192609216726283</id><published>2010-02-28T21:06:00.000-08:00</published><updated>2010-02-28T21:07:23.921-08:00</updated><title type='text'>iPhone Headphone Issue</title><content type='html'>The sound from my iPhone when using headphones was coming out funny.  The speaker was perfectly fine, but when using headphones, any voices (whether in music or while on the phone) had a weird tinny echo.  I tried resetting the phone a few times, but that didn't do anything.  I took out a flashlight and looked in the headphone outlet... it turned out there was lint in the jack.  Using a toothpick, I fished it out and then the sound was back to normal.  Just thought I'd post, in case anyone else is having the same problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-403192609216726283?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/403192609216726283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=403192609216726283' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/403192609216726283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/403192609216726283'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2010/02/iphone-headphone-issue.html' title='iPhone Headphone Issue'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-7833189259880237512</id><published>2010-01-04T21:04:00.000-08:00</published><updated>2010-01-04T21:11:30.198-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tweaks'/><title type='text'>Driverless Network Printer on Windows 7</title><content type='html'>Sheesh, I spent like half an hour trying to add a network printer on my new Windows 7 machine.  When I tried to add an HP Laserjet 1200 PCL5 printer, it said a driver couldn't be found, even though I saw Windows 7 had the driver when I tried to add it locally.  This is how I ended up adding the printer (instructions were found at: &lt;a href="http://www.sevenforums.com/drivers/2726-printer-network-no-driver.html"&gt;http://www.sevenforums.com/drivers/2726-printer-network-no-driver.html&lt;/a&gt;).  You'll need some computer know-how, but it's not too tough.  Essentially, you create a local printer, then change its settings to your network printer:&lt;br /&gt;&lt;br /&gt;0. Go to "Devices and Printers" from the start menu.&lt;br /&gt;1. Add Printer (click)&lt;br /&gt;2. Choose local printer&lt;br /&gt;3. Choose use existing port&lt;br /&gt;4. If your network printer type is not listed, click windows update (requires internet).&lt;br /&gt;5. Wait...&lt;br /&gt;6. Check to see if your printer is now listed.  If not, this guide won't work.&lt;br /&gt;7. Choose newly listed printer.&lt;br /&gt;8. Printer will then install.&lt;br /&gt;&lt;br /&gt;And to now use your network printer...&lt;br /&gt;&lt;br /&gt;1. Right click printer icon. Left click printer properties.&lt;br /&gt;2. Click port tab.&lt;br /&gt;3. Add new port. Local port&lt;br /&gt;4. Type in address of shared printer ie \\Name or ip address of computer with attached shared printer\Shared printer name&lt;br /&gt;5. Click general tab. Print test page. See if your test page printed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-7833189259880237512?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/7833189259880237512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=7833189259880237512' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7833189259880237512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7833189259880237512'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2010/01/driverless-network-printer-on-windows-7.html' title='Driverless Network Printer on Windows 7'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-3788907415156261563</id><published>2009-12-31T21:18:00.000-08:00</published><updated>2009-12-31T21:21:25.395-08:00</updated><title type='text'>Computer Upgrade</title><content type='html'>I upgraded my computer this holiday season and ran into some problems.  Thought I'd document some of them here.  I built my rig from parts; I spent a lot of time this month reading up on new technology.  It had been a few years since I last built a higher end PC.  In the end I basically went with newegg recommendations and I wasn't disappointed with their parts choices.  It was easy to figure out compatibility too.&lt;br /&gt;&lt;br /&gt;My first small problem was with my power supply.  I had a CORSAIR CMPSU-750TX and I couldn't find the 4-PIN connector.  Turns out that the 8 PIN connector could be separated into two 4 PIN connectors.  I had to read the manual before I noticed.  I don't know if this is standard in power supplies nowadays, but I had never encountered it before.&lt;br /&gt;&lt;br /&gt;The second problem was with my motherboard.  The screen stayed black after powering it on; I heard no beeps, it wasn't going through POST.  I got a M4A79XTD EVO with a Phenom II X4 955 CPU through a newegg combo deal.  I read a lot of reviews that said the combo was bad because the 955s being sent out were C3, which are incompatible with the BIOS shipped on the mobo (motherboard.)  Furthermore, you couldn't update the BIOS without a compatible CPU.  After googling, I found that C3 was the revision number of the processor.  On ASUS's page, &lt;a href="http://support.asus.com.tw/cpusupport/cpusupport.aspx?model=M4A79T%20Deluxe"&gt;http://support.asus.com.tw/cpusupport/cpusupport.aspx?model=M4A79T%20Deluxe&lt;/a&gt;, I found the list of supported CPUs for the mobo.  Each revision of AMD's CPUs has its own model number.  Mine was HDX955FBK4DGIBOX.  Took me a second to realize that the "BOX" could be ignored.  It turned out my CPU was C2, which worked with bios on the motherboard.  In the end, it turned out my RAM was bad on arrival.  I'm glad I was able to figure out the CPU issue or else I would have probably tried to return the motherboard.&lt;br /&gt;&lt;br /&gt;Lastly, I gave my wife most of my old parts, one of which was an ASUS A8V DELUXE motherboard.  I was unable to install Windows, I kept getting a BSOD (blue screen of death) saying that "The bios in this system is not fully acpi compliant."  However, the bios was ACPI compliant and I never had problems while I was using it.  The bios even had an "Enable ACPI" option, which was on.  I decided to reset the CMOS and see if that would fix it.  Since I lost my manual and couldn't tell where the jumper was, I simply removed the motherboard's battery for 5 minutes (make sure all power to the computer is unplugged first.)  That did the trick.&lt;br /&gt;&lt;br /&gt;Those were the trickier errors I ran into, but I had lots of other issues such as bad drives, configuring jumpers correctly, making things reach... stuff that required opening the machine a lot, but nothing that wasn't obvious.  So, I spent a lot of time building systems for my wife and I, but now that they're running, I'd say it was worth it.  Hopefully, you can avoid the problems I ran into.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-3788907415156261563?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/3788907415156261563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=3788907415156261563' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3788907415156261563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3788907415156261563'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2009/12/computer-upgrade.html' title='Computer Upgrade'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-4232973764430725822</id><published>2009-11-30T20:12:00.000-08:00</published><updated>2009-11-30T20:14:27.461-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Javascript Effects</title><content type='html'>I've been busy this month, but I found a lost blog post from 11/2007.  I think it's still relevant.  At least the links are still alive.  And Javascript is still really handy to know well:&lt;br /&gt;&lt;br /&gt;Well, I've been doing web page mock-ups at work, and I've gotten some pretty cool effects down.  It always amuses me how important the appearance is to a project.  It makes sense, since rock solid systems can't really be demo'ed, but one cool transparency effect can knock an audience off their feet in a couple seconds.  Not just anyone can comment when you describe how you brought your algorithm from O(n!) to O(log n), but everyone can say "Wow, that dragging and dropping is pretty nifty."  So don't ever neglect the appearance of your project if you want normal people to use it.  Luckily, effects are usually pretty easy to do on a web page, since someone else has probably done it before.  I wanted to take this post to share some links that I had found really useful.&lt;br /&gt;&lt;br /&gt;First of all, just in case you don't know css, read this.  CSS is really important to making a web page.  I'd suggest reading everything at that link for anyone who isn't an expert.&lt;br /&gt;&lt;br /&gt;For transparency effects, this webpage was my guide:  &lt;a href="http://www.mandarindesign.com/opacity.html"&gt;http://www.mandarindesign.com/opacity.html&lt;/a&gt;.  It described everything needed to have mouseover transparency working in all the major browsers, using css and javascript.  Very helpful.&lt;br /&gt;&lt;br /&gt;For drag and drop, I referred to this website: &lt;a href="http://www.walterzorn.com/dragdrop/dragdrop_e.htm"&gt;http://www.walterzorn.com/dragdrop/dragdrop_e.htm&lt;/a&gt;.  He did a really good job providing tons of examples and his own implementation.  From simple dragging and dropping to resizing images and sliding bars, this was a great reference to me.  He even provides javascript if you want to use his code directly.&lt;br /&gt;&lt;br /&gt;By the way, if you're one of those people who puts javascript programming on the same level as html/css programming, then read &lt;a href="http://www.surguy.net/rediscovering-javascript.html"&gt;Rediscovering Javascript&lt;/a&gt;.  Hopefully, you'll change your mind.  If you are new to programming, a great Javascript guide is "&lt;a href="http://eloquentjavascript.net/"&gt;Eloquent Javascript&lt;/a&gt;."  It has a nice interpreter, which means you can test javascript code quickly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-4232973764430725822?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/4232973764430725822/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=4232973764430725822' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4232973764430725822'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4232973764430725822'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2009/11/javascript-effects.html' title='Javascript Effects'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-4968697200920596630</id><published>2009-10-31T20:41:00.000-07:00</published><updated>2009-10-31T20:43:29.516-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tweaks'/><title type='text'>Removing and Ejecting Disks</title><content type='html'>Requires: Windows XP Professional&lt;br /&gt;&lt;br /&gt;So, you plug in a USB drive, do your stuff, and then you want to take it out.  Pretty common today, right?  So you've got to go to your taskbar, right click that "Safely Remove Drive" icon, and so on.  I thought it was kind of annoying, so I looked for a way to do this without having to use the mouse (and that was free.)  And I eventually found it at &lt;a href="http://www.uwe-sieber.de/usbstick_e.html"&gt;this site&lt;/a&gt;.  His english isn't too great, but he's not a native speaker and it's not -that- hard to understand.&lt;br /&gt;&lt;br /&gt;As he says, there are several tools that claim to do this.  Don't use them because they don't work correctly.  For example, in XP, DevEject fails to let you know if the operation failed.  If you google "safely remove usb xp command line" you'll get articles talking about the devcon tool.  Don't use that either because devcon causes the device in question to be uninstalled.  This is not desired and does NOT cause the device to be "unplugged."  So use the tools from &lt;a href="http://www.uwe-sieber.de/usbstick_e.html"&gt;http://www.uwe-sieber.de/usbstick_e.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So yay, now you can do usb stuff from command line.  Sometimes you'll get a failure message.  Unless you accidentally specified a non-removable drive, the most likely reason for this is that Windows has "locked" some of the files on the drive.  So annoying, especially since you'll not know how to unlock them, since you probably already closed all he programs that were using it.  If that's the case, use this program, "Unlocker", to free up those files.  It works like a charm and appears in the right click menu for easy use.  Download unlocker: &lt;a href="http://ccollomb.free.fr/unlocker/"&gt;http://ccollomb.free.fr/unlocker/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-4968697200920596630?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/4968697200920596630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=4968697200920596630' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4968697200920596630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4968697200920596630'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2009/10/removing-and-ejecting-disks.html' title='Removing and Ejecting Disks'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-6402573669131791903</id><published>2009-09-30T21:56:00.000-07:00</published><updated>2009-09-30T21:58:03.526-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Web Screnshots</title><content type='html'>Making screenshots of web pages (whole long screenshots, from top of the page to the bottom) is pretty important, so it's pretty useful to have a good screenshot tool.  The one I use is FireShot.  It's a firefox extension, but it can also be installed on IE.  It's nice, easy to use, and free.  You can save in different image formats as well.  It's a good tool.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/5648"&gt;Firefox&lt;/a&gt;&lt;br /&gt;&lt;a href="http://download.cnet.com/FireShot-for-Internet-Explorer/3000-12512_4-10862847.html"&gt;Internet Explorer&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-6402573669131791903?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/6402573669131791903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=6402573669131791903' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/6402573669131791903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/6402573669131791903'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2009/09/web-screnshots.html' title='Web Screnshots'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-3367702491036887663</id><published>2009-08-27T09:05:00.000-07:00</published><updated>2009-08-27T09:10:21.142-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Tweaks'/><title type='text'>Code Launcher</title><content type='html'>Requires: Windows (2000 and higher) and Ruby&lt;br /&gt;&lt;br /&gt;When I first started playing with lots of languages two years ago, I built a simple extensible ruby script for myself that compiles/executes source code.  I called it "Code Launcher."  I was using Textpad mostly at that time, so I set up Textpad to run codeLauncher on the active file with the press of "ctrl-1".  "Code Launcher" has a different effect depending on the extension of the currently opened file.  For example, I have HTML files open in firefox, ruby code run through a batch file (so it can have a guaranteed pause), and java code compiled and then run through a batch file.  It's a simple idea, but it was also a really useful idea that I still use for quick coding.  Here's the code for it... the nicest thing about it is that you can add and take from it freely and quickly.  Build in special cases for yourself and whatnot.&lt;br /&gt;&lt;br&gt;&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;div class="header"&gt;CodeLauncher.rb&lt;/div&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;"&gt;view plain&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;"&gt;copy to clipboard&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;"&gt;print&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('About',this);return false;"&gt;?&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-rb" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;#&amp;nbsp;This&amp;nbsp;program&amp;nbsp;was&amp;nbsp;created&amp;nbsp;for&amp;nbsp;use&amp;nbsp;in&amp;nbsp;TextPad,&amp;nbsp;so&amp;nbsp;that&amp;nbsp;I&amp;nbsp;could&amp;nbsp;add&amp;nbsp;this&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="comment"&gt;#&amp;nbsp;as&amp;nbsp;a&amp;nbsp;user&amp;nbsp;tool&amp;nbsp;which&amp;nbsp;would&amp;nbsp;do&amp;nbsp;exactly&amp;nbsp;what&amp;nbsp;I&amp;nbsp;wanted&amp;nbsp;to&amp;nbsp;the&amp;nbsp;current&amp;nbsp;open&amp;nbsp;file.&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;#&amp;nbsp;This&amp;nbsp;way,&amp;nbsp;I&amp;nbsp;didn't&amp;nbsp;need&amp;nbsp;a&amp;nbsp;different&amp;nbsp;user&amp;nbsp;tool&amp;nbsp;(and&amp;nbsp;different&amp;nbsp;key&amp;nbsp;shortcut)&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="comment"&gt;#&amp;nbsp;for&amp;nbsp;every&amp;nbsp;different&amp;nbsp;kind&amp;nbsp;of&amp;nbsp;file.&amp;nbsp;&amp;nbsp;I&amp;nbsp;did&amp;nbsp;this&amp;nbsp;in&amp;nbsp;Ruby&amp;nbsp;because&amp;nbsp;I&amp;nbsp;had&amp;nbsp;been&amp;nbsp;learning&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;#&amp;nbsp;it&amp;nbsp;and&amp;nbsp;liking&amp;nbsp;it&amp;nbsp;a&amp;nbsp;lot&amp;nbsp;at&amp;nbsp;the&amp;nbsp;time.&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="comment"&gt;#&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;#&amp;nbsp;The&amp;nbsp;current&amp;nbsp;problem&amp;nbsp;with&amp;nbsp;it&amp;nbsp;is&amp;nbsp;that&amp;nbsp;there&amp;nbsp;can&amp;nbsp;not&amp;nbsp;be&amp;nbsp;more&amp;nbsp;than&amp;nbsp;one&amp;nbsp;parameter.&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="comment"&gt;#&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;#&amp;nbsp;This&amp;nbsp;program&amp;nbsp;requires&amp;nbsp;ruby&amp;nbsp;1.8&amp;nbsp;and&amp;nbsp;AutoIt3&amp;nbsp;installed.&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="comment"&gt;#&amp;nbsp;03/20/07&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;require&amp;nbsp;&lt;span class="string"&gt;'win32ole'&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;CodeLauncher&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;initialize(&amp;nbsp;fileParam,&amp;nbsp;promptForParams&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;false&lt;/span&gt;&lt;span&gt;,&amp;nbsp;browser&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"C:\\Program&amp;nbsp;Files\\Mozilla&amp;nbsp;Firefox\\firefox.exe"&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params&amp;nbsp;=&amp;nbsp;&lt;span class="string"&gt;""&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;exit&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;!fileParam&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;#Get&amp;nbsp;parameters&amp;nbsp;if&amp;nbsp;parameters&amp;nbsp;are&amp;nbsp;asked&amp;nbsp;for&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;promptForParams&amp;nbsp;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;require&amp;nbsp;&lt;span class="string"&gt;'getParams.rb'&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app&amp;nbsp;=&amp;nbsp;FXApp.&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class="string"&gt;"Get&amp;nbsp;Parameters"&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"FXRuby"&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;gp&amp;nbsp;=&amp;nbsp;GetParams.&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;(app)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app.create&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;app.run&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params&amp;nbsp;=&amp;nbsp;gp.param&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;params&amp;nbsp;=&amp;nbsp;&lt;span class="string"&gt;"\"&amp;nbsp;\""&lt;/span&gt;&lt;span&gt;+params+&lt;/span&gt;&lt;span class="string"&gt;"\""&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;#parse&amp;nbsp;out&amp;nbsp;the&amp;nbsp;file&amp;nbsp;name&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;fileParam&amp;nbsp;=~&amp;nbsp;/(.*)\\(.*)\Z/&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fileDir&amp;nbsp;=&amp;nbsp;&lt;span class="variable"&gt;$1&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;fileName&amp;nbsp;=&amp;nbsp;&lt;span class="variable"&gt;$2&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;exit&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;extension&amp;nbsp;=&amp;nbsp;&lt;span class="variable"&gt;$2&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;fileName&amp;nbsp;=~&amp;nbsp;/(.*)\.(.*)\Z/&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;#Special&amp;nbsp;Cases&amp;nbsp;(if&amp;nbsp;any,&amp;nbsp;for&amp;nbsp;quick&amp;nbsp;parameter&amp;nbsp;testing)&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;#Extension&amp;nbsp;based&amp;nbsp;general&amp;nbsp;executions/compilations&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;#&amp;nbsp;Ruby,&amp;nbsp;simpy&amp;nbsp;open&amp;nbsp;using&amp;nbsp;a&amp;nbsp;batch&amp;nbsp;file&amp;nbsp;(for&amp;nbsp;the&amp;nbsp;pause&amp;nbsp;effect)&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;extension&amp;nbsp;==&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"rb"&lt;/span&gt;&lt;span&gt;&amp;nbsp;||&amp;nbsp;extension&amp;nbsp;==&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"rbw"&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;runInCmd(&amp;nbsp;fileDir,&amp;nbsp;fileName,&amp;nbsp;params,&amp;nbsp;&lt;span class="keyword"&gt;true&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;#&amp;nbsp;Java,&amp;nbsp;compile&amp;nbsp;the&amp;nbsp;code&amp;nbsp;an&amp;nbsp;run&amp;nbsp;in&amp;nbsp;a&amp;nbsp;batch&amp;nbsp;file&amp;nbsp;(for&amp;nbsp;the&amp;nbsp;pause&amp;nbsp;effect)&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;extension&amp;nbsp;==&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"java"&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;runInCmd(&amp;nbsp;fileDir,&amp;nbsp;&lt;span class="string"&gt;"javac\"&amp;nbsp;\""&lt;/span&gt;&lt;span&gt;+fileName,&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;""&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;false&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;runInCmd(&amp;nbsp;fileDir,&amp;nbsp;&lt;span class="string"&gt;"java\"&amp;nbsp;\""&lt;/span&gt;&lt;span&gt;+fileName.chomp(&lt;/span&gt;&lt;span class="string"&gt;".java"&lt;/span&gt;&lt;span&gt;),&amp;nbsp;params,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;true&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;#&amp;nbsp;HTML,&amp;nbsp;open&amp;nbsp;the&amp;nbsp;page&amp;nbsp;in&amp;nbsp;the&amp;nbsp;browser&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;extension&amp;nbsp;==&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"html"&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;openInBrowser(&amp;nbsp;browser,&amp;nbsp;fileDir+&lt;span class="string"&gt;"\\"&lt;/span&gt;&lt;span&gt;+fileName&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;#&amp;nbsp;PHP,&amp;nbsp;open&amp;nbsp;the&amp;nbsp;page&amp;nbsp;in&amp;nbsp;the&amp;nbsp;browser&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;extension&amp;nbsp;==&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"php"&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;openInBrowser(&amp;nbsp;browser,&amp;nbsp;fileDir+&lt;span class="string"&gt;"\\"&lt;/span&gt;&lt;span&gt;+fileName&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;#&amp;nbsp;JSP,&amp;nbsp;open&amp;nbsp;the&amp;nbsp;page&amp;nbsp;in&amp;nbsp;the&amp;nbsp;browser&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;extension&amp;nbsp;==&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"jsp"&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;openInBrowser(&amp;nbsp;browser,&amp;nbsp;fileDir+&lt;span class="string"&gt;"\\"&lt;/span&gt;&lt;span&gt;+fileName&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;#&amp;nbsp;batch,&amp;nbsp;simply&amp;nbsp;open&amp;nbsp;the&amp;nbsp;batch&amp;nbsp;file&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;extension&amp;nbsp;==&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"bat"&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;runInCmd(&amp;nbsp;fileDir,&amp;nbsp;fileName,&amp;nbsp;params,&amp;nbsp;&lt;span class="keyword"&gt;false&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;#Run&amp;nbsp;the&amp;nbsp;code&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;runAutoIT3(&amp;nbsp;cmdString&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;au3&amp;nbsp;=&amp;nbsp;WIN32OLE.&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class="string"&gt;"AutoItX3.Control"&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;au3.opt(&lt;span class="string"&gt;"WinTextMatchMode"&lt;/span&gt;&lt;span&gt;,&amp;nbsp;2)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;au3.RunWait(&amp;nbsp;cmdString&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;openInBrowser(&amp;nbsp;browser,&amp;nbsp;url&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;runAutoIT3(&amp;nbsp;browser+&lt;span class="string"&gt;"&amp;nbsp;\""&lt;/span&gt;&lt;span&gt;+url+&lt;/span&gt;&lt;span class="string"&gt;"\""&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;runInCmd(&amp;nbsp;fileDir,&amp;nbsp;command,&amp;nbsp;params,&amp;nbsp;leaveOpen&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmdString&amp;nbsp;=&amp;nbsp;&lt;span class="string"&gt;""&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;leaveOpen&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmdString&amp;nbsp;=&amp;nbsp;&lt;span class="string"&gt;"cmd.exe&amp;nbsp;/c&amp;nbsp;\"codeLauncherPause.bat&amp;nbsp;\""&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;fileDir&amp;nbsp;+&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"\"&amp;nbsp;\""&lt;/span&gt;&lt;span&gt;+&amp;nbsp;command&amp;nbsp;+&amp;nbsp;params&amp;nbsp;+&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"\"\""&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cmdString&amp;nbsp;=&amp;nbsp;&lt;span class="string"&gt;"cmd.exe&amp;nbsp;/c&amp;nbsp;\"cd&amp;nbsp;"&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;fileDir&amp;nbsp;+&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;\""&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;command&amp;nbsp;+&amp;nbsp;params&amp;nbsp;+&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"\"\""&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;runAutoIT3(&amp;nbsp;cmdString&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;__FILE__&amp;nbsp;==&amp;nbsp;&lt;/span&gt;&lt;span class="variable"&gt;$0&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;#Get&amp;nbsp;Parameters&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;filename&amp;nbsp;=&amp;nbsp;ARGV[0]&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;exit&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;!filename&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;browser&amp;nbsp;=&amp;nbsp;ARGV[1]&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;browser&amp;nbsp;=&amp;nbsp;&lt;span class="string"&gt;"C:\\Program&amp;nbsp;Files\\Mozilla&amp;nbsp;Firefox\\firefox.exe"&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;!browser&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;#execute&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CodeLauncher.&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;(&amp;nbsp;filename,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;false&lt;/span&gt;&lt;span&gt;,&amp;nbsp;browser&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;exit&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;# This program was created for use in TextPad, so that I could add this&lt;br /&gt;# as a user tool which would do exactly what I wanted to the current open file.&lt;br /&gt;# This way, I didn't need a different user tool (and different key shortcut) &lt;br /&gt;# for every different kind of file.  I did this in Ruby because I had been learning &lt;br /&gt;# it and liking it a lot at the time.&lt;br /&gt;#&lt;br /&gt;# The current problem with it is that there can not be more than one parameter.&lt;br /&gt;#&lt;br /&gt;# This program requires ruby 1.8 and AutoIt3 installed.&lt;br /&gt;# 03/20/07&lt;br /&gt;&lt;br /&gt;require 'win32ole'&lt;br /&gt;&lt;br /&gt;class CodeLauncher&lt;br /&gt; def initialize( fileParam, promptForParams = false, browser = "C:\\Program Files\\Mozilla Firefox\\firefox.exe" )&lt;br /&gt;  params = ""&lt;br /&gt;  exit if( !fileParam )&lt;br /&gt;&lt;br /&gt;  #Get parameters if parameters are asked for&lt;br /&gt;  if( promptForParams ) &lt;br /&gt;   require 'getParams.rb'&lt;br /&gt;   app = FXApp.new("Get Parameters", "FXRuby")&lt;br /&gt;   gp = GetParams.new(app)&lt;br /&gt;   app.create&lt;br /&gt;   app.run&lt;br /&gt;   params = gp.param&lt;br /&gt;   params = "\" \""+params+"\""&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  #parse out the file name&lt;br /&gt;  if( fileParam =~ /(.*)\\(.*)\Z/ )&lt;br /&gt;   fileDir = $1&lt;br /&gt;   fileName = $2&lt;br /&gt;  else&lt;br /&gt;   exit&lt;br /&gt;  end&lt;br /&gt;  extension = $2 if( fileName =~ /(.*)\.(.*)\Z/ )&lt;br /&gt;&lt;br /&gt;  #Special Cases (if any, for quick parameter testing)&lt;br /&gt;&lt;br /&gt;  #Extension based general executions/compilations&lt;br /&gt;&lt;br /&gt;  # Ruby, simpy open using a batch file (for the pause effect)&lt;br /&gt;  if( extension == "rb" || extension == "rbw")&lt;br /&gt;   runInCmd( fileDir, fileName, params, true )&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  # Java, compile the code an run in a batch file (for the pause effect)&lt;br /&gt;  if( extension == "java" )&lt;br /&gt;   runInCmd( fileDir, "javac\" \""+fileName, "", false )&lt;br /&gt;   runInCmd( fileDir, "java\" \""+fileName.chomp(".java"), params, true )&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  # HTML, open the page in the browser&lt;br /&gt;  if( extension == "html" )&lt;br /&gt;   openInBrowser( browser, fileDir+"\\"+fileName )&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  # PHP, open the page in the browser&lt;br /&gt;  if( extension == "php" )&lt;br /&gt;   openInBrowser( browser, fileDir+"\\"+fileName )&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  # JSP, open the page in the browser&lt;br /&gt;  if( extension == "jsp" )&lt;br /&gt;   openInBrowser( browser, fileDir+"\\"+fileName )&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  # batch, simply open the batch file&lt;br /&gt;  if( extension == "bat" )&lt;br /&gt;   runInCmd( fileDir, fileName, params, false )&lt;br /&gt;  end&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; #Run the code&lt;br /&gt; def runAutoIT3( cmdString )&lt;br /&gt;  au3 = WIN32OLE.new("AutoItX3.Control")&lt;br /&gt;  au3.opt("WinTextMatchMode", 2)&lt;br /&gt;  au3.RunWait( cmdString )&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def openInBrowser( browser, url )&lt;br /&gt;  runAutoIT3( browser+" \""+url+"\"" )&lt;br /&gt; end&lt;br /&gt;&lt;br /&gt; def runInCmd( fileDir, command, params, leaveOpen )&lt;br /&gt;  cmdString = ""&lt;br /&gt;  if( leaveOpen )&lt;br /&gt;   cmdString = "cmd.exe /c \"codeLauncherPause.bat \"" + fileDir + "\" \""+ command + params + "\"\""&lt;br /&gt;  else&lt;br /&gt;   cmdString = "cmd.exe /c \"cd " + fileDir + " &amp;amp;&amp;amp; \"" + command + params + "\"\""&lt;br /&gt;  end&lt;br /&gt;  runAutoIT3( cmdString )&lt;br /&gt; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;if __FILE__ == $0&lt;br /&gt; #Get Parameters&lt;br /&gt; &lt;br /&gt; filename = ARGV[0]&lt;br /&gt; exit if( !filename )&lt;br /&gt; browser = ARGV[1]&lt;br /&gt; &lt;br /&gt; browser = "C:\\Program Files\\Mozilla Firefox\\firefox.exe" if( !browser )&lt;br /&gt; &lt;br /&gt; #execute&lt;br /&gt; CodeLauncher.new( filename, false, browser )&lt;br /&gt; exit&lt;br /&gt;end&lt;/textarea&gt;&lt;/div&gt;&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;div class="header"&gt;codeLauncherPause.bat&lt;/div&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;"&gt;view plain&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;"&gt;copy to clipboard&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;"&gt;print&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('About',this);return false;"&gt;?&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-rb" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;cd&amp;nbsp;%1&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;%2&amp;nbsp;%3&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;pause&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;cd %1&lt;br /&gt;%2 %3&lt;br /&gt;pause&lt;/textarea&gt;&lt;/div&gt;And setting CodeLauncher to be run through "ctrl-1" in Textpad is pretty easy.  Go to configure, then select preferences, then select tools.  Add a DOS Command, name it whatever you want.  I called mine Code Launcher.&lt;br /&gt;&lt;br /&gt;Click Apply, then expand Tools.  For Parameters, type "codeLauncher.rb $File".  For Initial Folder, enter the full path to the codeLauncher.rb script.  Make sure "Close DOS window on exit" is checked.  Then click OK.  You're all set.&lt;br /&gt;&lt;br&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_XSrd14MaFHQ/SpavIIXmnnI/AAAAAAAAAAw/9JcxvkeO384/s1600-h/codeLauncher1.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 206px;" src="http://3.bp.blogspot.com/_XSrd14MaFHQ/SpavIIXmnnI/AAAAAAAAAAw/9JcxvkeO384/s320/codeLauncher1.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5374675759533563506" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XSrd14MaFHQ/SpavRmTlbhI/AAAAAAAAAA4/dj1CuCzXNuw/s1600-h/codeLauncher2.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 226px;" src="http://4.bp.blogspot.com/_XSrd14MaFHQ/SpavRmTlbhI/AAAAAAAAAA4/dj1CuCzXNuw/s320/codeLauncher2.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5374675922188594706" /&gt;&lt;/a&gt;&lt;br /&gt;As a parting note, make sure whatever you're using to develop code with does code launching (maybe build/execute is a better term) and make sure you tailor fit it to your usage.  Any decent development environment does... F5 is a common key to try.  This is really basic funcitonality that makes a developer's life tons easier.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-3367702491036887663?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/3367702491036887663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=3367702491036887663' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3367702491036887663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3367702491036887663'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2009/08/code-launcher.html' title='Code Launcher'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_XSrd14MaFHQ/SpavIIXmnnI/AAAAAAAAAAw/9JcxvkeO384/s72-c/codeLauncher1.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-1171834075385092087</id><published>2009-08-17T19:35:00.000-07:00</published><updated>2009-08-17T19:47:19.930-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>My Path to a Java/COM Bridge</title><content type='html'>Accurate as of July 2007.&lt;br /&gt;&lt;br /&gt;A company my company was subcontracting to for a project told us that we could only use their hardware via COM objects.  As a team, we didn't know very much about COM.  Our application was entirely Java based.  To us, their requirement implied that we needed to write JNI code, which frightened us because we've done -that- before.&lt;br /&gt;&lt;br /&gt;Since we didn't know that much about COM, I was tasked to do a study on COM and a feasibility study for using COM objects from Java.  I broke up the study into two parts.  First, I figured out the basics of COM so that I could explain it to my team members.  Second, I looked into and evaluated solutions to our problem.  (SPOILER: We ended up going with J-Integra.)&lt;br /&gt;&lt;br /&gt;The study was actually interesting and I think it's useful in general.  Being able to use COM means that you have a lot of opportunity to interact with Windows applications.  The ability to automate Microsoft Office applications is really convenient.  So I'm going to share some of the results of my COM studies.  First, I'll try to explain COM if you don't know much about it.  Then I'll go into a comparison of Java/COM bridges.&lt;br /&gt;&lt;br /&gt;I'm no expert on any of this, so don't let this be the end of your own studies.  And I don't really go very deeply into either COM nor the Java-COM bridges.  Also, I did quickly convert this from a private internal document to one for public use, so it might read funny in some places.  So use this article more as a starting point.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;If you want to learn, COM, listen&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To teach COM, I'm going to reference the best of what I've read in an order I find very conducive to learning COM.  I don't care too much about in-depthness to start off with: I build up to that when I feel I'm ready.  This order will reflect that.  So, let's start learning.  Please note that I'm writing from the perspective of using Visual Studio 2005 and Windows XP Home:&lt;br /&gt;&lt;br /&gt;1. &lt;a href="http://www.codeproject.com/com/comintro.asp"&gt;http://www.codeproject.com/com/comintro.asp&lt;/a&gt;&lt;br /&gt;This covers the COM interaction client side basics and is quite straightforward.  This article (and the ones that will follow) reference ATL without describing what it is.  The Active Template Library is simply a set of template-based C++ classes that simplify the programming of COM objects.  ATL includes an object wizard that sets up the primary structure of COM Objects (including OLE Automation servers and ActiveX controls) very quickly with a minimum of hand coding.  ATL allows creating smaller controls without support DLLs, so ATL is in a sense a lightweight alternative to Microsoft Foundation Classes (MFC) for the COM control environment.&lt;br /&gt;&lt;br /&gt;2. &lt;a href="http://www.codeproject.com/com/comintro2.asp"&gt;http://www.codeproject.com/com/comintro2.asp&lt;/a&gt;&lt;br /&gt;This covers making a COM server.  Note that the client will not work unless you register the DLL you create/download.  Do this by running "regsvr32 MsgBoxSvr.dll" in the command window.&lt;br /&gt;&lt;br /&gt;3. &lt;a href="http://www.microsoft.com/msj/1295/activex1295.aspx"&gt;http://www.microsoft.com/msj/1295/activex1295.aspx&lt;/a&gt;&lt;br /&gt;COM distinguishes between three interface types: custom, dispatch, and dual interfaces.  It's at least important to be familiar with the results of implementing the IDispatch interface.  The IDispatch interface is the interface that exposes the OLE Automation protocol.  The Automation (IDispatch) interface allows a client application to find out what properties and methods are supported by an object at run-time.  It also provides the information necessary to invoke these properties and methods.  Client applications do not need to be aware of the object members when they are compiled.&lt;br /&gt;&lt;br /&gt;Those three are good enough on their own as a starter, but personally, I needed more reinforcement.  And thus...&lt;br /&gt;&lt;br /&gt;4. &lt;a href="http://www.codeproject.com/com/rrcombasics.asp"&gt;http://www.codeproject.com/com/rrcombasics.asp&lt;/a&gt;&lt;br /&gt;Once again, COM basics.  The grammar is bad, but it will help reinforce the basics.&lt;br /&gt;&lt;br /&gt;5. &lt;a href="http://www.codeproject.com/com/Inside_COM.asp"&gt;http://www.codeproject.com/com/Inside_COM.asp&lt;/a&gt;&lt;br /&gt;Another in-depth Introduction to COM (Server and Client).  This one doesn't come with a code download.  &lt;br /&gt;&lt;br /&gt;6. &lt;a href="http://www.codeproject.com/com/mmtopo_comid.asp"&gt;http://www.codeproject.com/com/mmtopo_comid.asp&lt;/a&gt;&lt;br /&gt;Some vocabulary definitions, once again meant to reinforce the basics. &lt;br /&gt;&lt;br /&gt;An important aspect of my project at work was the need of being able to use callback methods (aka COM events) with COM.  The next links go over this:&lt;br /&gt;&lt;br /&gt;7. &lt;a href="http://www.samspublishing.com/articles/article.asp?p=25922&amp;seqNum=4&amp;rl=1"&gt;http://www.samspublishing.com/articles/article.asp?p=25922&amp;seqNum=4&amp;rl=1&lt;/a&gt;&lt;br /&gt;This explains the concepts of COM events.&lt;br /&gt;&lt;br /&gt;8. &lt;a href="http://www.codeproject.com/com/connectionpoint.asp?df=100&amp;forumid=14124&amp;exp=0&amp;select=1481687"&gt;http://www.codeproject.com/com/connectionpoint.asp?df=100&amp;forumid=14124&amp;exp=0&amp;select=1481687&lt;/a&gt;&lt;br /&gt;An example/tutorial going over COM events.  This code simply doesn't compile on Visual Studio 2005.  &lt;br /&gt;&lt;br /&gt;And since .Net is so important now, COM interoperability is an issue.  These articles give some basics on that.  A component available from .NET (written in C#) is a .NET component.  It is different from a COM component because it requires a few of the DLLs from the .NET Framework in order to work.&lt;br /&gt;&lt;br /&gt;9. &lt;a href="http://www.codeproject.com/useritems/BuildCOMServersInDotNet.asp"&gt;http://www.codeproject.com/useritems/BuildCOMServersInDotNet.asp&lt;/a&gt; / &lt;a href="http://www.codeproject.com/dotnet/cominterop.asp"&gt;http://www.codeproject.com/dotnet/cominterop.asp&lt;/a&gt;&lt;br /&gt;General stuff&lt;br /&gt;&lt;br /&gt;10. &lt;a href="http://support.microsoft.com/kb/828736/en-us"&gt;http://support.microsoft.com/kb/828736/en-us&lt;/a&gt;&lt;br /&gt;More about writing a .NET component.&lt;br /&gt; &lt;br /&gt;11. &lt;a href="http://support.microsoft.com/kb/313891"&gt;http://support.microsoft.com/kb/313891&lt;/a&gt;&lt;br /&gt;How to sink managed C# events.  I believe that this is the best way to providing callbacks for COM components in C#.&lt;br /&gt;&lt;br /&gt;The above information should be enough knowledge to understand what's going on when I get to explaining the Java/COM bridges.  I'm going to provide a few more links that go a little more in depth, but you can probably do without the extra information.  If you really wanted to learn COM, even this won't be enough for you.  You're going to have to buckle up and buy a book.  But anyway...&lt;br /&gt;&lt;br /&gt;12. &lt;a href="http://www.codeproject.com/com/com_in_c1.asp"&gt;http://www.codeproject.com/com/com_in_c1.asp&lt;/a&gt;&lt;br /&gt;To understand how COM really works, you should do it from C.  This is a series of 8 tutorials (com_in_c1 to com_in_c8) that will really let you know what's going on beyond all the Visual Studio gives you through its wizards and templates.&lt;br /&gt;&lt;br /&gt;13. &lt;a href="http://en.wikipedia.org/wiki/Component_Object_Model"&gt;http://en.wikipedia.org/wiki/Component_Object_Model&lt;/a&gt;&lt;br /&gt;Finally, for a refresher course, read the wikipedia page.  The links are nice.  You may want to wiki OLE Automation, ActiveX, ATL, and IDispatch while your out it.  Reviewing by reading is always beneficial, even if not as beneficial as reviewing by doing.&lt;br /&gt;&lt;br /&gt;14. &lt;a href="http://www.microsoft.com/com/default.mspx"&gt;http://www.microsoft.com/com/default.mspx&lt;/a&gt;&lt;br /&gt;Lastly, the definitive source on COM.  Good luck finding your way around there, lots of scattered information.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Java Couldn't Originally Make Connections Or Method Calls.... OM.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So, after all that reading, we're finally ready to see if we can figure out the problem.  The goal is to use Java to work with COM objects.  No matter how you look at it, this involves interacting with native code running outside the JVM.  Web Services (Java to Soap/Soap to COM) is an option, but due to the poor performance and the limited COM interaction (no events and worse), it's not a very good option.  It was possible to directly call COM objects using Microsoft's own JVM in Windows, but Microsoft dropped its Java support and who really wants to lock into a specific JVM anyways?  Basically, the only real option there is right now is to use JNI, which is not very fun.  Our best hope is that someone else has already written the JNI for us and wrapped it up in a not-as-unfun Java API.  Fortunately, this need for COM interactions is common enough that people have done that, to varying extents.&lt;br /&gt;&lt;br /&gt;There are open-source implementations and there are (costly) commercial solutions.  I'm going to point out eleven solutions that I've come across.  Please pay very close attention, these solutions are very different and support COM in different ways.  Make sure the solution you choose will do what you want and that it's something you can bear to work in.  I want to cover each of these solutions enough so that you know if it will work for you.  I'll make some comments about using it (and it's pricing) so you can decide if you can work with it.  When in doubt, don't take my word for it and go to a more reliable source, specifically the project's website.  Things could have definitely changed since I wrote this.&lt;br /&gt;&lt;br /&gt;BTW, I found this gem of a study.  It was very helpful to me: &lt;a href="http://www.mit.jyu.fi/minurmin/javacom/javacom_report.html"&gt;http://www.mit.jyu.fi/minurmin/javacom/javacom_report.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Comparisons&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I hunted down as many solutions as I could find, but ended up only reviewing three of them.  Feel free to do more research on your own.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Summaries&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;Hopeful #1&lt;/span&gt;: Jacob, &lt;a href="http://danadler.com/jacob/"&gt;http://danadler.com/jacob/&lt;/a&gt; -&gt; &lt;a href="http://sourceforge.net/projects/jacob-project/"&gt;http://sourceforge.net/projects/jacob-project/&lt;/a&gt;&lt;br /&gt;The potentially big problems with Jacob are its difficult error prone syntax, the lack of vtable call support, and inconsistencies in being able to access all the COM objects it should.  The benefits are the cost (open source) and the maturity of the project.&lt;br /&gt;        &lt;br /&gt;Jacob uses a lot of Reflection and does its mappings based on strings provided.  That means that typos are deadly and very difficult to track down because everything will compile right... it just won't work.  The Jacob API is very verbose: a Jacob call can easily be twice as many lines of code as opposed to a VBScript call.  Just another thing that makes debugging difficult.  There is no built in way to create wrappers, but I read about a technique of modifying Jacob to use wrappers.  I don't think it's worth the effort though.&lt;br /&gt;        &lt;br /&gt;Jacob has a lack of vtable call support, which means that it can not support custom interfaces.  The COM objects must support the IDispatch interface (meaning ActiveX/OLE objects).&lt;br /&gt;        &lt;br /&gt;Another problem that I've encountered seems to be an incompatibility with certain COM objects.  The calls won't work with certain objects (I've had very inconsistent experience with COM objects supporting callbacks in particular.)  I highly suspect that it's due to badly formed COM Objects, but as of yet, I haven't tracked down the specific problem.  It's not just my COM objects either: Callbacks won't work with Microsoft Office 2000, but will work with Microsoft Office 2003.&lt;br /&gt;        &lt;br /&gt;The benefits of using this solution is that it's open source and it's the most mature open source solution.  It has decently active forums for minor issues and plenty of people have reported success using it.  A commercial solution would be much, much better, but a Jacob solution will probably be manageable.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hopeful #2&lt;/span&gt;: Jsegue, &lt;a href="http://jsegue.sourceforge.net/"&gt;http://jsegue.sourceforge.net/&lt;/a&gt;&lt;br /&gt;This solution seems pretty good.  Unlike Jacob, it supports vtable calls.  However, its API is far worse and the wrapper solution is no good (requires C++ code.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hopeful #3&lt;/span&gt;: J-Integra, &lt;a href="http://j-integra.intrinsyc.com/"&gt;http://j-integra.intrinsyc.com/&lt;/a&gt;&lt;br /&gt;This seems to be the overall best tool I've found so far.  In addition, its API is easier to use than the other solutions.  It is a commercial product with all the disadvantages (cost) and benefits (support) associated.&lt;br /&gt;        &lt;br /&gt;For Java to COM support, J-Integra basically works by using their comtojava tool to create a Java Wrapper for a specified COM object.  The resulting wrapper class and a J-Integra jar are imported by the class that needs COM to Java interaction.  All COM calls are called as method calls of the wrapping class.  The comtojava tool is easy to use and doesn't require much more than specifiying the COM class to wrap.&lt;br /&gt;        &lt;br /&gt;COM events (callbacks) are implemented using Java's standard listener registration technique.  J-Integra connects with .NET components as well as COM components.&lt;br /&gt;        &lt;br /&gt;J-Integra provides support for many more Java/COM bridge needs.  It allows Java to be called from COM, it allows native interfaces to be used for speed (as opposed to a native COM implementation).  Probably the best things about J-Integra are its documentation and technical support.  Overall, J-Integra seems to be the best way to go for a Java/COM bridge, as long as you can afford it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hopeful #4&lt;/span&gt;: com4j, &lt;a href="https://com4j.dev.java.net/"&gt;https://com4j.dev.java.net/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hopeful #5&lt;/span&gt;: EXJCom, &lt;a href="http://www.ezjcom.com/purchase.html"&gt;http://www.ezjcom.com/purchase.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hopeful #6&lt;/span&gt;: JCOM, &lt;a href="http://sourceforge.net/projects/jcom/"&gt;http://sourceforge.net/projects/jcom/&lt;/a&gt;&lt;br /&gt;        Open source and abandoned (in all but name.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hopeful #7&lt;/span&gt;: JNIWrapper, &lt;a href="http://weblog.janek.org/Archive/2004/06/27/JNIWrapper-JavaDesktopInt.html"&gt;http://weblog.janek.org/Archive/2004/06/27/JNIWrapper-JavaDesktopInt.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hopeful #8&lt;/span&gt;: JaWin, &lt;a href="http://jawinproject.sourceforge.net/jawin.html"&gt;http://jawinproject.sourceforge.net/jawin.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hopeful #9&lt;/span&gt;: Java2Com, &lt;a href="http://www.nevaobject.com/default.htm"&gt;http://www.nevaobject.com/default.htm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hopeful #10&lt;/span&gt;: Bridge2Java, &lt;a href="http://www.alphaworks.ibm.com/tech/bridge2java"&gt;http://www.alphaworks.ibm.com/tech/bridge2java&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hopeful #11&lt;/span&gt;: DTJCB, &lt;a href="http://www.alphaworks.ibm.com/tech/dtjcb"&gt;http://www.alphaworks.ibm.com/tech/dtjcb&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Hopeful #12&lt;/span&gt;: &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=174727"&gt;http://sourceforge.net/project/showfiles.php?group_id=174727&lt;/a&gt;&lt;br /&gt;Not mature yet, but maybe later.  It might be worth looking into later.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Comclusion&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And that's all I came up with for my own study.  Hopefully, it will help you in whatever you're doing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-1171834075385092087?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/1171834075385092087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=1171834075385092087' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/1171834075385092087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/1171834075385092087'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2009/08/my-path-to-javacom-bridge.html' title='My Path to a Java/COM Bridge'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-6937712558387889157</id><published>2009-07-31T19:27:00.001-07:00</published><updated>2009-07-31T19:27:40.101-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tweaks'/><title type='text'>Replacing Explorer Navigation</title><content type='html'>Requires: Windows 2000/XP, AutoIt3, and PS Hot Launch.&lt;br /&gt;&lt;br /&gt;In internet explorer, you can use either backspace or alt-left to go to the previous page; the state is saved so that all selected items are still selected and all text in forms is still entered.  In windows explorer (y'know, what you Windows users use to traverse your systems) for XP the same thing seems to happen.  However, this is not the case.  &lt;br /&gt;&lt;br /&gt;Backspace actually corresponds to "Move Up One Directory" and Alt-left corresponds to "Back."  If you are used to using Backspace to go back on web pages, I would suggest getting used to Alt-Left.  Alt-Forward will move you forward (so it makes more sense) and making backspace go back may lead to problems will filling out web forms.  I mapped Alt-Up to move up a directory and Alt-Down to close the active window, using AutoIt scripts and PS Hot Key.  It took a while to wean off using backspace, but Alt-[Direction] actually makes more sense, is more unlikely to cause errors, and works the same on all windows computers.  And so it's the better alternative than remapping keys.&lt;br /&gt;&lt;br /&gt;(Haha, I've lied.  I ended up switching all my Alt-[Direction] shortcuts with Ctrl-[Direction], unless there's a program conflict.  I used AutoIt scripts mapped to key combinations via PS Hot Keys.  Ctrl instead of Alt made it a lot easier to use the commands one handed and I don't use other people's machines all that often anyway.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-6937712558387889157?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/6937712558387889157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=6937712558387889157' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/6937712558387889157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/6937712558387889157'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2009/07/replacing-explorer-navigation.html' title='Replacing Explorer Navigation'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-754530060712397417</id><published>2009-06-30T17:26:00.000-07:00</published><updated>2009-06-30T17:28:32.474-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tweaks'/><title type='text'>Removing and Ejecting Disks</title><content type='html'>Requires: Windows XP Professional&lt;br /&gt;&lt;br /&gt;So, you plug in a USB drive, do your stuff, and then you want to take it out.  Pretty common today, right?  So you've got to go to your taskbar, right click that "Safely Remove Drive" icon, and so on.  I thought it was kind of annoying, so I looked for a way to do this without having to use the mouse (and that was free.)  And I eventually found it at this site.  &lt;a href="http://www.uwe-sieber.de/usbstick_e.html"&gt;http://www.uwe-sieber.de/usbstick_e.html&lt;/a&gt;  His english isn't too great, but he's not a native speaker and it's not -that- hard to understand.&lt;br /&gt;&lt;br /&gt;As he says, there are several tools that claim to do this.  Don't use them because they don't work correctly.  For example, in XP, DevEject fails to let you know if the operation failed.  If you google "safely remove usb xp command line" you'll get articles talking about the devcon tool.  Don't use that either because devcon causes the device in question to be uninstalled.  This is not desired and does NOT cause the device to be "unplugged."  So use the tools from &lt;a href="http://www.uwe-sieber.de/usbstick_e.html"&gt;http://www.uwe-sieber.de/usbstick_e.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So yay, now you can do usb stuff from command line.  Sometimes you'll get a failure message.  Unless you accidentally specified a non-removable drive, the most likely reason for this is that Windows has "locked" some of the files on the drive.  So annoying, especially since you'll not know how to unlock them, since you probably already closed all he programs that were using it.  If that's the case, use this program, "Unlocker", to free up those files.  It works like a charm and appears in the right click menu for easy use.  Download Unlocker: &lt;a href="http://ccollomb.free.fr/unlocker/"&gt;http://ccollomb.free.fr/unlocker/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-754530060712397417?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/754530060712397417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=754530060712397417' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/754530060712397417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/754530060712397417'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2009/06/removing-and-ejecting-disks.html' title='Removing and Ejecting Disks'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-7080424816754134761</id><published>2009-05-24T08:44:00.000-07:00</published><updated>2009-05-24T08:46:37.931-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tweaks'/><title type='text'>Remapping keys for closing windows</title><content type='html'>&lt;a href="http://jdiscar.blogspot.com/2008/10/requirements-for-tweaks.html"&gt;Requires: Windows 2000/XP, AutoIt3, and PS Hot Launch.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Really simple tweak today.  In Windows, the shortcut to close a window is "Alt-f4."  That annoys me.  I mean, it takes two hands, the keys are far apart, blah blah blah... Really, this is one of those things that I probably should have just gotten used to, but... I didn't.  Instead, I found a way to use "ctrl-down", which works well for me since I'm using "ctrl-(other arrow keys)" for navigating windows explorer.  I find it easier and faster to use the right ctrl with the arrow keys for quick navigation.  My solution uses an Auto It script and PS Hot Launch.&lt;br /&gt;&lt;br /&gt;The AutoIt script is really simple:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WinClose( "" )&lt;br /&gt;&lt;br /&gt;It'll close the program that currently has focus.  Simply save that code and map it (using PS Hot Launch) to "ctrl-down."  You can use PS Hot Launch to to make up a lot of your own commands and tweak all your keyboard shortcuts without actually changing the keys.  The only thing to be careful about is not ruining pre-existing shortcuts.&lt;br /&gt;&lt;br /&gt;As I was writing this, I realized the title could be misread to mean closing the Windows Operating System.  In case that mistake lead you to read this, I'll give you a tip to close that from Command Line.  Simply type in:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;shutdown -s -f -t 0&lt;br /&gt;&lt;br /&gt;This'll shut down the computer, not give you program warnings, and do it without a delay.  Do "shutdown -?" for more options.  Cinchy.  You can put the code in a batch file and then map it to a key or put it on your desktop and click on it when you want to shutdown.  I think it's a better method than the click through GUI.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-7080424816754134761?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/7080424816754134761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=7080424816754134761' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7080424816754134761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7080424816754134761'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2009/05/remapping-keys-for-closing-windows.html' title='Remapping keys for closing windows'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-5465825065323996687</id><published>2009-04-02T09:11:00.000-07:00</published><updated>2009-04-02T09:12:08.611-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Sorting A Million Integers</title><content type='html'>Have you ever heard the popular programming interview question, "Show me how to sort one million 32 bit integers in 2MB of RAM?"&lt;br /&gt;&lt;br /&gt;I've read about it, but have never actually been asked it in an interview.  I think the correct response is that one million 32 bit integers would not fit in 2MB of RAM.  But if you assume the problem implies you have an unlimited amount disk space, then the problem is actually solvable.  I recently read a good article going over the solution to this problem, so I thought I'd share the links.&lt;br /&gt;&lt;br /&gt;The article (and its follow up) assume you know about heaps and heapsort.  In case you don't, a heap is a tree-like data structure and heapsort is a very fast sorting algorithm.  You can read about them more on wikipedia, &lt;a href="http://en.wikipedia.org/wiki/Heap_(data_structure)"&gt;Heap here&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Heapsort"&gt;Heapsort here&lt;/a&gt;.  If you're unfamiliar with heapsort, I'd strongly suggest you read about &lt;a href="http://en.wikipedia.org/wiki/Sorting_algorithm"&gt;Sorting Algorithms in general&lt;/a&gt;.  Although you'll probably never need to program one for work, it's really nice topic to know about and will probably help you learn to judge your own algorithms better.  By the way, here is a java implementation of Heapsort based on the pseudocode from its wikipedia article.&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;div class="header"&gt;Heap.java&lt;/div&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;"&gt;view plain&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;"&gt;copy to clipboard&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;"&gt;print&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('About',this);return false;"&gt;?&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-j" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;class&lt;/span&gt;&lt;span&gt;&amp;nbsp;Heap&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;[]&amp;nbsp;swap(&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;[]&amp;nbsp;a,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;first,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;last&amp;nbsp;)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;tmp&amp;nbsp;=&amp;nbsp;a[first];&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a[first]&amp;nbsp;=&amp;nbsp;a[last];&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a[last]&amp;nbsp;=&amp;nbsp;tmp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;a;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;[]&amp;nbsp;heapSort(&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;[]&amp;nbsp;a,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;count&amp;nbsp;)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a&amp;nbsp;=&amp;nbsp;heapify(a,&amp;nbsp;count);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;end&amp;nbsp;=&amp;nbsp;count&amp;nbsp;-&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;while&lt;/span&gt;&lt;span&gt;(&amp;nbsp;end&amp;nbsp;&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//swap&amp;nbsp;the&amp;nbsp;root&amp;nbsp;(maximum&amp;nbsp;value)&amp;nbsp;of&amp;nbsp;the&amp;nbsp;heap&amp;nbsp;with&amp;nbsp;the&amp;nbsp;last&amp;nbsp;element&amp;nbsp;of&amp;nbsp;the&amp;nbsp;heap&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a&amp;nbsp;=&amp;nbsp;swap(&amp;nbsp;a,&amp;nbsp;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span&gt;,&amp;nbsp;end&amp;nbsp;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//decrease&amp;nbsp;the&amp;nbsp;size&amp;nbsp;of&amp;nbsp;the&amp;nbsp;heap&amp;nbsp;by&amp;nbsp;one&amp;nbsp;so&amp;nbsp;that&amp;nbsp;the&amp;nbsp;previous&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//max&amp;nbsp;value&amp;nbsp;will&amp;nbsp;stay&amp;nbsp;in&amp;nbsp;its&amp;nbsp;proper&amp;nbsp;placement&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;end--;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//put&amp;nbsp;the&amp;nbsp;heap&amp;nbsp;back&amp;nbsp;in&amp;nbsp;max-heap&amp;nbsp;order&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a&amp;nbsp;=&amp;nbsp;siftDown(a,&amp;nbsp;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span&gt;,&amp;nbsp;end);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;a;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;[]&amp;nbsp;heapify(&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;[]a,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;count&amp;nbsp;)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//Start&amp;nbsp;is&amp;nbsp;a's&amp;nbsp;index&amp;nbsp;of&amp;nbsp;the&amp;nbsp;last&amp;nbsp;parent&amp;nbsp;node&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;start&amp;nbsp;=&amp;nbsp;(count-&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt;&lt;span&gt;)/&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;while&lt;/span&gt;&lt;span&gt;(&amp;nbsp;start&amp;nbsp;&amp;gt;=&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//Sift&amp;nbsp;down&amp;nbsp;the&amp;nbsp;node&amp;nbsp;at&amp;nbsp;index&amp;nbsp;start&amp;nbsp;to&amp;nbsp;the&amp;nbsp;proper&amp;nbsp;place&amp;nbsp;such&amp;nbsp;that&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//all&amp;nbsp;nodes&amp;nbsp;below&amp;nbsp;the&amp;nbsp;start&amp;nbsp;index&amp;nbsp;are&amp;nbsp;in&amp;nbsp;heap&amp;nbsp;order&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a&amp;nbsp;=&amp;nbsp;siftDown(a,&amp;nbsp;start,&amp;nbsp;count-&lt;span class="number"&gt;1&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;start--;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;a;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;public&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;static&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;[]&amp;nbsp;siftDown(&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;[]&amp;nbsp;a,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;start,&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;end)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;root&amp;nbsp;=&amp;nbsp;start;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//While&amp;nbsp;the&amp;nbsp;root&amp;nbsp;has&amp;nbsp;at&amp;nbsp;least&amp;nbsp;one&amp;nbsp;child...&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;while&lt;/span&gt;&lt;span&gt;(&amp;nbsp;root&amp;nbsp;*&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;lt;=&amp;nbsp;end&amp;nbsp;)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//root*2&amp;nbsp;points&amp;nbsp;to&amp;nbsp;the&amp;nbsp;left&amp;nbsp;child&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;int&lt;/span&gt;&lt;span&gt;&amp;nbsp;child&amp;nbsp;=&amp;nbsp;root&amp;nbsp;*&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt;&lt;span&gt;&amp;nbsp;+&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//If&amp;nbsp;the&amp;nbsp;child&amp;nbsp;has&amp;nbsp;a&amp;nbsp;sibling&amp;nbsp;and&amp;nbsp;the&amp;nbsp;child's&amp;nbsp;value&amp;nbsp;is&amp;nbsp;less&amp;nbsp;than&amp;nbsp;its&amp;nbsp;sibling's...&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;child&amp;nbsp;+&amp;nbsp;&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;lt;=&amp;nbsp;end&amp;nbsp;&amp;amp;&amp;amp;&amp;nbsp;a[child]&amp;nbsp;&amp;lt;&amp;nbsp;a[child+&lt;/span&gt;&lt;span class="number"&gt;1&lt;/span&gt;&lt;span&gt;]&amp;nbsp;)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//Then&amp;nbsp;point&amp;nbsp;to&amp;nbsp;the&amp;nbsp;right&amp;nbsp;child&amp;nbsp;instead&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;child&amp;nbsp;=&amp;nbsp;child+&lt;span class="number"&gt;1&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//If&amp;nbsp;out&amp;nbsp;of&amp;nbsp;max&amp;nbsp;heap&amp;nbsp;order...&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;a[root]&amp;nbsp;&amp;lt;&amp;nbsp;a[child]&amp;nbsp;)&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="comment"&gt;//Then&amp;nbsp;repeat&amp;nbsp;to&amp;nbsp;continue&amp;nbsp;sifting&amp;nbsp;down&amp;nbsp;the&amp;nbsp;child&amp;nbsp;now&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a&amp;nbsp;=&amp;nbsp;swap(a,&amp;nbsp;root,&amp;nbsp;child);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;=&amp;nbsp;child;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;span&gt;&amp;nbsp;{&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;a;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;a;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;public class Heap {&lt;br /&gt;&lt;br /&gt;  public static int[] swap( int[] a, int first, int last ) {&lt;br /&gt;    int tmp = a[first];&lt;br /&gt;    a[first] = a[last];&lt;br /&gt;    a[last] = tmp;&lt;br /&gt;    return a;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public static int[] heapSort( int[] a, int count ) {&lt;br /&gt;    a = heapify(a, count);&lt;br /&gt;&lt;br /&gt;    int end = count - 1;&lt;br /&gt;    while( end &amp;gt; 0 ) {&lt;br /&gt;      //swap the root (maximum value) of the heap with the last element of the heap&lt;br /&gt;      a = swap( a, 0, end );&lt;br /&gt;&lt;br /&gt;      //decrease the size of the heap by one so that the previous&lt;br /&gt;      //max value will stay in its proper placement&lt;br /&gt;      end--;&lt;br /&gt;&lt;br /&gt;      //put the heap back in max-heap order&lt;br /&gt;      a = siftDown(a, 0, end);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return a;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public static int[] heapify(int[]a, int count ) {&lt;br /&gt;    //Start is a's index of the last parent node&lt;br /&gt;    int start = (count-2)/2;&lt;br /&gt;&lt;br /&gt;    while( start &amp;gt;= 0 ) {&lt;br /&gt;      //Sift down the node at index start to the proper place such that&lt;br /&gt;      //all nodes below the start index are in heap order&lt;br /&gt;      a = siftDown(a, start, count-1);&lt;br /&gt;      start--;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return a;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public static int[] siftDown(int[] a, int start, int end) {&lt;br /&gt;    int root = start;&lt;br /&gt;&lt;br /&gt;    //While the root has at least one child...&lt;br /&gt;    while( root *2 + 1 &amp;lt;= end ) {&lt;br /&gt;      //root*2 points to the left child&lt;br /&gt;      int child = root * 2 + 1;&lt;br /&gt;&lt;br /&gt;      //If the child has a sibling and the child's value is less than its sibling's...&lt;br /&gt;      if( child + 1 &amp;lt;= end &amp;amp;&amp;amp; a[child] &amp;lt; a[child+1] ) {&lt;br /&gt;        //Then point to the right child instead&lt;br /&gt;        child = child+1;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      //If out of max heap order...&lt;br /&gt;      if( a[root] &amp;lt; a[child] ) {&lt;br /&gt;        //Then repeat to continue sifting down the child now&lt;br /&gt;        a = swap(a, root, child);&lt;br /&gt;        root = child;&lt;br /&gt;      } else {&lt;br /&gt;        return a;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    return a;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/textarea&gt;&lt;/div&gt;With the Heapsort explanation out of the way, here is the article.  It's very clear and well written by Guido van Rossum, the creator of Python.  &lt;a href="http://neopythonic.blogspot.com/2008/10/sorting-million-32-bit-integers-in-2mb.html"&gt;Here is the link&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In the comments, someone pointed out the link to a faster algorithm, which you can &lt;a href="http://news.ycombinator.com/item?id=341037"&gt;read about here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Guido van Rossum replied with:&lt;br /&gt;&lt;br /&gt;"That's a cool way of doing it, but not for Python, where an int takes 12 bytes and the list takes another 4 bytes per value. Given some other overhead you'd end up having to make a lot of passes over the full input (the same number as would be feasible with my version -- I used 100 but it could likely be less), which would probably be slower. It's interesting that a heap features in both algorithms. I'm not convinced that it's the fastest way to sort though, despite the O(N log N) complexity. Python's built-in sort is wicked."&lt;br /&gt;&lt;br /&gt;By the way, if you like reading articles about problem solving using programming, I suggest you also read &lt;a href="http://norvig.com/sudoku.html"&gt;Solving Every Sudoku Puzzle&lt;/a&gt; and &lt;a href="http://norvig.com/spell-correct.html"&gt;How to Write a Spelling Checker&lt;/a&gt;, both by Peter Norvig.  They're very good articles.  Does anyone know about any other very well written problem solving articles?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-5465825065323996687?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/5465825065323996687/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=5465825065323996687' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/5465825065323996687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/5465825065323996687'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2009/04/sorting-million-integers.html' title='Sorting A Million Integers'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-4531116609407157981</id><published>2009-03-24T19:36:00.000-07:00</published><updated>2010-01-10T21:35:18.876-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Manga Meeya</title><content type='html'>&lt;img style="display:block; margin:0px auto 10px; text-align:center;width: 625px; height: 500px;" src="http://aswembar.net/misc/MangaMeeya/MangaMeeyaSample.png" border="0" alt="" /&gt;&lt;br /&gt;A while ago, &lt;a href="http://jdiscar.blogspot.com/2007/05/cdisplay.html"&gt;I wrote a post about CDisplay&lt;/a&gt;, an awesome Comic Book Reading Tool.  I had several problems with it (such as its non customizable shortcuts, full screen mode that didn't work with my dual screens, random crashes while opening certain archives, difficulty in dealing with archives within archives...), but I didn't think that anything better existed out there.  I tried CDisplayEx, but that was way worse.  I was even tempted to write my own manga viewer called "CDisplayEx+Alpha."  But there's no need, because I found MangaMeeya, which is everything I ever wanted in a comic reader and more.&lt;br /&gt;&lt;br /&gt;My favorite features about MangaMeeya are its ability to display two pages at once, its smart look ahead feature, its ability to view pages either left-to-right or right-to-left, its fit-to-page image resizing, its ability to automatically deal with compressed files, and its customizability.  On top of all that, MangaMeeya is blazingly fast.  In addition to comic reading, it works really well as a generic image viewer... you can even delete images using MangaMeeya and use it to organize your galleries.  I really can't even imagine a better sequential image viewing tool.&lt;br /&gt;&lt;br /&gt;I don't really know the history of MangaMeeya or where it came from.  I don't even know its home page.  I think that it's a Japanese commercial product, but that development has ended over some copyright dispute.  At some point, some guy unofficially translated it into English.  If anyone has more information about MangaMeeya, please let me know, since I would like to pay for the program.&lt;br /&gt;&lt;br /&gt;Link to Download English MangaMeeya:&amp;nbsp;&amp;nbsp;&lt;a href="http://aswembar.net/misc/MangaMeeya/MangaMeeyaCE%20-%20English.zip"&gt;Download Here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Context Menu&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Although its internal file browser is nice, you will definitely want to add MangaMeeya to your right click context menu.  That'll allow you to right click on any file or folder and have it open in MangaMeeya.  You can do this by going into the registry and adding new shell commands to the '*' and 'Folder' extensions.  Or you can &lt;a href="http://misc.relic19.net/CMangaMeeyaContext.zip"&gt;download this batch file I wrote&lt;/a&gt; and then run it in the directory where MangaMeeyaCE-English.exe is located.  I've tested it on Windows XP SP2, Windows XP SP3, and Windows Vista.  It will modify your registry, but I can't imagine how it could ruin anything.  Still, I assume no responsibility if you somehow use it to wreck your system.  The context item will be named CMangaMeeya, which should always put it near the top of your right click list.&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;div class="header"&gt;CMangaMeeya.bat&lt;/div&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;"&gt;view plain&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;"&gt;copy to clipboard&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;"&gt;print&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('About',this);return false;"&gt;?&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-xml" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;@echo&amp;nbsp;off&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;if&amp;nbsp;not&amp;nbsp;exist&amp;nbsp;MangaMeeyaCE-English.exe&amp;nbsp;(&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;MangaMeeyaCE-English.exe&amp;nbsp;Not&amp;nbsp;Found&amp;nbsp;In&amp;nbsp;Current&amp;nbsp;Directory.&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;echo&amp;nbsp;Please&amp;nbsp;run&amp;nbsp;this&amp;nbsp;file&amp;nbsp;in&amp;nbsp;the&amp;nbsp;MangaMeeya&amp;nbsp;Directory!&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;echo.&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;pause&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;exit&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;echo&amp;nbsp;Creating&amp;nbsp;Registry&amp;nbsp;file...&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;echo&amp;nbsp;Windows&amp;nbsp;Registry&amp;nbsp;Editor&amp;nbsp;Version&amp;nbsp;5.00&amp;nbsp;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;mangameeya.reg&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;echo.&amp;nbsp;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;mangameeya.reg&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;echo&amp;nbsp;[HKEY_CLASSES_ROOT\Folder\shell]&amp;nbsp;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;mangameeya.reg&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;echo&amp;nbsp;[HKEY_CLASSES_ROOT\Folder\shell\CMangaMeeya]&amp;nbsp;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;mangameeya.reg&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;echo&amp;nbsp;[HKEY_CLASSES_ROOT\Folder\shell\CMangaMeeya\command]&amp;nbsp;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;mangameeya.reg&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;echo&amp;nbsp;@="\"%cd:\=\\%\\MangaMeeyaCE-English.exe\"&amp;nbsp;\"%%1\""&amp;nbsp;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;mangameeya.reg&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;echo.&amp;nbsp;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;mangameeya.reg&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;echo&amp;nbsp;[HKEY_CLASSES_ROOT\*\shell]&amp;nbsp;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;mangameeya.reg&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;echo&amp;nbsp;[HKEY_CLASSES_ROOT\*\shell\CMangaMeeya]&amp;nbsp;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;mangameeya.reg&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;echo&amp;nbsp;[HKEY_CLASSES_ROOT\*\shell\CMangaMeeya\command]&amp;nbsp;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;mangameeya.reg&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;echo&amp;nbsp;@="\"%cd:\=\\%\\MangaMeeyaCE-English.exe\"&amp;nbsp;\"%%1\""&amp;nbsp;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span class="tag"&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;mangameeya.reg&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;regedit&amp;nbsp;/s&amp;nbsp;mangameeya.reg&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;echo&amp;nbsp;Successfully&amp;nbsp;Added&amp;nbsp;Manga&amp;nbsp;Meeya&amp;nbsp;to&amp;nbsp;Context&amp;nbsp;Menu&amp;nbsp;as&amp;nbsp;CMangaMeeya!&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;pause&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;@echo off&lt;br /&gt;if not exist MangaMeeyaCE-English.exe (&lt;br /&gt;  echo MangaMeeyaCE-English.exe Not Found In Current Directory.&lt;br /&gt;  echo Please run this file in the MangaMeeya Directory!&lt;br /&gt;  echo.&lt;br /&gt;  pause&lt;br /&gt;  exit&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;echo Creating Registry file...&lt;br /&gt;&lt;br /&gt;echo Windows Registry Editor Version 5.00 &amp;gt; mangameeya.reg&lt;br /&gt;echo. &amp;gt;&amp;gt; mangameeya.reg&lt;br /&gt;echo [HKEY_CLASSES_ROOT\Folder\shell] &amp;gt;&amp;gt; mangameeya.reg&lt;br /&gt;echo [HKEY_CLASSES_ROOT\Folder\shell\CMangaMeeya] &amp;gt;&amp;gt; mangameeya.reg&lt;br /&gt;echo [HKEY_CLASSES_ROOT\Folder\shell\CMangaMeeya\command] &amp;gt;&amp;gt; mangameeya.reg&lt;br /&gt;echo @="\"%cd:\=\\%\\MangaMeeyaCE-English.exe\" \"%%1\"" &amp;gt;&amp;gt; mangameeya.reg&lt;br /&gt;echo. &amp;gt;&amp;gt; mangameeya.reg&lt;br /&gt;echo [HKEY_CLASSES_ROOT\*\shell] &amp;gt;&amp;gt; mangameeya.reg&lt;br /&gt;echo [HKEY_CLASSES_ROOT\*\shell\CMangaMeeya] &amp;gt;&amp;gt; mangameeya.reg&lt;br /&gt;echo [HKEY_CLASSES_ROOT\*\shell\CMangaMeeya\command] &amp;gt;&amp;gt; mangameeya.reg&lt;br /&gt;echo @="\"%cd:\=\\%\\MangaMeeyaCE-English.exe\" \"%%1\"" &amp;gt;&amp;gt; mangameeya.reg&lt;br /&gt;&lt;br /&gt;regedit /s mangameeya.reg&lt;br /&gt;&lt;br /&gt;echo Successfully Added Manga Meeya to Context Menu as CMangaMeeya!&lt;br /&gt;&lt;br /&gt;pause&lt;/textarea&gt;&lt;/div&gt;&lt;span style="font-weight:bold;"&gt;My CDisplay Clone Set Up&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Since I've used CDisplay for a few years, I've gotten used to many of its key shortcuts.  Since MangaMeeya is so customizable, I switched many of the key shortcuts to be more CDisplay-like.  If you're in the same boat as me, feel free to use my configuration settings.  Simply download my file and swap it with the file in your MangaMeeya directory.&lt;br /&gt;&lt;br /&gt;My Configuration Settings File:&amp;nbsp;&amp;nbsp;&lt;a href="http://misc.relic19.net/MangaMeeyaCE.ini"&gt;Download Here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;My Frequently Used Commands:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Right Arrow&lt;/span&gt;: Goes to the next section or page.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Left Arrow&lt;/span&gt;: Goes to the previous section or page.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Ctrl+l&lt;/span&gt;: Foes to the next directory or compressed file.  It's a lowercase 'L', not the number one.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Ctrl+Shift+l&lt;/span&gt;: Goes to the preview directory or compressed file.  It's a lowercase 'L', not the number one.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;l&lt;/span&gt;: Allows you to select a folder to open.  It's a lowercase 'L', not the number one.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;o&lt;/span&gt;: Allows you to select a file to open.  It's a lowercase 'O', not the number zero.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;`&lt;/span&gt;: Exits the program&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Ctrl+Return&lt;/span&gt;: Switches between full screen mode and Windowed mode.&lt;br /&gt;&lt;br /&gt;Well, if you read comics on your computer, I hope that you give MangaMeeya a try.  It's definitely worth it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-4531116609407157981?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/4531116609407157981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=4531116609407157981' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4531116609407157981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4531116609407157981'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2009/03/manga-meeya.html' title='Manga Meeya'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-6660182387213918894</id><published>2009-03-12T21:38:00.000-07:00</published><updated>2009-03-24T20:42:05.622-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Simple Anagrammer</title><content type='html'>While watching my family feverishly play word jumble one day, I decided to write a program to list anagrams.  They're still addicted to that game, but I've long since finished up my program.  Although it wasn't much effort, I thought I'd go over what I came up with.  I wrote code to find single word anagrams, sub anagrams, and multi word anagrams.  Since those may be my own nomenclature, I'll explain more clearly.  What I'm calling a Single Word Anagram is a single word made up from all the letters of one or more words, such as "cat" to "act" and "resume" to "sure me."  What I'm calling Sub Anagrams are possible shorter words made up from one or more words, such as "cat" to "catharsis" and "user" to "sure me."  What I'm calling Multi Word anagrams are two or more words made up from all the letters of , such as "sure me" to "resume."  Now let's get into my implementation.  You should know that my implementation does assume you're more concerned about processing time than memory space.&lt;br /&gt;&lt;br /&gt;Also, I originally wrote the code in java, but that language is not very suited for code snippets... it's so, so verbose.  So all my code examples are going to be in ruby, with an emphasis of being as concise as possible.  I left out all the optimizations I did for my java program, I'm only intending to give a general example of how the code works.  So the code runs very, very slowly for long words.  But, you'll get the idea of what's going on.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Word List&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Before I get into my algorithms, I should go over obtaining a good word list, which is probably the most important step.  A word list is exactly what it sounds like and it's what you'll use to determine if a word is real or not.  There are lots of word lists out there and you should choose one depending on how thorough you want to be and what language you want to use.  There's one in /usr/dict/words if you're using unix, but &lt;a href="http://bugs.opensolaris.org/view_bug.do;jsessionid=9e7ec0f28038d47bc703ac62d3c3?bug_id=4628215"&gt;it isn't very good&lt;/a&gt;.  I like the &lt;a href="http://wordlist.sourceforge.net/"&gt;very flexible set I found at word list called scowl&lt;/a&gt;.  It gives you a lot of different word lists you can pick and choose from.  The word lists are found in "[scowl home]\final"; they're arranged by a description followed by their part number.  A part number of 10 includes a small set of very common words, a part number of 95 contains a very large set of uncommon words.  No two sets for a description contain the same word.  For my word list, I used english-words.10, english-words.20, english-words.30, and english-words.40.  You can trim down the word lists however you want.&lt;br /&gt;&lt;br /&gt;By the way, I also found &lt;a href="http://wordnet.princeton.edu/obtain"&gt;a word list at wordnet&lt;/a&gt; that you can also use as a dictionary for looking up definitions.  It's free, which is nice.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Single Word Anagrams&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After you have your word list, you need a good algorithm.  Let's say you want to find all the anagrams of a word.  The most straightforward solution is to find all the permutations of the letters in that word and then figure out which ones are real by comparing to your word list.  Of course, this is horribly inefficient.  I mean, for every n length word you're doing n! comparisons.  It's doable on today's machines, just very, very slow.&lt;br /&gt;&lt;br /&gt;A better solution is to create a special dictionary (/hash table) for yourself.  The key will be the letters of a word arranged alphabetically, the value will be a list of words with that key.  So, for example, the key "abt" will contain the word list "bat, tab".  You'll have to iterate over your whole word list to create the dictionary, which will take a few seconds, but it is a one time thing.  And once it's created, listing the anagram is as easy as arranging the letters of your target word alphabetically and looking it up in the dictionary you created.  Make sure everything is lower case for your comparisons.&lt;br /&gt;&lt;br /&gt;Here's my ruby code:&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;div class="header"&gt;AnagrammerBySort.rb - Part 1&lt;/div&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;"&gt;view plain&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;"&gt;copy to clipboard&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;"&gt;print&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('About',this);return false;"&gt;?&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-rb" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;words&amp;nbsp;text&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;text.downcase.scan(/['\w]+/)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;getWordKey&amp;nbsp;word&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;word.split(&lt;/span&gt;&lt;span class="string"&gt;""&lt;/span&gt;&lt;span&gt;).sort!.to_s.strip&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;train&amp;nbsp;features&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;model&amp;nbsp;=&amp;nbsp;&lt;span class="builtin"&gt;Hash&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;{|hash,key|&amp;nbsp;hash[key]&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="builtin"&gt;Array&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;features.&lt;span class="keyword"&gt;each&lt;/span&gt;&lt;span&gt;&amp;nbsp;{|f|&amp;nbsp;model[getWordKey(f)].push(f)}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;model&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;NWORDS&amp;nbsp;=&amp;nbsp;train(words(&lt;span class="builtin"&gt;File&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class="string"&gt;"words.txt"&lt;/span&gt;&lt;span&gt;).read))&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;singleWordAnagram&amp;nbsp;word&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;NWORDS[getWordKey(word)]&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;def words text&lt;br /&gt;  text.downcase.scan(/['\w]+/)&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def getWordKey word&lt;br /&gt;  return word.split("").sort!.to_s.strip&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def train features&lt;br /&gt;  model = Hash.new{|hash,key| hash[key] = Array.new}&lt;br /&gt;  features.each {|f| model[getWordKey(f)].push(f)}&lt;br /&gt;  return model&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;NWORDS = train(words(File.new("words.txt").read))&lt;br /&gt;&lt;br /&gt;def singleWordAnagram word&lt;br /&gt;  return NWORDS[getWordKey(word)]&lt;br /&gt;end&lt;/textarea&gt;&lt;/div&gt;&lt;span style="font-weight:bold;"&gt;Sub Anagrams&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;To find sub anagrams, you first need to be able to determine if a word is a subset of another word.  Remember that duplicates count for anagrams, in that "aabc" is not a subset of "abcd."  There are many, many ways of checking subsets.  In my ruby code example, I just went for the most concise way.  It actually performs really poorly.&lt;br /&gt;&lt;br /&gt;Once you have a way to determine subsets, all you need to do is iterate over all the keys in your anagram dictionary to determine if they are subsets of your target word.  You could also create a new dictionary that maps all words in your word list to their sub anagrams, which would make many future sub anagram lookups instant (it won't be instant for words you haven't seen before.)&lt;br /&gt;&lt;br /&gt;Here's my ruby code:&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;div class="header"&gt;AnagrammerBySort.rb - Part 2&lt;/div&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;"&gt;view plain&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;"&gt;copy to clipboard&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;"&gt;print&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('About',this);return false;"&gt;?&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-rb" start="21"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;#&amp;nbsp;Whether&amp;nbsp;word1&amp;nbsp;a&amp;nbsp;subset&amp;nbsp;of&amp;nbsp;word2,&amp;nbsp;duplicates&amp;nbsp;are&amp;nbsp;not&amp;nbsp;ignored.&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;isSubset(&amp;nbsp;word1,&amp;nbsp;word2&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;word1.split(&lt;span class="string"&gt;""&lt;/span&gt;&lt;span&gt;).uniq.&lt;/span&gt;&lt;span class="keyword"&gt;each&lt;/span&gt;&lt;span&gt;&amp;nbsp;{&amp;nbsp;|f|&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;false&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(word1.count(f)&amp;nbsp;&amp;gt;&amp;nbsp;word2.count(f))&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;true&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;subAnagrams&amp;nbsp;word&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;solution&amp;nbsp;=&amp;nbsp;&lt;span class="builtin"&gt;Array&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;NWORDS.keys.&lt;span class="keyword"&gt;each&lt;/span&gt;&lt;span&gt;&amp;nbsp;{|f|&amp;nbsp;solution.push(NWORDS[f])&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(isSubset(f,word))&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;solution.flatten!&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;# Whether word1 a subset of word2, duplicates are not ignored.&lt;br /&gt;def isSubset( word1, word2 )&lt;br /&gt;  word1.split("").uniq.each { |f| &lt;br /&gt;    return false if(word1.count(f) &amp;gt; word2.count(f)) &lt;br /&gt;  }&lt;br /&gt;  return true&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def subAnagrams word&lt;br /&gt;  solution = Array.new&lt;br /&gt;  NWORDS.keys.each {|f| solution.push(NWORDS[f]) if(isSubset(f,word)) }&lt;br /&gt;  return solution.flatten!&lt;br /&gt;end&lt;/textarea&gt;&lt;/div&gt;(Edit: I found this page which explains a much faster (although much more memory intensive) method for finding Sub Anagrams that uses a tree algorithm *somewhat* similar to a tree.  If you want to get deeper into anagrams, you should definitely &lt;a href="http://blog.notdot.net/2007/10/Damn-Cool-Algorithms-Part-3-Anagram-Trees"&gt;take a look at it&lt;/a&gt; as well as &lt;a href="http://blog.notdot.net/2007/10/Update-on-Anagram-Trees"&gt;its follow up&lt;/a&gt;.  The comments are really useful to read too.)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Multi Word Anagrams&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Multi Word Anagrams are easy after knowing how to make single word anagrams and sub anagrams.  This is how I did it:&lt;br /&gt;&lt;br /&gt;1) Make a candidate list of all possible sub anagrams of your target word.&lt;br /&gt;2) Iterate the candidate list.  In each iteration, remove the first word on the candidate list and compare it to all other words on the candidate list.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;A) Add a combination of the words (Word A Word B) to the candidate list if they are a subset of the target word.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;B) Record all words that have the same key as the target word key.&lt;br /&gt;3) All the words you've recorded is your solution.&lt;br /&gt;&lt;br /&gt;This has to be done carefully or you'll quickly run out of memory.  You should add logic to make sure a word is added to the list only if you want to evaluate it later.&lt;br /&gt;&lt;br /&gt;Here's my ruby code:&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;div class="header"&gt;AnagrammerBySort.rb - Part 3&lt;/div&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;"&gt;view plain&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;"&gt;copy to clipboard&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;"&gt;print&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('About',this);return false;"&gt;?&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-rb" start="35"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;multiWordAnagrams&amp;nbsp;word&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;solution&amp;nbsp;=&amp;nbsp;&lt;span class="builtin"&gt;Array&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;candidates&amp;nbsp;=&amp;nbsp;subAnagrams(word)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;while&lt;/span&gt;&lt;span&gt;&amp;nbsp;candidates.size&amp;nbsp;&amp;gt;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;nbsp;=&amp;nbsp;candidates.delete(candidates[0])&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;candidates.&lt;span class="keyword"&gt;each&lt;/span&gt;&lt;span&gt;&amp;nbsp;{|g|&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(&amp;nbsp;getWordKey(word)&amp;nbsp;==&amp;nbsp;getWordKey(f+&lt;/span&gt;&lt;span class="string"&gt;"&amp;nbsp;"&lt;/span&gt;&lt;span&gt;+g)&amp;nbsp;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;solution.push(f+&lt;span class="string"&gt;"&amp;nbsp;"&lt;/span&gt;&lt;span&gt;+g)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;elsif&lt;/span&gt;&lt;span&gt;(&amp;nbsp;isSubset(&amp;nbsp;getWordKey(f+&lt;/span&gt;&lt;span class="string"&gt;"&amp;nbsp;"&lt;/span&gt;&lt;span&gt;+g),&amp;nbsp;getWordKey(word)&amp;nbsp;)&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;candidates.push(f+&lt;span class="string"&gt;"&amp;nbsp;"&lt;/span&gt;&lt;span&gt;+g)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;solution&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;#&amp;nbsp;Testing&amp;nbsp;#&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;require&amp;nbsp;&lt;span class="string"&gt;'pp'&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;print&amp;nbsp;&lt;span class="string"&gt;"Enter&amp;nbsp;word:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;word&amp;nbsp;=&amp;nbsp;gets.strip&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;print&amp;nbsp;&lt;span class="string"&gt;"Single&amp;nbsp;Anagrams:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;pp&amp;nbsp;singleWordAnagram(word)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;print&amp;nbsp;&lt;span class="string"&gt;"Sub&amp;nbsp;Anagrams:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;pp&amp;nbsp;subAnagrams(word)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;print&amp;nbsp;&lt;span class="string"&gt;"Multi&amp;nbsp;Word&amp;nbsp;Anagrams:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;pp&amp;nbsp;multiWordAnagrams(word)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;def multiWordAnagrams word&lt;br /&gt;  solution = Array.new&lt;br /&gt;  candidates = subAnagrams(word)&lt;br /&gt;  while candidates.size &amp;gt; 0    &lt;br /&gt;    f = candidates.delete(candidates[0])&lt;br /&gt;    candidates.each {|g|    &lt;br /&gt;      if( getWordKey(word) == getWordKey(f+" "+g) ) &lt;br /&gt;        solution.push(f+" "+g)&lt;br /&gt;      elsif( isSubset( getWordKey(f+" "+g), getWordKey(word) ) )&lt;br /&gt;        candidates.push(f+" "+g)&lt;br /&gt;      end&lt;br /&gt;    }&lt;br /&gt;  end&lt;br /&gt;  return solution&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# Testing #&lt;br /&gt;require 'pp';&lt;br /&gt;print "Enter word: "; word = gets.strip&lt;br /&gt;print "Single Anagrams: "; pp singleWordAnagram(word)&lt;br /&gt;print "Sub Anagrams: "; pp subAnagrams(word)&lt;br /&gt;print "Multi Word Anagrams: "; pp multiWordAnagrams(word)&lt;/textarea&gt;&lt;/div&gt;&lt;span style="font-weight:bold;"&gt;Alternative Dictionary&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I think alphabetical keys work very well for full word anagrams, but not as well for sub anagrams.  The solution I preferred involved using a different key for the anagram dictionary.  First assign each letter of the alphabet a prime number greater than 1.  'a' can be 2, 'b' can be 3, and so on.  All characters you don't care about (such as apostraphes, periods, and spaces) should be assigned 1.  You can find a list of prime numbers &lt;a href="http://primes.utm.edu/lists/small/1000.txt"&gt;here&lt;/a&gt;.  Use the smallest numbers you can, otherwise you'll have bigger problems later.  The key for the new dictionary will be the product of the letters in the word.  Like before, the value will be a list of words sharing the key.  Since you're multiplying prime numbers, you'll know that if Word A / Word B is 0, then the words are anagrams of each other.  If Word A % Word B is 0, then the Word A is a sub anagram of Word B.  To determine sub anagrams, traverse all the keys in your dictionary and find the anagram lists that divide into the target word key evenly.  Finding Multi Word Anagrams will also be basically the same as before, but switching out the way you determined words are anagrams or sub anagrams.&lt;br /&gt;&lt;br /&gt;One thing to watch out for with the prime number method is the size the of the key.  In java, a 32 Bit Int won't even hold the word resume.  I used a long, but even that has issues if I'm trying to find the anagrams for a sentence, much less a paragraph.  You can use code to deal with really large numbers or you can just just report an error if the word can't be represented.  How you deal with this problem is up to you.&lt;br /&gt;&lt;br /&gt;I admit, the prime number algorithm doesn't actually go noticably faster, although there should be significantly less comparisons being made.  Furthermore, it does have a limit in the words based on the maximum size of the key.  I still like this algorithm better.  Anyways, here's the code using the prime number methodology:&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;div class="header"&gt;AnagrammerByPrime.rb&lt;/div&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;"&gt;view plain&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;"&gt;copy to clipboard&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;"&gt;print&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('About',this);return false;"&gt;?&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-rb" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;#!/usr/bin/ruby&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;LETTERS&amp;nbsp;=&amp;nbsp;{&amp;nbsp;&lt;span class="string"&gt;'a'&lt;/span&gt;&lt;span&gt;=&amp;gt;2,&lt;/span&gt;&lt;span class="string"&gt;'b'&lt;/span&gt;&lt;span&gt;=&amp;gt;3,&lt;/span&gt;&lt;span class="string"&gt;'c'&lt;/span&gt;&lt;span&gt;=&amp;gt;5,&lt;/span&gt;&lt;span class="string"&gt;'d'&lt;/span&gt;&lt;span&gt;=&amp;gt;7,&lt;/span&gt;&lt;span class="string"&gt;'e'&lt;/span&gt;&lt;span&gt;=&amp;gt;11,&lt;/span&gt;&lt;span class="string"&gt;'f'&lt;/span&gt;&lt;span&gt;=&amp;gt;13,&lt;/span&gt;&lt;span class="string"&gt;'g'&lt;/span&gt;&lt;span&gt;=&amp;gt;17,&lt;/span&gt;&lt;span class="string"&gt;'h'&lt;/span&gt;&lt;span&gt;=&amp;gt;19,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="string"&gt;'i'&lt;/span&gt;&lt;span&gt;=&amp;gt;23,&lt;/span&gt;&lt;span class="string"&gt;'j'&lt;/span&gt;&lt;span&gt;=&amp;gt;29,&lt;/span&gt;&lt;span class="string"&gt;'k'&lt;/span&gt;&lt;span&gt;=&amp;gt;31,&lt;/span&gt;&lt;span class="string"&gt;'l'&lt;/span&gt;&lt;span&gt;=&amp;gt;37,&lt;/span&gt;&lt;span class="string"&gt;'m'&lt;/span&gt;&lt;span&gt;=&amp;gt;41,&lt;/span&gt;&lt;span class="string"&gt;'n'&lt;/span&gt;&lt;span&gt;=&amp;gt;43,&lt;/span&gt;&lt;span class="string"&gt;'o'&lt;/span&gt;&lt;span&gt;=&amp;gt;47,&lt;/span&gt;&lt;span class="string"&gt;'p'&lt;/span&gt;&lt;span&gt;=&amp;gt;53,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="string"&gt;'q'&lt;/span&gt;&lt;span&gt;=&amp;gt;59,&lt;/span&gt;&lt;span class="string"&gt;'r'&lt;/span&gt;&lt;span&gt;=&amp;gt;61,&lt;/span&gt;&lt;span class="string"&gt;'s'&lt;/span&gt;&lt;span&gt;=&amp;gt;67,&lt;/span&gt;&lt;span class="string"&gt;'t'&lt;/span&gt;&lt;span&gt;=&amp;gt;71,&lt;/span&gt;&lt;span class="string"&gt;'u'&lt;/span&gt;&lt;span&gt;=&amp;gt;73,&lt;/span&gt;&lt;span class="string"&gt;'v'&lt;/span&gt;&lt;span&gt;=&amp;gt;79,&lt;/span&gt;&lt;span class="string"&gt;'w'&lt;/span&gt;&lt;span&gt;=&amp;gt;83,&lt;/span&gt;&lt;span class="string"&gt;'x'&lt;/span&gt;&lt;span&gt;=&amp;gt;89,&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="string"&gt;'y'&lt;/span&gt;&lt;span&gt;=&amp;gt;97,&lt;/span&gt;&lt;span class="string"&gt;'z'&lt;/span&gt;&lt;span&gt;=&amp;gt;101&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;LETTERS.default=1&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="comment"&gt;#&amp;nbsp;Warning:&amp;nbsp;Requiring&amp;nbsp;2&amp;nbsp;Character&amp;nbsp;Minimum,&amp;nbsp;includes&amp;nbsp;apostrophes&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;words&amp;nbsp;text&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;text.downcase.scan(/[&lt;span class="string"&gt;'\w]{1}['&lt;/span&gt;&lt;span&gt;\w]+/)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="comment"&gt;#&amp;nbsp;Warning:&amp;nbsp;Not&amp;nbsp;checking&amp;nbsp;for&amp;nbsp;value&amp;nbsp;overflows&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;getWordKey&amp;nbsp;word&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;product&amp;nbsp;=&amp;nbsp;1&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;n&amp;nbsp;=&amp;nbsp;word.length&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;(0..n-1).collect&amp;nbsp;{|c|&amp;nbsp;product&amp;nbsp;*=&amp;nbsp;LETTERS[word[c,1]]&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;product&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;train&amp;nbsp;features&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;model&amp;nbsp;=&amp;nbsp;&lt;span class="builtin"&gt;Hash&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;{|hash,key|&amp;nbsp;hash[key]&amp;nbsp;=&amp;nbsp;&lt;/span&gt;&lt;span class="builtin"&gt;Array&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;features.&lt;span class="keyword"&gt;each&lt;/span&gt;&lt;span&gt;&amp;nbsp;{|f|&amp;nbsp;model[getWordKey(f)].push(f)}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;model&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;NWORDS&amp;nbsp;=&amp;nbsp;train(words(&lt;span class="builtin"&gt;File&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class="string"&gt;"words.txt"&lt;/span&gt;&lt;span&gt;).read))&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;singleWordAnagram&amp;nbsp;word&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;NWORDS[getWordKey(word)]&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;subAnagrams&amp;nbsp;word&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;solution&amp;nbsp;=&amp;nbsp;&lt;span class="builtin"&gt;Array&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;NWORDS.keys.&lt;span class="keyword"&gt;each&lt;/span&gt;&lt;span&gt;&amp;nbsp;{|f|&amp;nbsp;solution.push(NWORDS[f])&amp;nbsp;&lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;(getWordKey(word)%f==0)&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;solution.flatten!&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;def&lt;/span&gt;&lt;span&gt;&amp;nbsp;multiWordAnagrams&amp;nbsp;word&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;solution&amp;nbsp;=&amp;nbsp;&lt;span class="builtin"&gt;Array&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;candidates&amp;nbsp;=&amp;nbsp;subAnagrams(word)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;while&lt;/span&gt;&lt;span&gt;&amp;nbsp;candidates.size&amp;nbsp;&amp;gt;&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;nbsp;=&amp;nbsp;candidates.delete(candidates[0])&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;candidates.&lt;span class="keyword"&gt;each&lt;/span&gt;&lt;span&gt;&amp;nbsp;{&amp;nbsp;|g|&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span&gt;&amp;nbsp;(&amp;nbsp;getWordKey(word)&amp;nbsp;==&amp;nbsp;getWordKey(f+&lt;/span&gt;&lt;span class="string"&gt;"&amp;nbsp;"&lt;/span&gt;&lt;span&gt;+g)&amp;nbsp;)&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;solution.push(f+&lt;span class="string"&gt;"&amp;nbsp;"&lt;/span&gt;&lt;span&gt;+g)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;elsif&lt;/span&gt;&lt;span&gt;(&amp;nbsp;getWordKey(word)&amp;nbsp;%&amp;nbsp;getWordKey(f+&lt;/span&gt;&lt;span class="string"&gt;"&amp;nbsp;"&lt;/span&gt;&lt;span&gt;+g)&amp;nbsp;==&amp;nbsp;0&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;candidates.push(f+&lt;span class="string"&gt;"&amp;nbsp;"&lt;/span&gt;&lt;span&gt;+g)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span class="keyword"&gt;return&lt;/span&gt;&lt;span&gt;&amp;nbsp;solution&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="comment"&gt;#&amp;nbsp;Testing&amp;nbsp;#&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;require&amp;nbsp;&lt;span class="string"&gt;'pp'&lt;/span&gt;&lt;span&gt;;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;print&amp;nbsp;&lt;span class="string"&gt;"Enter&amp;nbsp;word:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;word&amp;nbsp;=&amp;nbsp;gets.strip&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;print&amp;nbsp;&lt;span class="string"&gt;"Single&amp;nbsp;Anagrams:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;pp&amp;nbsp;singleWordAnagram(word)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;print&amp;nbsp;&lt;span class="string"&gt;"Sub&amp;nbsp;Anagrams:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;pp&amp;nbsp;subAnagrams(word)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;print&amp;nbsp;&lt;span class="string"&gt;"Multi&amp;nbsp;Word&amp;nbsp;Anagrams:&amp;nbsp;"&lt;/span&gt;&lt;span&gt;;&amp;nbsp;pp&amp;nbsp;multiWordAnagrams(word)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;#!/usr/bin/ruby&lt;br /&gt;&lt;br /&gt;LETTERS = { 'a'=&amp;gt;2,'b'=&amp;gt;3,'c'=&amp;gt;5,'d'=&amp;gt;7,'e'=&amp;gt;11,'f'=&amp;gt;13,'g'=&amp;gt;17,'h'=&amp;gt;19,&lt;br /&gt;'i'=&amp;gt;23,'j'=&amp;gt;29,'k'=&amp;gt;31,'l'=&amp;gt;37,'m'=&amp;gt;41,'n'=&amp;gt;43,'o'=&amp;gt;47,'p'=&amp;gt;53,&lt;br /&gt;'q'=&amp;gt;59,'r'=&amp;gt;61,'s'=&amp;gt;67,'t'=&amp;gt;71,'u'=&amp;gt;73,'v'=&amp;gt;79,'w'=&amp;gt;83,'x'=&amp;gt;89,&lt;br /&gt;'y'=&amp;gt;97,'z'=&amp;gt;101 }&lt;br /&gt;LETTERS.default=1&lt;br /&gt;&lt;br /&gt;# Warning: Requiring 2 Character Minimum, includes apostrophes&lt;br /&gt;def words text&lt;br /&gt;  text.downcase.scan(/['\w]{1}['\w]+/)&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# Warning: Not checking for value overflows&lt;br /&gt;def getWordKey word&lt;br /&gt;  product = 1&lt;br /&gt;  n = word.length&lt;br /&gt;  (0..n-1).collect {|c| product *= LETTERS[word[c,1]] }&lt;br /&gt;  return product&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def train features&lt;br /&gt;  model = Hash.new{|hash,key| hash[key] = Array.new}&lt;br /&gt;  features.each {|f| model[getWordKey(f)].push(f)}&lt;br /&gt;  return model&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;NWORDS = train(words(File.new("words.txt").read))&lt;br /&gt;&lt;br /&gt;def singleWordAnagram word&lt;br /&gt;  return NWORDS[getWordKey(word)]&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def subAnagrams word&lt;br /&gt;  solution = Array.new&lt;br /&gt;  NWORDS.keys.each {|f| solution.push(NWORDS[f]) if(getWordKey(word)%f==0) }&lt;br /&gt;  return solution.flatten!&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;def multiWordAnagrams word&lt;br /&gt;  solution = Array.new&lt;br /&gt;  candidates = subAnagrams(word)&lt;br /&gt;  while candidates.size &amp;gt; 0 &lt;br /&gt;    f = candidates.delete(candidates[0])&lt;br /&gt;    candidates.each { |g| &lt;br /&gt;      if ( getWordKey(word) == getWordKey(f+" "+g) ) &lt;br /&gt;        solution.push(f+" "+g)&lt;br /&gt;      elsif( getWordKey(word) % getWordKey(f+" "+g) == 0 )&lt;br /&gt;        candidates.push(f+" "+g)&lt;br /&gt;      end&lt;br /&gt;    }&lt;br /&gt;  end&lt;br /&gt;  return solution&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# Testing #&lt;br /&gt;require 'pp';&lt;br /&gt;print "Enter word: "; word = gets.strip&lt;br /&gt;print "Single Anagrams: "; pp singleWordAnagram(word)&lt;br /&gt;print "Sub Anagrams: "; pp subAnagrams(word)&lt;br /&gt;print "Multi Word Anagrams: "; pp multiWordAnagrams(word)&lt;/textarea&gt;&lt;/div&gt;Those are the basic solutions to all the problems I played with.  The above should be good inspiration to make your own anagrammer.  There's still lots of fine tuning and optimizations you can add that I didn't get into.  For example, you may want to ignore words with apostrophes or words less than two characters.  You could work in a multi-threaded fashion as well.  There are also lots of word list tweaks you can do.  There's also a lot of features you can add; fun behavioral tweaks.  For example, you might want to look for sentences from your multi word anagrams by throwing them through a grammar checker.  There are lots of really fun anagrams out there and I'm sure you could write a program to find many more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-6660182387213918894?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/6660182387213918894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=6660182387213918894' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/6660182387213918894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/6660182387213918894'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2009/03/simple-anagrammer.html' title='Simple Anagrammer'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-4898446730308170679</id><published>2009-03-10T18:49:00.000-07:00</published><updated>2009-03-10T18:57:57.310-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tweaks'/><title type='text'>Limited User Accounts</title><content type='html'>I'm usually working on a Solaris machine at work, but occasionally I need to use Windows.  I don't do much development on it, but I use it a lot for creating presentations, reports, and design documents, as well as sending e-mails.  When I use Windows at work (which isn't really that often), I'm forced to use a machine where I've only got a Limited User Account (LUA).  I understand the account type is necessary the way we're doing things at work.  But it was annoying because the LUA account prevents me from installing a lot of the programs I'm used to having and a lot of the OS tweaks I'm used to doing.&lt;br /&gt;&lt;br /&gt;Apparently, there are a bunch of people who purposefully don't use an Administrator account, primarily for safety reasons.  They've got a website over at &lt;a href="http://nonadmin.editme.com"&gt;http://nonadmin.editme.com&lt;/a&gt; where they explain how they use Windows with an LUA and are still be able to do all their day to day tasks.  That website was an excellent resource.  While it hasn't convinced me to use an LUA at home, I no longer have any complaints about using it at work.  I got all my most important programs installed.  I thought I'd share the two most important workarounds for me.&lt;br /&gt;&lt;br /&gt;1. Installing DLLs&lt;br /&gt;&lt;br /&gt;There's a program called RegSvrEx that will allow you to register your DLLs when you have a LUA.  It's a replacement for RegSvr.  Instead of registering the DLL globally (which is potentially dangerous for everyone, I guess), it has an option to just register the DLL for your account (which can only be dangerous for you.)  So download the program from &lt;a href="http://www.codeproject.com/w2k/regsvrex.asp"&gt;http://www.codeproject.com/w2k/regsvrex.asp&lt;/a&gt; and run it from command line using "&lt;span style="font-weight:bold;"&gt;RegSvrEx /c [path to dll]&lt;/span&gt;".&lt;br /&gt;&lt;br /&gt;2. Adding Right Click Options&lt;br /&gt;&lt;br /&gt;Notepad sucks.  It really, really sucks.  Not only will it mess up UNIX text files, it takes forever to open large files, looks really ugly... man, Notepad isn't good for much.  As a text editor, I usually use Textpad.  I couldn't get Textpad to install with an LUA, so I went with Notepad++, which is also excellent.  But everything still opens with Notepad.  Bah.  This workaround allowed me to add Notepad++ to my right click menu, which saved me from so many "Open With" dialogues.  It's really simple to do.  Create a "notepadplus.reg" file with the following contents for your preferred editor and then execute it.  This script is easily modifiable for whichever program you want to add to your menu.  Please note that you will be modifying your registry:&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;div class="header"&gt;notepadplus.reg&lt;/div&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;"&gt;view plain&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;"&gt;copy to clipboard&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;"&gt;print&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('About',this);return false;"&gt;?&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-c" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;Windows&amp;nbsp;Registry&amp;nbsp;Editor&amp;nbsp;Version&amp;nbsp;5.00&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;[HKEY_CLASSES_ROOT\*\shell]&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;[HKEY_CLASSES_ROOT\*\shell\[texteditor&amp;nbsp;name]]&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;[HKEY_CLASSES_ROOT\*\shell\[texteditor&amp;nbsp;name]\command]&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;@=&lt;span class="string"&gt;"\"[path&amp;nbsp;to&amp;nbsp;editor,&amp;nbsp;don't&amp;nbsp;forget&amp;nbsp;to&amp;nbsp;escape&amp;nbsp;'\'&amp;nbsp;characters]\"&amp;nbsp;\"%1\""&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;Windows Registry Editor Version 5.00&lt;br /&gt;&lt;br /&gt;[HKEY_CLASSES_ROOT\*\shell]&lt;br /&gt;&lt;br /&gt;[HKEY_CLASSES_ROOT\*\shell\[texteditor name]]&lt;br /&gt;&lt;br /&gt;[HKEY_CLASSES_ROOT\*\shell\[texteditor name]\command]&lt;br /&gt;@="\"[path to editor, don't forget to escape '\' characters]\" \"%1\""&lt;/textarea&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-4898446730308170679?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/4898446730308170679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=4898446730308170679' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4898446730308170679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4898446730308170679'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2009/03/limited-user-accounts.html' title='Limited User Accounts'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-761475592367430007</id><published>2008-12-05T23:24:00.000-08:00</published><updated>2009-03-12T21:45:26.435-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Syntax Highlighters (Code to Html)</title><content type='html'>Since I'm writing a blog that occasionally contains code, I figured I needed to have a nice way to display code.  This post will go over the solutions I've used.  If you want to search for solutions on your own, the best base term to use is "syntax highlighter."  Of course, the term "syntax highlighter" applies to more than just formatting code for html... but the term "code to html" doesn't return very good results.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Code2Html&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When I first started blogging, I used code2html at &lt;a href="http://www.palfrader.org/code2html"&gt;http://www.palfrader.org/code2html&lt;/a&gt;.  It's a fully functional syntax highlighter... but the result really isn't that pretty.  It's actually very bare bones.  But it was pretty easy to use.  You can do the "code to html"-ing on their website or you can download a stand alone application (it's a perl script) to do the conversion offline.  The documentation is good and I had no problem using it.  I could easily produce the following code example:&lt;pre&gt;&lt;a name="line1"&gt;1&lt;/a&gt; &lt;font color="a52a2a"&gt;&lt;strong&gt;alert&lt;/strong&gt;&lt;/font&gt;(&lt;font color="#008000"&gt;&amp;quot;Hello World!&amp;quot;&lt;/font&gt;)&lt;/pre&gt;&lt;span style="font-weight:bold;"&gt;Ruby Rio and Syntax&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I really didn't have a problem with using code2html until I started getting interested in ruby, which led me to find blogs with code examples like this (I'm using an image as the example for convenience in this case):&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_XSrd14MaFHQ/SToqLRRCYWI/AAAAAAAAAAU/DXa0ANjJhic/s1600-h/riosample.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 433px; height: 93px;" src="http://4.bp.blogspot.com/_XSrd14MaFHQ/SToqLRRCYWI/AAAAAAAAAAU/DXa0ANjJhic/s400/riosample.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5276576286519746914" /&gt;&lt;/a&gt;The entire process to format the ruby code this way is very well described on Wolfmans Howling's blog at &lt;a href="http://blog.wolfman.com/articles/2006/05/26/howto-format-ruby-code-for-blogs"&gt;http://blog.wolfman.com/articles/2006/05/26/howto-format-ruby-code-for-blogs&lt;/a&gt;.  But as cool as it is, it only works well with ruby code, and I eventually decided I needed something to highlight the other languages I use too.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Syntax Highlighter&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;That led me to Syntax Highlighter, which is the solution I currently use.  It's an interesting take on syntax highlighting in that it does the conversions on the fly and is entirely written in javascript.  It goes through the web page's dom tree at load time and replaces any code blocks contained by a "&amp;lt;pre name='code'&amp;gt;" tag and converts its content to syntax highlighted code.  It supports many options, such as line numbering and columns.  Take a look at &lt;a href="http://code.google.com/p/syntaxhighlighter"&gt;http://code.google.com/p/syntaxhighlighter&lt;/a&gt;, the documentation is good and clear.  Syntax Highlighter is very good looking and very simple to use.&lt;br /&gt;&lt;br /&gt;However, I prefer static html code and don't find it inconvenient to have to convert and paste the code myself.  I figured that if I do the highlighting once myself, it's less strain on the user's computer.  I also wanted to add a title to the code block as well as change the appearance a little.  Since all the javascript is freely available, I made a lot of my own modifications to resolve those issues.  It was pretty fun to do and a good javascript exercise for me.  It did take some work to finesse everything, but I think I got it all working correctly.&lt;br /&gt;&lt;br /&gt;You can &lt;a href="http://syntaxhighlighter.relic19.net/StaticSyntaxHighlighter.zip"&gt;download my solution here&lt;/a&gt;.  Because it's a javascript-only solution, you can run it offline.  Just open up the index.html file in your browser, enter your code, and press the convert code link.  Then you can copy the code from the result textbox to whatever page you want.  Just remember to include a css file, shCoreStaticInclude.js, and the clipboard.swf file in whatever page you paste the code on.  I wrote up detailed instructions here.  If you want to give it a try online, I have it at &lt;a href="http://syntaxhighlighter.relic19.net"&gt;http://syntaxhighlighter.relic19.net&lt;/a&gt;.  That page has a much more detailed description of the process I just described.  Here's a sample from my modified syntax highlighter:&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;div class="header"&gt;helloWorld.js&lt;/div&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;"&gt;view plain&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;"&gt;copy to clipboard&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;"&gt;print&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('About',this);return false;"&gt;?&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-c" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;alert(&lt;/span&gt;&lt;span class="string"&gt;"Hello&amp;nbsp;World!"&lt;/span&gt;&lt;span&gt;);&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;alert("Hello World!");&lt;/textarea&gt;&lt;/div&gt;&lt;span style="font-style:italic;"&gt;(Edit: Syntax Highlighter has since updated to version 2.0.  It can be now found at &lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter"&gt;http://alexgorbatchev.com/wiki/SyntaxHighlighter&lt;/a&gt;.  I have no intention of updating my Static Syntax Highlighter at this time.  If substantial enhancements to appearance have been made, I'll consider it, but right the only graphical change I've noticed is the new icon usage for the toolbar.)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Quick Highlighter&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;While I was playing with Syntax Highlighter I came across another top notch syntax highlighter called Quick Highlighter at &lt;a href="http://quickhighlighter.com"&gt;http://quickhighlighter.com&lt;/a&gt;.  It converts code to html, much like code2html.  You can allow the css to be embedded to avoid having to link to a separate css file.  It supports way more languages and formatting options compared to Syntax Highlighter.  It's almost as pretty as Syntax Highlighter too.  The only downside is that it seems to work exclusively through a web interface, which is why I ultimately decided against using it.  Syntax Highlighter is a lot more customizable for me since I can download and muck around with the source code, changing the way it operates, a feat I couldn't as easily do with Quick Highlighter.  However, if I found quickhighlighter before I found any of the other solutions, then I probably would have never switched from it.  Here's a sample from Quick Highlighter:&lt;br /&gt;&lt;br /&gt;&lt;div class="javascript javascript" style="font-family:monospace;color: #006; border: 1px solid #d0d0d0; background-color: #f0f0f0;"&gt;&lt;ol&gt;&lt;li style="font-weight: normal;font: normal normal 130% 'Courier New', Courier, monospace; color: #003030;"&gt;&lt;div style="font-family: monospace; font-weight: normal; font-style: normal; margin:0; padding:0; background:inherit;color: #000020;"&gt;&lt;span style="color: #000066;"&gt;alert&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #3366CC;"&gt;&amp;quot;Hello World!&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;;&lt;/div&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Gist&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I also came across Gist, at &lt;a href="http://gist.github.com/"&gt;http://gist.github.com/&lt;/a&gt;, as a syntax highlighter.  The nicest thing about Gist is that it does all the work for you.  You type in code on their webpage and it gives you code to embed on your webpage.  You don't need to add any extra includes or css files or even register yourself at their website... Gist takes care of everything for you.  It's open source, so you can use your own server if you don't trust Gist.  I like my Syntax Highlighter more because of the appearance and options... but really, it's just my personal taste.  I definitely see the usefulness, in the simple convenience, of this solution.&lt;br /&gt;&lt;br /&gt;To use it, simply go through their website and enter your code to get the embedded code snippet, such as...&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;"&gt;view plain&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;"&gt;copy to clipboard&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;"&gt;print&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('About',this);return false;"&gt;?&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-c" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;&amp;lt;script&amp;nbsp;src=&lt;/span&gt;&lt;span class="string"&gt;"http://gist.github.com/24490.js"&lt;/span&gt;&lt;span&gt;&amp;gt;&amp;lt;/script&amp;gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;&amp;lt;script src="http://gist.github.com/24490.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;/textarea&gt;&lt;/div&gt;Add that code snippet to your html and it will show up as...&lt;br /&gt;&lt;br /&gt;&lt;script src="http://gist.github.com/24490.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;More Highlighters&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here are some other highlighters.  Check them out if you'd like.  I didn't see anything extraordinarily special about them, so I don't want to do full write ups... but options are always nice, I guess.  They have good documentation of their own.  Let me know in the comments if you know of any other syntax highlighters!&lt;br /&gt;&lt;a href="http://wiki.ahnfelt.dk/Highlighter.html"&gt;http://wiki.ahnfelt.dk/Highlighter.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://pygments.org/"&gt;http://pygments.org/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://shjs.sourceforge.net/"&gt;http://shjs.sourceforge.net/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-761475592367430007?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/761475592367430007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=761475592367430007' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/761475592367430007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/761475592367430007'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2008/12/syntax-highlighters-code-to-html.html' title='Syntax Highlighters (Code to Html)'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_XSrd14MaFHQ/SToqLRRCYWI/AAAAAAAAAAU/DXa0ANjJhic/s72-c/riosample.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-1640485948051731130</id><published>2008-11-29T10:41:00.000-08:00</published><updated>2008-11-30T10:07:44.368-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>C Pointers</title><content type='html'>So, do you still get confused about C Pointers?  Don't fret, unless you've had a fair amount of practice, it's understandable not to have it all straight.  But if you want to get them straight fast, I'd suggest you take a half hour and read this excellent three part article on pointers:&lt;br /&gt;&lt;br /&gt;1. &lt;a href="http://www.freshsources.com/19930276.HTM"&gt;http://www.freshsources.com/19930276.HTM&lt;/a&gt;&lt;br /&gt;2. &lt;a href="http://www.freshsources.com/199302BB.HTM"&gt;http://www.freshsources.com/199302BB.HTM&lt;/a&gt;&lt;br /&gt;3. &lt;a href="http://www.freshsources.com/199302F2.HTM"&gt;http://www.freshsources.com/199302F2.HTM&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Need some C pointer reminders?  It's especially good to review them before a major interview if you don't use them every day, since you know they'll probably ask you to reverse a string or something.  So here's a quick review:&lt;br /&gt;&lt;br /&gt;You take the address of something with &amp;amp;:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-style: italic;"&gt; // Address of a is:&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-style: italic;"&gt; ptr = &amp;a;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you've got an address you can "reach into" it with *:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-style: italic;"&gt; // Contents of ptr is *ptr&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-style: italic;"&gt; a = *ptr;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The only odd case is when declaring a pointer. Declare a pointer to an int as:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="font-style: italic;"&gt; int *p;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;which is most easily thought of as "*p is an int."  So if you reach into p with *, then you'll get an int.&lt;br /&gt;&lt;br /&gt;One more time, in rules form:&lt;br /&gt;&lt;br /&gt;1. &amp;amp;: Always takes the address of a variable.  Mentally read &amp;amp; as "address of."&lt;br /&gt;&lt;br /&gt;2. *: There are two cases:&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;a. Declaring types&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;b. Returns the contents of the address stored in a variable.  Mentally read this as "content of."&lt;br /&gt;&lt;br /&gt;Hopefully, you'll never forget your pointers now.  By the way, &lt;a href="http://www.freshsources.com/"&gt;fresh sources&lt;/a&gt; has tons of other good in-depth articles that cover C, C++, and Java.  You should take a look.  And if you're still trying to get comfy with C, but you haven't read and worked through &lt;a href="http://www.amazon.com/Programming-Language-Prentice-Hall-Software/dp/0131103628/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1227727751&amp;amp;sr=8-1"&gt;K&amp;amp;R's C Programming Language&lt;/a&gt;... umm... what are you waiting for?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-1640485948051731130?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/1640485948051731130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=1640485948051731130' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/1640485948051731130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/1640485948051731130'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2008/11/c-pointers.html' title='C Pointers'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-2525521400588126116</id><published>2008-10-19T20:12:00.000-07:00</published><updated>2008-10-19T20:22:44.423-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tweaks'/><title type='text'>Reactivating Dynamic Drives for Windows XP Professional</title><content type='html'>&lt;a href="http://jdiscar.blogspot.com/2008/10/requirements-for-tweaks.html"&gt;Requires: Windows XP Professional and optionally Ruby, AutoIt&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here's a quick thing that I learned and set up.  First, the problem.  I frequently use a usb external hard drive at home.  As a dynamic disk, everytime I plugged the hard drive in I had to right click my computer, select manage, select disk management, select my external hard drive, and reactivate the disk.  Or (after I removed the "My Computer"  icon from my desktop) control panel-&gt;administrative tools-&gt;computer management-&gt;disk management-&gt;external drive-&gt;reactivate disk.  It's not too much of a hassle, but it is stupidly annoying to have to go through that sequence often.  If you have multiple disks that you want to manually individually activate, always have certain dynamic drives plugged in and want them activated at startup, or (like me) you just don't want to touch the mouse if there's another way, then you'd want a way to automate this process.  So I found a way to avoid all the mindless clicking.&lt;br /&gt;&lt;br /&gt;It's not really anything new.  It's just making use of the diskpart command line utility.  Here's documentation on diskpart.  I wrote a small ruby script to run the diskpart for me.  You can use a static batch script and text file to do this as well.  In my actual implementation, I have a different ruby script that makes sure I'm activating the "right" disk.  But this sample solution will always activate disk 1:&lt;br /&gt;&lt;div class="dp-highlighter"&gt;&lt;div class="bar"&gt;&lt;div class="tools"&gt;&lt;div class="header"&gt;activateDynamicDisk.rb&lt;/div&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;"&gt;view plain&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;"&gt;copy to clipboard&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;"&gt;print&lt;/a&gt;&lt;a href="#" onclick="dp.sh.Toolbar.Command('About',this);return false;"&gt;?&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;ol class="dp-rb" start="1"&gt;&lt;li class="alt"&gt;&lt;span&gt;&lt;span&gt;require&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;'win32ole'&lt;/span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;f&amp;nbsp;=&amp;nbsp;&lt;span class="builtin"&gt;File&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;(&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"online.txt"&lt;/span&gt;&lt;span&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"w"&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;f.print(&amp;nbsp;&lt;span class="string"&gt;"select&amp;nbsp;disk&amp;nbsp;1\n"&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;f.print(&amp;nbsp;&lt;span class="string"&gt;"online\n"&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;f.close&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;au3&amp;nbsp;=&amp;nbsp;WIN32OLE.&lt;span class="keyword"&gt;new&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span class="string"&gt;"AutoItX3.Control"&lt;/span&gt;&lt;span&gt;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class="alt"&gt;&lt;span&gt;au3.Run(&amp;nbsp;&lt;span class="string"&gt;"diskpart&amp;nbsp;/s&amp;nbsp;c:\online.txt"&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li class=""&gt;&lt;span&gt;&lt;span class="builtin"&gt;File&lt;/span&gt;&lt;span&gt;.delete(&amp;nbsp;&lt;/span&gt;&lt;span class="string"&gt;"online.txt"&lt;/span&gt;&lt;span&gt;&amp;nbsp;)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;textarea style="display: none;" class="originalCode"&gt;require 'win32ole'&lt;br /&gt;f = File.new( "online.txt", "w" )&lt;br /&gt;f.print( "select disk 1\n" )&lt;br /&gt;f.print( "online\n" )&lt;br /&gt;f.close&lt;br /&gt;au3 = WIN32OLE.new("AutoItX3.Control")&lt;br /&gt;au3.Run( "diskpart /s c:\online.txt" )&lt;br /&gt;File.delete( "online.txt" )&lt;/textarea&gt;&lt;/div&gt;Really easy, eh?  You can easily set it up to run every time windows boots up.  I should also mention dynamic drives only work with Windows XP Pro, so my external drive is unusable with a home edition.  Now, the next trick is figuring out how to run this script whenever I plug the device in.  I wonder how that's done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-2525521400588126116?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/2525521400588126116/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=2525521400588126116' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/2525521400588126116'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/2525521400588126116'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2008/10/reactivating-dynamic-drives-for-windows.html' title='Reactivating Dynamic Drives for Windows XP Professional'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-3944936123964527040</id><published>2008-10-15T22:07:00.000-07:00</published><updated>2008-10-15T22:11:17.228-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tweaks'/><category scheme='http://www.blogger.com/atom/ns#' term='Hacks'/><title type='text'>Requirements for Tweaks</title><content type='html'>On this blog, I'm going to occasionally talk about tweaks I make to my machines (of various OSes.)  When I say tweak, I mean a special configuration or short script to make my computer more suited to my needs.  So basically a hack, but without the bad connotation people give the word "hack" nowadays.&lt;br /&gt;&lt;br /&gt;As I've been reinstalling machines, I've been making notes about what I do to them and thought it would be useful to have an easy to find reference online, so I'll be posting cleaned up versions of these notes.  Each tweak requires a certain environment (OS and programs), so I'm going to go over the common requirements in depth in this post.  That way, when I reference a program, I'll just link here.  I'll add to the following list as needed.  Here's the list so far:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Windows XP Professional (SP2/SP3)&lt;/span&gt; - This is one of Microsoft's Windows Operating System (OS) versions.  I'll leave it up to you to figure out how to get the OS and how to install it.  XP Professional is different than XP Home, so the tweaks I describe may not be compatable with both.  I use Professional myself and don't have access to a Home machine to test things on.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Windows Vista Ultimate&lt;/span&gt; - This is one of Microsoft's Windows Operating System (OS) versions.  It's newer than XP.  I'll leave it up to you to figure out how to get the OS and how to install it.  Vista is different than XP, but many of the tweaks I describe should be compatable with both.  The only version I have access to is Ultimate.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Solaris 10&lt;/span&gt; - This is one of Sun's Solaris Operating System (OS) versions.  It is UNIX based and is notably different from previous versions due to its zones.  This is one of the Operating Systems I use most at work.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;AutoIt&lt;/span&gt; - Auto It is a freeware automation language for Windows.  It allows you to easily simulate a windows user with a script... you can send key presses or text to any windoe application.  AutoIt scripts end with au3.  AutoDownload an installer from &lt;a href="http://www.autoitscript.com/autoit3/"&gt;http://www.autoitscript.com/autoit3/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;PS Hot Launch&lt;/span&gt; - PS Hot Launch is a Windows program that allows you to map keyboard shortcuts to files.  Invoking the keyboard shortcut will execute the file specified.  For example, you can make ctrl-win-w open microsoft word and win-v open your winamp.  Using too many of these is not a good idea because you'll probably start running into conflicts.  But for a few applications, this program can work wonders.  Play around with it.  Download this from: &lt;a href="http://www.pssoftlab.com/pshl_info.phtml"&gt;http://www.pssoftlab.com/pshl_info.phtml&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ruby&lt;/span&gt; - Ruby is a dynamic, reflective, general purpose object-oriented programming language.  It's a scripting language very much like Perl.  Ruby scripts end with either rb or rbw (windowless).  In order to run ruby scripts, you need the Ruby VM.  You can download it from &lt;a href="http://www.ruby-lang.org"&gt;http://www.ruby-lang.org&lt;/a&gt;.  There are installers for all of the popular Operating Systems under downloads.  Once you've installed ruby, add the fxruby gem by running "gem install fxruby" in a command/terminal prompt.  Fxruby is what I use for GUIs.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Batch Files&lt;/span&gt; - A batch file is a Windows text file, with the extension .bat or .cmd, containing a series of commands intended to be executed by the command interpreter.  When a batch file is run, the shell program (usually COMMAND.COM or cmd.exe) reads the file and executes its commands, normally line-by-line.  A batch file is analogous to a shell script in Unix-like operating systems.  When working in windows, it's very useful knowing how to batch script as it allows you to lots of automation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-3944936123964527040?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/3944936123964527040/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=3944936123964527040' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3944936123964527040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3944936123964527040'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2008/10/requirements-for-tweaks.html' title='Requirements for Tweaks'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-5532449868664921921</id><published>2008-10-12T19:51:00.000-07:00</published><updated>2008-10-12T20:03:57.487-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Creating Windows Icons</title><content type='html'>So I'm writing a Windows C# application (I'll talk about it later) and I wanted to use my own icon for it.  I needed a .ico image, Visual Studio wouldn't let me use any other image file types.  I usually use Adobe Photoshop for my editing, but that program doesn't support natively icons.  I found a Photoshop &lt;a href="http://www.telegraphics.com.au/svn/icoformat/trunk/dist/README.html"&gt;plugin for icon files at this website&lt;/a&gt; and it worked perfectly.  There was no hassle at all.&lt;br /&gt;&lt;br /&gt;I created a 16x16 icon and added it to all my forms easily.  I set the icon to be used as the default icon through the project properties (under the application submenu) and that worked perfectly too.  I'm really happy with how it turned out.&lt;br /&gt;&lt;br /&gt;This post was really just to give out the link to the website for the photoshop icon plugin.  Oh yeah, I'm probably going to be posting a good deal of C# stuff for a while since I've been playing with it a lot recently.  Just some fair warning...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-5532449868664921921?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/5532449868664921921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=5532449868664921921' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/5532449868664921921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/5532449868664921921'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2008/10/creating-windows-icons.html' title='Creating Windows Icons'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-4127051793140905125</id><published>2008-10-05T22:30:00.001-07:00</published><updated>2008-10-05T22:54:09.548-07:00</updated><title type='text'>Virii and XP Royale</title><content type='html'>Yeesh, it's been a long time since I posted here.  Like just about everyone, I'm pretty busy... but the "busy-ness" gives me some good things to write about.  So I'll be posting a lot more regularly for a while.&lt;br /&gt;&lt;br /&gt;The most recent "busy-ness" was a full reinstallation of one of my desktop computers.  It wasn't something that I really planned to do... I ended up catching a virus while testing google adsense (some ringtone ad) with an Internet Explorer 5 browser.  I wasn't being that careful on that machine, since I didn't really didn't expect to catch anything through adsense links.  It was a serious virus too.  Like most of them, it put a bunch of adware on the machine (which would pop up sporadically), but it also tried to add some fetching programs and some dll files.  Nasty, nasty... anyways, I didn't entirely trust that the anitvirus on the machine was able to catch everything, so I decided to wipe the whole harddrive (I used Active@KillDisk) and reinstall.  I put on Windows XP Professional SP3 instead of Vista and went through the process of configuring the machine to my needs.  It kinda needed to be done anyway, the machine was getting cluttered and I didn't lose any data since it's not a machine I really use for anything important.&lt;br /&gt;&lt;br /&gt;One nice thing I found while reinstalling was the Windows XP Royale Noir theme.  I like its look better than Windows Vista.  It's a really sleek, black XP theme that I read the developers never fully released.  Someone got a hold of it and finished it up, then made it available.  I liked it so much I switched my main desktop computer to the theme... even though I'm pretty sure it makes the machine run slower.&lt;br /&gt;&lt;br /&gt;Download and check out the theme here: &lt;a href="http://www.softpedia.com/get/Desktop-Enhancements/Themes/Royale-Noir-Theme.shtml"&gt;http://www.softpedia.com/get/Desktop-Enhancements/Themes/Royale-Noir-Theme.shtml&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To use the theme, you will need patch your uxtheme dll by running this program: &lt;a href="http://www.softpedia.com/get/System/OS-Enhancements/UXTheme-MultiPatcher.shtml"&gt;http://www.softpedia.com/get/System/OS-Enhancements/UXTheme-MultiPatcher.shtml&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-4127051793140905125?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/4127051793140905125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=4127051793140905125' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4127051793140905125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4127051793140905125'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2008/10/virii-and-xp-royale.html' title='Virii and XP Royale'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-16369029983718670</id><published>2008-03-25T22:45:00.000-07:00</published><updated>2008-03-25T22:52:47.379-07:00</updated><title type='text'>Binary Interfaces</title><content type='html'>Here's something I dug up from an old folder that may have some merit being posted.  Heh... It's from when I first started working... I've learned a lot about programming since then, so don't judge me for my choices from back then, ok?&lt;br /&gt;&lt;br /&gt;This is the result of research into creating a binary interface for one of our protocols that exclusively used XML strings.  The goal was to pass binary data through XML.  We wanted to use a standard if possible, if not, then something close to a standard.  Today, I'd probably spend all my time arguing to not use XML for binary transfers.  Since we were using Java, Java RMI would have been sufficient for what we were doing back then with very little hassle.  If not, I bet it would be easier to find solutions. &lt;br /&gt;&lt;br /&gt;But here's what I came up with back then:&lt;br /&gt;&lt;br /&gt;Option one is to encode the binary data into XML.  Simply create a tag &lt;data&gt;&lt;/data&gt; and place the bytes in.  The only problem is that XML has a limited character set, so the byte stream will need to be encoded into characters and then decoded after it’s received.  There are different algorithms for encoding.  If large data sets are anticipated to be transferred and the byte value distribution within the set to be skewed, it would be best to go with the Huffman encoding approach (which encodes based on byte frequency).  If we anticipate the data set to be small or we want to make a quick application, it’s best to go with a Base-64 encoding scheme (which encodes based on a standard 3 byte to 4 character scheme).  The better algorithm (Huffman encoding) gives about 1 character per 1 byte of data and the second best, but more popular, algorithm (Base 64) gives about 1.5 characters per one byte of data.  This method is simple, though definitely not ideal due to the overhead of encoding and decoding as well as the not-quite 1 to 1 byte to character conversion.  Also, the encoding is not a standard and so the receiver may not know how to decode the data.&lt;br /&gt;&lt;br /&gt;Option two is a Multipart/Related MIME.  The essential idea for this is to send a MIME multipart/related message over http that can contain multiple types of data, such as xml and an image.  There is a SOAP standard that allows for this (which even allows for the xml to reference the data, which is used if the binary data is to be one of the parameters), though it does not seem to be an XML standard.  However, at this point, there IS no XML standard (according to my research) and this seems to be as close to a standard as anything else.  Multipart/Related MIME messages are currently used for e-mail attachments.&lt;br /&gt;&lt;br /&gt;Option Three is DIME messaging, which is a new specification for handling binary data with SOAP messages (or other messages.)  It doesn't seem to be widespread, but it seems to be getting there.  It is quite similar to Multipart/Related MIME messages, but offers a few key benefits.  Essentially, it sacrifices flexibility for simplicity; so it is faster and simple to create.  Also, it allows to break up large data sets so that they can be sent in chunks.  Furthermore, DIME will have standards that will apply to more than just http.  Microsoft will be motivated to focus on DIME for binary attachments in its future with SOAP tools and platforms.&lt;br /&gt;&lt;br /&gt;Those are the most feasible options found trying to keep the current XML messaging intact.&lt;br /&gt;&lt;br /&gt;Sources:&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnservice/html/service01152002.asp"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnservice/html/service01152002.asp&lt;/a&gt; - DIME&lt;br /&gt;&lt;a href="http://www.w3.org/TR/SOAP-attachments"&gt;http://www.w3.org/TR/SOAP-attachments&lt;/a&gt; - Multipart MIME&lt;br /&gt;&lt;a href="http://www.javaworld.com/javaworld/javatips/jw-javatip117.html?tip"&gt;http://www.javaworld.com/javaworld/javatips/jw-javatip117.html?tip&lt;/a&gt; - Encoding&lt;br /&gt;&lt;br /&gt;We ended up going with Option 1 using the Base 64 approach.  For transferring mostly 70KB files around, it's performed decently.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-16369029983718670?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/16369029983718670/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=16369029983718670' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/16369029983718670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/16369029983718670'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2008/03/binary-interfaces.html' title='Binary Interfaces'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-7396311276507067649</id><published>2008-02-29T21:31:00.001-08:00</published><updated>2008-02-29T21:31:30.281-08:00</updated><title type='text'>TSOL Tomcat 5.5 Installation</title><content type='html'>1.  TOMCAT 5.5.x Installation&lt;br /&gt;&lt;br /&gt;I had this sitting around, I figure someone out there might have a use for it.  And so I present, instructions for installing Tomcat 5.5.x on Trusted Solaris 8:&lt;br /&gt;&lt;br /&gt;1.    Download the Tomcat binary 5.5.x from http://jakarta.apache.org/tomcat/ and extract it into a local directory referred to from here on as $CATALINA_HOME.&lt;br /&gt;&lt;br /&gt;2.    In $CATALINA_HOME, copy the contents of $CATALINA_HOME/conf into $CATALINA_HOME/confOriginal.  Then delete both directories $CATALINA_HOME/logs and $CATALINA_HOME/conf.&lt;br /&gt;&lt;br /&gt;3.    Make multi-level directories for $CATALINA_HOME/logs and $CATALINA_HOME/conf.  Copy all files in $CATALINA_HOME/confOriginal into $CATALINA_HOME/conf under every label you intend to run a server under.&lt;br /&gt;&lt;br /&gt;4.    If using Tomcat 5.5.x and J2SDK 1.4 or 1.3:  Download compat.jar and unzip it in ../$CATALINA_HOME.  Verify that it has placed xercesImpl.jar and xml-apis.jar into $CATALINA_HOME/common/endorsed&lt;br /&gt;&lt;br /&gt;5.    Go into $CATALINA_HOME/bin and run startup.sh.  Verify that the installation was successful by visiting http://localhost:8080 in your web browser.  You should see the Tomcat startup page.  Shutdown by running shutdown.sh in $CATALINA_HOME/bin.&lt;br /&gt;&lt;br /&gt;6.    The 5.5.x version of Tomcat does not come with the admin service.  It can be useful, so install that as well following these steps:&lt;br /&gt;    1. Unzip jakarta-tomcat-5.5.x-admin.zip &amp;amp; copy conf\ and server\ folders and contents over your own Tomcat conf &amp;amp; server folders (into $CATALINA_HOME folder)&lt;br /&gt;    2. Copy $CATALINA_HOME\server\webapps\admin\admin.xml to $CATALINA_HOME\webapps\admin.xml&lt;br /&gt;    3. Add a line to $CATALINA_HOME\conf\tomcat-users.xml to allow a user to login to the manager &amp;amp; admin modules, e.g.: &lt;user username="admin" password="admin1" roles="admin,standard,manager"&gt;&lt;br /&gt;    4. Restart Tomcat&lt;br /&gt;    5. Visit http://localhost:8080/admin and login using admin/admin1&lt;br /&gt;&lt;br /&gt;7.  Verify the installation by visiting http://localhost:8080/admin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-7396311276507067649?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/7396311276507067649/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=7396311276507067649' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7396311276507067649'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7396311276507067649'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2008/02/tsol-tomcat-55-installation.html' title='TSOL Tomcat 5.5 Installation'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-376453275403801156</id><published>2008-01-09T19:07:00.001-08:00</published><updated>2008-12-20T17:13:23.050-08:00</updated><title type='text'>Scanlation Notes</title><content type='html'>This post no longer exists.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-376453275403801156?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/376453275403801156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=376453275403801156' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/376453275403801156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/376453275403801156'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2008/01/scanlation-notes.html' title='Scanlation Notes'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-1960103592855145843</id><published>2007-12-31T20:25:00.001-08:00</published><updated>2008-02-27T08:24:03.274-08:00</updated><title type='text'>Testimony 2007</title><content type='html'>Since it is the Christmas month, where the birth of Christ is celebrated, I thought it would be appropriate to take a break from talking about programming to post my testimony as a Christian.  This is a testimony that I gave in church at what feels like a few months ago, although it may actually have been a year ago.  It was written to be about five minutes long.  Re-reading it, I realize I used a fair amount of Christian lingo, so it might not mean the same thing if you don't know much about Christianity.&lt;br /&gt;&lt;br /&gt;Oh yeah, in case you didn't know (or guess by now), I'm a Christian.  Denominationally... I'd say I'm non-denominational, but if you need to be told a denomination, I guess you could call me methodist.  I basically believe in having a close, personal relationship with the loving God/Jesus/Holy Spirit through prayer, fellowship with other Christians, and studying the bible.  I don't believe I have any business judging other people or forcing my beliefs on others.  However, I won't hide what I believe either and I hope my beliefs show in my everday life because they are the most important part of who I am.  So read it or ignore it, this is my one of many accounts about why I belive in God.  It's not meant to convert anyone or anything like that, just to let you know a little bit more about who I am.  So here goes:&lt;br /&gt;&lt;br /&gt;My parents are both Christian and they brought me up as a Christian.  We had bible studies every night, where my dad read to us from some family devotions book, swapping our names in for the characters in the life application stories.  I prayed before going to bed every night and before every meal.  My parents brought my sisters and I to church every Sunday, where I would attend the Sunday School I enjoyed so much, especially in fourth grade.  That class was focused on filling out worksheets, which was actually a lot of fun to me.  You see, we'd always show up late, and I enjoyed being the first done with the most correct answers despite always coming in late.&lt;br /&gt;&lt;br /&gt;When I was seven years old, I prayed the important prayer of asking Jesus to come into my life.  Probably a few months after that, I was baptised at the beach.  Things are good when you give your life up to Jesus.&lt;br /&gt;&lt;br /&gt;But are they really?  Honestly, my life has been really blessed.  Did God really have anything to do with it or was that just the way it was?  Things go well and I feel at peace when I pray, but is it because God is answering my prayer or is it due to self reflection?  To feed those doubts was the fact that so many of the arguments against Christianity, like evolutionary debates and religious social studies, resonate quite well with me.  Furthermore, I had the feeling that being a Christian and the existence of a god is stifling and inconvenient.  I thought life would certainly be more efficient and fun without God.  For example, praying takes up time.  Figuring out and acting on what I believe to be "God's will" seemed really limiting.&lt;br /&gt;&lt;br /&gt;With that mentality, I decided that it not only made sense not to believe in God, but it was a good decision for my life.  So no more praying, no more paying attention in church (of course I'd still have to go with my parents), no more trying to figure out God's will.  But... that didn't go as well as I hoped.&lt;br /&gt;&lt;br /&gt;Without my relationship with God, something was just missing.  I knew it wasn't something as simple as "I feel purposeless" or the "feeling of loss."  At church recently, we talked about the fingerprints of God... touches God leaves that shows He's there, even if you can't see Him.  The touch of God was missing from my life that I didn't want Him to lead.  For me, the most explainable missing fingerprint was a sense of knowing my place in everything, the sense of somewhat understanding everything around me.&lt;br /&gt;&lt;br /&gt;Soon after, I prayed to God and He spoke to me.  I was inspired to pursue a deeper relationship with God.  To start off, I just prayed a lot more.  I studied the bible closer and would have long discussions about it with other Christians.  That led me to worship more geniunely and involve myself more in God's work.  I didn't feel like I was making myself do something I didn't want as I tried to followed God's will more while developing a relationship with Him.  God has blessed my life greatly, with my friends, and with my wife Carrie, and with my family, and with work.  There's nothing so far in my, albeit short so far, life that I really regret and a great part of that is because I truly believe God has been guiding me and I've been listening.  Things don't always work out in the short term, but I've almost never minded thanks to God, and something better has always come around so far.&lt;br /&gt;&lt;br /&gt;My story isn't very dramatic.  I've spent almost all my life as a Christian pursuing a relationship with God.  Having a relationship with God gives me an almost perpetual sense of fulfillment, joy, and peace in my life.  Of course, even though I believe a relationship with God makes it easier, I know I could get all of that without Him.  But there's still that unexplainable touch of God that only comes from a relationship with Him.  And that really means everything to me... I think it might have to be experienced to really understand.&lt;br /&gt;&lt;br /&gt;And of course, I still have doubts, although it hasn't escalated to the situation I described earlier again.  But it really very much is a cycle to me.  Doubt, study, and prayer continually bring me in a closer relationship with God.  The thing that helps me most though doubt is that I know God exists, since I have a relationship with Him, and I've seen Him transform lives.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-1960103592855145843?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/1960103592855145843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=1960103592855145843' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/1960103592855145843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/1960103592855145843'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2007/12/testimony-2007.html' title='Testimony 2007'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-1225197563028726591</id><published>2007-11-30T20:15:00.001-08:00</published><updated>2007-11-30T20:24:04.687-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>TCP Monitor</title><content type='html'>At work, I've done a lot of client/server work.  Whether using RMI JDBC, or SOAP Messages, or our own custom protocols, a lot of my work has involved sending messages back and forth.  The easiest way for me to debug programs was with &lt;a href="https://tcpmon.dev.java.net/"&gt;tcpmon&lt;/a&gt;.  This incredibly useful tool sits between a client and server.  It displays any data passedit recieves to the screen, then forwards the message to its destination.  Go to the page to read more about it.  I've really found it invaluble.&lt;br /&gt;&lt;br /&gt;Heh heh... this post was actually just to keep up with an update a month.  I'm glad I thought of something useful to post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-1225197563028726591?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/1225197563028726591/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=1225197563028726591' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/1225197563028726591'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/1225197563028726591'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2007/11/tcp-monitor.html' title='TCP Monitor'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-9202022215709067303</id><published>2007-10-21T17:11:00.002-07:00</published><updated>2007-10-21T17:12:20.405-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>SQL Server and JDBC</title><content type='html'>This describes how I set up JDBC to interact with a Sql Server Express 2005 database.  Sql Server Express 2005 was installed on a Windows XP machine.  The database was being accessed using JDBC on a remote Trusted Solaris machine running Java 1.2.  The following instructions should apply to more configurations than just that though.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- Installing Sql Server Express 2005 -&lt;br /&gt;&lt;br /&gt;1. Install Sql Server Express.&lt;br /&gt;&lt;br /&gt;Download it from &lt;a class="linkification-ext" href="http://www.microsoft.com/sql/downloads/trial-software.mspx#EXC" title="Linkification: http://www.microsoft.com/sql/downloads/trial-software.mspx#EXC"&gt;http://www.microsoft.com/sql/downloads/trial-software.mspx#EXC&lt;/a&gt;.  During install, selecting all the default options is fine.  The only thing you would want to change is using Mixed Mode authentication instead of Windows Authentication.  If you didn't select that option, I'll tell you how to do it later, so don't worry about it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2. Allow TCP/IP Connectivity&lt;br /&gt;&lt;br /&gt;Configure TCP/IP connectivity for use with IBM Director Server.  By default, SQL Server Express Edition does not have TCP/IP connectivity enabled after installation.  This means you won't be able to remotely access the database.  In addition, the TCP port must be set for use with IBM Director Server. Complete the following steps:&lt;br /&gt;&lt;br /&gt;  1. Click Start &gt; All Programs &gt; Microsoft SQL Server 2005 &gt; Configuration Tools &gt; SQL Server Configuration Manager.&lt;br /&gt;  2. In the left pane of the SQL Server Configuration Manager window, expand SQL Server 2005 Network Configuration and then click Protocols for SQLEXPRESS.&lt;br /&gt;  3. In the right pane of the SQL Server Configuration Manager window, right-click TCP/IP and click Enable. Click OK to acknowledge the warning message.&lt;br /&gt;  4. Right-click TCP/IP again and click Properties.&lt;br /&gt;  5. In the TCP/IP Properties window, click the IP Addresses tab, and then expand IPALL.&lt;br /&gt;  6. Under IPALL, clear the TCP Dynamic Ports field and then type a port number in the TCP Port field. Usually, the port number should be set to 1433.&lt;br /&gt;  7. In the TCP/IP Properties window, click OK, and then click OK to acknowledge the warning message.&lt;br /&gt;  8. In the left pane of the SQL Server Configuration Manager window, click SQL Server 2005 Services.&lt;br /&gt;  9. In the right pane of the SQL Server Configuration Manager window, right-click SQL Server (SQLEXPRESS) and click Restart.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3. Install SQL Server Management Studio&lt;br /&gt;&lt;br /&gt;Download SQL Server Management Studio Express from &lt;a class="linkification-ext" href="https://www.microsoft.com/downloads/details.aspx?familyid=C243A5AE-4BD1-4E3D-94B8-5A0F62BF7796&amp;amp;displaylang=en" title="Linkification: https://www.microsoft.com/downloads/details.aspx?familyid=C243A5AE-4BD1-4E3D-94B8-5A0F62BF7796&amp;amp;displaylang=en"&gt;https://www.microsoft.com/downloads/details.aspx?familyid=C243A5AE-4BD1-4E3D-94B8-5A0F62BF7796&amp;amp;displaylang=en&lt;/a&gt;.  If you didn't allow Mixed mode Authentication for the Sql Server Express earlier, complete the following steps:&lt;br /&gt;&lt;br /&gt;   1. In SQL Server Management Studio Object Explorer, right-click the server, and then click Properties.&lt;br /&gt;   2. On the Security page, under Server authentication, select "SQL Server and Windows Authentication mode."&lt;br /&gt;   3. In the SQL Server Management Studio dialog box, click OK, to acknowledge the need to restart SQL Server.&lt;br /&gt;   4. In Object Explorer, right-click your server, and then click Restart. If SQL Server Agent is running, it must also be restarted.&lt;br /&gt;   5. In Object Explorer, expand Security, expand Logins, right-click sa, and then click Properties.&lt;br /&gt;   6. On the General page, you may have to create and confirm a password for the sa login.&lt;br /&gt;   7. On the Status page, in the Login section, click Enabled, and then click OK.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;4. Create Your Database&lt;br /&gt;&lt;br /&gt;- Create the database using SQL Server Management Studio.  Add a user to the database by going into [database_name]/security/users.&lt;br /&gt;- Give the user permissions for remote access.&lt;br /&gt;   a) Right Click [database_name], select properties.&lt;br /&gt;   b) Go into properties.&lt;br /&gt;   c) Select the user and grant all permissions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- JDBC Access -&lt;br /&gt;&lt;br /&gt;Microsoft provides a JDBC Driver for SQL Server 2005, which can be downloaded from &lt;a class="linkification-ext" href="http://msdn2.microsoft.com/en-us/data/aa937724.aspx" title="Linkification: http://msdn2.microsoft.com/en-us/data/aa937724.aspx"&gt;http://msdn2.microsoft.com/en-us/data/aa937724.aspx&lt;/a&gt;.  There's a "sqljdbc.jar" in the pack that you'll need to put on your classpath.  Then you can use the following Driver and Url:&lt;br /&gt;&lt;br /&gt;Driver: com.microsoft.sqlserver.jdbc.SQLServerDriver&lt;br /&gt;Url: jdbc:sqlserver://[host]:[port, default 1433];"databaseName=[database_name]"&lt;br /&gt;&lt;br /&gt;However, I needed to use Java 1.2 for my application and Microsoft's JDBC driver does not support it.  It doesn't support 1.3 either.  I found another great free driver at &lt;a class="linkification-ext" href="http://sourceforge.net/project/shownotes.php?release_id=369359&amp;amp;group_id=33291" title="Linkification: http://sourceforge.net/project/shownotes.php?release_id=369359&amp;amp;group_id=33291"&gt;http://sourceforge.net/project/shownotes.php?release_id=369359&amp;amp;group_id=33291&lt;/a&gt; which fit my needs: free, supports java 1.2, and easy to use.  There's a jtds.jar in the pack that you'll need to put on your classpath.  Then you can use the following Driver and Url.&lt;br /&gt;&lt;br /&gt;Driver: net.sourceforge.jtds.jdbc.Driver&lt;br /&gt;Url: jdbc:jtds:sqlserver://[host]:[port, default 1433]/[database_name]&lt;br /&gt;&lt;br /&gt;I'm assuming you know how to use JDBC already, so this guide ends here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-9202022215709067303?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/9202022215709067303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=9202022215709067303' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/9202022215709067303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/9202022215709067303'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2007/10/sql-server-and-jdbc.html' title='SQL Server and JDBC'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-3096948257565166274</id><published>2007-10-21T17:11:00.001-07:00</published><updated>2007-10-21T17:11:28.359-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>MS Access and JDBC</title><content type='html'>This describes how I set up JDBC to interact with a Microsoft Access .mdb database.  The MS Access Database was installed on a Windows XP machine.  The database was being accessed using JDBC on a remote Trusted Solaris machine running Java 1.2.  The following instructions should apply to more configurations than just that though.&lt;br /&gt;&lt;br /&gt;- Create the Microsoft Access Database -&lt;br /&gt;&lt;br /&gt;    1. Go into Control Panel -&gt; Administrative Tools -&gt; Data Sources (ODBC)&lt;br /&gt;    2. Click on the System DSN tab&lt;br /&gt;    3. Click the Add Button, choose Microsoft Access (*.mdb)&lt;br /&gt;    4. Choose the database name.  Click the "create" button and decide on the location.&lt;br /&gt;    5. Click the Advanced button to give the database a username and password.&lt;br /&gt;    6. You can edit these options using the Configure button.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- JDBC Access for Microsoft Access -&lt;br /&gt;&lt;br /&gt;You can use JDBC to access the MS Access database using Sun's built in ODBC driver. The Driver and the Url are as follows:&lt;br /&gt;&lt;br /&gt;    Driver: sun.jdbc.odbc.JdbcOdbcDriver&lt;br /&gt;    Url: jdbc:obbc:[database_name]&lt;br /&gt;&lt;br /&gt;However, I needed to access the database from a remote host.  I couldn't find any direct way to do this, due to the nature of the MS Access database.  So to use access the database remotely, I used RmiJdbc.  You can download it at http://rmijdbc.objectweb.org/. &lt;br /&gt;&lt;br /&gt;RmiJdbc is a bridge to allow remote access to JDBC drivers.  You'll find the RmiJdbc jar in the package, which you'll need to include on your classpath.  Then you can use the following Driver and Url (to connect to the mdb Access database):&lt;br /&gt;&lt;br /&gt;    Driver: org.objectweb.rmijdbc.Driver&lt;br /&gt;    Url: jdbc:rmi://[host]/jdbc:obbc:[database_name]&lt;br /&gt;&lt;br /&gt;In order for this to work, RmiJdbc needs to be listening for requests.  Start up the server by executing "org.objectweb.rmijdbc.RJJdbcServer" on the machine the MS Access database is located on.  Remember that to put the RmiJdbc jar on your classpath.&lt;br /&gt;&lt;br /&gt;I'm assuming that you know how to use JDBC, so I'm going to end my instructions here.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[Reference]&lt;br /&gt;http://rmijdbc.objectweb.org/&lt;br /&gt;http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=2691&amp;amp;lngWId=2&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-3096948257565166274?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/3096948257565166274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=3096948257565166274' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3096948257565166274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3096948257565166274'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2007/10/ms-access-and-jdbc.html' title='MS Access and JDBC'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-588543811349872879</id><published>2007-10-21T17:09:00.000-07:00</published><updated>2007-10-21T17:10:29.715-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>MySQL and JDBC</title><content type='html'>This describes how I set up a MySql database to talk with JDBC.  The MySql database and server were installed on a Windows XP machine.  The database was being accessed using JDBC on a remote Trusted Solaris machine running Java 1.2.  The following instructions should apply to more configurations than just that though.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- MySql Database and Server -&lt;br /&gt;&lt;br /&gt;1. Download MySql Server from http://www.mysql.org.  For my installation, I used MySql Server 4.1, which I downloaded from http://www.mysql.org/downloads/mysql/4.1.html.&lt;br /&gt;2. Install MySql Server using all the default options.  Afterwards, you can add the MySql bin path to your PATH enviroment variable for convenience if you want.&lt;br /&gt;3. It's time to create your Database.  I used the mysql tool, which can be found in the bin folder of the MySql installation.  It's a command line tool.  Here is an example of session for setting your database up.&lt;br /&gt;&lt;br /&gt;    1) C://&gt; mysql -u root -p&lt;br /&gt;    2) &gt; create database test;&lt;br /&gt;    3) &gt; select host,user,password from mysql.user;&lt;br /&gt;    4) &gt; GRANT ALL PRIVILEGES ON *.* to 'user'@'%' identified by 'pass';&lt;br /&gt;    5) &gt; select host,user,password from mysql.user;&lt;br /&gt;&lt;br /&gt;The first line logs you in.  The second line creates a database called test.  The fourth line grants priviliges to the database.  '*.*' means these all privilges will be granted on everything, 'user' is the username, 'pass' is the password, '%' is a wildcard for the host; Altogether, line 4 allows user to access any mysql database from any host using the password pass.  You can limit the host to just localhost or a specific IP and you can limit privileges to a specific database.  Lines 3 and 5 will allow you to see if your user was set up correctly: you'll see new entries in the table.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- JDBC Access for MySql -&lt;br /&gt;&lt;br /&gt;1. Download the MySql JDBC Driver (called Connector/J) from http://www.mysql.org.  It was under Downloads, Connectors, Connector/J.  Because I needed to use Java 1.2, I needed to download the older Connector/J 3.0.  If you're using a newer JVM, you can use a higher version.&lt;br /&gt;2. Extract the archive and add the jar found at the top level to java's classpath.  The mysql jar shouldn't have '-g' in its name anywhere.&lt;br /&gt;3. Now you can write your java code.  Use the following Driver and Url:&lt;br /&gt;    Driver: com.mysql.jdbc.Driver&lt;br /&gt;    Url: jdbc:mysql://[host, default localhost]:[port, default 3306]/[database_name]&lt;br /&gt;4. This isn't a JDBC guide, so I'll end here.  Happy coding.  And good luck.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;TroubleShooting&lt;br /&gt;&lt;br /&gt;1. Error 'Can not connect to host': You don't have permission to connect to the database from the machine you're using.  This probably means you didn't grant permission to your database correctly.&lt;br /&gt;2. "ClassDefNotFound: java/lang/reflect/InvocationHandler": I go this error when I was trying to use the 5.0 Connector/J with Java 1.2.  The 3.0 Connector/J is the only version that supports such an old JVM.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-588543811349872879?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/588543811349872879/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=588543811349872879' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/588543811349872879'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/588543811349872879'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2007/10/mysql-and-jdbc.html' title='MySQL and JDBC'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-2359246362952664254</id><published>2007-09-02T20:47:00.000-07:00</published><updated>2007-09-02T21:16:44.042-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Keep What You Stream</title><content type='html'>Streaming Video and Streaming Music are all nice and good when you have a good internet connection.  But that's not always the case.  Fortunetely, there's free software to help you grab your favorite online media without having to reload a web page endlessly.  These are the ones I use, there may be better programs out there, but I've been fine with just these.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/3006"&gt;Download Helper&lt;/a&gt;&lt;br /&gt;I think I've made it clear that I use firefox, this video downloader is a firefox plugin.  Let's say you've just watched a YouTube video and want to save it.  If you have this installed, then you can just right-click the page, go to the "Download Helper" option, and then choose the flv file.  (Youtube videos are flv format, &lt;a href="http://www.blogger.com/www.free-codecs.com/download/K_Lite_Mega_Codec_Pack.htm"&gt;K-lite Mega Codec&lt;/a&gt; allows you to watch them, or there are tons of easy to find "flv to avi" programs.)  I used Youtube in this example, but this Download Helper will work with just about any streaming video site.  Oh yeah, here's a good tip, go to the preferences menu and add 'swf' to the MediaLink and MediaReq tabs so that you can download flash files.&lt;br /&gt;&lt;a href="http://audacity.sourceforge.net/download/"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a href="http://audacity.sourceforge.net/download/"&gt;Audacity&lt;/a&gt; or &lt;a href="http://www.nbxsoft.com/download-sound-recorder.php"&gt;Free MP3 Sound Recorder&lt;/a&gt;&lt;br /&gt;These two programs will allow you to record sounds, both can record to the MP3 format.  Audacity doubles as an editing program, Free MP3 Sound Recorder is more limited but much simpler to use.  Both seem safe to me.  If you don't trust me, you can google search to find a bunch of other options.  Oh yeah, you need to choose either stereo mix or wave in for the sound device if you want to record stuff playing on your computer.  This is a problem for certain computers, all the fixes for it seem expensive.&lt;br /&gt;&lt;a href="http://downloadstatusbar.mozdev.org/"&gt;&lt;br /&gt;Download Statusbar&lt;/a&gt;&lt;br /&gt;And while we're talking about downloading stuff... if you're using firefox, please also be using download status bar.  It's a million times better and less intrusive that that default download pop-up manager.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-2359246362952664254?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/2359246362952664254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=2359246362952664254' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/2359246362952664254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/2359246362952664254'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2007/09/get-what-you-see.html' title='Keep What You Stream'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-4173329130611918931</id><published>2007-08-05T09:00:00.000-07:00</published><updated>2007-08-05T09:02:44.914-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Links'/><title type='text'>Fun Reads</title><content type='html'>I found some kinda fun technical reads.  They're on the funny side, fun reads.  Enjoy.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://discovermagazine.com/2007/brain/i-chat-therefore-i-am/article_print"&gt;http://discovermagazine.com/2007/brain/i-chat-therefore-i-am/article_print&lt;/a&gt;&lt;br /&gt;Alice and Jaberwocky AI chatting with each other.&lt;br /&gt;&lt;a href="http://worsethanfailure.com/Articles/The_Complicator_0x27_s_Gloves.aspx"&gt;&lt;br /&gt;http://worsethanfailure.com/Articles/The_Complicator_0x27_s_Gloves.aspx&lt;/a&gt;&lt;br /&gt;The complicator gloves.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://steve-yegge.blogspot.com/2006/12/parabola.html"&gt;http://steve-yegge.blogspot.com/2006/12/parabola.html&lt;/a&gt;&lt;br /&gt;Steve Yegge writes a story.&lt;br /&gt;&lt;a href="http://scienceblogs.com/principles/2007/05/many_worlds_many_treats.php"&gt;&lt;br /&gt;http://scienceblogs.com/principles/2007/05/many_worlds_many_treats.php&lt;/a&gt;&lt;br /&gt;Teaching Quantum Mechanics to a Dog&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.pbm.com/%7Elindahl/mel.html"&gt;http://www.pbm.com/~lindahl/mel.html&lt;/a&gt;&lt;br /&gt;A Real Hacker.  This one is classic, but I needed to add it anyway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-4173329130611918931?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/4173329130611918931/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=4173329130611918931' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4173329130611918931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/4173329130611918931'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2007/08/fun-reads.html' title='Fun Reads'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-3187684105319653383</id><published>2007-08-03T20:13:00.001-07:00</published><updated>2007-08-04T22:25:12.800-07:00</updated><title type='text'>Java and Web Services</title><content type='html'>Today's blog goes over a bunch of web service stuff I learned for a project at work.  A web service implementation was desirable because of the potential for interoperability.  However, we wanted to send images and have support alerts.  None of us really knew about the recent advancements in web services, so I spent a week or two doing a feasibility study.  I ended up learning a lot about JAX-WS, Asynchronous Callbacks, and MTOM.  So, I'm going to share what I've learned.  This entry was written 1/18/2007, so it may not be all that accurate today.  Don't blame me, blame our every changing technology.&lt;br /&gt;&lt;br /&gt;-- Web Service Study --&lt;br /&gt;&lt;br /&gt;Web services have developed a lot between 2004 and 2006.  Many new features and capabilities have been added to the tools, which has also made creating and using web services more complex.  The technology is still very new and although there are people using it, there isn't much documentation about it.  This makes it very difficult to find information about it, especially to the depth that I wanted.  At this point, I have a "pretty good" idea about what is out there and how it works.  Which means that I can use the APIs and create services, but as for how it really works... I'm basically making educated guesses.&lt;br /&gt;&lt;br /&gt;There are at least four different Java web service implementations that support asynchronous callbacks and MTOM out there:&lt;br /&gt;&lt;br /&gt;1. JAX-WS (big name): &lt;a class="linkification-ext" href="https://jax-ws.dev.java.net/" title="Linkification: https://jax-ws.dev.java.net/"&gt;https://jax-ws.dev.java.net/&lt;/a&gt;&lt;br /&gt;2. Axis 2 (big name): &lt;a class="linkification-ext" href="http://ws.apache.org/axis2/" title="Linkification: http://ws.apache.org/axis2/"&gt;http://ws.apache.org/axis2/&lt;/a&gt;&lt;br /&gt;3. xFire (claims excellent performance): &lt;a class="linkification-ext" href="http://xfire.codehaus.org/" title="Linkification: http://xfire.codehaus.org/"&gt;http://xfire.codehaus.org/&lt;/a&gt;&lt;br /&gt;4. JibxSoap: &lt;a class="linkification-ext" href="http://jibx.sourceforge.net/jibxsoap/index.html" title="Linkification: http://jibx.sourceforge.net/jibxsoap/index.html"&gt;http://jibx.sourceforge.net/jibxsoap/index.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- JAX-WS --&lt;br /&gt;&lt;br /&gt;I only focused on, and will only be discussing, the JAX-WS 2.0 approach.  JAX-WS 2.0 is the successor to JAX-RPC.  There are two major reasons for this decision.&lt;br /&gt;&lt;br /&gt;Firstly, JAX-WS 2.0 is included in Java 6.  This means applications using it will require no third party software dependencies or additional jar files for supporting web services.  Unfortunetely, the ant tasks to build web services are not included with Java 6, so we as developers still need to get a separate special JAX-WS jar for the development side.  The needed classes are the ant versions of the apt and wsimport tools.  However, as far as running the client goes, only Java 6, the application, and possibly some client side xml will be necessary.  I have verified using a JAX-WS developed application with only JDK 6.&lt;br /&gt;&lt;br /&gt;Secondly, JAX-WS also seems to be the most determined to follow specifications, although I'm not sure how standard or widely adopted these specifications are.  JAX-WS seems to concentrate on the WS-I standards, which has no track record of adoption.  JAX-WS seems to be trying to ensure interoperability with Microsoft's Indigo platform.  Going beyond the interoperability provided by JAX-WS itself, the JAX-WS project also provides the foundation for the Web Services Interoperability Technology (WSIT) that provides enterprise features that interoperate with Microsoft Windows Communication Foundation.  The WSIT software works as documented, but is known to be incomplete and contain known bugs at this time&lt;br /&gt;&lt;br /&gt;JAX-WS currently claims to support:&lt;br /&gt;   JAX-WS 2.0&lt;br /&gt;   WS-I Basic Profile 1.1&lt;br /&gt;   WS-I Attachments Profile 1.0&lt;br /&gt;   WS-I Simple SOAP Binding Profile 1.0&lt;br /&gt;&lt;br /&gt;The JAX-WS team claims that the next release (JAX-WS 2.1)  will support:&lt;br /&gt;   WS-Addressing - This standard defines a mechanism for callbacks where the client sends an address the server can send alerts to.&lt;br /&gt;&lt;br /&gt;[Selected Relevant Links]&lt;br /&gt;JAX-WS Homepage: &lt;a class="linkification-ext" href="https://jax-ws.dev.java.net/" title="Linkification: https://jax-ws.dev.java.net/"&gt;https://jax-ws.dev.java.net/&lt;/a&gt;&lt;br /&gt;Web Services in Java: &lt;a class="linkification-ext" href="http://www-128.ibm.com/developerworks/java/library/ws-java1.html" title="Linkification: http://www-128.ibm.com/developerworks/java/library/ws-java1.html"&gt;http://www-128.ibm.com/developerworks/java/library/ws-java1.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- Using JAX-WS --&lt;br /&gt;&lt;br /&gt;I'm going to briefly describe how to create a web service and a client to access that web service using JAX-WS.  Coding web service server/client applications in JAX-WS requires very specfic design decisions and code annotations.  While they aren't very hard to write once you learn them, they take a fair amount of time to learn.  And once you get the code running, there may still be a significant amount of effort deploying the service and debugging interoperability problems.&lt;br /&gt;&lt;br /&gt;JAX-WS allows (actually, I think forces) you to use annotations to define a web service.  Defining a web service would look like this:&lt;br /&gt;&lt;br /&gt;   import javax.jws.WebMethod;&lt;br /&gt;   import javax.jws.WebService;&lt;br /&gt;&lt;br /&gt;   @WebService(name = "StockQuote", serviceName = "StockQuoteService")&lt;br /&gt;   public class StockQuoteImpl {&lt;br /&gt;  @WebMethod(operationName = "getQuote")&lt;br /&gt;  public double getQuote(String ticker) {&lt;br /&gt;    double result = 0.0;&lt;br /&gt;               if (ticker.equals("GOOG")) {&lt;br /&gt;                     result = 320.0;&lt;br /&gt;               }&lt;br /&gt;               return result;&lt;br /&gt;          }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;Once the code is written, you need to run the apt tool on it, which provides a facility for programmatically processing the annotations added to Java.  If you want to use this in an ant build, you would want to download the JAX-WS jar which includes com.sun.tools.ws.ant.apt.  After you've run apt, then you need to create your war file using the war tool and a custom xml file.   Deploy the war file and your web service will be ready to use.&lt;br /&gt;&lt;br /&gt;Then, you can write some client code to use this service.&lt;br /&gt;&lt;br /&gt;   public class StockQuoteClient {&lt;br /&gt;  public static void main(String[] args) {&lt;br /&gt;               StockQuote port = new StockQuoteService().getStockQuotePort();&lt;br /&gt;               double result = port.getQuote("GOOG");&lt;br /&gt;               System.out.printf("The stock price of %s is $%f.\n", ticker, result);&lt;br /&gt;          }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;Then you must use wsimport, which generates JAX-WS portable artifacts.  If you want to use this in an ant build, you would want to download the JAX-WS jar, which includes com.sun.tools.ws.ant.wsimport.  wsimport works by getting the wsdl and creating all the artifacts needed to use this service.  In this case, it would generate the JAXB 2.0 binding classes GetQuote, GetQuoteResponse, package-info, and ObjectFactory.  Furthermore, it creates the service endpoint interface StockQuote, which provides the client view of the service, and the class StockQuoteService, which allows a client to interact with the client runtime. A point to note here is that, even though the wsimport is from the RI, the artifacts it generates are portable.&lt;br /&gt;&lt;br /&gt;With the artifacts created, you can now compile the client.  Then you can run the client.  Supporting asynchronous callbacks or mtom, which are addressed in the following sections, will add complexity on top of what has been described here.&lt;br /&gt;&lt;br /&gt;[More Detailed Tutorial]&lt;br /&gt;JAX-WS Example: &lt;a class="linkification-ext" href="http://today.java.net/pub/a/today/2006/06/13/web-services-with-jax-ws-2.0.html" title="Linkification: http://today.java.net/pub/a/today/2006/06/13/web-services-with-jax-ws-2.0.html"&gt;http://today.java.net/pub/a/today/2006/06/13/web-services-with-jax-ws-2.0.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- Web Service Asynchronous Callbacks and JAX-WS --&lt;br /&gt;&lt;br /&gt;Asynchronous web services still imply a request-response protocol.  However, asynchronous web services allow the application to do other things while it is waiting for a response from the server.  So instead of a blocking operation, you have a non-blocking operation.&lt;br /&gt;&lt;br /&gt;In the JAX-WS implementation, you tell the client application to asynchonously use web services through a combination of code and xml.  The xml is actually WSDL bindings.  This does not mean that the WSDL file on the server side needs special JAX-WS specific bindings that will effect interoperability.  Instead it is optional and you may specify client-side xml to merge with the server obtained WSDL.  Of course, this means that a .NET client accessing the service would somehow need to know to use asynchronous calls.  There isn't any mechanism for that yet.&lt;br /&gt;&lt;br /&gt;On the JAX-WS website, it is claimed that "the connection is kept open until the response is received.  After that, the callback is called.  client/server side handlers do not affect this behaviour."  As this implies, using a web service asynchronously is implemented entirely by the client.  I believe that when you make an asynchronous request to a web service, JAX-WS creates a new thread that waits for the response so that there is no blocking unless you need the returned data to continue.  There isn't any massive polling, just a waiting for a response.  Like I said before, the syntax for coding this isn't complicated, but it takes a lot of time to learn and the interoperability may be difficult.&lt;br /&gt;&lt;br /&gt;There are two ways to use asynchronous services, which are polling and callback.  Each approach definitely has its own benefits and disadvantages.&lt;br /&gt;&lt;br /&gt;The polling approach allows you to poll an object that is created when you make the web service request about whether or not a response has been recieved from the server.  If it has received a response, you can then request the data response from that object.  As I said before, I do not believe that this actually polls the server.&lt;br /&gt;&lt;br /&gt;The callback approach allows you to define a callback method when you make the web service request.  When the response is received, the callback method is automatically executed.  There is no need for you to do anything after making the request, although you can still check if the response has been received yet.&lt;br /&gt;&lt;br /&gt;From what I understand, in all implementations, asynchronous web services is completely done on the client side and does not require the implementation to follow any standards.  Using the TCPMon tool, I looked into the SOAP messages sent by a test application I developed and verified that there was no change between using the web service synchronously and asynchronously.  Asynchronous callbacks are implemented by all the major web service platforms.  There is no standardized way to suggest that the web service be used asynchronously, but it won't be impossible.&lt;br /&gt;&lt;br /&gt;Java 6 also includes an embedded http server.  What this means is that an endpoint can be embedded in client via the JAX-WS API.  So using this, the client can send its address to the server, and the server can push information whenever anything is available to a service on the client's server.  For this kind of callback, WS-Adressing has a specification about how this should work.  JAX-WS does not follow this, but they say that they plan to for the next release.  Oh yeah, the embedded server appears to randomly refuse requests if it receives many requests.&lt;br /&gt;&lt;br /&gt;[Examples of Use]&lt;br /&gt;JAX-WS Asynchronous Callback Example: &lt;a class="linkification-ext" href="http://today.java.net/pub/a/today/2006/09/19/asynchronous-jax-ws-web-services.html" title="Linkification: http://today.java.net/pub/a/today/2006/09/19/asynchronous-jax-ws-web-services.html"&gt;http://today.java.net/pub/a/today/2006/09/19/asynchronous-jax-ws-web-services.html&lt;/a&gt;&lt;br /&gt;Endpoints in Mustang Example: &lt;a class="linkification-ext" href="http://weblogs.java.net/blog/jitu/archive/2006/01/web_service_end.html" title="Linkification: http://weblogs.java.net/blog/jitu/archive/2006/01/web_service_end.html"&gt;http://weblogs.java.net/blog/jitu/archive/2006/01/web_service_end.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- Attachments and JAX-WS --&lt;br /&gt;&lt;br /&gt;The built-in support for Binary Attachments in JAX-WS is MTOM (Message Transmission and Optimization Mechanism).  MTOM is a method of efficiently sending binary data to and from web services.  It uses XOP (XML-binary Optimized Packaging) to transmit binary data and is intended to replace both MIME and DIME attachments.&lt;br /&gt;&lt;br /&gt;The SOAP Message Transmission Optimization Mechanism, paired with the XML-binary Optimized Packaging [XOP], was proposed to address the inefficiencies related to the transmission of binary data in SOAP documents. This solution proposes a method in which XML messages are dissected in order to transmit binary blobs as MIME attachments in a way that is transparent to the application. Since an attachment is not really part of the XML payload, binary data does not need to be base64 encoded, thus reducing its size and increasing its processing speed.&lt;br /&gt;&lt;br /&gt;MTOM is supported by the JAX-WS API and is transparent to the user and developer.  MTOM is also supported by Microsoft .NET starting in WSE 3.0.  The other web service alternative is encoding the data (such as base64 conversion), which is much more inefficient.  Unfortunetely, MTOM still doesn't seem all that fast.&lt;br /&gt;&lt;br /&gt;[References]&lt;br /&gt;&lt;br /&gt;MTOM W3C Recommendation: &lt;a class="linkification-ext" href="http://www.w3.org/TR/soap12-mtom/" title="Linkification: http://www.w3.org/TR/soap12-mtom/"&gt;http://www.w3.org/TR/soap12-mtom/&lt;/a&gt;&lt;br /&gt;MTOM and JAX-WS: &lt;a class="linkification-ext" href="http://java.sun.com/webservices/docs/2.0/jaxws/mtom-swaref.html" title="Linkification: http://java.sun.com/webservices/docs/2.0/jaxws/mtom-swaref.html"&gt;http://java.sun.com/webservices/docs/2.0/jaxws/mtom-swaref.html&lt;/a&gt;&lt;br /&gt;MTOM Performance and Description: &lt;a class="linkification-ext" href="http://weblogs.java.net/blog/spericas/archive/2006/04/mtom_performanc.html" title="Linkification: http://weblogs.java.net/blog/spericas/archive/2006/04/mtom_performanc.html"&gt;http://weblogs.java.net/blog/spericas/archive/2006/04/mtom_performanc.html&lt;/a&gt;&lt;br /&gt;JAX-WS MTOM Usage Example: &lt;a class="linkification-ext" href="http://blogs.sun.com/milan/entry/using_web_service_to_send" title="Linkification: http://blogs.sun.com/milan/entry/using_web_service_to_send"&gt;http://blogs.sun.com/milan/entry/using_web_service_to_send&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- From the Web Browser --&lt;br /&gt;&lt;br /&gt;As for the web browser, there really hasn't been any outstanding development in that field.  People have done funny things to allow callbacks (like using transfers for embedded video for the html requests).  The methods were unreliable and very unlikely to really be adopted.  Polling still seems like the best way, although it could be heavy on bandwidth.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- SOAP Thoughts -&lt;br /&gt;&lt;br /&gt;To end off, I want to rant about SOAP:&lt;br /&gt;&lt;br /&gt;SOAP is bloated and you can't find many people that actually like it.  Sure, some businesses/people are using it, but the implementations don't work like they're supposed to.  SOAP is confusing.  It isn't easy to figure out what the standards are or what the standards are trying to say.  Microsoft and Sun claim to be working off the same standards, but I'm not convinced they interpret them the same way.  SOAP is complicated.  You need compatible generation tools, WSDL files, SOAP web applications, and web clients for anything to even work.  The interoperability it's designed for still isn't quite there because there are many different standards out there or the implementations of SOAP don't follow the standards correctly.  I'm not convinced that it will remain popular for very long.  SOAP services are incredibly difficult to create unless you have tools to do most of the work for you.  If you have the right tools, it's not too hard to write applications, but the learning curve is pretty steep if you actually want to know what's going on.  And you will need to know what's going on if you're writing anything more complicated than a stock-quote example.  And it will be very difficult to troubleshoot any problems.  SOAP still isn't very mature.  A lot about it has changed in the past year and there's not much to suggest that it won't radically change in the next year.&lt;br /&gt;&lt;br /&gt;I wonder if some of the other stuff (REST or something else altogether) will eventually replace it.  I am impressed with how much web services have developed, but a lot of this development has added a lot of complexity.  Web Services are easier to make (thanks to the tools) and more official standards are taking form, but they are more complicated than ever to understand and make by hand (which means they are not easy to debug.)  Of course, none of this means that SOAP won't gain popularity and become increasingly important.  It seems like the most in-use, buzzed up thing right now, which is good for lastibility.&lt;br /&gt;&lt;br /&gt;[A Fun Read]&lt;br /&gt;SOAP dialogue: &lt;a class="linkification-ext" href="http://wanderingbarque.com/nonintersecting/2006/11/15/the-s-stands-for-simple/" title="Linkification: http://wanderingbarque.com/nonintersecting/2006/11/15/the-s-stands-for-simple/"&gt;http://wanderingbarque.com/nonintersecting/2006/11/15/the-s-stands-for-simple/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- Conclusion -&lt;br /&gt;&lt;br /&gt;And that's it.  Sorry if it's fragmented sounding, I hope you were able to learn something useful.  Like to look into REST.  For more fun, look into the latest javascript advancements, as well as Adobe Flex.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-3187684105319653383?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/3187684105319653383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=3187684105319653383' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3187684105319653383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3187684105319653383'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2007/08/java-and-web-services.html' title='Java and Web Services'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-9133053641660907502</id><published>2007-05-23T20:30:00.000-07:00</published><updated>2007-05-26T22:26:40.411-07:00</updated><title type='text'>Of Wiki</title><content type='html'>My wiki software of choice is currently &lt;a href="http://wiki.splitbrain.org/wiki:dokuwiki"&gt;dokuwiki&lt;/a&gt;.  It is true that I haven't put much research into it, but I mean, once you find one good solution, do you really want to look for others?  Well, I guess if it's really important... but wiki's (especially the internal project wikis we need) generally aren't.  Dokuwiki is very feature-rich.  It's based around PHP.  My favorite template for it is &lt;a href="http://wiki.splitbrain.org/wiki:tpl:battlehorse"&gt;battlehorse&lt;/a&gt;.  There really anything else I need to say about it, I just wanted to mention it since I've had good success with it.  I'm currently using it for our project's homepage at work and I've had no problems doing everything I want with it.  It took me maybe a half hour to set up completely to my liking and I haven't had to mess with its internals since.  So Dokuwiki is a big yay.&lt;br /&gt;&lt;br /&gt;I was using &lt;a href="http://jspwiki.org/"&gt;JSP Wiki&lt;/a&gt; at first, which is also pretty nice.  It was also convenient since Apache Tomcat was already all set up on our server.  However, there aren't that many good looking templates for it and I didn't have the time to make my own.  But JSP Wiki is a yay if you don't mind the lack of template options and want a jsp solution.  But be warned, the default template isn't really pretty at all, at best I'd call it functional.&lt;br /&gt;&lt;br /&gt;If neither of those are your cup of tea or you really want to do some serious comparisons, &lt;a href="http://www.wikimatrix.org/"&gt;this is a website that compares wikis&lt;/a&gt;.  And if you really like wikipedia, here's &lt;a href="http://www.lifehacker.com/software/wikipedia/geek-to-live-set-up-your-personal-wikipedia-163707.php"&gt;a guide to set up MediaWiki&lt;/a&gt;.  And that concludes my short advice on wikis.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-9133053641660907502?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/9133053641660907502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=9133053641660907502' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/9133053641660907502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/9133053641660907502'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2007/05/of-wiki.html' title='Of Wiki'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-7386785871895546441</id><published>2007-05-15T21:55:00.000-07:00</published><updated>2009-03-24T20:01:52.913-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>CDisplay</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;img style="height: 500px;" alt="MySettings" src="http://misc.relic19.net/CDisplaySample.jpg" /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-style:italic;"&gt;Edit: Since writing this post, I've switched over to &lt;a href="http://jdiscar.blogspot.com/2009/03/manga-meeya.html"&gt;Manga Meeya&lt;/a&gt;, which is much, much better.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In my opinion, there's &lt;span style="font-style:italic;"&gt;(edit: almost)&lt;/span&gt; no program better than CDisplay for reading downloaded sequential art (that's comics!)  I use it for photos and other image browsing too.  My favorite features are the smart look ahead, ability to show two pages at once, ability to view pages either left-to-right or right-to-left, automatic resizing, smart preloading, ability to automatically deal with compressed files, and easy commands.  I can't think of a better sequential image viewing program.  I'll tell you how to set it up and use it.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;&lt;span style="font-weight: bold;"&gt;- Setting Up -&lt;/span&gt;&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;First, &lt;a href="http://www.geocities.com/davidayton/CDisplay"&gt;download CDisplay here&lt;/a&gt;.  Extract it into "C:\Program Files\CDisplay\".  Double Click on CDisplay.exe.  You can press 'w' to show or hide the menu bar, whichever you prefer.  I like to keep it hidden to maximize the viewing area.  Now you have to customize the program.  Press 'c' to open up the configuration options.  Customize them however you like, these are my setting changes from the default:&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;img style="width: 542px; height: 600px;" alt="MySettings" src="http://misc.relic19.net/CDisplaySettings.png" /&gt;&lt;br /&gt;&lt;/div&gt;  Notice the option "Japanese Mode" under Program Settings.  It's used for going right-to-left instead of left-to-right, in case you're reading asian sequential art.  After this is done, start enjoying CDisplay!  'l' (lowercase L) will allow you to choose the files you want to open.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;&lt;span style="font-weight: bold;"&gt;- My Most Used Commands -&lt;/span&gt;&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;l&lt;/span&gt;: Allows you to select a file to open.  It's a lowercase 'L', not a one.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ctrl+l&lt;/span&gt;: Goes to the next directory or compressed file.  It's a lowercase 'L', not a one.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ctrl+Shift+l&lt;/span&gt;: Goes to the preview directory or compressed file.  It's a lowercase 'L', not a one.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Space&lt;/span&gt;: Goes to the next section or page.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ctrl+Shift+Space&lt;/span&gt;: Goes to the previous section or page.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;&lt;span style="font-weight: bold;"&gt;- Context Menu -&lt;/span&gt;&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;I think it's very convenient to add CDisplay to the Windows XP right click context menu for zip/rar files and folder icons.  This is how to do it:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;- For Zip/Rar Files -&lt;/span&gt;&lt;br /&gt;1. Open "My Computer"&lt;br /&gt;2. In the menu bar, go to Tools-&amp;gt;Folder Options.&lt;br /&gt;3. Click on the "File Types" tab.&lt;br /&gt;4. On the "Registered file types:" list, find and click on "ZIP"&lt;br /&gt;5. In the "Details for 'ZIP' extension" area, click the advanced button.  An "Edit File Type"  windows will pop up.&lt;br /&gt;6. Click the "New..." Button&lt;br /&gt;7. For Action, type: CDisplay.  For application, type: &lt;span style="font-weight: bold;"&gt;"C:\Program Files\CDisplay\" "%1"&lt;/span&gt;&lt;br /&gt;8. Close up.  Now, whenever you right click a zip file, you can choose CDisplay to open it in CDisplay.  To do this for rar files, repeat steps 1-7, switching the word ZIP with RAR.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;- For Folders -&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;1. Create "C:\Program Files\CDisplay\CDisplayFolder.bat" with the contents:&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    &lt;span style="font-weight: bold;"&gt;        setlocal EnableDelayedExpansion&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;        cd %1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;        for %%i in (*) do set name="%~1\%%i" !name!&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;        %2 %name%&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;    2. Open "My Computer"&lt;br /&gt;3. In the menu bar, go to Tools-&amp;gt;Folder Options.&lt;br /&gt;4. Click on the "File Types" tab.&lt;br /&gt;5. On the "Registered file types:" list, find and click on "Folder" (under the File Types column)&lt;br /&gt;6. In the "Details for 'Folder' extension" area, click the advanced button.  An "Edit File Type" windows will pop up.&lt;br /&gt;7. Click the "New..." Button&lt;br /&gt;8. For Action, type: CDisplay.  For application, type: &lt;span style="font-weight: bold;"&gt;"C:\Program Files\CDisplay\CDisplayFolder.bat" "%1" "C:\Program Files\CDisplay\CDisplay.exe"&lt;/span&gt;&lt;br /&gt;9. Close up.  Now whenever you you right click a folder, you can choose CDisplay to open the images.&lt;br /&gt;&lt;br /&gt;You can not edit a folder context command using the above directions.  If you need to edit the newly created CDisplay context command for folders do the following.  This is playing with the registry,     so you shouldn't do this unless you really have to:&lt;br /&gt;&lt;br /&gt;1. Press "win+r" for Run and type: &lt;span style="font-weight: bold;"&gt;regedit&lt;/span&gt;&lt;br /&gt;2. Navigate to HKEY_LOCAL_MACHINE/Software/Classes/Folder/shell/CDisplay/command. Be careful to not go to ".Folder".&lt;br /&gt;3. Double Click the (Default) file to the right.&lt;br /&gt;4. You can now edit the command, it's the value field of the pop up window.&lt;br /&gt;&lt;br /&gt;&lt;big&gt;&lt;span style="font-weight: bold;"&gt;- Closing Notes -&lt;/span&gt;&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;The CDisplay project is no longer being actively developed and the author vanished off the face of the earth (or something ^_^.)  Others try to continue his work, but I haven't given them a try yet.  &lt;a href="http://en.wikipedia.org/wiki/CDisplay"&gt;You can find links to them here&lt;/a&gt;, if you want to try them.  Anyways, that's all I have to say about CDisplay.  After all this explaining effort on my part, you better go try the program out!  It's really nifty.  ^_^  Have fun.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-7386785871895546441?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/7386785871895546441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=7386785871895546441' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7386785871895546441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/7386785871895546441'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2007/05/cdisplay.html' title='CDisplay'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-2550781452821849969</id><published>2007-03-01T18:33:00.000-08:00</published><updated>2007-03-01T18:34:19.382-08:00</updated><title type='text'>And I'm Back</title><content type='html'>Wow, it's been a while since I blogged last.  I got a new job which has been keeping me busy and tired.  Put me in weird moods.  Y'know, the kinds of moods that encourages playing Twilight Princess and not the kind of mood that encourages writing blogs that aren't read by other people.  But things are calming down now, and my desire to get more stuff done has risen again.  I've got a lot to post about, mostly stuff that I've learned while working at my new job.  But that stuff is for later.  Today, I just wanted to say that I was alive, and say I'd be posting again.  Now let's see if this blog'll ever show up on google searches for Jonathan Discar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-2550781452821849969?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/2550781452821849969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=2550781452821849969' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/2550781452821849969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/2550781452821849969'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2007/03/and-im-back.html' title='And I&apos;m Back'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-3511073829303841388</id><published>2006-12-05T08:08:00.000-08:00</published><updated>2006-12-05T08:09:45.728-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Interview'/><title type='text'>Interview Notes 1</title><content type='html'>Three of my old interview logs, maybe you can use them to help you prepare for one of your early career software programming job interviews.  Maybe I'll put a more recent batch of these up later.&lt;br /&gt;&lt;br /&gt; &lt;span style="font-weight: bold;"&gt;&lt;br /&gt;4/16&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; I had a phone screen recently, man those things are fun.  First one in a while, though mostly just for fun, and I wasn't well prepared at all since it came out of the blue.  I actually took notes afterwards, so I thought I'd briefly discuss the interview.&lt;br /&gt;&lt;br /&gt; First we talked about Java's Access Control modifiers (public, private, protected, package) and about which each modifier did what.  I couldn't remember package though.  I feel stupid, because after I said I couldn't remember the last modifier, we talked about packages and I didn't make the connection for a while.  We talked about what packages are, why we use them, and how to classes to a package.  That's when I finally made that connection.&lt;br /&gt;&lt;br /&gt; Then we talked about Interfaces.  What they are, what they're used for, and why you would use them versus standard inheritance.&lt;br /&gt;&lt;br /&gt; Next, we talked about Exceptions.  The two types of exceptions, why to use throw versus try/catch, and how the Method Call Stack was used with Exceptions.&lt;br /&gt;&lt;br /&gt; Then we went into Threads.  He had me give an explanation of them, how to use them.  I gave him some code of how to create a new thread and gave him some examples of when we use them without explicitly creating (in someone else's code, like with Swing, as well as when processing http sessions).&lt;br /&gt;&lt;br /&gt; We talked about Reflection, what it is used for, and why it is used.  I had to give some code using the refection package.&lt;br /&gt;&lt;br /&gt; Next we went over databases.  He had me give him code to make a simple query on a table and print the results out.  He asked me a little about SQL also, like how to insert and delete stuff.&lt;br /&gt;&lt;br /&gt; We then talked about Unit Testing and Functional Testing.  I didn't know this.  It turns out unit testing tests one class while funtional testing tests an entire project.  He also asked me if I'd used Ant before.  I told him I used Make instead, but I think I'll look into Ant now.&lt;br /&gt;&lt;br /&gt; Lastly, we talked about J2EE.  Three types (servlets, JMS, web services).  We didn't go much into it since I didn't know much.  And that was the end of the interview.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;span style="font-weight: bold;"&gt;4/20&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; I had another interview; the people were very laid back there.  The first interviewer mostly asked me about what I had done before.  The coding questions were to write the code for a page of boxes with text in them, design a database layout for certain information, and then usin Javascript to resize a box when a button was clicked.  With the second guy, we mostly talked about a card shuffling algorithm I brought up when I said I made a card game before.  He told me about a "Perfect Shuffle", when cards interleave one by one.  7 (or 8) straight perfect shuffles result in the cards being in their original position, which is a technique used by card sharks.  He asked me what kind of stuff I wanted to work on before letting me go.  It was a pretty fun interview, all in all.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; &lt;span style="font-weight: bold;"&gt;4/25&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; First stage interview today; went through three people in about an hour and a half.&lt;br /&gt;&lt;br /&gt; First guy mostly talked to me about data structures.  Started off with asking me how I would index all the pictures on the internet and make sure not to index pictures multiple time.  I said to use a hash table.  Then he had me do some pointer logic in c.  How to reverse a string in place and how to copy one file to another.&lt;br /&gt;&lt;br /&gt; The second guy asked me a lot about my old work experience.  At the end he asked me one programming question, which was to write code copying&lt;br /&gt;&lt;br /&gt; The third guy mostly gave me puzzles to solve.  He asked me how many sugar cubes were in a cube that was 10 sugar cubes across and 10 sugar cubes high.  Then he asked me some kind of math problem about finding out how long it would take to run across a field.  Then, for some reason, he had me do some recusive programming: Just the Fibonacci code and traversing a tree.  He ended by asking me a badly worded problem.&lt;br /&gt;&lt;br /&gt; That problem ended up being this: Imagine you and your friend are on other sides of a river.  There is a box with two locks: you have the key to one of the locks and your friend has the key to the other lock.  Both locks need to be unlocked to open the box and the locks don't touch each other.  You want to deliver an important message to your friend, but you can't do it yourself and you don't want to risk anyone else seeing the message.  What do you do?&lt;br /&gt;&lt;br /&gt; Of course, once I clarified the problem, I realized it was an encryption abstraction and answered: "Put the message in the box, lock your lock, and have a messenger bring it to the friend.  He locks his lock and has the messenger return it to you.  You unlock your lock and have the messenger return it to your friend.  Now the friend unlocks his lock and takes out the document."  And that was the end of the interview.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-3511073829303841388?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/3511073829303841388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=3511073829303841388' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3511073829303841388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/3511073829303841388'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/12/interview-notes-1.html' title='Interview Notes 1'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-5607568560958889875</id><published>2006-11-22T08:53:00.000-08:00</published><updated>2006-11-22T08:54:28.145-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>SQLite 3 and Java</title><content type='html'>The other day, I went off about how great SQLite was and everything, as well as how to use it with Ruby.  Today I'll tell you how to use SQLite with Java.  Just download SQLite JDBC drivers from &lt;a href="http://www.ch-werner.de/javasqlite/javasqlite-20060714-win32.zip"&gt;here&lt;/a&gt;.  Figure out where sqlite.jar and sqlite_jni.dll (native file) are, allow your java program to find them, and then access your sqlite database using JDBC.  If you aren't familiar with jni and you're using windows, you can throw that DLL file into C:/WINDOWS.  Support is cake for anyone who has used Java before.  The documentation for the SQLite JDBC project can be found over &lt;a href="http://www.ch-werner.de/javasqlite/overview-summary.html"&gt;here&lt;/a&gt;.  As I said before, SQLite is a good database, especially for personal projects (where running your own database server is overkill) and quick testing.  Also, the SQLite SQL implementation supports more than the in-memory database HSQLdb does, which I feel is the other good alernative.  I'm liking SQLite more than HSQLdb.  But I'm probably especially whiny about HSQLdb right now, since it didn't support the SQL case-when statement that I wanted to use for my last project.&lt;br /&gt;&lt;br /&gt; As for examples... well, it's JDBC: the beauty of it is I don't need to give examples.  But since I have examples, here's some very brief code to create a connection.  If you don't know JDBC, &lt;a href="http://java.sun.com/javase/technologies/database/index.jsp"&gt;read the JDBC documentation from Sun&lt;/a&gt;, it's probably worth knowing regardless of what you program for.  With that, following this brief example (for which requires importing java.sql.Connection and having sqlite.jar and sqlite_jni.dll on your paths), I'm all done.&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;&lt;br /&gt;   &lt;span style="color:#444444;"&gt;// Load the Database Engine JDBC driver&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#2040a0;"&gt;Class&lt;/span&gt;.&lt;span style="color:#2040a0;"&gt;forName&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt; &lt;span style="color:#008000;"&gt;"SQLite.JDBCDriver"&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;;&lt;br /&gt;&lt;br /&gt;   &lt;/span&gt;&lt;span style="color:#444444;"&gt;// connect to the database&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#2040a0;"&gt;Connection&lt;/span&gt; &lt;span style="color:#2040a0;"&gt;conn&lt;/span&gt; &lt;span style="color:#4444ff;"&gt;=&lt;/span&gt; &lt;span style="color:#2040a0;"&gt;DriverManager&lt;/span&gt;.&lt;span style="color:#2040a0;"&gt;getConnection&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt; &lt;span style="color:#008000;"&gt;"jdbc:sqlite:/filename"&lt;/span&gt;, &lt;span style="color:#008000;"&gt;""&lt;/span&gt;, &lt;span style="color:#008000;"&gt;""&lt;/span&gt; &lt;span style="color:#4444ff;"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;;&lt;br /&gt;&lt;br /&gt;   &lt;/span&gt;&lt;span style="color:#444444;"&gt;//close the connection. So pointless.&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#2040a0;"&gt;conn&lt;/span&gt;.&lt;span style="color:#2040a0;"&gt;close&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/span&gt;&lt;span style="color:#4444ff;"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-5607568560958889875?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/5607568560958889875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=5607568560958889875' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/5607568560958889875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/5607568560958889875'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/11/sqlite-3-and-java.html' title='SQLite 3 and Java'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-5472705059432793037</id><published>2006-11-20T16:27:00.000-08:00</published><updated>2006-11-20T16:35:07.497-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>SQLite 3 and Ruby</title><content type='html'>As per my wife's request, I built a financial management spreadsheet application, because "we" needed to keep better track of our finances..  I'll probably go into that program some other day as it's actually proven useful.  But enough about that, today I want to talk about the database I used for it.  This database was SQLite 3.  If you haven't heard of it, SQLite is an ACID-compliant relational database management system contained in a relatively small C library where the SQLite library is linked in and thus becomes an integral part of the program with the database accessed through simple function calls.  Yes, that long run-on sentence was courtesy of wikipedia, copy, and paste.  In my words: SQLite is a database that exists as an easy to access text file (via c function calls) instead of requiring an external database server to be running somewhere waiting for requests.  A free and tiny embedded database with great SQL support.&lt;br /&gt;&lt;br /&gt;My program was written in &lt;a href="http://poignantguide.net/ruby/"&gt;ruby&lt;/a&gt;.  For database access, I used the sqlite3-ruby gem, which wraps up those c function calls with ruby.  If you're unfamiliar with gems, they're simply packaged ruby applications that allow easy installs.  Simply go to your command prompt and type in "gem install sqlite3."  This will work as long as you've installed ruby with gems and have an internet connection.&lt;br /&gt;&lt;br /&gt;Once you've installed the gem, you're all set.  To show how easy it is to use, I'll go through a short example.  This example creates a database with a table describing teams and a table describing how a certain team scored on a certain game.  It then queries the database in order to print out team rankings.  Yeah, it's an odd way to get that information, but it was part of a homework assignment I had.  I'm unsure whether the query is very good, but it's going to serve as my example.&lt;br /&gt;&lt;br /&gt;First, create your connection and (possibly) insert information thusly.&lt;br /&gt;&lt;pre&gt;&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;sqlite3&lt;/span&gt;&lt;span class="punct"&gt;'&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="keyword"&gt;if&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;!&lt;/span&gt;&lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;exists?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;test.db&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;  db&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;SQLite3&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Database&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;test.db&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="comment"&gt;#The database is automatically created&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;  db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;execute&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;create table team ( id INTEGER PRIMARY KEY, name VARCHAR(255) )&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;  db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;execute&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;create table team_gm ( id INTEGER PRIMARY KEY, game_id INTEGER, team_id INTEGER, score INTEGER )&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;  db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;execute&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;insert into team_gm values( 1, 1, 1, 5 )&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;  db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;execute&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;insert into team_gm values( 2, 1, 2, 5 )&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;  db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;execute&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;insert into team_gm values( 3, 2, 1, 3 )&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;  db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;execute&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;insert into team_gm values( 4, 2, 2, 6 )&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;else&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;  db&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;SQLite3&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Database&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;test.db&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;Then query and manipulate data thusly.  You've got lots of freedom here.  I suggest to at least &lt;a href="http://sqlite-ruby.rubyforge.org/faq.html"&gt;read the FAQ&lt;/a&gt; if you don't want to read all the documentation.&lt;br /&gt;&lt;pre&gt;&lt;span class="ident"&gt;query&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;select z.name, sum(case when x.score &amp;gt; y.score then 1 else 0 end) as wins, &lt;/span&gt;&lt;span class="punct"&gt;" +&lt;/span&gt;&lt;br /&gt;&lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;sum(case when x.score &amp;lt; y.score then 1 else 0 end) as losses, sum(case when x.score = y.score then 1 else 0 end) as ties from team_gm x &lt;/span&gt;&lt;span class="punct"&gt;" +&lt;/span&gt;&lt;br /&gt;&lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;join team z on x.team_id = z.id &lt;/span&gt;&lt;span class="punct"&gt;" +&lt;/span&gt;&lt;br /&gt;&lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;join team_gm y on x.game_id = y.game_id AND x.team_id &amp;lt;&amp;gt; y.team_id group by x.team_id &lt;/span&gt;&lt;span class="punct"&gt;" +&lt;/span&gt;&lt;br /&gt;&lt;span class="punct"&gt;"&lt;/span&gt;&lt;span class="string"&gt;order by wins-losses-ties desc&lt;/span&gt;&lt;span class="punct"&gt;"&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="ident"&gt;db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;execute&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt; &lt;span class="ident"&gt;query&lt;/span&gt; &lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;  print&lt;/span&gt; &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;0&lt;/span&gt;&lt;span class="punct"&gt;],"&lt;/span&gt;&lt;span class="string"&gt;: &lt;/span&gt;&lt;span class="punct"&gt;",&lt;/span&gt;&lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;2&lt;/span&gt;&lt;span class="punct"&gt;],"&lt;/span&gt;&lt;span class="string"&gt; Wins, &lt;/span&gt;&lt;span class="punct"&gt;",&lt;/span&gt;&lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;3&lt;/span&gt;&lt;span class="punct"&gt;],"&lt;/span&gt;&lt;span class="string"&gt; Losses, &lt;/span&gt;&lt;span class="punct"&gt;",&lt;/span&gt;&lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="number"&gt;4&lt;/span&gt;&lt;span class="punct"&gt;],"&lt;/span&gt;&lt;span class="string"&gt; Ties&lt;span class="escape"&gt;\n&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;"&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;And finally close your connection thusly.&lt;br /&gt;&lt;pre&gt;&lt;span class="ident"&gt;db&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;close&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;This database was exactly what I wanted and the sqlite ruby access is very simple.  Granted, I'm probably way behind for not having used this before (I've been using HSQLDB for my "easy" databases), but at least I know now.  I bet I'll be using it a lot now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-5472705059432793037?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/5472705059432793037/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=5472705059432793037' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/5472705059432793037'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/5472705059432793037'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/11/sqlite-3-and-ruby.html' title='SQLite 3 and Ruby'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-1638071319134872726</id><published>2006-11-13T07:59:00.000-08:00</published><updated>2006-11-13T08:03:30.148-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>Regular Expressions and Dates</title><content type='html'>Regular expressions are great and I think programmers should always keep in practice with them because you really never know when it'll be useful to parse through text.  When I was first learning Regular Expressions, I practised with dates.  Eventually, I made myself a short program in ruby.  It takes a string as input and if the string suggests a date, the program is supposed to figure out which date.  Lots of stuff can be done with that date, such as a report of the day of the week, how far in days the date is from today, or when the end of the month is.  All the calculations are trivial if a date is given.  The tricky part was determining if a string specified a date, and if so, extracting the date.&lt;br /&gt;&lt;br /&gt; As I said, I used regular expressions for figuring out what the date meant.  I thought of all the formats a user might use and made a case for each of them.  This has actually been a useful exercise and I've used the results of it a lot.  The following are all the cases that I could think of... I very much doubt that I got all of them.  Remember, this is for ruby, so the reg-exp formatting may be different for you.  The i means ignore case and \A and \Z can be used to specify the beginning and end of the string respectively.  The only way I can think of improving the recognition for now is to allow for spelling errors.  Can you think of any other ways a person might reasonably suggest a date as a string?  Here goes.&lt;br /&gt;&lt;br /&gt; 1. Of the format MM/DD/YY, MM-DD-YY, or MM\DD\YY.  YY may be YYYY in any of the cases.  This is the trickiest pattern, since the user may mean either Year/Month/Day or Month/Day/Year.  Two digits for the year makes it difficult to assume what the user meant.  I chose to use the Month/Day/Year form, unless the user uses four digits to specify the year, in which point it is easy to figure out what they meant.  Therefore, YYYY/MM/DD is also a valid format .  As for the year, if four digits are not specified, then I assume that they are specifying the current millineum (2000).&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;/\A(\d+)\s*(-|\/|\\)\s*(\d+)\s*((-|\/|\\)\s*(\d+))?/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; 2. Of the format "June 27, 1983", "Jun 27, 1983", or "June 27" (in which the current year is implied).  Granted Junileropwf 27, 1983 would also be valid here, but I didn't think such cases were important enough to detect and were instead a waste the readibility of the expression.  In specifying the month, a minimum of 3 characters are required.  The comma is optional, but at least one space must separate the tokens.  If a day and year are not specified, then day one of the specified month in the current year should be used.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;/(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)([^\s]* (\d+)(.*))?/i&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; 3. Of the format YYYYMMDD.  It has to be in that order, I didn't make allowances in this case.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;/(\d\d\d\d)(\d\d)(\d\d)/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;4. Of the format YYYY.  The date is interpreted as Jan 1 of the year YYYY.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;/(\d\d\d\d)/&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; 5. Last or Next or Current Day of the Week (ie last Thu, next Thursday, or Thursday).  I used a minimum of three letters for the weekday name to avoid matching cases I didn't want it to match.  Once again, I didn't test that the letters following the first three were correct because I didn't think it improved the match any more.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;/(last |next |this |)(sun|mon|tue|wed|thu|fri|sat).*/i&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; 6. Yesterday, today, tomorrow.  Also, my wife and I made up words Yupterday (the day before yesterday) and Threemorrow (the day after tomorrow.)  [--We wanted to make up for the lack of an English word for these common references.  Yes, we're pretty goofy people.  Please feel free to adopt the words.]  The test for these is really simple and reg-exp isn't even really needed.  It's actually less effecient if you want single matches, O(nm) instead of O(n).  Here's the case for the heck of it:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;/(today|tomorrow|yesterday|yupterday|threemorrow)/i&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; If you think the program I described might be useful, &lt;a href="http://aswembar.net/jed/dateInfo.html"&gt;here's the whole current version as html&lt;/a&gt;.  Do whatever you want with it.  I've found it useful and added a bunch of date converting methods for flavor (like get the end of the month, return day statistics, or get number of days between two dates) , but the heart of the whole thing is still the regular expressions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-1638071319134872726?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/1638071319134872726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=1638071319134872726' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/1638071319134872726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/1638071319134872726'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/11/regular-expressions-and-dates.html' title='Regular Expressions and Dates'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-8260851338665201935</id><published>2006-11-08T15:39:00.000-08:00</published><updated>2006-11-08T16:14:28.313-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Links'/><category scheme='http://www.blogger.com/atom/ns#' term='Funny'/><title type='text'>Some Funny Links</title><content type='html'>Today, I (probably stupidly) gave away the link to my blog to more people.  To make up for the low quality of my previous posts, I offer some of the funnier links I've come across.  Of course, they are probably the kind of humor that only I'd enjoy.  But at least I tried.  Yeah, these are all pretty old.&lt;br /&gt;&lt;br /&gt;General&lt;br /&gt;&lt;a href="http://www.somethingawful.com/index.php?a=140&amp;amp;p=2"&gt;An old He-Man storybook with commentary&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.aswembar.net/jed/funnyEssays/"&gt;English Papers&lt;/a&gt;&lt;a href="http://hokie.us/transcript.html"&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://seanbaby.com/superfriends/riddler.htm"&gt;How stupid Superfriends is looking back.  Specifically, the Riddler.&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.worldoflongmire.com/features/romance_novels/index.htm"&gt;Retitled Romance Novels&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;++ Images&lt;br /&gt;&lt;a href="http://aswembar.net/jed/hangman.jpg"&gt;Did I get the job?&lt;/a&gt;&lt;br /&gt;&lt;a href="http://aswembar.net/jed/findx.gif"&gt;Find X&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.penny-arcade.com/comic/2003/12/08"&gt;My favorite web comic strip.&lt;/a&gt;&lt;br /&gt;&lt;a href="http://aswembar.net/jed/bunny.jpg"&gt;Bunny&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;# Some Programming Humor&lt;br /&gt;&lt;a href="http://www.crisscross.com/forum/Worlds_worst_hacker%25_IRC_t%20ranscript/m_422436/tm.htm"&gt;1. Stupid Hacker&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ariel.com.au/jokes/The_Evolution_of_a_Programmer.html"&gt;2. Evolution of a Software Engineer&lt;/a&gt;&lt;br /&gt;&lt;a href="http://totl.net/PerlContest/"&gt;3. Clock in Perl&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Quotation of the day: "I like to throw sandwiches at the homeless.  It satisfies both my altruistic and sadistic urges."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-8260851338665201935?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/8260851338665201935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=8260851338665201935' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8260851338665201935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/8260851338665201935'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/11/today-i-probably-stupidly-gave-away.html' title='Some Funny Links'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-9000809145837670527</id><published>2006-11-06T22:04:00.000-08:00</published><updated>2006-11-20T16:08:11.052-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reads'/><category scheme='http://www.blogger.com/atom/ns#' term='Links'/><title type='text'>Good Free Reads</title><content type='html'>Stories are an important part of life.  Not only are they entertaining, but they can effect your life if you let them.  A good story will not only spark your imagination, but will give you new pespectives about the world.  Of course, there are a lot of times where stories just take too long to read.  I had a friend who brought books to work to read which he never ended up liking.  It took months to finish each book and along the way my friend would lose interest.  Good short stories would be way better for short bursts of reading, so I suggested some to him and he seemed to enjoy them a lot more.  It worked well.  And so I'll share with the internet in general.&lt;br /&gt;&lt;br /&gt;The following is a list of online stories (that probably don't justify this really long introduction.)  Although a bit on the computer geeky side, these are all stories that I think are especially good reads (which is why I wanted to share them.)  They are all free, excellent quick reads that focus on ideas and characters rather than visualization and are located on fairly unsuspicious urls.  In other words, they're ideal for fun short break or lunch time reading.  If you know of anything else you think I should add to this list, please please please e-mail me.  ^_^&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Stories&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;(1) &lt;a href="http://www.hatrack.com/"&gt;Orson Scott Card&lt;/a&gt;&lt;br /&gt;Without doubt, Orson Scott Card is my favorite author.  At his website, many short stories are provided.  Here are my favorites.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(a) &lt;a href="http://www.hatrack.com/osc/stories/atlantis.shtml"&gt;Atlantis&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;It's very long and takes a bit before it's interesting, but it's really good once it does.  If you've read Pastwatch, you might think you already read this... but you haven't, keep reading.&lt;br /&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(b) &lt;a href="http://www.hatrack.com/osc/stories/enders-game.shtml"&gt;Ender's Game&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    If you like the book and haven't read this, I think it's still worthwhile.  If you haven't heard of Ender's Game... after reading this, I'm sure you'll want to pick up the full novel.&lt;br /&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(c) &lt;a href="http://www.hatrack.com/osc/stories/homeless-in-hell.shtml"&gt;Homeless in Hell&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    It's a Christmas story about an interesting interpretation of Hell and Santa Clause.&lt;br /&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(d) &lt;a href="http://www.hatrack.com/osc/stories/missed.shtml"&gt;Missed&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    It's kinda on the sad side about a guy coping with death, please keep that in mind.  Quite short though.  One short break's worth.&lt;br /&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(e) &lt;a href="http://www.hatrack.com/osc/stories/prior-restraint.shtml"&gt;Prior Restraint&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    This is a pretty interesting story, but I can't say anything about it without kind of ruining it.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;(2) Neal Stephenson&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(a) &lt;a href="http://www.vanemden.com/books/neals/jipi.html"&gt;Jipi and the Paranoid Chip&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    Lots of very cool ideas, flow of thoughts, and character interaction.  As with Neal Stephenson's stuff, it has an abrupt ending.&lt;br /&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(b) &lt;a href="http://www.metaweb.com/wiki/wiki.phtml?title=Stephenson:Neal:The_Great_Simoleon_Caper"&gt;The Great Simolean Caper&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    Interesting, it touches upon some of his normal themes.  Smart characters, cool capers.  Ending isn't as abrupt as normal, I think.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;  (3) &lt;a href="http://www.baen.com/library/rcook.htm"&gt;Wizardry&lt;/a&gt;&lt;br /&gt;Rick Cook wrote a series that blends fantasy with programming.  Sound strange?  It really isn't that strange and it's actually really quite cool.  If you don't like fantasy or programming... then... maybe you should keep away.  The first two novels (of five) were made free.  They're the best ones anyways, in my opinion.  These novels are pretty short, but it should still take a few hours to get through them.  Maybe a week of lunches alone.&lt;br /&gt;&lt;br /&gt;(4) &lt;a href="http://project.baka-tsuki.net/index.php?title=Suzumiya_Haruhi"&gt;Suzumiya Haruhi no Yutsu&lt;/a&gt;&lt;br /&gt;This is a translation of a series of Japanese light novels.  Some chapters are long, but it's not difficult at all to find constant good stopping points.  This story is about a normal high school guy trying to deal with a very eccentric classmate who seems to unknowingly control the world and a bunch of supernatural people drawn to her.  It's a comedy, mostly.  Wiki for more information, but if you like Japanese comics/animation then this is an excellent find.  There's also an anime of this series.&lt;br /&gt;&lt;br /&gt;(5) &lt;a href="http://www.rinji.tv/densha/"&gt;Densha Otoko original posts&lt;/a&gt;&lt;br /&gt;Umm... this is the black sheep of the list.  It's not really a story, although it does tell a story.  It's an organized, edited version of a forum thread that chronicles the relationship between an otaku (japanese super geek) at the thread asking for help and a non-otaku woman he had helped.  It's pretty fun to read though... a very geeky romance story.  Also, a Japanese drama came out of this (also called Densha Otoko), and it's pretty funny.&lt;br /&gt;&lt;br /&gt;(6) &lt;a href="http://www.qiqi.com/cgi-bin/bk2.pl?fd1=book&amp;amp;fd2=wx&amp;fd3=jinyong&amp;amp;in=jy01"&gt;The Book and the Sword&lt;/a&gt;&lt;br /&gt;A great Chinese story to complement the Japanese stories.  While the book is very long, the story arcs in the book are actually very episodic and pretty short.  The Book and the Sword is a kung fu novel by Jin Yong and it's a really fun read.&lt;br /&gt;&lt;br /&gt;(7) &lt;a href="http://adin.dyndns.org/adin/TheLastQ.htm"&gt;The Last Question&lt;/a&gt;&lt;br /&gt;I can't really say I like Asimov's writing.  I mean, I like his ideas and I do understand why he's important to sci-fi, but I don't like his writing style and so I rarely have fun reading his stuff.  The ideas carry this story pretty well though.  Since this was a pretty well thought out story, very famous, and a very quick read I decided to list it here.  Passes the time on a very slow day, at the very least.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Essays&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The following is a list of my favorite online essays.  Any programmer and many non-programmers should find many excellent reads in this list.  What's here deals primarily with introductions to ideas, examples of thought flows, productivity boosters, and springboards to interesting topics.  While some are technical, they don't delve very deeply into the actual technology, instead giving you enough information to decide if you want to devote the time to really learn the topic.  With all that said, here's the list.  All good reads.  If you know of anything else you think I should add to this list, please please please e-mail me.  ^_^&lt;br /&gt;&lt;br /&gt;(1) &lt;a href="http://www.hatrack.com/"&gt;Orson Scott Card&lt;/a&gt;&lt;br /&gt;Yep, my favorite author again.  In addition to novels, he also does a lot of reviews and world commentaries on his web site.  I find them interesting, even if I don't agree with everything that he says.   These essays were carefully chosen by me as the ones that were the most interesting and thought-provoking to me.  Read more of them if you'd like, as most of them are quite interesting.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(a) &lt;a href="http://www.ornery.org/essays/warwatch/2005-02-20-1.html"&gt;Why Making Choices is So Hard&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    This is the first of OSC's essays that resonated with me.  This talks about making choices.&lt;br /&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(b) &lt;a href="http://www.ornery.org/essays/warwatch/2005-09-11-1.html"&gt;Freakonomics&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    A review of Freakonomics, which is an interesting book.  It also takes an example from the book and expands upon it, reaching another theory.  I like seeing people's thoughts flow and this essay has a lot of very nice examples of thinking about cause and effect, as well as morality.&lt;br /&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(c) &lt;a href="http://www.ornery.org/essays/warwatch/2005-07-24-1.html"&gt;Weapons of Mass Destruction&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    This one provides interesting thoughts about what makes a weapon a WMD as well as some commentary about how OSC thinks the balance in the world works.&lt;br /&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(d) &lt;a href="http://www.ornery.org/essays/warwatch/2005-06-19-1.html"&gt;Taking Animals Seriously&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    This one is very interesting.  It contains a lot of ideas about how people think, as well as how different people see the world.  It does this by focusing on an autistic author who has devoted her life to making animal slaughterhouses more humane.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;  (2) &lt;a href="http://steve.yegge.googlepages.com/"&gt;Steve Yegge's Essay Collection&lt;/a&gt;&lt;br /&gt;&lt;a href="http://steve-yegge.blogspot.com/"&gt;Link to his current blog&lt;/a&gt;&lt;br /&gt;Steve Yegge writes a lot.  His writings made me begin to really improve my programming and they constantly cause me to evaluate the way I think about things.  That's why I believe these are very important.  I think every programmer should read these because after reading, whether or not you agree, you will have thought a lot.  Especially the fresher programmers, like me.  Plus, they're pretty entertaining and he says funny stuff.  I chose to list my favorite essays. Narrowing them down is difficult since I found it very worthwhile reading them all.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(a) &lt;a href="http://steve.yegge.googlepages.com/tour-de-babel"&gt;Tour De Babel&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(b) &lt;a href="http://steve.yegge.googlepages.com/why-you-should-blog"&gt;You Should Write Blogs&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(c) &lt;a href="http://steve.yegge.googlepages.com/five-essential-phone-screen-questions"&gt;Five Essential Phone Screen Questions&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(d) &lt;a href="http://steve.yegge.googlepages.com/practicing-programming"&gt;Practicing Programming&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(e) &lt;a href="http://steve.yegge.googlepages.com/saving-time"&gt;Saving Time&lt;/a&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(f) &lt;a href="http://steve.yegge.googlepages.com/practical-magic"&gt;Practical Magic&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(3) &lt;a href="http://www.spack.org/wiki/InTheBeginningWasTheCommandLine"&gt;In the Beginning, there was the Command Line&lt;/a&gt; by Neal Stephenson&lt;br /&gt;In the End, I find this horribly long, boring in places, and a little out of date.  But since I didn't grow up during the era, I ended up learning a huge amount from this.  Some of the ideas are interesting, especially if you're pretty new computers.  If you really enjoyed this, &lt;a href="http://www.wired.com/wired/archive/4.12/ffglass_pr.html"&gt;Mother Earth Mother Board&lt;/a&gt; is freely available too.  This is another monstrously long essay... it might as well be a novel.  It's about Neal Stephenson following FLAG, a global undersea fiber optic cable.  He comments a lot about the history and politics around FLAG, as well as about his surroundings.  But some spots are way too slow for me.&lt;br /&gt;&lt;br /&gt;(4) Joel on Software: &lt;a href="http://www.joelonsoftware.com/articles/BestSoftwareWriting.html"&gt;Best Software Writing&lt;/a&gt;&lt;br /&gt;&lt;a href="http://brevity.org/misc/bestswi.html"&gt;Essay Links for Best Software Writing&lt;/a&gt;&lt;br /&gt;&lt;a href="http://joelonsoftware.com/Archive.html"&gt;Archive Links&lt;/a&gt;&lt;br /&gt;Joel on Software is one of those famous blogs with lots of entries worth reading.  I can't think of anything in particular, except maybe this post.  He released a compilation of what he felt were the best programming related essays of the year 2005.  They really are some of the best software essays.  Plus he talked about what makes writing good.  The second link I've provided gives links to all the essays he chose.  The last link is to his archives for his major blog entries.  You may as well just start with the first essay there and work your way down.&lt;br /&gt;&lt;br /&gt;(5) Random Tech Essays&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(a) &lt;a href="http://sztywny.titaniumhosting.com/2006/07/23/stiff-asks-great-programmers-answers/"&gt;10 Question, 8 Programmers&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    This was a very interesting interview.  10 questions which 8 well-known programmers answer.  Very, very interesting and a very cool idea.  Everyone aspiring to be a good programmer should give this a read because it's good to know how those among "the best" view the field.&lt;br /&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(b) &lt;a href="http://www.defmacro.org/ramblings/fp.html"&gt;Lisp for Imperative Programmers&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    This is an introduction to functional programming where the reader is assumed to know only about procedural programming.  Anyways, if you're a purely procedural programmer (C, Java, Ruby, etc..) and wanted to know what functional programming was all about, I can't think of any better read than this.&lt;br /&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(c) &lt;a href="http://www.techsupportalert.com/best_46_free_utilities.htm"&gt;The Best 46 Free Utilities&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    This is a list of what the author considers the best windows free utilities for various tasks.  I like his suggestions and this is the first place I will go if I want to find a new tool.  Hey, it's kind of like an essay.&lt;br /&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(d) &lt;a href="http://www.fastcompany.com/magazine/06/writestuff.html"&gt;Programming Rock Solid Code&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    This is an interesting piece about the work environment of a place that must write the code to launch and run a multi-billion dollar shuttle.&lt;br /&gt;&lt;/div&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(e) &lt;a href="http://inst.eecs.berkeley.edu/%7Emaratb/readings/NoSilverBullet.html"&gt;No Silver Bullet&lt;/a&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    A classic CS essay about programming tools and languages.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-9000809145837670527?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/9000809145837670527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=9000809145837670527' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/9000809145837670527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/9000809145837670527'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/11/recently-while-driving-home-from-work.html' title='Good Free Reads'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-1773406441635801304</id><published>2006-11-04T21:45:00.000-08:00</published><updated>2006-11-10T08:50:52.641-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Reads'/><category scheme='http://www.blogger.com/atom/ns#' term='Links'/><title type='text'>Jin Yong's Wuxia</title><content type='html'>&lt;span style="font-weight: bold;"&gt;  Quick Summary of Links:&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.qiqi.com/cgi-bin/bk2.pl?fd1=book&amp;amp;fd2=wx&amp;fd3=jinyong&amp;amp;in=jy01"&gt;Romance of the Book and Sword&lt;/a&gt; (&lt;a href="http://www.amazon.com/gp/product/0195907272/ref=pd_luc_21_0_r1c2_a2_i/103-6163007-3571823"&gt;Buy the translation&lt;/a&gt;)&lt;br /&gt;&lt;a href="http://www.qiqi.com/cgi-bin/bk2.pl?fd1=book&amp;amp;fd2=wx&amp;fd3=jinyong&amp;amp;in=jy02"&gt;Sword of the Yueh Maiden&lt;/a&gt;&lt;br /&gt;&lt;a href="http://wuxiapedia.com/novels/jin_yong/divine_eagle_gallant_knight"&gt;Return of the Condor Heroes (Divine Eagle, Gallant Hero)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://wuxiamania.phorumz.com/wuxiamania.html"&gt;Wuxia English Forum&lt;/a&gt;&lt;br /&gt;&lt;a href="http://wuxiapedia.com/"&gt;Wuxia Fan Translations&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Actual Entry:&lt;/span&gt;&lt;br /&gt;I've been reading Jin Yong's (aka Louis Cha) Wuxia novels recently.  Jin Yong is known as one of the best Wuxia writers.  He created 15 Wuxia stories that are famous throughout a lot of the world.  I've read three of the stories (soon to be four), but that's only because it's all the translated-into-english text I can find.  If I could read Chinese, I could just read it all from &lt;a href="http://www.qiqi.com/cgi-bin/bk2.pl?fd1=book&amp;amp;fd2=wx&amp;fd3=jinyong&amp;amp;in=jinyong"&gt;here&lt;/a&gt; (but it's all simplified.)&lt;br /&gt;&lt;br /&gt;Maybe I'm getting ahead of myself.  Wuxia is a genre that comes out of China and literally means "martial arts heroes."  They take place in China's past, usually among real events, but everyone's abilities are hyper exaggerated.  It's a blend of philosophy, conflicting honor codes, and fantasy martial arts.  The best I can compare it to in western culture would be modern takes on Arthurian or Robin Hood stories.  I guess Westerns are kind of similar also.  If you've seen "Crouching Tiger, Hidden Dragon", that's an example of a wuxia story.  Except Jin Yong's stories are much better than these examples, and a lot more stuff happens involving much cooler characters.&lt;br /&gt;&lt;br /&gt;If you like shonen japanese stories, there is no doubt you'll love the stories Jin Yong has written.  In fact, you'll very likely like the novels more than those comics.  I'm pretty sure almost all the really good anime fighting ideas (with the chi or martial arts moves) were stolen from China.  The fighting used is really interesting and very well imagined.  The novels have lots of romance elements, political plots, and technique-laden action.  The characters are all really cool and interesting.&lt;br /&gt;&lt;br /&gt;So far, I've read the Book and the Sword, Return of Condor Heroes, and Sword of the Yueh Maiden.  I've ordered Deer and the Cauldron... but it's pretty pricey at $35 for each of the three books that make the story up.  Each book I've read has been very good.  Read Sword of the Yueh Maiden if you're doubtful.  It's the only short story of Jin Yong's novels and it's a great taste of what the genre is like.  For a full listing of his stories, please &lt;a href="http://en.wikipedia.org/wiki/Jin_Yong"&gt;consult his wikipedia entry&lt;/a&gt;, from which you can also get summaries.  Beware of spoiling yourself though.  I'm going to go over the works that are completely available in English.  There are a lot of translations of his, but most of them are in progress works.&lt;br /&gt;&lt;br /&gt;Sword of the Yueh Maiden is a short story about two nations at war with each other.  &lt;a href="http://www.qiqi.com/cgi-bin/bk2.pl?fd1=book&amp;amp;fd2=wx&amp;fd3=jinyong&amp;amp;in=jy02"&gt;You can read it in English here&lt;/a&gt;.  The weaker nation isn't weaker by much: its only problem is that the swordsmen of the other nation are far stronger.  The story is about one of the court advisors looking for a way to overcome this weakness.&lt;br /&gt;&lt;br /&gt;The Book and the Sword can be &lt;a href="http://www.qiqi.com/cgi-bin/bk2.pl?fd1=book&amp;amp;fd2=wx&amp;fd3=jinyong&amp;amp;in=jy01"&gt;read here&lt;/a&gt; and &lt;a href="http://www.amazon.com/gp/product/0195907272/ref=pd_luc_21_0_r1c2_a2_i/103-6163007-3571823"&gt;bought here&lt;/a&gt;.  It's about the actions of a very heroic secret society.  It starts with several rescue plots until the "big secret" is uncovered.  It has a large cast of characters, such as Chen who fights using go stones and a whip to hit accupoints.  There's also the lightning fast one-armed brother and the Mastermind strategist brother.  These characters are naturally all ranked in their organization.  There are great and powerful female characters as well.  It's all great fun.&lt;br /&gt;&lt;br /&gt;Return of Condor Heroes follows the growth of a boy named Yang Guo and his relationship with his teacher Xiaolongnu.  Yang Guo is the brilliant son of a defeated villian and no one wants him to grow up like his father.  However, all his masters treat him poorly so he runs away to a cave where he becomes the student of Xiaolongnu.  Lots and lots of stuff happen from there and Yang Guo grows stronger and stronger even despite bad things happening all the time.  It's been fan translated and &lt;a href="http://wuxiapedia.com/novels/jin_yong/divine_eagle_gallant_knight"&gt;that translation can be found her&lt;/a&gt;&lt;a href="http://wuxiapedia.com/novels/jin_yong/divine_eagle_gallant_knight"&gt;e&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The Deer and the Cauldron was translated into English and released as three installments.  &lt;a href="http://www.amazon.com/Deer-Cauldron-Louis-Cha/dp/0195903234/ref=pd_sim_b_1/103-6163007-3571823"&gt;Book one can be purchased here&lt;/a&gt;, &lt;a href="http://www.amazon.com/gp/product/0195903250/ref=pd_luc_21_0_r1c1_a1_i/103-6163007-3571823"&gt;book two can be purchased here&lt;/a&gt;, and &lt;a href="http://www.amazon.com/gp/product/0195903277/ref=pd_rvi_gw_1/103-6163007-3571823"&gt;book three can be purchased here&lt;/a&gt;.  I haven't read it yet, but it's supposed to be funny.  I will update this when I get to read it.&lt;br /&gt;&lt;br /&gt;The Fox Volant of the Snowy Mountain was also translated into english and &lt;a href="http://www.amazon.com/gp/product/9622017339/ref=pd_rvi_gw_3/103-6163007-3571823"&gt;can be purchased here&lt;/a&gt;.  However, I've heard that the translation was really bad.&lt;br /&gt;&lt;br /&gt;Unfortunately for me, these books have been adapted into TV series, which I've been spending a lot of energy recently obtaining and then a lot of time watching.  These series all last about 40 episodes and it's still not really enough time to show all the events from the novels.  Furthermore, these things are pretty much corny and horrible as far as I've seen.  They try to rely on cg effects that would be embarrassing in a old playstation game and really has no business in a live action film.  I also don't like all the unnatural sounding voice dubs.  Despite all my problems with them, I keep watching and am slowly beginning to enjoy it.  The stories are good and every once in a while, things are done right (read: not ridiculously poorly.)  The only one I've seen like that so far is Tian Long Ba Bu 2002.  Return of Condor Heroes 2006 was ridiculous, but the actors looked too cool to complain too much.  Okay, mostly Liu Yifei.&lt;br /&gt;&lt;br /&gt;Tian Long Ba Bu follows three fairly different heroes whose paths constantly intertwine.  There are a lot of characters here and a lot of twists.  It's a fun series to watch and no segment really drags for very long.  Some story arcs are especially gripping.  The best thing is that there are so many characters that are very likable and all the different storylines are equally interesting.  The thing that makes this a good tv series is the (relatively) low use of CG, the good casting, and the actually fun to watch fight scenes.  I hope I can find another adaptation like this.&lt;br /&gt;&lt;br /&gt;I want to mention that, so far, Jin Yong's stories are the only wuxia I've read that I'd really recommend at this point.  I've gone through &lt;a href="http://wuxiapedia.com/novels/gu_long/the_sword_and_the_exquisiteness"&gt;The Sword and the Exquisiteness&lt;/a&gt; and &lt;a href="http://wuxiapedia.com/novels/gu_long/sentimental_swordsman_ruthless_sword"&gt;Sentimental Swordsman, Ruthless Sword&lt;/a&gt; by another very famous wuxia author, Gu Long.  While I did read through them both, I didn't like them very much.  I couldn't relate to his characters and I felt that they were very one dimensional - a few very good, many very bad, or some inconsequential.  I do not feel that he built a very compelling or deep world for his stories to take place.  I read &lt;a href="http://en.wikipedia.org/wiki/Gu_Long"&gt;his wiki entry&lt;/a&gt;, and I think that the differences I saw between Gu Long and Jin Yong are reflected in the ways that they led their lives.&lt;br /&gt;&lt;br /&gt;And that's all I've got to say.   I just wanted you to give this genre a try if you haven't already, y'know, bring it to your attention.  I had no idea about the quality of this stuff until I happened by it after reading the wiki entry on the movie Kung Fu hustle.  I mean, you want to open your horizons and see what popular Chinese fiction is like, right?  I tried to explain it, but there was no way I could do the stories justice.  So please just follow any of the links I gave earlier and give it a try.   If you'd like more information, read &lt;a href="http://en.wikipedia.org/wiki/Jin_Yong"&gt;Jin Yong's wikipedia entry&lt;/a&gt;, the &lt;a href="http://wuxiapedia.com/"&gt;fan translation base&lt;/a&gt;, and &lt;a href="http://wuxiamania.phorumz.com/wuxiamania.html"&gt;this forum&lt;/a&gt;.  I'll update this entry as I get more information and as more translations are completed.&lt;br /&gt;&lt;br /&gt;Oh, and one last thing slightly related thing.  I recently found a freely available translation of the Romance of the Three Kingdoms.  If that interests you, &lt;a href="http://www.threekingdoms.com/"&gt;take a look over here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-1773406441635801304?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/1773406441635801304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=1773406441635801304' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/1773406441635801304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/1773406441635801304'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/11/jin-yongs-wuxia.html' title='Jin Yong&apos;s Wuxia'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-116236401022196733</id><published>2006-10-31T22:53:00.000-08:00</published><updated>2006-11-06T22:29:46.292-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Essential Program End</title><content type='html'>So it did end up taking a full month for me to list all my much-loved programs after all.  I don't think I'll be doing it again.  Instead, &lt;a href="http://aswembar.net/jed/free_files/XPEnvironment.html"&gt;I'm going to put up the full list of my essential programs over here&lt;/a&gt;, which I'll keep updated with all the good stuff I find and use.  I don't think that this will happen very frequently, except with those firefox plugins.  I also added a section for the quick games that I like to have around; a solitaire hater's solitaire.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-116236401022196733?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/116236401022196733/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=116236401022196733' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/116236401022196733'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/116236401022196733'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/10/essential-program-end.html' title='Essential Program End'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-116226184726387177</id><published>2006-10-30T18:29:00.000-08:00</published><updated>2006-11-05T07:27:25.501-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Essential Programs 1: Nifties</title><content type='html'>These are applications I love... but I guess I could live without.  They make my life easier and help keep my eyes, brain, and wrists happy.  For me, they are necessary applications for convenience.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://ccollomb.free.fr/unlocker/"&gt;Unlocker&lt;/a&gt;&lt;br /&gt;I organize (read: cut and paste) my directories a lot and use external drives frequently.  Windows is pretty stupid sometimes (read: very often) and annoyingly locks files so that they can't be moved or deleted and the external drive can not be stopped.  Using this program, it's very easy to free things up (right click and click unlock over any file or folder.)  Now you can delete and move stuff or stop your external drive.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.ntwind.com/software/taskswitchxp.html"&gt;TaskSwitch XP&lt;/a&gt;&lt;br /&gt;Much desired (by me anyway) improvement to alt-tab.  It allows the window to be "stickied" and it will not close unless the enter or escape key is pressed.  Also, it allows you to exclude programs from the list, move minimized windows to the end, and all kinds of other convenient things.  Download it, play with it, and if you don't like it remove it.  But you'll probably like it.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.uwe-sieber.de/usbstick_e.html"&gt;EjectMedia / RemoveMedia&lt;/a&gt;&lt;br /&gt;To safely remove external disks (like an external hard drive or a USB drive), you normally have to right click some icon, double click another, right click again, and finally tell windows to stop the disk.  These programs allow you to do this in one step: "EjectMedia.exe E:".  Tie it into your Super Smart Windows Input/Output Box and you get a much simpler way of stopping your devices.  You could also script it together with Unlocker for better use.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.microsoft.com/windowsxp/downloads/powertoys/xppowertoys.mspx"&gt;TweakUI&lt;/a&gt;&lt;br /&gt;This allows you to tweak a bunch of stuff in windows.  Like... it let's you remove the recycle bin from the desktop, customize displays... man, too many stuff.  Just download it and play through the options.  If you don't see anything useful, just uninstall it.&lt;br /&gt;&lt;br /&gt;() More Firefox Extensions&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;    () &lt;a href="https://addons.mozilla.org/firefox/52/"&gt;Statusbar Clock&lt;/a&gt;&lt;br /&gt;  Puts a clock in the status bar.  I use dual screens, usually with firefox opened, so this allows me to see the time when I look at the bottom right no matter what.  This is important to me, though it may not be for most people.  I just really like to know the time.&lt;br /&gt;&lt;br /&gt;() &lt;a href="https://addons.mozilla.org/firefox/1280/"&gt;Clear Private Data Button&lt;/a&gt;&lt;br /&gt;  Adds a button to clear private data.  It's useful when you need it.&lt;br /&gt;&lt;br /&gt;() &lt;a href="https://addons.mozilla.org/firefox/879/"&gt;Mouseless Browsing&lt;/a&gt;&lt;br /&gt;  This is an extension that I love the concept of, but I still think needs a little work.  Essentially, it assigns numeric ids to links so that you can quickly select the links without needing to use a mouse.  However, sometimes it can take quite a while to assign all the numeric ids, which makes the whole thing pointless.  I would like it a lot more if I could have it automatically be on for certain sites.  Nevertheless, I like the extension a lot and I do use it when I really want to avoid the mouse.&lt;br /&gt;&lt;br /&gt;  () &lt;a href="http://perso.orange.fr/marc.boullet/ext/extensions-en.html"&gt;All-In-One Gesture&lt;/a&gt;&lt;br /&gt;  This allows you to do tasks (like back and forward and close) by using the mouse.  I'm still undecided whether or not I really like this.  I'm not quite sure how much it gets in my way and causes me to do stuff on accident.  The only gestures I occasionally use are for back (left), forward (right), next page (&amp;gt;), previous page (&amp;lt;), and close (down) anyways.  I dunno... I'm generally anti-mouse anyways also... but even though I rarely use it, it is really cool idea...&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.customizegoogle.com/"&gt;Customize Google&lt;/a&gt;&lt;br /&gt;  Another one that I'm not quite sure if I really like or not.  I don't want to block google ads and the customization doesn't really mean that much to me.  Mostly, I like the google images links going directly to the real image.  Is it worth having a whole extra extension for this?  I don't really know.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-116226184726387177?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/116226184726387177/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=116226184726387177' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/116226184726387177'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/116226184726387177'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/10/essential-programs-1-nifties.html' title='Essential Programs 1: Nifties'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-116165320639636226</id><published>2006-10-23T18:24:00.000-07:00</published><updated>2006-11-05T07:27:13.227-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Essential Programs 1: Occasionally Essential</title><content type='html'>I use these, but not all that much, so I wouldn't really say I *need* them.  They are incredibly useful the times I do need them, which might happen a few times a month, if that.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.daemon-tools.cc/dtcc/download.php"&gt;Virtual CD: D-Tools&lt;/a&gt;&lt;br /&gt;Every once in a while, I find this useful.  It allows you to load a cue/iso file as a real CD.  I prefer it to Alcohol 120%.  Also, It's free.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://office.microsoft.com/en-us/default.aspx"&gt;Office: Microsoft Office&lt;/a&gt;&lt;br /&gt;Sometimes Microsoft Word and Excel are necessary, so... I very rarely use this stuff anymore though, mostly just when people send me stuff or expect me to send them stuff that is in these formats.  I prefer html tables to organize my lists and text documents nowadays for my&lt;br /&gt;work.  At work, I do use Excel frequently though.  Too bad the suite isn't free.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://ww2.nero.com/enu/index.html"&gt;CD/DVD Burning: Ahead Nero&lt;/a&gt;&lt;br /&gt;Yeah, this is common and it's not free (though you get it with most of your Burners nowadays).  I rarely burn stuff anymore (external hard drives and usb drives have replaced most of my needs for cd/dvd), but when I do need to create a cd/dvd, this is what I use.  Perhaps it's not the best tool.  I really don't care.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://msdn.microsoft.com/vstudio/"&gt;Visual Studio&lt;/a&gt;&lt;br /&gt;For C# and windows application development.&lt;br /&gt;&lt;br /&gt;() More Firefox Plugins&lt;br /&gt;&lt;br /&gt;&lt;div style="margin-left: 40px;"&gt;() &lt;a href="http://ietab.mozdev.org/"&gt;IETab&lt;/a&gt;&lt;br /&gt;(Text stolen from joelonsoftware) IETab takes advantage of the fact that Internet Explorer is available as an ActiveX control, which is available to be embedded in any Windows application, to open certain websites in Firefox using Internet Explorer. Whenever a website comes up complaining that you need to get "Netscape 4.0 or some&lt;br /&gt;other modern browser" you can just right click on the tab and it'll pop up right in Firefox being rendered by Internet Explorer. You can set up a list of websites that always come up in IE tabs.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://chrispederick.com/work/webdeveloper/"&gt;Web Developer Extension&lt;/a&gt;&lt;br /&gt;This helps web developing an incredible amount.  I can't imagine not using this toolbar and trying to design a site.  It lets you disable anything, resize the window, mark boundaries, validate code, and tons more.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-116165320639636226?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/116165320639636226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=116165320639636226' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/116165320639636226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/116165320639636226'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/10/essential-programs-1-occasionally.html' title='Essential Programs 1: Occasionally Essential'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-116153560063160570</id><published>2006-10-22T09:43:00.000-07:00</published><updated>2006-11-05T07:27:00.478-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Essential Programs 1: Essentials B</title><content type='html'>() &lt;a href="http://vapaa.dc.inet.fi/%7Erainy/index.php?pn=projects&amp;amp;project=rainmeter"&gt;System Measurements: Rainmeter&lt;/a&gt;&lt;br /&gt;This program is a bunch of meters.  It has a plug-in architecture that allows you to measure anything you want, but I find plug-in writing... very time-consuming, though I wrote some that I use.  Most importantly, it does all the measurements of the task manager.  However, it stays on your desktop and you can (somewhat) easily configure the appearance.  I admit that this kind of slows down the system and isn't all that necessary... but... I can't help but use it because it looks cool.  I have a key combination that pops it up on the screen for me.  Here's a snapshot of my set-up:.  And here's some skins.&lt;br /&gt;   () Skin Set I use.  It's a modification of other skins that I found.&lt;br /&gt;   () Original Ayuka Skin in English&lt;br /&gt;   () Original To Heart 2 Skin&lt;br /&gt;   () Good weather set&lt;br /&gt;  &lt;br /&gt;() &lt;a href="http://www.winamp.com/"&gt;MP3 Player: Winamp&lt;/a&gt;&lt;br /&gt;Okay, I really have no good reason for using this other than it was my first MP3 player.  My wife prefers the Windows Media Player, and most people use iTunes now (it seems)... but, I stick with winamp.  I don't really configure it at all (I have four different playlists and make sure breaks between songs are clear).  All I use it for is listening to MP3s, which I can queue (but so can everything else).  Well, although I don't strongly recommend it, I've never been dissatisfied with it, so that is that.  I use an old kare-kano skin for it because I haven't spent any time looking for new ones.  But it is really annoying that winamp does not internally support Unicode (or any other kind of language support).&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.eset.com/"&gt;Anti-Virus: NOD32&lt;/a&gt;&lt;br /&gt;This is not free at all, but it's the best Anti-Virus program I know of.  It catches a lot of stuff Norton and Symantec don't catch, and that doesn't seem to happen the other way around.  Anyways, you can search for free anti-virus programs if the cost for such an important program is an issue (but in that case, why are you using xp instead of a unix-like system?)&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.lavasoftusa.com/software/adaware/"&gt;Anti-Spyware: AD Aware&lt;/a&gt;&lt;br /&gt;Not that good, but it gets rid of spyware.  I'm currently looking for a replacement to this.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.321download.com/LastFreeware/index.html#jv16"&gt;Registry Cleaner: RegCleaner&lt;/a&gt;&lt;br /&gt;Based on what I've seen, I believe that cleaning the registry helps.  This is the best free registry cleaner that I've found and I've read it has one of the lower chances of messing things up.  Lots of people suggest the general tool CCleaner to me, but I don't like it as much.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://filezilla.sourceforge.net/"&gt;FTP Client: Filezilla&lt;/a&gt;&lt;br /&gt;A simple to use FTP Client that has all the features you'd expect.  It's also completely free, which is a huge plus to me.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.cygwin.com/"&gt;Cygwin&lt;/a&gt;&lt;br /&gt;Umm... &lt;a class="linkification-ext" href="http://en.wikipedia.org/wiki/Cygwin" title="Linkification: http://en.wikipedia.org/wiki/Cygwin"&gt;http://en.wikipedia.org/wiki/Cygwin&lt;/a&gt;.  Either you need at and have it, or you have no idea what you'd do with it.  I guess there's that slim chance you need it and haven't heard of it... but... well, just read up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-116153560063160570?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/116153560063160570/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=116153560063160570' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/116153560063160570'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/116153560063160570'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/10/essential-programs-1-essentials-b.html' title='Essential Programs 1: Essentials B'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-116044400089649028</id><published>2006-10-09T18:31:00.000-07:00</published><updated>2006-11-05T07:25:50.237-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Essential Programs 1: Essentials A</title><content type='html'>() &lt;a href="http://www.textpad.com/"&gt;Text Editor: TextPad 4&lt;/a&gt;&lt;br /&gt;This program isn't free (though there is a never-expiring evaluation version) and isn't really all that great (compared to vi and emacs, anyways).  However, I've been using it for my windows development for a while and I really got it customized to my likings, so I stick with it.  I hope to migrate over to emacs soon, but the learning curve for a good Text Editor is just so steep and I'll have to translate all my plugin code.  So for now, I've got this.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.free-codecs.com/download/K_Lite_Codec_Pack.htm"&gt;Video Codecs: K-Lite Codec Mega Pack&lt;/a&gt;&lt;br /&gt;This is all that you need in order to play video on your windows machine.  Whenever you find a new video format you can't play, all that means is that you haven't gotten the latest codec pack.  It comes with the "Windows Media Classic" and "BSPlayer" players.  Personally, I use "Windows Media Player Classic."  Make sure you get the "Mega Pack" version, otherwise you don't get Real Media and Quicktime alternatives.&lt;br /&gt; &lt;br /&gt;() &lt;a href="http://azureus.sourceforge.net/"&gt;BitTorrent Client: Azureus&lt;/a&gt;&lt;br /&gt;For me, this had the best download speeds of the three I tried (uTorrent, BitComet, Azureus).  This could have merely been coincidence, so I'll be redoing my tests soon and my client may change as a result.  However, I really like the plugin architecture and there are a few plugins that I really love.  Plus, I've got lots of memory and I grew up on Java.  The plugins I really like are:&lt;br /&gt;   (1) Auto Speed&lt;br /&gt;   (2) Auto Scheduler&lt;br /&gt;   (3) SafePeer&lt;br /&gt;&lt;br /&gt;() Super Smart Windows Input/Output Program: Windows Miko&lt;br /&gt;The mouse slows you down.  While it's great for intuitive design, it's horrible to use for things you do a lot.  I know it hurts my wrist, slows me down, and annoys me in general.  And so I really suggest writing what I call a "Super Smart Windows Input/Output Program."  It's basically a command prompt (I really miss using *nix at work), except more catered to your needs.  "Windows Miko" is my implementation, written in Ruby.  The main idea is that you type something, and Miko does something as a response (opens a web page, makes a note, gives you information, does a calculation, launches a program...).  It uses regular expressions and is very extensible.  She has a plug-in personality and appearance also.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.pssoftlab.com/pshl_info.phtml"&gt;Hot Launcher: PS Hot Launch&lt;/a&gt;&lt;br /&gt;This application allows you to run programs from key presses.  There are some keys and combinations it doesn't allow you to use, but letters, numbers, alt, shift, and win are all available in any combination.  It's wise not to use too many keyboard shortcuts though because they aren't intuitive at all.  I think a Hot Launcher is best used with scripts.  For example, my key press "Ctrl+Down" replaces "Alt-F4" via an AutoIt3 script.  Also, I use "Win-V" to go to Windows Miko, and from there I can quickly get to run any progam by some nickname.  This is faster than using a mouse to double click an icon somewhere and doesn't require worrying about key conflicts or contrived combinations.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.cdisplay.net/"&gt;Sequential Art Viewer: CDisplay&lt;/a&gt;&lt;br /&gt;The best, by far, image viewer to read my manga with on a windows machine.  At some point, I considered writing my own software, but there isn't anything that I would do differently than this program.  If you read scanned comics in Windows, this is probably your best bet, you just have to try it for yourself to really understand.  Its best features are allowing you to view two pages at a time and its smart "next" feature.  I also modified my right click menu to open folders with CDisplay.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.7-zip.org/"&gt;File Archiver/Zip Utility: 7-zip&lt;/a&gt;&lt;br /&gt;Unzipper, basically on par with WinRar in its unzipping.  The major difference between the two for my purposes is that it is completely free.  I actually do like using WinRar better, but I'm not willing to pay for it yet and so refuse to use it.  You may have a difference of opinion.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.ceruleanstudios.com/"&gt;IM Client: Trillian&lt;/a&gt;&lt;br /&gt;This is the instant messenger client I use.  It allows you to chat with people using AIM, Yahoo, MSN, and ICQ protocols.  I have friends that use these different clients, so it's useful to have one program I can use to chat with all of them.  I'm aware of the IM client Miranda, which can be made to look very cool.  Since I like how Trillian looks on my desktop and it seems to have no other benefits, I've stuck with Trillian.&lt;br /&gt;&lt;br /&gt;() &lt;a href="http://www.adobe.com/products/photoshop/"&gt;Image Editing: Photoshop 7.0&lt;/a&gt;&lt;br /&gt;Definitely not free, but I think it's worth it.  Plus, I've been using it for years, so I am pretty familiar with it.  For web sites, I think it's pretty important to have a real good image editor.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-116044400089649028?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/116044400089649028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=116044400089649028' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/116044400089649028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/116044400089649028'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/10/essential-programs-1-essentials.html' title='Essential Programs 1: Essentials A'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-115994176537984271</id><published>2006-10-03T23:00:00.000-07:00</published><updated>2006-11-05T07:26:12.999-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Essential Programs 1: Web Browser</title><content type='html'>&lt;a href="http://www.mozilla.com/"&gt;Web Browser: Firefox&lt;/a&gt;&lt;br /&gt;My main browser, I doubt I have to justify its inclusion to you, so I won't.  I will admit Opera is tons faster.  But firefox's customability (its options, themes, and extensions) wins me over.  For themes, I switch between the default, opera, and iFox themes.  As for extensions (plug-ins)... They are the reason I love firefox, so I'm going to list out all the ones that I use.&lt;br /&gt;&lt;br /&gt; () &lt;a href="https://addons.mozilla.org/firefox/190/"&gt;Linkification&lt;/a&gt;&lt;br /&gt; This plugin changes plain-text urls to hyperlinks in html (stuff you can click on).  For example, certain forums do no allow hyperlinks, so instead people type them out.  To visit their links, you probably have to copy and paste into the address bar and press enter.  Linkifcation will style the link text and let you click on it directly.  This extension is very similar to Text Link (which allows you to go to the textual link by double clicking on it.)  Supposedly, Linkification is slower to use because it needs to parse the entire page first.  I decided to go with the better usability, but I'd use Text Link if i was worried about performance.&lt;br /&gt;&lt;br /&gt; () &lt;a href="http://nextplease.mozdev.org/"&gt;NextPlease!&lt;/a&gt;&lt;br /&gt; This extension allows you to easily go to the "next" and "previous" pages.  For example, instead of clicking the "Next" link on a google search, I press Shift+Ctrl+Right.  This becomes very useful for me when browsing forums.  It works by looking for links with certain keywords (reg-exp) or specific images, and you can customize it as you need.  I think it's my favorite plug-in.&lt;br /&gt;&lt;br /&gt; () &lt;a href="http://tmp.garyr.net/"&gt;Tab Mix Plus &lt;/a&gt;&lt;br /&gt; Gives you a lot of control over your tabs; you really have to install this and play around with it to understand its usefulness.  A few of the nice features of this is session saving, tab progress bars, specifying tab widths, and allowing multiple rows of tabs.  This offers so much, so I won't even try to explain it all, you just need to try it out.  If you want to see my preferences, here they are: My Preferences.&lt;br /&gt;&lt;br /&gt; () &lt;a href="http://downloadstatusbar.mozdev.org/"&gt;Download Status Bar&lt;/a&gt;&lt;br /&gt; Shows your downloads in a new bar above the status bar instead of opening that annoying popup download manager.  I hate the download manager and this interface is very, very nice (and customizable.)&lt;br /&gt;&lt;br /&gt; () &lt;a href="http://adblock.mozdev.org/"&gt;AdBlock&lt;/a&gt;&lt;br /&gt; () &lt;a href="http://www.pierceive.com/"&gt;Adblock Filter Set G&lt;/a&gt;&lt;br /&gt; Probably the best ad-blockr available.  I think Firefox has a lot of these features built it, but it really makes customization and setting up new things to block very simple.  I tend to leave text and most image as, but I block all pop-up and flashing ads.  The filter just allows Adblock to update its list of bad ads every four days or so.&lt;br /&gt;&lt;br /&gt; () &lt;a href="http://www.longfocus.com/firefox/gmanager/"&gt;Gmail Manager&lt;/a&gt;&lt;br /&gt; This extension notifies you of new gmail for multiple accounts.  You set it up to check for new mail at set intervals.  It'll bring you to your account in a single click.  It's very handy, at least, if you use gmail with multiple accounts and are forgetful in checking it (that's definitely me...)&lt;br /&gt;&lt;br /&gt; () &lt;a href="https://addons.mozilla.org/extensions/moreinfo.php?id=26"&gt;Organize Status Bar&lt;/a&gt;&lt;br /&gt; This extension allows you to organize your status bar.  It's useful because a lot of these extensions will place (usually useful) icons in the status bar.  Sometimes, you really don't want them.  Other times, you want them in a different order.  This extension can fulfil both wishes.&lt;br /&gt;&lt;br /&gt; () &lt;a href="https://addons.mozilla.org/firefox/710/"&gt;Menu Editor&lt;/a&gt;&lt;br /&gt; This extension allows you to edit firefox menus.  This includes all the top menus (like File and Edit) as well as the menu when you right click anything.  Similar to organize status bar, this is mostly useful to remove the clutter from the other extensions.  However, I did end up clearing up a lot of menu items under the Tools menu as well.&lt;br /&gt;&lt;br /&gt; () &lt;a href="https://addons.mozilla.org/extensions/moreinfo.php?id=436"&gt;Session Saver&lt;/a&gt;&lt;br /&gt; This extension lets you save your sessions.  It automatically goes about its business in the background, so even if Firefox crashes or you accidentally close it, you can have it go back to what it was.  It even saves the text and such that you had entered.  Tab Mix Plus does this, but I find this plug-in does a better job.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-115994176537984271?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/115994176537984271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=115994176537984271' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/115994176537984271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/115994176537984271'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/10/essential-programs-1-web-browser.html' title='Essential Programs 1: Web Browser'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-115984101432888821</id><published>2006-10-02T18:43:00.000-07:00</published><updated>2006-11-05T07:26:47.056-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programs'/><title type='text'>Intro to Essential Programs</title><content type='html'>I thought about it, and I decided to start listing out the programs that I use most often.  If you're anything like me, you'll like the list, unless you already use all of it.  Oh, last thing.  Please don't take the following few posts as a best of list... seriously, I don't have the time or energy to research what "the best" is.  These are just my favorites out of what I've seen, I don't claim to have sniffed out the best out there (hopefully they're among the best though).  If you want more general yet all-encompassing "best of" lists, let me point you to:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.techsupportalert.com/best_46_free_utilities.htm"&gt;The 46 Best-Ever Freeware Utilities&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.apn.gr/manager/publish/freeware.shtml"&gt;100 Best Freeware Utilities&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So, pretty soon, I'll start posting stuff, let me know if you have any suggestions of better stuff, I'm always willing to take a look at other tools.  This series of posts may very well completely fill up the rest of the entire month.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-115984101432888821?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/115984101432888821/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=115984101432888821' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/115984101432888821'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/115984101432888821'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/10/intro-to-essential-programs.html' title='Intro to Essential Programs'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-115966862377259636</id><published>2006-09-30T19:07:00.000-07:00</published><updated>2006-11-04T21:56:57.199-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tweaks'/><title type='text'>Screen Saving and Locking</title><content type='html'>I use dual monitors and I liked the windows screensaver that cycles through your images.  However, that screensaver only works on one screen (at least for me) and I am using two.  I found the google pack screensaver which will get the images on both screens (and do some other nifty stuff, like an photo stacking effect and specifying multiple image directories to draw from.)  I use a modified version of the screensaver that removes the google logo and doesn't require you to download the entire google pack.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://wim.arkanasoft.com/blog/archive/2006/01/07/modified-google-pack-screensaver/"&gt;Here's the link. &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://aswembar.net/jed/free_files/gbsaver.zip"&gt;If that link doesn't work, use this one.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Oh, and there's another screensaver related thing I did.  We all know how to set the screensaver to turn on and lock after "x" minutes.  And we (probably) all know how to lock windows manually (I use the built in win+l shortcut myself.)  But... how can you turn on the screensaver and lock windows manually?&lt;br /&gt;&lt;br /&gt;If you run the screensaver by double-clicking it (or executing the file without any options), it actually runs in its "test" mode, so the computer isn't locked.  In order to get it to run AND lock the computer, use a batch file (text file that ends in .bat) with the following text:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt; ::initiate screensaver of choice&lt;br /&gt; "[insert path to google screensaver program; i.e. C:\gbsaver.exe]" /s&lt;br /&gt;&lt;br /&gt; ::lock the workstation&lt;br /&gt; %windir%\system32\rundll32.exe user32.dll,LockWorkStation&lt;br /&gt;&lt;/pre&gt;I mapped that batch file to "win+;" using PS Hot Launch and it has worked very well for me; instant screen lock and a nice showing off of pictures to my friends to coworkers.  I bet they really apreciate that.&lt;br /&gt;&lt;br /&gt;I do realize that since I'm using LCD monitors, screensavers don't really save the screen.  With CRT monitors, screensavers changed the image on the monitor so that no image got "burned" into it (my wife's old crt had an error message ghosted into it.)  With LCD monitors, it just wastes power and probably wears down the life of the LCD.  This tweak was for fun; I have the monitor power off after 10 minutes or so anyway.  I mainly use it to show off my cool images and getting rid of the boring lock screen.  Also, it helps me not feel so bad about downloading so many wallpapers, but never using them.  &lt;a href="http://en.wikipedia.org/wiki/Screen_saver"&gt;Read more about screen savers and their history at wikipedia&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-115966862377259636?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/115966862377259636/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=115966862377259636' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/115966862377259636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/115966862377259636'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/09/screen-saving-and-locking.html' title='Screen Saving and Locking'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-115940403524077940</id><published>2006-09-27T17:39:00.000-07:00</published><updated>2006-11-04T21:57:05.834-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tweaks'/><title type='text'>Changing That Green XP Start Button</title><content type='html'>Here's all the best information I could gather on changing the look and feel of the Windows XP non-classic start button.  You know, that annoyingly green button on your side bar.  I'm pretty sure that somewhere there's a program that you can simply run to do this all for you.  But these instructions are all "do-it-yourself"... meaning you'll be playing with the registry and system resources.  I think it's pretty fun, pretty simple, and gives you a better idea of how Windows works.  Have fun and say goodbye to your bright green start button!  And good luck trying to think of something better to put there, I just got replaced the button with a line and an all black windows logo icon.  And that's all I have to say.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://users.rowan.edu/%7Emarzig76//images/Change%20the%20color%20of%20your%20start%20button.txt"&gt;Changing the color of the start button&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://sarahlane.typepad.com/sarahword/2004/06/hack_xps_start_.html"&gt;Changing the text and image on the start button&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;- Image Replacement tips from&lt;/span&gt;&lt;span style="text-decoration: underline; font-weight: bold;"&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; Yuki (above link) -&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I would like to comment about the shape of the start button icon.&lt;br /&gt;&lt;br /&gt;There are some examples of customized start button icon in the web; they all are rectangular in shape. But you notice that Windows default flag icon is not such a shape and it "blends" to the start button.&lt;br /&gt;&lt;br /&gt;This blending is produced by an "alpha channel" in the default bitmap image. To see it, open the bitmap in the explorer.exe with ResHacker, choose "Action -&gt; Save(S) [Bitmap : 143 : 10xx]...", and save it as .bmp file. Then you can open it with an image processing program such as Photoshop and see the alpha channel in the channel palette. You can not see it by simple copy and paste from ResHacker to Photoshop.&lt;br /&gt;&lt;br /&gt;Alpha channel is a grayscale image hidden in the file that indicates the "opaqueness" of the entire image. White means complete opaque, black means transparent and gray indicates semi-transparent with its darkness.&lt;br /&gt;&lt;br /&gt;You can create your own image with an alpha channel like the original. Don't forget to check the "Include alpha channel" checkbox in save dialog of Photoshop. Save your own, replace it with original bitmap in explore.exe and you can have your beautifully "blended", custom shaped start button icon.&lt;br /&gt;&lt;br /&gt;The size of default icon is 25 pixels in width and 20 pixels in height for "Luna" theme (ID=143), but you may notice a complete black (transparent) region of 5 pixels width at the rightmost of the image. Apparently, this region is intended to make a space between the icon and the following text. So if you make an icon with no margin (or no alpha channel), the icon sticks to the text. This is not beautiful, of course. So the default size of Luna theme icon can be explained as 20 * 20 pixels with 5 pixels space. Curiously, the default icon for "Classic" theme (ID=176) is 16 * 16 pixels, without any space. Luna theme can be space-consuming. This is probably for considering generalization of wide-screen. The size of icon is not restricted to 25 * 20, so you can create smaller icon instead.&lt;br /&gt;&lt;br /&gt;By the way, I think it is dangerous to overwrite explorer.exe without testing. You can test it by Ctrl-Alt-Delete, quit explorer.exe, run your own such as C:\WINDOWS\explorer2.exe as a new task, and see it.&lt;br /&gt;&lt;br /&gt;You can rename explorer.exe while it is running. So you can easily rename explorer.exe in simple safe mode with explorer. Command prompt is not necessary. Safe mode is necessary to bypass system file protection. Go to C:\WINDOWS in safe mode, rename explorer.exe to explorer_orig.exe , rename your explorer2.exe to explorer.exe and restart the PC.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-115940403524077940?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/115940403524077940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=115940403524077940' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/115940403524077940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/115940403524077940'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/09/changing-that-green-xp-start-button.html' title='Changing That Green XP Start Button'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-35024663.post-115932672770419846</id><published>2006-09-26T20:11:00.000-07:00</published><updated>2006-11-04T08:22:57.859-08:00</updated><title type='text'>Introduction</title><content type='html'>Hey all, I'm Jonathan Discar and this is my blog.  Due to the influence of reading many blogs recently (mostly, the influence is from Steve Yegge) I decided to start up one of my own.  I could go on and on about why I did it if I wanted to bore you, but basically the decision was made because I want to improve my typing speed.  I don't have much important to say right now, but I'm hoping that'll change someday.  Until then, I decided to mostly share stuff I've found entertaining or handy.  It shouldn't be very complicated or controversal, but hopefully it'll be useful to some people and not entirely boring and personal.  So, computer techy tutorial and link highlights mostly.  We'll see how this goes.  After a while, when I finally really realize no one is going to read this and th blog becomes truly just for me, I'll be way more loose and babble on endlessly about random thoughts: worse than I'm doing now.  I'll see, I'll see.&lt;br /&gt;&lt;br /&gt;Oh yeah, this is me:  I'm currently 23 years old and I'm a programmer.  I primarily make stuff using Ruby and Java.  My personal projects tend to be  programming automation tools, websites, and tinkering with new technologies.  I like to tinker with stuff and I spend my free "zoning-out" time surfing for random infomation, reading some book or another (usually in the genre of sci-fi, fantasy, manga, or programming), playing video games, or watching japanese anime and the occasional tv show, usually a sitcom. I spend the rest of my free time cleaning up and hanging out with friends.  Nope, no traditional hobbies with me.  Man, what a very vague bio.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/35024663-115932672770419846?l=jdiscar.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jdiscar.blogspot.com/feeds/115932672770419846/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=35024663&amp;postID=115932672770419846' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/115932672770419846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/35024663/posts/default/115932672770419846'/><link rel='alternate' type='text/html' href='http://jdiscar.blogspot.com/2006/09/introduction.html' title='Introduction'/><author><name>Jonathan Discar</name><uri>http://www.blogger.com/profile/01629614278728548721</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
