Sunday, January 20, 2008
Interpolation is just a fancy word for variable substitutioin in a string.

According to the free dictionary interpolate means:
1. To insert or introduce between other elements or parts.
2.
    a. To insert (material) into a text.

Perl does this very well, other language less so.  Less is a hybrid of the C# method for string formatting.  I find it pretty convenient when creating a lot of dynamic html to insert using that oh so hander innerHTML property.  Remember, innerHTML is usually the fastest way to add dynamic html.

function format(format) {
var params = arguments;
var toReturn = format;

for (var i = 0; i < params.length - 1; i++) {
var rString = '\\$\\{' + (i) + '\\}';
var regex = new RegExp(rString, "g");
toReturn = toReturn.replace(regex, params[i + 1]);
}

return toReturn;
}

Here's the original interpolation function that extended the string object.  I don't really think that extending builtin objects is a great idea unless there is no other way.

Sunday, January 20, 2008 7:46:19 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Wednesday, January 09, 2008

OK, so I've been using Python quite a bit lately and I've been enjoying it.  I've been getting stuff done with it too.  Python inter-operates with COM quite well and that saved me a lot of pain yesterday.  However, learning Python has caused me pain in other areas.

Yesterday I had to perform some maintenance in a C# ASP.NET app that I had written not too long ago.  Even though I use the CoolStorage.NET and some other nice time savers, it has become painful to write C# code.  It's just too verbose.

I used to marvel at people who claimed that you don't need an IDE to develop with Python.  I thought that was blasphemy as Visual Studio was the bee's knees in C# development.  However, I'm amazed at how much more I'm engaged in coding when I'm writing Python (or JavaScript).  You have to pay attention to what you're doing, no IDE is going to help you out.  However, this heightened state of concentration is actually fantastic for writing good code.

I use Notepad++ as my editor for Python (and JavaScript and HTML, etc) when I'm not using C# and Visual Studio.  I find its adequate for the job and it does have a function/method browser built in.  It also does HTML auto-complete and it can highlight a psp template file where I have Python, HTML and JavaScript all in one file.  It's also very stable, something that Visual Studio is not.

Visual Studio 2005 is flaky.  Sometimes all my Windows will rearrange or reset.  Other odd things happen and I find myself re configuring my layout from scratch.  Actually worse than scratch because every thing is helter skelter around. 

The worst part though is the amount of code I have to write to keep the compiler happy.  I know what I want to do and I know how I want to do it but I have to tell the compiler what I'm doing ahead of time so that it's happy.  Honestly, this is a great feature for a newbie or someone who really doesn't want to learn the language.  However, it becomes a burden after a while.  The C family of language has so many tokens (symbols like { [ ( ; , for while do foreach if) that your code becomes very noisy very fast.  Python is nice and clean which is something that I've come to appreciate.

I think I've found a better appreciation for Python (and JavaScript) because I've used C#/C++/Java.  For my everyday programming needs Python can handle everything I need to do.  However, at my current job getting Python into the mix might be a bit hard.  However, it might be worth it.  We spend so much of our day writing Programs that should just be nice and easy scripts.  We have so many programs and projects that could easily be one python file.  We do a lot of file transfer and validation. 

So yes, I'm feeling the pain of C#.  I just don't need/want that bug IDE and big language for what I need to do. 

Python does it faster, smaller and cleaner. 

Wednesday, January 09, 2008 9:33:53 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, January 08, 2008

Have you ever need to browse to several pages and print them?  It seems like it should be easy and it is with this little Python script.

I had an Intranet based system that displayed items in a browser.  The manager of the group I built this for asked for a hard copy of every item that fit a certain criteria.  So instead of them going to over 400 pages by hand I just created this simple script. 

It worked like a charm.

#start script

from win32com import client
import time

ie = client.Dispatch("InternetExplorer.Application")

