<?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-4375994787022296080</id><updated>2011-10-10T10:20:58.170-07:00</updated><category term='small form factor'/><category term='sleep'/><category term='personal information'/><category term='text'/><category term='javascript'/><category term='sql'/><category term='cloud computing'/><category term='mysql'/><category term='python'/><category term='php'/><category term='security'/><category term='rails'/><category term='programming'/><category term='closure'/><category term='source control'/><category term='parsing'/><category term='paranoia'/><category term='csv'/><category term='cheap computing'/><title type='text'>Janitor Programmer</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Mike</name><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>49</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4375994787022296080.post-7125434569902996106</id><published>2011-07-08T14:19:00.001-07:00</published><updated>2011-07-08T14:21:20.538-07:00</updated><title type='text'>webrat needs to be bundled as well</title><content type='html'>In addition to getting rspec installed correctly, webrat is required to test the page content with response.should have_selector("title"....&lt;br /&gt;&lt;br /&gt;Here are the &lt;a href="http://getsatisfaction.com/railstutorial/topics/rspec_undefined_method_has_selector"&gt;instructions&lt;/a&gt;. I had to include the proper version (0.7.0) in the Gemfile, then do a bundle install.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-7125434569902996106?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/7125434569902996106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=7125434569902996106' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7125434569902996106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7125434569902996106'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2011/07/webrat-needs-to-be-bundled-as-well.html' title='webrat needs to be bundled as well'/><author><name>Mike</name><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-4375994787022296080.post-6371895644312112668</id><published>2011-07-08T13:13:00.001-07:00</published><updated>2011-07-08T13:14:14.687-07:00</updated><title type='text'>getting rspec installed</title><content type='html'>The tutorial I'm using calls for using rspec for testinhttp://www.blogger.com/img/blank.gifg. In order to get it so I could install it and add it I had to follow &lt;a href="https://github.com/rspec/rspec-rails"&gt;these instructions&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-6371895644312112668?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/6371895644312112668/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=6371895644312112668' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/6371895644312112668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/6371895644312112668'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2011/07/getting-rspec-installed.html' title='getting rspec installed'/><author><name>Mike</name><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-4375994787022296080.post-5102412868246072976</id><published>2011-07-07T13:20:00.001-07:00</published><updated>2011-07-07T13:25:42.550-07:00</updated><title type='text'>Finally really working on Rails</title><content type='html'>After several false starts we have a project at work where we are looking at using Rails. So far so good. I'm using &lt;a href="http://ruby.railstutorial.org/ruby-on-rails-tutorial-book"&gt;http://ruby.railstutorial.org/ruby-on-railshttp://www.blogger.com/img/blank.gif-tutorial-book&lt;/a&gt; as my tutorial and so far it is my kind of book. I'm using the bitnami &lt;a href="http://bitnami.org/stack/rubystack"&gt;rubystack&lt;/a&gt; virtual machine using Rails 3 in ubuntu. There have been a couple of hiccups along the way. 1) is remembering to use sudo on the VM for most installs and updates and even running the server to test the appliction. Not a HUGE deal, but a minor annoyance. Also, when doing the push the first time to deploy to heroku, I got an error saying that heroku does not appear to be a git repository. The fix for that is &lt;a href="http://getsatisfaction.com/heroku/topics/fatal_heroku_does_not_appear_to_be_a_git_repository"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-5102412868246072976?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/5102412868246072976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=5102412868246072976' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5102412868246072976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5102412868246072976'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2011/07/finally-really-working-on-rails.html' title='Finally really working on Rails'/><author><name>Mike</name><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-4375994787022296080.post-2058075438504908449</id><published>2011-04-17T21:08:00.001-07:00</published><updated>2011-04-17T21:09:20.005-07:00</updated><title type='text'>Math and web design</title><content type='html'>An interesting article about using prime numbers and tiling backgrounds for creating interesting effects with a minimal cost.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://designfestival.com/the-cicada-principle-and-why-it-matters-to-web-designers/?utm_medium=email&amp;utm_campaign=Design+View+83+-+Cicadas+Pseudo-random+Organic+Tiling+and+Top+Design+Mistakes+HTML&amp;utm_content=Design+View+83+-+Cicadas+Pseudo-random+Organic+Tiling+and+Top+Design+Mistakes+HTML+CID_068c8ba45a4520e40c5d7eb008dc7279&amp;utm_source=Newsletter&amp;utm_term=The+Cicada+Principle+and+Why+It+Matters+to+Web+Designers"&gt;http://designfestival.com/the-cicada-principle-and-why-it-matters-to-web-designers/?utm_medium=email&amp;utm_campaign=Design+View+83+-+Cicadas+Pseudo-random+Organic+Tiling+and+Top+Design+Mistakes+HTML&amp;utm_content=Design+View+83+-+Cicadas+Pseudo-random+Organic+Tiling+and+Top+Design+Mistakes+HTML+CID_068c8ba45a4520e40c5d7eb008dc7279&amp;utm_source=Newsletter&amp;utm_term=The+Cicada+Principle+and+Why+It+Matters+to+Web+Designers&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-2058075438504908449?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/2058075438504908449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=2058075438504908449' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/2058075438504908449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/2058075438504908449'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2011/04/math-and-web-design.html' title='Math and web design'/><author><name>Mike</name><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-4375994787022296080.post-3048636024532358128</id><published>2011-01-11T07:50:00.000-08:00</published><updated>2011-01-11T07:51:49.534-08:00</updated><title type='text'>useful erlang posts</title><content type='html'>I'm starting to learn about erlang. here are some useful posts I found.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://yarivsblog.blogspot.com/2008/05/erlang-vs-scala.html"&gt;http://yarivsblog.blogspot.com/2008/05/erlang-vs-scala.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ferd.ca/an-open-letter-to-the-erlang-beginner-or-onlooker.html"&gt;http://ferd.ca/an-open-letter-to-the-erlang-beginner-or-onlooker.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-3048636024532358128?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/3048636024532358128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=3048636024532358128' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/3048636024532358128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/3048636024532358128'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2011/01/useful-erlang-posts.html' title='useful erlang posts'/><author><name>Mike</name><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-4375994787022296080.post-3995567434440354158</id><published>2011-01-03T19:25:00.000-08:00</published><updated>2011-01-03T20:02:04.072-08:00</updated><title type='text'>There Are No Internal Users</title><content type='html'>Anybody who has worked for a small company or in an IT department where most of your users are 20 feet down the hall has heard the following; "Don't worry about creating an admin interface, this application is just for internal users."&lt;br /&gt;&lt;br /&gt;The problem with internal users is that they don't really exist in the sense that "decision makers" would like them to. There are people that use your application and people that do not use your application. That said people are separated by a hallway instead of an interstate does not make them particularly special. When you are asked to design for internal users you are usually being asked to skimp on these features:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Administrative interfaces. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Ease of use enhancements. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Documentation. &lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Please, please, &lt;strong&gt;PLEASE &lt;/strong&gt;avoid the temptation to cut drastically on the above features. They don't have to have the spit and polish you would give to a client facing application (a misspelled word here or there won't kill anybody) but these features should exist, they should make sense, and they should be useable without people having to email you every 3 months asking if you can make one little change here or there.&lt;br /&gt;&lt;br /&gt;Without an administrative interface, you will need to remember what all the tables and files in your application are responsible for. You will need to completely memorize the internal structure of the application, or you will need to wade through piles of code every time somebody has a request. Neither situation is good. Those brain cells are better spent remembering good places to eat lunch, and the time you save by not designing a proper administrative interface will be spent every time somebody has a question about making a configuration change. Either spend a little time and effort now, or a lot later. Multiple times. Until you either get fed up and kill somebody, quit, or write the administrative interface anyway.&lt;br /&gt;&lt;br /&gt;Anything you put in front of users should be intuitive. Granted in most cases internal users, or users in any niche market, can be expected to have a level of sophisitication that is above average, but if interfaces don't make sense, the application isn't serving its purpose. Computers and applications are supposed to be tools that make people's lives easier, not puzzles. At least, not in this case.&lt;br /&gt;&lt;br /&gt;Documentation is critical. Even if it is nothing more than an email briefly explaining the application's feature set and how to use the main features. You don't need a complete manual detailing why you chose the lovely magenta headers, but you should have something that users, and you, can refer to that explains what the application does and how it does it. For this sort of documenation I prefer a wiki. It can be a pain to go update the documentation every time something changes, but you will be kicking yourself when, 8 months after deployment, somebody comes down the hall with a question that you don't remember the answer to. Instead of taking 15 minutes to skim through some docs, you will be taking hours going through an old code base you barely remember.&lt;br /&gt;&lt;br /&gt;I've found this particularly true for instances where I am writing small one-off applications, excel macros, python scripts, etc. that are written to solve a particular issue. There are stretches where I crank out 3 or 4 of these a week, and then many months later somebody asks me for a program that performs some function I've already taken care of, or they ask about using something they haven't touched in a while and they've deleted the email that contains the directions. If you write many small utilities, at some point you will start losing track of what they all do. Simple to use interfaces with clear documentation will save your users from some angst and will save you from wasting time either going through old code or, worse, reinventing your own wheel.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-3995567434440354158?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/3995567434440354158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=3995567434440354158' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/3995567434440354158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/3995567434440354158'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2011/01/there-are-no-internal-users.html' title='There Are No Internal Users'/><author><name>Mike</name><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-4375994787022296080.post-7078661484124443737</id><published>2010-12-16T07:09:00.000-08:00</published><updated>2010-12-16T07:37:59.339-08:00</updated><title type='text'>The problem with Javascript</title><content type='html'>Let me open this by saying that I like JavaScript. The syntax is comfortable for a lot of people and it lets you do all kinds of funky stuff because functions are first class objects and prototype based classes. It also enjoys an extremely wide install base because it is in almost every browser people use. I believe that it has a bad reputation mostly because it has suffered from years of poor and differing implementations. I also think it bears the brunt of having a variety of DOMs (These days IE vs. everybody else) associated with it; much the same way that I think C++ has a bad reputation because a lot of people's experience with C++ began and ended with MFC.&lt;br /&gt;&lt;br /&gt;But there is one problem JavaScript has that was clarified to me after reading &lt;a href="http://blogs.sitepoint.com/2009/11/12/google-closure-how-not-to-write-javascript/"&gt;this&lt;/a&gt; critique of Google Closure. The problem, in a nutshell, is that the developer has to act as an optimizing compiler in many instances. Looking at most of the critiques, they revolve around optimizations that most people in the 21st century are either accustomed to having taken care of for them, or their computing power is so great compared to what they do that they don't care. At this point an interpreted language in a browser is handicapped in both of these areas.&lt;br /&gt;&lt;br /&gt;Looking at the list of critiques, slow loops because you access a property on every loop check, slow case statements and dealing with multiple types of strings are all things that most developers don't have to worry about anymore. The problems with the code in the library and more efficient ways to do the same thing cover a large part of the post. That you can write many paragraphs on this sort of thing and that these optimizations are necessary is indicative that implementations of the language still has plenty of room for improvement. The concatenation of "" to a value to make it a string more efficiently than using String() is, to me, the most egregious example of this. (somevalue + "").replace() may be fast, but it sure is ugly to look at.&lt;br /&gt;&lt;br /&gt;The author at one point even takes a jab at Google, saying their time may have been better spent just writing proper JavaScript instead of making the investment in making Chrome's JavaScript performance better. I'm guessing this is tongue in cheek, wry humor. Otherwise the implication is that JavaScript is fine on the performance front. As long as the programmer has to perform the sorts of optimization hacks described in the above post, that is simply not the case.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-7078661484124443737?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/7078661484124443737/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=7078661484124443737' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7078661484124443737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7078661484124443737'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/12/problem-with-javascript.html' title='The problem with Javascript'/><author><name>Mike</name><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-4375994787022296080.post-6352171493585378291</id><published>2010-12-02T13:31:00.000-08:00</published><updated>2010-12-02T13:45:13.188-08:00</updated><title type='text'>random subsets of data ii</title><content type='html'>In doing more work to get random subsets, the previous solution fails miserably if you are going to be using a view. You can run the EXEC statement in a stored procedure but cannot use it in a view. And furthermore, calling a stored procedure from a view is somewhere between extremely problematic and impossible, depending on who you talk to. Using the RANK function and partitioning the data you can get a similar result.&lt;br /&gt;&lt;br /&gt;Let us use the same idea as the &lt;a href="http://janprog.blogspot.com/2010/11/random-subsets-of-data.html"&gt;previous example&lt;/a&gt; and assume we want at least one employee from every department. The only requirement for the following query is that you are asking for more employees than you have departments.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;select top 100 T1.* from&lt;br /&gt;&lt;br /&gt;(select &lt;br /&gt;&lt;br /&gt;RANK() over &lt;br /&gt;(PARTITION by Department order by newid()) as r,  &lt;br /&gt;&lt;br /&gt;* &lt;br /&gt;from Employees&lt;br /&gt;where Active = 1&lt;br /&gt;&lt;br /&gt;) as T1&lt;br /&gt;order by t1.r, t1.Department&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Note, as before, that this is a sql server query. Modifications may need to be made for different flavors of SQL. What this is doing is for every department the employees are getting randomly ranked thanks to order by NEWID(). By selecting the top 100 and ordering by rank and then department, you'll get all of the 1's from every department, then all of the 2's and so on until you get 100.&lt;br /&gt;&lt;br /&gt;The order by department is strictly unnecessary. I did it to make viewing and verifying the results easier.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-6352171493585378291?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/6352171493585378291/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=6352171493585378291' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/6352171493585378291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/6352171493585378291'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/12/random-subsets-of-data-ii.html' title='random subsets of data ii'/><author><name>Mike</name><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-4375994787022296080.post-5484145162249821772</id><published>2010-11-19T12:42:00.000-08:00</published><updated>2010-11-19T13:05:28.865-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>random subsets of data</title><content type='html'>I recently had a request to return a random subset of contacts from a database, but to be sure that there were some contacts from each group represented. Let us say that you have a database with employees and you want to get a list of some random people from each department. Here is how I went about doing it:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;declare @s1 varchar(max)&lt;br /&gt;&lt;br /&gt;select @s1 = coalesce(@s1 + ' union all ', '') +&lt;br /&gt;e from (&lt;br /&gt;&lt;br /&gt;select distinct&lt;br /&gt;'select * from (select top 11 percent * from &lt;br /&gt;Employees where Department = '''&lt;br /&gt;+ Department + ''' order by newid()) &lt;br /&gt;as [t' + Department + ']'  as e&lt;br /&gt;from Employees) T1&lt;br /&gt;exec (@s1)&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What we are doing here is generating the text for a query that will select the top N contacts from the Employee list for each department. The coalesce function will put all of these queries together into one query that will union the results into a single table. The exec function will execute the query.&lt;br /&gt;&lt;br /&gt;Note that this is a TSQL example to run on SQL Server. You may have to translate this, depending on your database system.&lt;br /&gt;&lt;br /&gt;If you want a fixed number then what I would do is tweak the percent to get a number than is slightly more than the number desired then just select the top N from that. This runs the risk of not getting somebody from every department. Another method would be to select a number slightly less than your target, then select some random number of records to add to the result. This is more complex, but may be what you need.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-5484145162249821772?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/5484145162249821772/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=5484145162249821772' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5484145162249821772'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5484145162249821772'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/11/random-subsets-of-data.html' title='random subsets of data'/><author><name>Mike</name><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-4375994787022296080.post-5268114684160933549</id><published>2010-10-29T09:02:00.000-07:00</published><updated>2010-10-29T09:07:03.164-07:00</updated><title type='text'>Returning data tables from Web Services in .NET</title><content type='html'>This is just a small reminder, and I don't know why it gets me every time, but it does. I guess I return data tables from web services infrequently enough where I don't think about it. Maybe writing it down somewhere will help me remember. When creating a data table to return from a web service, give the table a name.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;DataTable dt = new DataTable("nameMyTable");&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;If you don't, the first time you hit the service when testing you will get an exception about the table not having a name. And then you will curse to yourself and then give it a name and move on with your life.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-5268114684160933549?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/5268114684160933549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=5268114684160933549' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5268114684160933549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5268114684160933549'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/10/returning-data-tables-from-web-services.html' title='Returning data tables from Web Services in .NET'/><author><name>Mike</name><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-4375994787022296080.post-4141371092631123017</id><published>2010-10-22T08:51:00.000-07:00</published><updated>2010-10-22T09:06:21.588-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>scripts for processing stuff</title><content type='html'>Often I need to write something up quick to process a file, or process files in a directory and I'll want a GUI for these things so I can pass them along to other people to use. Here are two python scripts that I use as templates for picking either a file or a directory and then doing something with it. The object here isn't to have everything "correct" according to the latest design fashion or methodology. With this script I can import a python module that takes a file or directory name and does the processing I want, plug in the function name, pass the parameter and then move on with my life.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Pick a file and do something with it:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;from tkinter import *&lt;br /&gt;from tkinter.messagebox import *&lt;br /&gt;from tkinter.filedialog import *&lt;br /&gt;&lt;br /&gt;class FileProcessor(Frame):&lt;br /&gt;&lt;br /&gt;# Object constructor&lt;br /&gt;    def __init__(self, parent=None):&lt;br /&gt;        Frame.__init__(self, parent)&lt;br /&gt;&lt;br /&gt;        self.txtFile = Entry(parent)&lt;br /&gt;        self.txtFile.place(x=6,y=64,width=375,height=24)&lt;br /&gt;        self.txtFile.insert(0,'')&lt;br /&gt;&lt;br /&gt;        self.btnPickFile = Button(parent,text='Pick File', command=self.btnPickFileClick)&lt;br /&gt;        self.btnPickFile.place(x=6,y=20,width=96,height=24)&lt;br /&gt;&lt;br /&gt;        self.btnRun = Button(parent,text='RUN', command=self.btnRunClick)&lt;br /&gt;        self.btnRun.place(x=6,y=114,width=96,height=30)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# Methods (event handlers) of object&lt;br /&gt;    def btnPickFileClick(self):&lt;br /&gt;        print (self.txtFile.get())&lt;br /&gt;        self.txtFile.delete(0,END)&lt;br /&gt;        self.txtFile.insert(0,askopenfilename())&lt;br /&gt;&lt;br /&gt;    def btnRunClick(self):&lt;br /&gt;        fileName = self.txtFile.get()&lt;br /&gt;        self.runFile(fileName)&lt;br /&gt;&lt;br /&gt;    def runFile(self, fileName):&lt;br /&gt;        print('code goes here to run when click: ' + fileName)&lt;br /&gt;        showinfo('The file is',fileName)&lt;br /&gt;&lt;br /&gt;# Method called if script is run directly&lt;br /&gt;# instead of imported or used as a class&lt;br /&gt;if __name__ == '__main__':&lt;br /&gt;    root = Tk()&lt;br /&gt;    root.title('Process File')&lt;br /&gt;    myForm = FileProcessor(root)&lt;br /&gt;    myForm.pack()&lt;br /&gt;    root.geometry("423x156")&lt;br /&gt;    root.minsize(423,156)&lt;br /&gt;    root.maxsize(423,156)&lt;br /&gt;    root.mainloop()&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Pick a directory and do something wit it:&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;from tkinter import *&lt;br /&gt;from tkinter.messagebox import *&lt;br /&gt;from tkinter.filedialog import *&lt;br /&gt;&lt;br /&gt;class DirectoryProcessor(Frame):&lt;br /&gt;&lt;br /&gt;# Object constructor&lt;br /&gt;    def __init__(self, parent=None):&lt;br /&gt;        Frame.__init__(self, parent)&lt;br /&gt;&lt;br /&gt;        self.txtDir = Entry(parent)&lt;br /&gt;        self.txtDir.place(x=6,y=64,width=375,height=24)&lt;br /&gt;        self.txtDir.insert(0,'')&lt;br /&gt;&lt;br /&gt;        self.btnPickFile = Button(parent,text='Pick Directory', command=self.btnPickFileClick)&lt;br /&gt;        self.btnPickFile.place(x=6,y=20,width=96,height=24)&lt;br /&gt;&lt;br /&gt;        self.btnRun = Button(parent,text='RUN', command=self.btnRunClick)&lt;br /&gt;        self.btnRun.place(x=6,y=114,width=96,height=30)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# Methods (event handlers) of object&lt;br /&gt;    def btnPickFileClick(self):&lt;br /&gt;        print (self.txtDir.get())&lt;br /&gt;        self.txtDir.delete(0,END)&lt;br /&gt;        self.txtDir.insert(0,askdirectory())&lt;br /&gt;&lt;br /&gt;    def btnRunClick(self):&lt;br /&gt;        dirName = self.txtDir.get()&lt;br /&gt;        self.runDir(dirName)&lt;br /&gt;&lt;br /&gt;    def runDir(self, directoryName):&lt;br /&gt;        print('code goes here to run when click: ' + directoryName)&lt;br /&gt;        showinfo('The directory is',directoryName)&lt;br /&gt;&lt;br /&gt;# Method called if script is run directly&lt;br /&gt;# instead of imported or used as a class&lt;br /&gt;if __name__ == '__main__':&lt;br /&gt;    root = Tk()&lt;br /&gt;    root.title('Process Directory')&lt;br /&gt;    myForm = DirectoryProcessor(root)&lt;br /&gt;    myForm.pack()&lt;br /&gt;    root.geometry("423x156")&lt;br /&gt;    root.minsize(423,156)&lt;br /&gt;    root.maxsize(423,156)&lt;br /&gt;    root.mainloop()&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-4141371092631123017?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/4141371092631123017/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=4141371092631123017' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4141371092631123017'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4141371092631123017'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/10/scripts-for-processing-stuff.html' title='scripts for processing stuff'/><author><name>Mike</name><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-4375994787022296080.post-4837823186246420869</id><published>2010-09-30T10:54:00.000-07:00</published><updated>2010-09-30T11:53:14.340-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='text'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Putting a string on a single line</title><content type='html'>Often times text is written on multiple lines for the sake of clarity. Sometimes these lines need to be consolidated to a single line. This happens to me a lot with SQL queries that end up needing to be in a config file somewhere. I'll write them out all pretty so they make sense (as much sense as some SQL can make...) and then I'll need to consolidate that down to one line. Here is a python one liner that does just that, given a string named mystr&lt;br /&gt;&lt;br /&gt;" ".join([x.strip() for x in mystr.split("\n")])&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-4837823186246420869?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/4837823186246420869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=4837823186246420869' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4837823186246420869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4837823186246420869'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/09/putting-string-on-single-line.html' title='Putting a string on a single line'/><author><name>Mike</name><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-4375994787022296080.post-2633310834407632981</id><published>2010-09-08T09:54:00.000-07:00</published><updated>2010-09-08T09:56:51.898-07:00</updated><title type='text'>Don't make me slap you, Beavis</title><content type='html'>Every single time somebody asks "how hard can it be?" or "why is the estimate so big?", I want to smack them. Hard. Some folks at 37signals were kind enough to offer an example that answers these sorts of questions when asked about a seemingly simple &lt;a href="http://answers.37signals.com/basecamp/52-how-can-i-move-or-copy-to-do-lists-between-projects#reply_6986"&gt;feature&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I applaud the fine folks at 37signals for publishing things like this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-2633310834407632981?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/2633310834407632981/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=2633310834407632981' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/2633310834407632981'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/2633310834407632981'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/09/dont-make-me-slap-you-beavis.html' title='Don&apos;t make me slap you, Beavis'/><author><name>Mike</name><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-4375994787022296080.post-6253922683054926272</id><published>2010-08-09T08:24:00.001-07:00</published><updated>2010-08-09T08:27:43.314-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='csv'/><category scheme='http://www.blogger.com/atom/ns#' term='text'/><category scheme='http://www.blogger.com/atom/ns#' term='parsing'/><title type='text'>splitting csv files</title><content type='html'>I'm sure I've ranted about this before. I'll rant about this again. I just hate seeing examples from people in C# where they say that you just split a CSV file by using mystring.Split(',') and you will get an array where each item is the value for each field. One would assume, since they mention C#, that at some point in their lives they have worked with excel style CSV files that have data like&lt;br /&gt;&lt;br /&gt;"Bob","Hello, Dear","""Dude, where's your car"""&lt;br /&gt;&lt;br /&gt;The string split method obviously will not correctly handle this case at all. Here is a page I found with a nice little function that works for me in most cases. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.tedspence.com/index.php?entry=entry070604-124237"&gt;http://www.tedspence.com/index.php?entry=entry070604-124237&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hopefully this will work for you, too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-6253922683054926272?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/6253922683054926272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=6253922683054926272' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/6253922683054926272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/6253922683054926272'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/08/splitting-csv-files.html' title='splitting csv files'/><author><name>Mike</name><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-4375994787022296080.post-7799775230852452383</id><published>2010-07-30T14:01:00.000-07:00</published><updated>2010-07-30T14:07:16.449-07:00</updated><title type='text'>I leave it as an exercise to the reader...</title><content type='html'>When did this become a euphemism for "this is hard"?&lt;br /&gt;&lt;br /&gt;I say this because I'm doing research on Visual Studio 2010 and one of the selling points is the Parallel Extensions for .NET. In a great many of the articles and tutorials I've found, the author goes through some totally brain dead examples that have no relevance to real life to show the basics. This is then followed by a discussion of some of the more interesting parts of the framework and then a paragraph or two about things you might try and finally something like "I leave it as an exercise for the reader to...." followed by something that might actually be interesting.&lt;br /&gt;&lt;br /&gt;This is one of the reasons, by the way, that I prefer actual books to cobbling together a manual from various web pages. I know a lot of people say they will never by another programming book again because you can find everything you need on the web. I have not found this to be the case. And even when it is the case in a lot of instances one has to go through a lot of effort to cull the good nuggets from the pile of information you find. It's almost like panning for gold. Most good books do this for you already and the really good ones even include some decent examples of using libraries and techniques that have some relevance to real life.&lt;br /&gt;&lt;br /&gt;I just needed to vent. Back to my research.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-7799775230852452383?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/7799775230852452383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=7799775230852452383' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7799775230852452383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7799775230852452383'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/07/i-leave-it-as-exercise-to-reader.html' title='I leave it as an exercise to the reader...'/><author><name>Mike</name><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-4375994787022296080.post-388299634938311316</id><published>2010-07-23T12:42:00.000-07:00</published><updated>2010-07-23T12:45:05.388-07:00</updated><title type='text'>Working with outlook</title><content type='html'>I found a nice piece of software called &lt;a href="http://www.dimastr.com/redemption/"&gt;Outlook Redemption&lt;/a&gt;. I had to process some msg files that I had exported and this thing came in handy and was super simple to use. For what I needed, &lt;a href="http://stackoverflow.com/questions/15880/read-from-msg-files"&gt;this&lt;/a&gt; was enough to get going.&lt;br /&gt;&lt;br /&gt;From time to time I'm still amazed at the software that is freely available to just get things done and move on with your life.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-388299634938311316?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/388299634938311316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=388299634938311316' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/388299634938311316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/388299634938311316'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/07/working-with-outlook.html' title='Working with outlook'/><author><name>Mike</name><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-4375994787022296080.post-5882885604741878110</id><published>2010-06-19T11:20:00.001-07:00</published><updated>2010-06-19T11:20:41.485-07:00</updated><title type='text'>link with good info on posting to page</title><content type='html'>here is some information on posting to pages in facebook using the API&lt;br /&gt;&lt;br /&gt;&lt;a href="http://forum.developers.facebook.com/viewtopic.php?id=45796"&gt;http://forum.developers.facebook.com/viewtopic.php?id=45796&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-5882885604741878110?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/5882885604741878110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=5882885604741878110' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5882885604741878110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5882885604741878110'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/06/link-with-good-info-on-posting-to-page.html' title='link with good info on posting to page'/><author><name>Mike</name><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-4375994787022296080.post-1200168335332885405</id><published>2010-06-18T10:11:00.000-07:00</published><updated>2010-06-18T10:22:02.858-07:00</updated><title type='text'>NULL is a four letter word</title><content type='html'>I used to be a big fan of NULL. It represents something that isn't really there and in many, many cases it makes sense logically and mathematically. I even had a good way of explaining it to lay-people that didn't really get it. think of it like bank accounts and account numbers for those bank accounts. An existing account with a balance of zero is different than not having an account at all, right? This worked for most people to help explain the difference, especially in text fields where the value of some fields would be the empty string and others would be NULL.&lt;br /&gt;&lt;br /&gt;Lately though, I've come to the realization that this doesn't really matter. You can explain this in a multitude of ways that make sense, but when Judy in marketing wants to send an email to all of the people that are not in the Accounting department, she doesn't care about NULL. As the more technically or mathematically inclined among us know, if the department field for somebody is NULL, in most databases it would not be comparable to a string because it has no value to compare.&lt;br /&gt;&lt;br /&gt;Select * from Employees where dept != 'Accounting'&lt;br /&gt;&lt;br /&gt;will not return the people where dept is NULL in most cases. And this is usually very bad in the real world.&lt;br /&gt;&lt;br /&gt;I'm done with NULL if anything close to a reasonable default exists. It just eliminates so many real world problems. I know from time to time I've come across people on discussion boards that have expressed this view and for the longest time I've disagreed with that notion on principle. I know many others that have as well. After much wailing and gnashing of teeth, I finally get it.&lt;br /&gt;&lt;br /&gt;Consider it the 8th dirty word, after fuck, shit, piss, cunt, cocksucker, motherfucker and tits.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-1200168335332885405?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/1200168335332885405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=1200168335332885405' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/1200168335332885405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/1200168335332885405'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/06/null-is-four-letter-word.html' title='NULL is a four letter word'/><author><name>Mike</name><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-4375994787022296080.post-1343162937476635895</id><published>2010-06-10T09:51:00.000-07:00</published><updated>2010-06-10T10:07:32.730-07:00</updated><title type='text'>Fun with HTML 5</title><content type='html'>I found a sample that had a simple particle system in html 5. I made one small improvement (pass in the type of particle to render) and changed it from raindrops to what could be a simple campfire. I like fire :-)&lt;br /&gt;&lt;br /&gt;I put this up on a page &lt;a href="http://janprog.blogspot.com/p/fire-particle-sample.html"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://janprog.blogspot.com/p/fire-particle-sample.html" width="500" height="600"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-1343162937476635895?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/1343162937476635895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=1343162937476635895' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/1343162937476635895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/1343162937476635895'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/06/fun-with-html-5.html' title='Fun with HTML 5'/><author><name>Mike</name><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-4375994787022296080.post-483757875847972087</id><published>2010-05-17T11:06:00.000-07:00</published><updated>2010-05-17T11:08:49.921-07:00</updated><title type='text'>test facebook like button</title><content type='html'>&lt;iframe src="http://www.facebook.com/plugins/like.php?href=http%253A%252F%252Fjanprog.blogspot.com&amp;amp;layout=standard&amp;amp;show_faces=true&amp;amp;width=450&amp;amp;action=like&amp;amp;font&amp;amp;colorscheme=light&amp;amp;height=80" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:450px; height:80px;" allowTransparency="true"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-483757875847972087?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/483757875847972087/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=483757875847972087' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/483757875847972087'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/483757875847972087'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/05/test-facebook-like-button.html' title='test facebook like button'/><author><name>Mike</name><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-4375994787022296080.post-7296262041939535532</id><published>2010-02-19T07:29:00.000-08:00</published><updated>2010-02-19T07:58:38.918-08:00</updated><title type='text'>The cyclical nature of programming</title><content type='html'>Anybody who has been in this business for a long time knows that there are a lot of cycles in technology. Boom/bust cycles. Cycles where we process a lot of stuff on servers, then distribute it to nodes on the network, then move back to processing a lot stuff on servers. I'm sure there are others, but these are the two big ones that come to mind.&lt;br /&gt;&lt;br /&gt;One thing I've noticed lately is that this is happening over on &lt;a href="http://news.ycombinator.com/"&gt;hacker news&lt;/a&gt;. Over the past couple of weeks there appear to have been a lot of links to items that I read many years ago. Some of them weren't even new then. Lots of Peter Norvig stuff. Some links to old Dykstra papers. That sort of thing. Things that should be part of the collective programmer consciousness, I guess.&lt;br /&gt;&lt;br /&gt;I think this sort of thing is why we spend a lot of time rebuilding the wheel, as it were. You don't have to look to hard to find a large group of software folks that are convinced the credentials and formal schooling are waaaay overrated. But then you run into these periods where a large group seems to stumble upon some piece of writing or some paper and has to share it with the world, as if they've discovered something new and exciting and awesome. While I respect and love the enthusiasm of these sorts of things, I'm wondering how much overlap there is in these two groups. I would guess a lot. Maybe that's just my natural pessimism and cynicism kicking in.&lt;br /&gt;&lt;br /&gt;I know that several well known people have lists of required reading for programmers. It just seems that these aren't very well known in the programming community at large. I've passed some of these around to various people. Some of them really bug me, however, because they are ephemeral. I know a lot of people, for example, that used to recommend one or more Extreme Programming books. Very enthusiastically. Now, they wouldn't touch them with a ten foot pole. They've moved on to Scrum. And soon I imagine they will move to some yet unnamed flavor of the month. Mostly in an effort to collect more consulting revenue.&lt;br /&gt;&lt;br /&gt;I think I'm going to start collecting some of these. I'd like to break this particular cycle. Here are a few that come to mind. They mostly contain basic fundamentals or things that have stood the test of time. They are the sorts of things that are, in some cases, part of the collective hacker unconsciousness. Eric Raymond has written about this hacker culture stuff and has done a much better job than I could hope to do.&lt;br /&gt;&lt;br /&gt;Eric can be polarizing, but he has some great writings. No matter what side of the ESR fence you sit on, at least he makes you think.&lt;br /&gt;&lt;a href="http://catb.org/~esr/faqs/hacker-howto.html"&gt;How to become a hacker&lt;/a&gt;&lt;br /&gt;&lt;a href="http://catb.org/~esr/writings/cathedral-bazaar/"&gt;Cathedral and the bazarr&lt;/a&gt;&lt;br /&gt;&lt;a href="http://catb.org/~esr/writings/taoup/"&gt;The Art of Unix Programming&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.norvig.com/"&gt;norvig.com&lt;/a&gt; - Just an all around smart guy with lots of good things to say.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.joelonsoftware.com/"&gt;Joel on Software&lt;/a&gt; - The forums on this site used to be GREAT. The business of software board is still pretty good. The older essays are definitely worth a read.&lt;br /&gt;&lt;br /&gt;The Mythical Man-month. Fred Brooks. Classic book. Short, too, which is nice :-)&lt;br /&gt;&lt;br /&gt;I'll add others as they come to mind.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-7296262041939535532?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/7296262041939535532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=7296262041939535532' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7296262041939535532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7296262041939535532'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/02/cyclical-nature-of-programming.html' title='The cyclical nature of programming'/><author><name>Mike</name><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-4375994787022296080.post-5628879841428085624</id><published>2010-02-10T09:41:00.000-08:00</published><updated>2010-02-10T09:43:41.985-08:00</updated><title type='text'>Writing more code isn't always the answer</title><content type='html'>This is one of my very favorite stories of writing good code and how metrics can go horribly wrong.&lt;br /&gt;&lt;a href="http://www.folklore.org/StoryView.py?project=Macintosh&amp;story=Negative_2000_Lines_Of_Code.txt"&gt;&lt;br /&gt;http://www.folklore.org/StoryView.py?project=Macintosh&amp;story=Negative_2000_Lines_Of_Code.txt&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;"Bill Atkinson, the author of Quickdraw and the main user interface designer, who was by far the most important Lisa implementor, thought that lines of code was a silly measure of software productivity. He thought his goal was to write as small and fast a program as possible, and that the lines of code metric only encouraged writing sloppy, bloated, broken code. "&lt;br /&gt;&lt;br /&gt;Generally speaking, I'm with Bill.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-5628879841428085624?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/5628879841428085624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=5628879841428085624' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5628879841428085624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5628879841428085624'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2010/02/writing-more-code-isnt-always-answer.html' title='Writing more code isn&apos;t always the answer'/><author><name>Mike</name><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-4375994787022296080.post-1042448372952302482</id><published>2009-12-16T12:10:00.000-08:00</published><updated>2009-12-16T12:11:57.228-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='csv'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Finding potential problems in CSV files</title><content type='html'>I have to periodically work with CSV files from a variety of sources and the problems with them are pretty well known. Here is a little python script I use that helps me find values that contain double quotes, which are often not properly escaped in the files I receive&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;flines = open(fn,"r").readlines()&lt;br /&gt;currline = flines[1]&lt;br /&gt;&lt;br /&gt;for l in flines:&lt;br /&gt;    vals = l.split(",")&lt;br /&gt;    for v in vals:&lt;br /&gt;        if '"' in v.strip()[1:-1]:&lt;br /&gt;            print v&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-1042448372952302482?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/1042448372952302482/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=1042448372952302482' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/1042448372952302482'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/1042448372952302482'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/12/finding-potential-problems-in-csv-files.html' title='Finding potential problems in CSV files'/><author><name>Mike</name><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-4375994787022296080.post-993639125122824833</id><published>2009-12-06T14:54:00.000-08:00</published><updated>2009-12-16T12:15:14.038-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='closure'/><category scheme='http://www.blogger.com/atom/ns#' term='sleep'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Javascript, sleep and closures</title><content type='html'>My wife is working on a web site and she needs a different div to show up every few seconds, ad nauseum. I hack in javascript enough to be dangerous, so every time I try something new or something I haven't done in a long time, I turn to Google. My idea for this was to simply have a loop that goes through the elements, makes one visible, then sleeps for a few seconds, show the next one, etc. So I thought I would google javascript sleep and see what came back.&lt;br /&gt;&lt;br /&gt;What I got was, to me at least, mostly a &lt;a href="http://www.google.com/search?q=javascript+sleep"&gt;horror show&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Lots of examples with busy waiting and splitting functions up and a lot of code that worked, in so much as it did what somebody wanted. But the code was hard to read, hard to parse, hard to update and in some cases would burn up all the cpu you let it. Knowing all of the features available in javascript I KNEW there had to be a better way, but I wasn't finding anything I thought was "good", at least in the first page of google results. Maybe I just didn't look hard enough. But at this point I figured if I thought about this for a few minutes I would come up with a better solution in less time than I could find one that pleased me. Here, after a few minutes of thought, is what I came up with&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;function divrotate(interval,divarray)&lt;br /&gt;{&lt;br /&gt; currI = 0&lt;br /&gt; currLen = divarray.length&lt;br /&gt; currE = document.getElementById(divarray[currI]);&lt;br /&gt; currE.style.display = '';&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; showNext = function()&lt;br /&gt; {&lt;br /&gt;  currE.style.display = 'none';&lt;br /&gt;  currI++;&lt;br /&gt;  if (currI == currLen) currI = 0;&lt;br /&gt;  currE = document.getElementById(divarray[currI]);&lt;br /&gt;  currE.style.display = '';&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; setInterval("this.showNext()", interval);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Here is what the call would look like from your HTML page&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;      &amp;lt;script src="/divrotate.js" type="text/javascript"&amp;gt;&lt;br /&gt;   &amp;lt;/script&amp;gt;&lt;br /&gt;      &lt;br /&gt;      &amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;   divrotate(8000, new Array("section1","section2","section3"));&lt;br /&gt;   &amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;what you are passing in is an interval, in milliseconds, and the array of elements (in this case DIV) that you want to iterate through. The divrotate function gets the current element and shows it, then a closure is created that will hide the current element, get the next one and show it. setInterval is used to call the closure at the interval specified by the caller.&lt;br /&gt;&lt;br /&gt;Simple code, and it doesn't peg the CPU.&lt;br /&gt;&lt;br /&gt;I am sure that there has got to be some other examples that are straightforward and allow the equivalent of sleep. This seems like too common of a thing to not be elegantly handled somewhere, but quick searches in scriptaculous and mootools don't show my anything promising. I see lots of forum posts with the usual "Use setInterval or setTimeout, you'll see lots of examples if you Google for it!"&lt;br /&gt;&lt;br /&gt;I know this is far from a generic sleep example, but I hope this helps somebody that wants to do something similar. I also hope that it serves as a decent example of closures. Closures are a powerful language construct that, judiciously used, can be of great benefit when they are available. A good discussion of closers in javascript can be found &lt;a href="http://www.jibbering.com/faq/faq_notes/closures.html"&gt;here&lt;/a&gt;, and upon reading it there is an example that comes close to what I have done above, but the example is generic enough that it does not show the use of variables that are in scope.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-993639125122824833?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/993639125122824833/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=993639125122824833' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/993639125122824833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/993639125122824833'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/12/javascript-sleep-and-closures.html' title='Javascript, sleep and closures'/><author><name>Mike</name><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-4375994787022296080.post-7353093298048715107</id><published>2009-11-02T12:21:00.000-08:00</published><updated>2009-12-16T12:13:02.832-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='csv'/><title type='text'>Simple utility for getting data from CSV files</title><content type='html'>Most programmers at some point spend a lot of time hacking apart CSV files. I recently got to yank apart yet another csv and while Excel is handy for these sorts of tasks, it can't do everything quickly, so I hacked up a little utility using php5 and sqlite to help query data and get results fast.&lt;br /&gt;&lt;br /&gt;Here is &lt;a href="http://www.janitorprogrammer.com/csvsql/"&gt;csvsql&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You just upload the file, first row is headers and you can type in the filter part of a where clause to narrow the data. click a button and put out a CSV representation of the data that should be excel friendly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-7353093298048715107?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/7353093298048715107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=7353093298048715107' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7353093298048715107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7353093298048715107'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/11/simple-utility-for-getting-data-from.html' title='Simple utility for getting data from CSV files'/><author><name>Mike</name><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-4375994787022296080.post-4895656676137935305</id><published>2009-09-24T04:51:00.000-07:00</published><updated>2009-09-24T04:53:44.358-07:00</updated><title type='text'>A Post After My Own Heart</title><content type='html'>Joel writes about what he calls &lt;a href="http://www.joelonsoftware.com/items/2009/09/23.html"&gt;Duct Tape Programmers&lt;/a&gt;. Best thing he's written in a while, if you ask me. Not that you did, but it is definitely worth a read. I'm also planning on picking up Coders At Work, which he mentions in the article. Sounds like a great read.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-4895656676137935305?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/4895656676137935305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=4895656676137935305' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4895656676137935305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4895656676137935305'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/09/post-after-my-own-heart.html' title='A Post After My Own Heart'/><author><name>Mike</name><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-4375994787022296080.post-5412330128135334228</id><published>2009-09-08T14:46:00.001-07:00</published><updated>2009-12-16T12:13:41.376-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='paranoia'/><category scheme='http://www.blogger.com/atom/ns#' term='personal information'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>"Anonymous" data</title><content type='html'>Just one more reason to be very careful about what information you put on the internet. Most people think gender, zip code and birthdate won't give much away. Most people are &lt;a href="http://arstechnica.com/tech-policy/news/2009/09/your-secrets-live-online-in-databases-of-ruin.ars"&gt;wrong&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-5412330128135334228?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/5412330128135334228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=5412330128135334228' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5412330128135334228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5412330128135334228'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/09/anonymous-data.html' title='&quot;Anonymous&quot; data'/><author><name>Mike</name><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-4375994787022296080.post-7572979066087812380</id><published>2009-08-11T09:38:00.000-07:00</published><updated>2009-12-16T12:14:23.194-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='small form factor'/><category scheme='http://www.blogger.com/atom/ns#' term='cheap computing'/><title type='text'>This is just plain cool</title><content type='html'>When I was at U of M my &lt;a href="http://www.si.umich.edu/people/faculty-detail.htm?sid=100"&gt;software engineering professor&lt;/a&gt; would talk about how small storage and computers were becoming and how we won't be needing these big boxes anymore.&lt;br /&gt;&lt;br /&gt;I saw &lt;a href="http://arcfn.com/2009/08/worlds-smallest-arc-server.html"&gt;this&lt;/a&gt; on &lt;a href="http://news.ycombinator.com/"&gt;hacker news&lt;/a&gt; and it just looks cool. With a bunch of &lt;a href="http://plugcomputer.org/"&gt;SheevaPlugs&lt;/a&gt; you can turn a powerstrip or 2 into a server farm :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-7572979066087812380?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/7572979066087812380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=7572979066087812380' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7572979066087812380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7572979066087812380'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/08/this-is-just-plain-cool.html' title='This is just plain cool'/><author><name>Mike</name><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-4375994787022296080.post-7354014115992116951</id><published>2009-08-09T22:18:00.000-07:00</published><updated>2009-12-16T12:14:45.542-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Rails Stuff</title><content type='html'>Finally been hacking on some code this weekend for my rails project. I want to have people login with user credentials and a couple of resources on using restful_authentication that I found EXTREMELY useful are here:&lt;br /&gt;&lt;br /&gt;A great demo&lt;br /&gt;&lt;a href="http://media.railscasts.com/videos/067_restful_authentication.mov"&gt;http://media.railscasts.com/videos/067_restful_authentication.mov&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;and&lt;br /&gt;&lt;br /&gt;if you get an error when trying to login&lt;br /&gt;&lt;a href="http://blog.anthonychaves.net/tag/rails"&gt;&lt;br /&gt;http://blog.anthonychaves.net/tag/rails&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Also the controller for my default class had this added to it so we don't get into an infinte loop when trying to login for the first time&lt;br /&gt;&lt;br /&gt;  skip_before_filter :login_required&lt;br /&gt;&lt;br /&gt;I also added this on the user controller so we can go create a new user without having to login. Duh!&lt;br /&gt;&lt;br /&gt;I'm using Rails for .NET Developers from The Pragmattic Programmers to guide me along with lots of online docs. I'm also learning Ruby as I go. It seems to share with python the same notion of 'what you expect will work'. Pretty much I've been typing things and they are working, without too many tweaks. It's kind of nice. I'm doing super simple run of the mill stuff, so I'm not expecting too many things to blow up as of yet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-7354014115992116951?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/7354014115992116951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=7354014115992116951' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7354014115992116951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7354014115992116951'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/08/rails-stuff.html' title='Rails Stuff'/><author><name>Mike</name><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-4375994787022296080.post-8823229743413284764</id><published>2009-08-04T21:00:00.000-07:00</published><updated>2009-08-04T21:09:09.461-07:00</updated><title type='text'>Best Quote Talking about the Apple App store ever</title><content type='html'>"Apple requires you to be 17 years or older to purchase a censored dictionary that omits half the words Steve Jobs uses every day."&lt;br /&gt;&lt;br /&gt;This little gem is from what appears to be an increasingly common scenario of rejections leading to rants against the App Store. I'm sure the Apple Faithful don't mind (I'm sure the faithful would be happy to watch Steve give their spouses/partners a rim job and then split them open, bathe in their entrails, cook them and then eat them), but for the average developer, it would seem that a lot of Apple's coolness is wearing very, very thin.&lt;br /&gt;&lt;br /&gt;Here's the full post about Ninjawords and their &lt;a href="http://daringfireball.net/2009/08/ninjawords"&gt;debacle&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-8823229743413284764?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/8823229743413284764/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=8823229743413284764' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/8823229743413284764'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/8823229743413284764'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/08/best-quote-talking-about-apple-app.html' title='Best Quote Talking about the Apple App store ever'/><author><name>Mike</name><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-4375994787022296080.post-5129396212244113736</id><published>2009-07-17T10:36:00.000-07:00</published><updated>2009-07-17T10:40:34.899-07:00</updated><title type='text'>Sofware Engineering and Metrics</title><content type='html'>Tom DeMarco (Yes, &lt;a href="http://www.systemsguild.com/GuildSite/TDM/Tom_DeMarco.html"&gt;THAT Tom DeMarco&lt;/a&gt;) wrote an interesting piece on his current view of &lt;a href="http://www2.computer.org/cms/Computer.org/ComputingNow/homepage/2009/0709/rW_SO_Viewpoints.pdf"&gt;Software Engineering&lt;/a&gt;. Definitely worth the read.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-5129396212244113736?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/5129396212244113736/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=5129396212244113736' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5129396212244113736'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5129396212244113736'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/07/sofware-engineering-and-metrics.html' title='Sofware Engineering and Metrics'/><author><name>Mike</name><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-4375994787022296080.post-872899762738948844</id><published>2009-07-15T08:47:00.000-07:00</published><updated>2009-12-16T12:15:56.813-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='personal information'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud computing'/><title type='text'>Clouds can be Dangerous</title><content type='html'>Agree or not with &lt;a href="http://www.techcrunch.com/2009/07/15/our-reaction-to-your-reactions-on-the-twitter-confidential-documents-post/"&gt;TechCrunch&lt;/a&gt;'s decision to publish some data from some Twitter documents they received, I think the most important thing to note is what they say about using gmail and other cloud services&lt;br /&gt;&lt;br /&gt;"It’s not our fault that Google has a ridiculously easy way to get access to accounts via their password recovery question. It’s not our fault that Twitter stored all of these documents and sensitive information in the cloud and had easy-to-guess passwords and recovery questions. We’ve been sitting in the office for eight hours now debating what the right thing to do is in this situation. We’ve spoken with our lawyers. We’ve spoken with Twitter. And we’ve heard what our readers have to say. All of that factors in to our decision on what to post or not to post."&lt;br /&gt;&lt;br /&gt;I have been wondering how many people will need to get burned and to what degree before they start taking this sort of thing seriously. Given that Google's entire business model is selling targeted advertising, they have an incentive to collect as much data about you as possible. You would think for this reason alone people would be wary of dumping too much stuff into Google's hands. The annoyance factor would get to be outrageous, I would think. That's not even considering that Google has to be a HUGE target for any sort of cracker that wants to track down any kind of information. I'm sure they do their very best to keep everything as locked down as possible, but it's really hard to compromise the information if it isn't there to be compromised in the first place.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-872899762738948844?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/872899762738948844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=872899762738948844' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/872899762738948844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/872899762738948844'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/07/clouds-can-be-dangerous.html' title='Clouds can be Dangerous'/><author><name>Mike</name><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-4375994787022296080.post-3283592267080385826</id><published>2009-07-10T13:18:00.001-07:00</published><updated>2009-12-16T12:16:18.736-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>The current and future state of programming</title><content type='html'>An interesting read from &lt;a href="http://blogs.law.harvard.edu/philg/2005/03/08/#a7726"&gt;Philip Greenspun&lt;/a&gt;. Apparently some students were able to find their admission status by modifying a URL. This, apparently, qualifies as "hacking". Ugh.&lt;br /&gt;&lt;br /&gt;I am particularly fond of the sentence "As progressively dumber programmers build progressively more complex systems we will see more of this kind of attempt to paper over coding mistakes with lawyers, sanctions, policies, and laws." I know people that have been lamenting this sort of thing for years. To hear it put so clearly is refreshing. Not that anybody will really care. Until their credit cards and bank accounts get hacked, that is. But by then it will be too late. And they'll care for about 20 minutes and then get back on with their lives. *sigh*&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-3283592267080385826?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/3283592267080385826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=3283592267080385826' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/3283592267080385826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/3283592267080385826'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/07/current-and-future-state-of-programming.html' title='The current and future state of programming'/><author><name>Mike</name><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-4375994787022296080.post-5571376747358331686</id><published>2009-07-09T06:28:00.000-07:00</published><updated>2009-12-16T12:16:59.390-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>NIH Syndrome</title><content type='html'>Most people in software are at least aware of Not Invented Here syndrome. We're in the middle of fighting with it right now, on the other side where we have some dependencies that are causing issues because we rely on some libraries for a very important piece of our software and the library has upgraded and if we use the upgrade we are, for all practical purposes, going to have to do a rewrite. So I was going to write this big long article in defense of NIH and why it makes sense to roll your own sometimes, but then I remembered that Joel on Software had tackled this already.&lt;br /&gt;&lt;br /&gt;I reread the piece and it is basically saying the exact same thing I was going to say, so &lt;a href="http://www.joelonsoftware.com/articles/fog0000000007.html"&gt;here it is&lt;/a&gt;. I can't say that I would go to Joel's extreme of &amp;quot;If it's a core business function -- do it yourself, no matter what.&amp;quot;, but you need to seriously think about the cost of upgrading dependencies if the dependency is a core piece of what you are doing. It's not a matter of IF it will bite you in the ass, but WHEN and how hard.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-5571376747358331686?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/5571376747358331686/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=5571376747358331686' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5571376747358331686'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5571376747358331686'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/07/nih-syndrome.html' title='NIH Syndrome'/><author><name>Mike</name><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-4375994787022296080.post-6532956758926474796</id><published>2009-06-19T14:28:00.000-07:00</published><updated>2009-12-16T12:17:45.573-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='source control'/><title type='text'>Reviewing files from Subversion</title><content type='html'>Recently I had to deploy some updates to a website and wanted to get a list of all the files that had been updated to make sure I got everything. With recent versions of subversion and using python this turned out to be rather simple:&lt;br /&gt;&lt;br /&gt;First, get a list of all the files that have been checked in and stick them in a text file.&lt;br /&gt;&lt;br /&gt;C:\Utils\svn-win32-1.4.3\bin&gt;svn diff --summarize -r902:966 svn://myServer/myRepository/myProject/trunk &gt; c:\diff.txt&lt;br /&gt;&lt;br /&gt;Then use the following lines of python to get the file names and sort them to make tracking them down easy&lt;br /&gt;&lt;br /&gt;mylines = open("c:\\diff.txt" , "r").readlines()&lt;br /&gt;myarr = [x.split(" ")[-1].strip() for x in mylines]&lt;br /&gt;myarr.sort()&lt;br /&gt;&lt;br /&gt;Now print out myarr, put it in its own file or do whatever you want with it to deploy or review your updates.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-6532956758926474796?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/6532956758926474796/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=6532956758926474796' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/6532956758926474796'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/6532956758926474796'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/06/reviewing-files-from-subversion.html' title='Reviewing files from Subversion'/><author><name>Mike</name><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-4375994787022296080.post-4134680492485181692</id><published>2009-06-18T07:34:00.001-07:00</published><updated>2009-12-16T12:21:55.309-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>False Productivity</title><content type='html'>I'm finishing up a project for a buddy of mine that is in php. It's an old school simple CRUD app and as such I didn't go too overboard with the functionality. It does what the client asked and the code is reasonably clean but not something that you could refer to as having much of an architecture.&lt;br /&gt;&lt;br /&gt;Since it is all raw HTML and PHP I had to code everything up by hand. At my regular job we do almost everything in ASP.NET. This got me to thinking as I was working on these two things side by side that, after roughly clocking the hours of similar projects, that a lot of the productivity I've been feeling I've been getting from ASP.NET is false. As one of my co-workers is fond of saying, the complexity has to exist somewhere, all we really do is move it around. This struck me keenly because my layout and design skills are not great, so even coding up a simple interface that does what it is supposed to takes a little bit of effort and since I'm not using any frameworks at all for the PHP app, I got to code it all by hand. In the APS.NET world you would drag and drop a couple controls and be done. Poof!&lt;br /&gt;&lt;br /&gt;But, then, the data access layer coding began. And the DAL for the PHP app was dead simple to code. And it wsa doing some reasonably interesting things. Nothing crazy, but a couple joins here and there, you're usual stuff. In ASP.NET, once you go outside their little box, things become somewhat painful. I've had instance where putting together the interface was drag and drop a few things and then the prototype of the data access was a few minutes of drag and drop but then things start happening. The production data has millions of rows and your test data only has a few thousand, so the paging and access for the paging needs to be recoded. Oh, wait, there's a fancy new datagrid widget doo-hickey that your manager read about somewhere. Can we use that? And on and on with the little things that make a seemingly quick and simple job time consuming. Just like that the productivity you thought you had gained went up in smoke. In some cases it actually gets worse because you either have to start over or make what your additions fit into what you've written already AND make it fit into the ASP.NET universe.&lt;br /&gt;&lt;br /&gt;I guess the point here is that things aren't always as time saving as they appear. I know people say a lot of things. My language is X more productive than yours. You get demos from vendors showing how easy something is. Three drags, a double click and a pinch of salt and you have a fully functioning app! Just be suspicious of such claims. Chances are the three drag demo has little resemblance to the actual work you do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-4134680492485181692?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/4134680492485181692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=4134680492485181692' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4134680492485181692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4134680492485181692'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/06/false-productivity.html' title='False Productivity'/><author><name>Mike</name><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-4375994787022296080.post-8033715274830984902</id><published>2009-05-29T10:18:00.000-07:00</published><updated>2009-12-16T12:22:21.766-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Well, I'm drinking the Kool Aid</title><content type='html'>My brother in law and I had an idea for a project and from what he and many others have said, it would be a perfect Rails project, so I downloaded Rails and got a copy of Rails for .NET Developers and I started reading last night. It looks like it should do the trick. This is a pretty simple application, so it seems like a great fit for what Rails is supposed to be good for. Having seen &lt;a href="http://meetinbetween.us/"&gt;some of the things&lt;/a&gt; people put together for Rails Rumble, I'm hoping I can bang this thing out fairly quickly.&lt;br /&gt;&lt;br /&gt;Anyway, given I've done my share of python, C++, C# and VB with a smattering of Javascript and PHP and vague memories of lisp and a bitter taste in my mouth for perl, I'll see how this works out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-8033715274830984902?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/8033715274830984902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=8033715274830984902' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/8033715274830984902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/8033715274830984902'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/05/well-im-drinking-kool-aid.html' title='Well, I&apos;m drinking the Kool Aid'/><author><name>Mike</name><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-4375994787022296080.post-3033541865348579428</id><published>2009-05-10T09:09:00.000-07:00</published><updated>2009-12-16T12:22:49.980-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='mysql'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='php'/><title type='text'>Thank you Microsoft</title><content type='html'>Look, a lot of us in this industry bash Microsoft and in many cases rightfully so. But this weekend I was doing some work for a friend who has a client that has a site running IIS, SQL Server and PHP. I did the prototype of what I'm working on in PHP and mySQL on my laptop and then had to port the database layer over to SQL Server. This app is far from rocket science, so I wasn't worried in the least about doing the first version against mySQL. So I downloaded SQL Server, installed it on my laptop after hitting many Next&gt; buttons, updated my code to use the standard mssql module that comes with PHP and then started testing. That's when the problems started. I did the usual googling and came up with somethings I had forgotten to do on the install, like enable TCP/IP in the Configuration Manager and other assorted bookkeeping stuff. But after that and getting other clients to connect successfully, the PHP app kept having issues connecting, never mind doing any actual work. I had done a ton of research, tried everything I found and then some, and finally gave up trying to use the standard PHP module.&lt;br /&gt;&lt;br /&gt;Since in my regular job I work almost exclusively with Microsoft technology, I am mostly up to date on what they do. I know as of late they've been doing some work to help support a lot of web and open source technology out there. So I was wondering if maybe, just maybe, then had a PHP client. They have a database client for java, after all. So I figured what the hell and found the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=61BF87E0-D031-466B-B09A-6597C21A2E2A&amp;displaylang=en"&gt;SQL Server driver for PHP 1.0&lt;/a&gt;. After downloading the file, I think it was just over an hour from extracting the files to the PHP extensions directory until I had a working version on SQL Server. I've had somewhat similar experiences lately with flickr and facebook tools found on codeplex.&lt;br /&gt;&lt;br /&gt;The one thing that made this very painless is everything I needed to get this installed and configured was all in one place. The help file was actually helpful and told me what I needed to know to get things going. I didn't have ot hit half a dozen websites in order to figure out I needed to have the SQL Server 2005 native client driver installed. It just told me. Granted it was annoying to have to uninstall the 2008 driver and download and install the 2005 driver, but given a co-workers recent experiences with setting up ubercart, this was completely painless. He spent HOURS going from site to site, getting modules, downloading updates, installing dependencies when the modules he installed didn't come with everything he needed, etc. I'm glad it wasn't me. I probably would have given up. Personally I find this the most frustrating part about the open source community. I don't understand how projects like this gain the traction they do. They're hard to set up and hard to keep updated because in many ways these things are like a house of cards. I use some open source tools (python being by far my favorite) but, by and large, I find the lack of good documentation (by good I mean useful. I've found a LOT of documentation on most things, but generally it isn't worth the electrons spent rendering them on my screen) to be a HUGE hurdle to overcome. There is no reason I should have to spend hours and hours searching for documentation that still doesn't fix the problem. In general the open source community doesn't understand why people don't use their products more. How can they keep flocking to "Micro$oft Windoze" and their other schlock when there are cheaper and superior alternatives available???? Well, I think documentation is about 70% of the answer to that question. And the usual response is that open source projects are, in a lot of cases, done by people for free in their spare time and, let's face it, I do not know a single developer that likes writing documentation that is for end users. Well, if you don't like doing that, people aren't going to be able to use your product, no matter how superior it might be in a technological sense.&lt;br /&gt;&lt;br /&gt;So I wanted to take a minute to say thank you to the people at Microsoft for putting these types of tools together and for the community that surrounds &lt;a href="http://www.codeplex.com/"&gt;CodePlex&lt;/a&gt; and other similar sites. As a company that is generally viewed as closed and being competitive to a fault, it is nice to see that this is pretty much a caricature of the organization. They obviously have their issues, but I think they are really beginning to realize that if they are ultimately going to not only survive, but thrive, that they need to embrace and support a lot of the other good work going on out there. There are, of course, plenty of selfish reasons to do this, but there are just as many reasons not to do this and it is probably easier not to.&lt;br /&gt;&lt;br /&gt;In general I think this is starting to be a return to what made Microsoft the dominant software company on the planet. When office and Windows were first born, they had a LOT of competition and, as others have pointed out, one of the things that made Microsoft software good back in the day is that they went to great lengths to interoperate with other software out there. Excel worked well with Lotus files and Word was able to read and write WordPerfect files, for example. Not to mention DOS and Windows being able to run on a wide assortment of machines. Maybe not well all the time, but well enough.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-3033541865348579428?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/3033541865348579428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=3033541865348579428' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/3033541865348579428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/3033541865348579428'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/05/thank-you-microsoft.html' title='Thank you Microsoft'/><author><name>Mike</name><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-4375994787022296080.post-2834853309466331287</id><published>2009-04-24T12:12:00.000-07:00</published><updated>2009-12-16T12:23:17.071-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Case insensitive validators in .NET</title><content type='html'>I have just done some work on a control that needed to have some validation for dynamically generated text boxes. I did some poking around for adding validators dynamically that would be client side and would check for words by being case insensitive. I found a few solutions to this that involved server side validation and I wanted to keep it on the client. The ASP.NET validators use javascript on the client side and there isn't anything I could find that would easily let me do a case insensitive compare on the client side using the .NET controls. For example, I couldn't pass /sometext/i to the validator and have the 'i' attribute recognized.&lt;br /&gt;&lt;br /&gt;A solution hit me on the way home. I was checking for the common occurences of 'true' and 'false', 'True|False|true|false'. Which was probably going to be fine but every now and then you hold the shift a second too long or you have caps lock down and you enter TRUE or FAlse and those wouldn't work out and while they would evaluate to a boolean once they hit the server, they would never get there because of the validation.&lt;br /&gt;&lt;br /&gt;So now my expression looks like '[Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]'. that does the trick very nicely. It isn't great to read, but this is a very specific case and I've certainly seen worse. And I don't need to do a mix of server and client side validation now, which makes me happy. I wouldn't do this for something that was involved, but for this particular case it is simple to implement, not totally unreadable and prevents a useless round trip to the server.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-2834853309466331287?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/2834853309466331287/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=2834853309466331287' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/2834853309466331287'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/2834853309466331287'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/04/case-insensitive-validators-in-net.html' title='Case insensitive validators in .NET'/><author><name>Mike</name><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-4375994787022296080.post-1041657352514915153</id><published>2009-03-11T12:30:00.000-07:00</published><updated>2009-03-11T12:32:58.594-07:00</updated><title type='text'>11, 58, 29, 16, 33, 21, 24, 29, ...</title><content type='html'>These are the minutes remaining on a large file copy (6+ GB) in Windows. Why bother giving the estimate?&lt;br /&gt;&lt;br /&gt;That's today's rant. Back to waiting for the file copy to finish. 8 minutes to go. Maybe...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-1041657352514915153?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/1041657352514915153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=1041657352514915153' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/1041657352514915153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/1041657352514915153'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/03/11-58-29-16-33-21-24-29.html' title='11, 58, 29, 16, 33, 21, 24, 29, ...'/><author><name>Mike</name><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-4375994787022296080.post-765356306924854400</id><published>2009-02-23T13:45:00.000-08:00</published><updated>2009-02-23T13:59:40.779-08:00</updated><title type='text'>8 steps to millions?</title><content type='html'>Doesn't this sound easy?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.guardian.co.uk/technology/gamesblog/2009/feb/10/gameculture-apple"&gt;http://www.guardian.co.uk/technology/gamesblog/2009/feb/10/gameculture-apple&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I wonder how many people started cranking out yet another game after reading this. I'm half tempted.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-765356306924854400?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/765356306924854400/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=765356306924854400' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/765356306924854400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/765356306924854400'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/02/8-steps-to-millions.html' title='8 steps to millions?'/><author><name>Mike</name><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-4375994787022296080.post-7013320673261833595</id><published>2009-01-04T19:24:00.000-08:00</published><updated>2009-01-04T19:30:50.253-08:00</updated><title type='text'>Agile</title><content type='html'>Generally speaking, I'm not a big fan of Agile Development for two reasons.&lt;br /&gt;&lt;br /&gt;1. All the hype.&lt;br /&gt;&lt;br /&gt;2. A lot of contradictory information and advice, sometimes from the same person. One time you hear that you have to adopt all the steps of a given methodology. Another time you hear that you can't be brain dead about adopting the steps, but need to pick and choose what works for you. A big selling point of Agile is little documentation, given that as a rule developers hate writing documentation. But then this gets taken to its illogical conclusion and many of the Agile work I've seen has zero design and planning. People just start coding and think the design will magically assert itself at some point. In fact, for a trade that generally prides itself on being logical, there is a lot, in practice, that I see illogical about adoption of Agile methodologies.&lt;br /&gt;&lt;br /&gt;That being said, I agree with the position of most items on the Agile Manifesto. It's just in practice I haven't seen it work too well often. Even the reported successes are usually qualified and, depending on the stakeholder you ask, the success really isn't a success.&lt;br /&gt;&lt;br /&gt;To that end, I think this latest entry on Artima is a good read and crystallizes a few of the issues that lead to this state of things. &lt;a href="http://www.artima.com/weblogs/viewpost.jsp?thread=246513"&gt;http://www.artima.com/weblogs/viewpost.jsp?thread=246513&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-7013320673261833595?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/7013320673261833595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=7013320673261833595' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7013320673261833595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/7013320673261833595'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2009/01/agile.html' title='Agile'/><author><name>Mike</name><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-4375994787022296080.post-2818503176485887306</id><published>2008-12-11T11:40:00.000-08:00</published><updated>2008-12-11T11:55:50.623-08:00</updated><title type='text'>Marketing to developers</title><content type='html'>I just got a piece of marketing schlock in my inbox today from Salesforce.com&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-family: times new roman;font-size:130%;" &gt;Code Warriors: Have We Got a Challenge for You!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: times new roman;font-size:85%;" &gt;By now you've heard the buzz and excitement about Force.com Sites, and may even have attended our recent Sites Developer Preview Webinar. Now be among the first to get hands-on with this ground-breaking technology:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-family: times new roman;color:red;" &gt;&lt;br /&gt;Enter the Force.com Sites Developer Challenge&lt;/span&gt;&lt;span style="font-family: times new roman;font-size:85%;" &gt;—and broadcast your stellar coding skills to the world! We'll reward you with hero status on Force.com developer Web sites and blogs, plus a terrific prize.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: times new roman;"&gt;&amp;lt;and it goes on and on and on....&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Stuff like this drives me, and most good developers I know, crazy.&lt;br /&gt;&lt;br /&gt;Look, the majority of developers I know are not warriors. They couldn't fight their way out of a wet paper bag. Like King Arthur's nights, a vicious rabbit could decimate most of them.&lt;br /&gt;&lt;br /&gt;There is no buzz and excitement from anybody I personally know about Force.com Sites. First I heard of anything resembling buzz and excitement is in the email that came from Force.com.&lt;br /&gt;&lt;br /&gt;Most people with stellar coding skills are working on operating system kernels, 3d rendering images, games, bio informatics, genetic algorithms, language compilers or interpreters, etc. They most certainly aren't working on web apps that mainly consist of gluing API calls together. Product catalogs and surveys don't exactly stretch the grey matter.&lt;br /&gt;&lt;br /&gt;I'm guessing the people that buy into this stuff are probably the development managers that usually receive this stuff and, well, since salesforce.com might be part of some strategic direction, the developers get this email forwarded to them and they are &amp;quot;encouraged&amp;quot; to enter. I got this in my inbox because I work at a small company and, for good or ill, I get to deal with most of this stuff directly. The only reason I even opened it was because I thought it might make good blog fodder. Most of this kind of stuff is insulting to the intelligence. &lt;br /&gt;&lt;br /&gt;Code Warrior. Sheesh. Now where did I leave my swords...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-2818503176485887306?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/2818503176485887306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=2818503176485887306' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/2818503176485887306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/2818503176485887306'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2008/12/marketing-to-developers.html' title='Marketing to developers'/><author><name>Mike</name><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-4375994787022296080.post-5786273930383575265</id><published>2008-12-09T12:57:00.000-08:00</published><updated>2009-12-16T12:33:22.441-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>working with utf16 in python</title><content type='html'>I got a file from a client that was exported from SQL Server and was encoded as utf16. I needed to do some work on it. I had to google around a bit to find some help on handling the gobble-de-gook that I was seeing&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; f = open("f:\\contact.txt","r")&lt;br /&gt;&gt;&gt;&gt; l = f.readline()&lt;br /&gt;&gt;&gt;&gt; l&lt;br /&gt;'\xff\xfe6\x003\x003\x00D\x003\x00A\x008\.....\n'&lt;br /&gt;&lt;br /&gt;Here is how to do it&lt;br /&gt;&lt;br /&gt;&gt;&gt;&gt; import codecs&lt;br /&gt;&gt;&gt;&gt; f = codecs.open("f:\\contact.txt", "r", "utf16")&lt;br /&gt;&gt;&gt;&gt; l = f.readline()&lt;br /&gt;&gt;&gt;&gt; l&lt;br /&gt;u'633D3A84-3870-4A93-9755-000215260850,8568,NULL,Scooby,Shaggy,NULL,,NULL,mymail@address.com,1902-06-01 00:00:00.000,NULL\r\n'&lt;br /&gt;&gt;&gt;&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-5786273930383575265?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/5786273930383575265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=5786273930383575265' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5786273930383575265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/5786273930383575265'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2008/12/working-with-utf16-in-python.html' title='working with utf16 in python'/><author><name>Mike</name><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-4375994787022296080.post-8399070702196187666</id><published>2008-11-20T12:10:00.000-08:00</published><updated>2008-11-20T12:21:51.966-08:00</updated><title type='text'>eXtreme Annoyance</title><content type='html'>It is hard for me to get eXcited about eXtreme spellings. Most of these ideas aren't eXceptional or eXquisite in any eXplainable way. A lot of these eXtreme methods lack eXactness, clear eXplanations and fall apart under close eXamination. Even the Success Stories for eXtreme Programming are less than eXceptional.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-8399070702196187666?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/8399070702196187666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=8399070702196187666' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/8399070702196187666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/8399070702196187666'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2008/11/extreme-annoyance.html' title='eXtreme Annoyance'/><author><name>Mike</name><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-4375994787022296080.post-4253532193525908582</id><published>2008-11-18T08:40:00.001-08:00</published><updated>2008-11-18T08:41:05.401-08:00</updated><title type='text'>If this is the new trend, I quit!</title><content type='html'>&lt;a href="http://discuss.joelonsoftware.com/default.asp?joel.3.700535.8"&gt;http://discuss.joelonsoftware.com/default.asp?joel.3.700535.8&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Roof over your head for a part time job. Seems creepy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-4253532193525908582?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/4253532193525908582/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=4253532193525908582' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4253532193525908582'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4253532193525908582'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2008/11/if-this-is-new-trend-i-quit.html' title='If this is the new trend, I quit!'/><author><name>Mike</name><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-4375994787022296080.post-4734391197673062068</id><published>2008-10-24T10:31:00.000-07:00</published><updated>2008-10-24T10:33:37.566-07:00</updated><title type='text'>FINALLY</title><content type='html'>Some new installments on &lt;a href="http://regularexpressions.com/"&gt;regularexpressions&lt;/a&gt;. That has been one of my favorite reads on the internet for actual practical information on using scripting languages and things outside the usual enterprise application java/.NET/LAMP world  that so many of us inhabit.&lt;br /&gt;&lt;br /&gt;Glad it's back with new material!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-4734391197673062068?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/4734391197673062068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=4734391197673062068' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4734391197673062068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4734391197673062068'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2008/10/finally.html' title='FINALLY'/><author><name>Mike</name><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-4375994787022296080.post-4578409768026912469</id><published>2008-10-17T14:24:00.000-07:00</published><updated>2008-10-17T14:29:40.580-07:00</updated><title type='text'>Opening explorer shells</title><content type='html'>I'm often in the command line on a windows box and need to open an explorer shell for a variety of reasons. You can simply type &lt;span style="font-weight: bold;"&gt;explorer .&lt;/span&gt; (don't forget the dot) at the prompt and a window will open that points at the current directory.&lt;br /&gt;&lt;br /&gt;I got tired of typing that much and created a file called ex.bat that I dropped in my windows directory. You can put it anywhere in your path. Here is the contents of the batch file&lt;br /&gt;&lt;br /&gt;&lt;code&gt;@echo off&lt;br /&gt;explorer .&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Just copy the above, stick it in a text file and save it to c:\windows\ex.bat. Then typing &lt;span style="font-weight:bold;"&gt;ex&lt;/span&gt; at the command prompt will do the same as &lt;span style="font-weight:bold;"&gt;explorer .&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-4578409768026912469?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/4578409768026912469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=4578409768026912469' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4578409768026912469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4578409768026912469'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2008/10/opening-explorer-shells.html' title='Opening explorer shells'/><author><name>Mike</name><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-4375994787022296080.post-4918504393171982785</id><published>2008-10-17T08:55:00.000-07:00</published><updated>2008-10-17T08:59:07.033-07:00</updated><title type='text'>New spot for quick updates</title><content type='html'>Having spent time writing full length articles on &lt;a href="http://www.janitorprogrammer.com"&gt;janitor programmer&lt;/a&gt;, I figured I needed a spot to just put quick updates of things I've stumbled across and figured out. Rather than write my own or install wordpress or one of a hundred other things, I figured I may as well take advantage of blogger.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4375994787022296080-4918504393171982785?l=janprog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://janprog.blogspot.com/feeds/4918504393171982785/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4375994787022296080&amp;postID=4918504393171982785' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4918504393171982785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4375994787022296080/posts/default/4918504393171982785'/><link rel='alternate' type='text/html' href='http://janprog.blogspot.com/2008/10/new-spot-for-quick-updates.html' title='New spot for quick updates'/><author><name>Mike</name><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>