def printPage(url):

    print "printing " + url
    ie.Navigate(url)

    while ie.Busy:
        time.sleep(1)
        print 'navigating...'

    print 'starting print job...'
    ie.ExecWB(6, 2)
    print 'executed print job.'
  
    while ie.Busy:
        time.sleep(1)
        print 'printing...'


printPage("http://google.com")
ie.Quit()

#end script

Sources:

http://www.darkcoding.net/software/printing-word-and-pdf-files-from-python/

http://www.grimsworld.org.uk/printie.html

Tuesday, January 08, 2008 3:44:48 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Sunday, December 16, 2007
Or ORM's Are Not the Whole Answer
OR Some ORM's Are A Better Answer

One point I feel I need to make.  So many people seem to think that at some point an ORM will appear that will just magically work.  It will map all your entities to objects and "just work."

So an endless parade of ORM's continue to lurch forth from the hinterlands. 

I'm amazed that people like Bruce Eckel think that an ORM powerful enough will just solve the problem.

The thinking is usually something like "we can shield the user from that ugly, mean SQL with some nice procedural and markup tricks." 

I've come to believe that anytime you try to hide/wrap/abstract a powerful technology/language (SQL, JavaScript, HTML, etc) you end up with at best a leaky abstraction and at worst a complete mess.

SQL is concise and powerful.  It doesn't need to be hidden.  It's not that hard to understand.  It's at least easier to understand than most of the ORM frameworks.  It's quite ridiculous what kind of code acrobatics you must perform to add parameters to a query. 

One of the biggest problems with an ORM is predicting what kind of code they will generate/execute.  The more considerate frameworks include a logging function of some sort.  This is nice but when I go to look at some code and I find a bunch of ORM garbage code, I find myself wishing for the SQL.

I used to hate embedded SQL, then I realized there really is nothing wrong with it, and it fact it's preferable as I found out what a web page is doing all in one file, without analyzing a (now unsupported) ORM or trying to find a stored procedure in the database.

The stored procedure approach is not that bad, I just find myself shying away from them as code re-use is a myth.  Yes, now I've become a true OOP Heretic.  Code re-use, especially between projects, is a rarity.  And this is the major problem with ORM's, they tend to emphasize the one object for every situation paradigm.

If I have an employee table, naturally I will have an employee object, if I'm an OOP ORM Myrmidon.  So I try to use this Employee object for my employee edit screen, my employee absence report, my employee salary report, my company org chart, etc, etc.  However, I soon find my nice clean ERD and UML diagrams become corrupted by the business needs.  We have to join in extra tables.  Pretty soon we are writing all manner of custom logic in our programming language of choice.  We have to use a little somthing like join_to(tables.employee_benefits).get_by(table.columns.user_name='a%').limit(10).sort_by(table.columns.user_name). 

We are wasting resources by bringing back unneeded columns.  Because the One True Employee contains fields for every situation, we populate the whole object for every request.  We can resort to lazy loading and other performance optimizations for expensive entities. 

The Better Solution

The answer is that there is no answer.  However, I think the frameworks like CoolStorage.NET and the db library in Web.Py have a nice ability to load data from queries into objects.  This takes away about 80 percent of the pain of Database/Object interaction and let's us use queries specific to the Use Case at hand.

I think the best we can do is to use the best tool for the job, in the case of talking to databases that tool is SQL.  We should use SQL and take advantage of automatic mapping. 

Learning SQL one time is much better than learning a new ORM every year.  I feel the same for HTML, JavaScript, CSS and the rest of fundamental technologies of our trade. 



 |  |  | 
Sunday, December 16, 2007 3:54:42 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Wednesday, December 05, 2007
http://www.aspfaqs.com/webtech/042606-1.shtml

One of the best (not to mention easiest) paging methods I've seen.  In fact it requires no temp tables or table variables. 

Paging is something that is so common yet seems to hard to get right and keep performant that it pays to have a nice easy template to start from.  I've posted this mainly for my own benefit so I have a permanant bookmark to this code.

The example uses a stored procedure, but its important to understand that a stored procedure is not required to make this work.

Here's the code:

CREATE PROCEDURE [dbo].[usp_PageResults_NAI]

(
@startRowIndex int,
@maximumRows int
)
AS

DECLARE @first_id int, @startRow int
    
-- A check can be added to make sure @startRowIndex isn't > count(1)
-- from employees before doing any actual work unless it is guaranteed
-- the caller won't do that

-- Get the first employeeID for our page of records
SET ROWCOUNT @startRowIndex
SELECT @first_id = employeeID FROM employees ORDER BY employeeid

-- Now, set the row count to MaximumRows and get
-- all records >= @first_id
SET ROWCOUNT @maximumRows

SELECT e.*, d.name as DepartmentName
FROM employees e
INNER JOIN Departments D ON
e.DepartmentID = d.DepartmentID
WHERE employeeid >= @first_id
ORDER BY e.EmployeeID

SET ROWCOUNT 0

GO






 |  | 
Wednesday, December 05, 2007 2:43:40 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Saturday, November 24, 2007

In my previous post about what people use computers for, I stated that computers are for saving state.  Duh.  I felt I needed to make that clear to myself as I explored functional programming languages like Erlang, F# and Scheme.  State seems to be a dirty word relegated to second class citizenry in a functional world.

I think that functional language have an uphill battle for mainstream acceptance.  A bit bolder, I think they are a small niche and always will be a small niche.  In fairness, I think most of literature on functional languages portray them as a special purpose languages.  As the saying goes, the right tool for the job.  Microsoft is looking for F# developers to write driver validation software. 

My goal is to find languages that are applicable to general purpose problems.  I'm not a mathematician and I don't need so solve theorems.  Most of the programming jobs I've completed involved storing and manipulating some shared stated, a database.

Yet another realization courtesy of a man seeking to explain the failure of the best language on earth

Local state in programming is just like scratch paper for mathematics.  Some rare gifted individuals don't need it and can do the calculus in their head.  For the rest of us scratch paper and number two pencils are the only alternative.

While debugging, I can inspect the state of the system, either with the debugging facilities or with well placed print statements. 

So local state helps us understand our systems.  Global state, again databases, are the reason our systems exist.  Some in the Erlang camp want to wish this away.  However, I think Erlang advocates understand that Erlang was built for telecom switches.  Erlang's usefulness in general purpose programming is yet to be determined.  If you're building a system that manipulates global shared state (most of the web applications in existence), choosing a language that waves its hands at shared state in the name of concurrency might not be your best choice.

Now we come to the revelation stage of our journey.  What can we do in mainstream languages to deal with global  shared state (databases) effectively?  I've found something in my own development work that is effective for me.  It's not a new language, but in fact, works in many languages, including C# and Python.

My solution may not be a silver bullet, but then I might not be hunting werewolves.  I can't claim to have invented it.  For from it.  All I can claim is that I've seen this pattern work across languages.  I can also tell you that it might be a wooden stake, useful if you are hunting vampires.

 

Saturday, November 24, 2007 10:16:25 AM (Central Standard Time, UTC-06:00)  #    Comments [2]
 Friday, November 23, 2007

For a (brief) while, I was learning F#.  It proved an interesting excursion.  If you into mathematical correctness F# and OCaml maybe just the languages for you.  Myself?  Well I'm looking for something with a little more to offer in the functionality department.  I want a language where I can do most anything.  I'm willing to sacrifice mathematical niceties.

Python seems to be that language.  Python is one of the languages I knew I would love when I tried it, so I've held off diving into it until I had gone through almost every other one.  I've journeyed through Lisp, Scheme, C++, C#, Java, Ruby, F#/OCaml and dabbled in a few less known like Factor and Cat. 

Python Advantages:

  • Available and almost every platform (every platform I'm interested in)
  • Terse clear syntax
  • Whitespace (yes, I do enjoy the whitespace!)
  • Easy to learn, easy to teach (I taught C++ to undergrads during my time in Hell)
  • More complete than Ruby
  • Better documented than Ruby
  • Good riddance to the Edit/Compile/Wait/Debug loop (hello Edit/Test, Edit/Test, Edit/Test...)
  • Python is available on the CLR as Iron Python and on Java as Jython.

Disadvantages

  • It's not C# (heh)
  • It's not Java (heh, heh)
  • Performance (slower than the above)

I believe that Gabriel is correct and that worse is better.  Worse as in Python is not Lisp.  Even Dr Norvig, chief brain in a jar at Google, thinks Python is good for something.

Note that Python is one of the four languages in use at Google.  Google has, in fact, hired the Frost Giant.

Python is used in game scripting.  My favorite game series of all time uses Python as the scripting engine.

I've also found one of the best Web Frameworks to date to use with Python.  I'll detail that it a future post. 

Right now Project X is moving forward on rockets fueled by Python.  This is the most complete proof of concept I've completed in an alternate language (not C#) and I'm LOVING it.

 

Friday, November 23, 2007 9:59:18 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, October 30, 2007
This is an interesting article from the 1920's written by a proprietor of a grocery supply business.  What the author considers brilliant may not fit the definition that many of us have.  I think a better term would be "schemer" or "dreamer" or something similar.  Anyway my main interest in the article is based on my assertion that many in the software profession are "brilliant." 

I myself find it hard to finish projects but easy to start them.  If you believe in personality tests than I am an INTP.  This means I have a tendency to live in my head.  I need to constantly fight to finish things and to stay interested in projects.  I'm always exploring new languages and technologies.  This is both a boon and a burden in the technology field.  I'm usually up to date on the latest technology but I have to push myself to finish projects that become a little too mundane.  I also read many articles from programming.reddit.com and similar sources.  If I'm not careful I can consume a whole night or day reading such articles.  The plus side is that I'm a sponge for information.  The negative is that I may have a hard time applying it as I'm always trying something new.

I believe that we must understand ourselves to be successful.  I am aware of my weaknesses and by my awareness I am able to realize what I must work on to be successful.  I must force myself to complete current projects and to apply my research.  When I am able to do this I can produce results that are amazing.  However, I always have the potential to waste days and nights reading.  However, it may be debatable whether reading is really ever a waste.  I watch very little television as I prefer to read and program instead.

In my opinion, this article can be summed up as "find hard workers."  Not brilliant by any means but a good read none the less.

Article:  Why I Never Hire Brilliant Men

Tuesday, October 30, 2007 9:26:17 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Friday, October 19, 2007
Nullables always felt not quite done.

Here is a technique to add an extra minute to the microwave timer and get a more fully compatible conversion function:

http://blog.pumacode.org/2006/05/18/using-convert-changetype-on-nullable-types/

Nullable types are awesome for dealing with databases.  Its a fact of life that most databases are going to use null and you need to deal with it in your code.  However what does null map to for a value type? 

The answer is unknown.  If C# were truly object oriented then wouldn't value types be reference types instead.  I'm guessing there are some big performance implications to this.  So we have nullable types.  A solution that is almost ready for prime time. 

Side Note:  If you truly wanted a consitent web front end for a database then null would map all the way through to things like dropdownlists where they would map to the default "please choose" option.  This would be an awesome rails like feature.  I'll have to do that when I get around to building my own web framework.

That's not likely to happen anytime soon.  I actually built server controls that did the above.  However, the overhead of maintaing server controls and making them behave just like regular built in server controls is just too much of a burden at this point.  I'll have to revisit this at some point.

Friday, October 19, 2007 10:28:47 PM (Central Standard Time, UTC-06:00)  #    Comments [0]