Categories
Contact Doug!
Learn About Doug!
View Doug Boude's online resume
updated 11/18/2009

View Doug Boude's profile on LinkedIn
Link to me!

Follow Doug Boude on Twitter
Follow me!

Be Doug's friend on Facebook
Befriend me!
(I promise not to follow you home)
OO Lexicon
Chat with Doug!
Recent Entries
You may also be interested in...
Web Hosting

<< July, 2006 >>
SMTWTFS
1
2345678
9101112131415
16171819202122
23242526272829
3031
Search Blog

Recent Comments
Re: Disappearing IE Popup Window During Save/Open Dialog (by LZ at 4/20 7:58 AM)
Re: Create Dynamic WHERE Clauses in PHP (by pooja at 3/20 7:29 AM)
Re: Just What IS a 'Service Layer', Anyway? (by EugenK at 3/07 7:56 PM)
Re: Using Google as your CF Mail Server (by 5starwebteam.com at 2/25 1:27 AM)
Re: Why Provide for Service layer objects in CFWheels? (by Steven Benjamin at 1/25 11:43 AM)
Re: What is an 'Advanced' Coldfusion Developer? (by ColdFusion Developer at 12/24 5:14 AM)
Re: Equivalent of SQL "TOP X" in Oracle (by Ashenafi Desalegn at 12/06 5:29 AM)
Re: PHP Export to Excel Snippet (by serene at 12/05 1:44 AM)
Re: Just What Is 'Application Logic', Anyway? (by Arif at 11/13 8:06 AM)
Re: Hosts File Changes Not Acknowledged on Vista 64 (by Aaron at 10/22 2:31 PM)
Re: PHP Export to Excel Snippet (by Jafar Shah at 10/10 4:28 AM)
Re: Viewing Option Text (in IE7) that's Wider than the Select List (by Chenelle S at 10/04 12:53 PM)
Re: PHP Export to Excel Snippet (by Kilo at 9/26 5:20 PM)
Re: Porting Coldfusion Code to Mura (by tariq at 9/03 9:51 AM)
Re: Just What IS a 'Service Layer', Anyway? (by James at 8/27 4:06 PM)
Re: Calculating Business Hours (by helen at 8/14 2:54 AM)
Re: What IS 'Business Logic', Anyway? (by dougboude at 8/06 11:30 AM)
Re: What IS 'Business Logic', Anyway? (by Adrianne at 8/06 10:29 AM)
Re: Family Law: The Weapon of Choice for Woman Scorned (by dougboude at 8/04 4:39 PM)
Re: Family Law: The Weapon of Choice for Woman Scorned (by Lola LB at 8/04 7:43 AM)
Archives
Photo Albums
Funnies (5)
Family (3)
RSS

Powered by
BlogCFM v1.11

24 July 2006
FLEX VENTING
flingin some poo

 I came back for the third time, attempting to consume the subject of Flex2. The first two times were during versions 1 and 1.5, so I figured that surely by THIS iteration the process would have been simplified and the documentation straightforward. Alas, I was wrong. Ay, and my achin' head and permanently furrowed brow! After wrestling for TWO DAYS with a "simple" Hello World app using Remoting against a CFC that did nothing more than return a string and FAILING to get it to work, I find myself dealing with a lot of mixed emotions here and asking myself some scary questions. For instance, "Am I just RETARDED? Or is the truth moreso that this product is so convoluted, complicated, and cryptic that the public should be protected from it? Is the documentation written by martians who work inside a small Plexiglas dome where the servers are pampered by hordes of dedicated and zealous admins? Are these people "so far gone" into gnurdome that they can no longer relate to the lone developer in such a way as to make understanding this new product a no-brainer? It's cruel and unusual, that's what it is, for Adobe to spend so much energy preaching the Flex word and then to leave their hopeful proselytes to drown in the mire of cryptic, unordered, non-functional documentation, examples, and instructions. I guess I'm a bit miffed by the fact that I STILL am unable to get a solid understanding or a working example of something that's in at least its third iteration in a year. So I'm back to asking myself the question of whether or not I'm just mentally challenged.

I can't just keep myself wondering, so let me go out on the net and see how many success stories I can find, that should help me cast a true light on my personal Flex experiences thus far.

Okay, first stop is Ben Forta's blog. Surely I'll find successes there. Oh! What's this? A blog post regarding a sample phone directory app! Reading, reading, reading...wow, that's a short post with a LOT of comments on it, eh? And what is the majority of these commenters saying? What's that? Yes! That they can't get a simple friggin sample app to work either! Oh, a few did manage to do so...some have no idea what they did to make it work, some had it working and have no idea what they did that broke it. The ones that DID manage to get it to work had to dig into sparsely documented or NON-documented items to give balance back to the Flex Force. Eegad, man.

Okay, just for my own peace of mind then, let me at least take a look at Adobe's sample apps so I can prove to myself that Flex really is a ready-for-prime-time, working product. Oh! What's THIS? (try logging in in demo mode)

Apparently, as I have seen up to this point, Flex really IS a delicate, fragile flower. Freakin AS errors on Adobe's own sample app? Now THAT'S ENCOURAGING, ISN'T IT? Hmm, let me speak to some of my wise and talented peers (no sarcasm here...they really are) and see how they are progressing with learning Flex. Perhaps they can open my blind eyes to what I'm missing here.

The first I actually work with, so he worked with me on my Hello World directly; wow, couldn't get it to work. Fancy that.

The second peer I spoke with is as gung ho about Flex and as much an ADOBE-ite as anybody I know of. He had me try a couple of things, then admitted that the examples he tried had worked, but he wasn't sure if it was actually using remoting or not. I do recall a week or so back that this same peer was venting MIGHTILY to me about his multiple attempts to get Flex Data Services installed and working, and how the only documentation that he could find DIDN'T EVEN APPLY to his server setup (which isn't an uncommon setup). He never did manage to get FDS configured and working.

The third peer I spoke with actually just returned from a  Nuremburg...er, San Jose Adobe rally, a good two days of which was spent being "taught" Flex. He shared with me how exciting it was for the room full of 40 or so CF gurus (some of which proclaimed Flex power user-ship) when A FEW of them actually got a file upload demo to work! Wow! Two days, and the grand finale sample was a file upload???? Granted, I wasn't there and wasn't privy to any particulars of the instruction...but a file upload??? I'm pretty sure things like that are *supposed* *to* *be* *simple*...aren't they? This particular peer,  in his own innocence and lack of personal experience configuring and setting up Flex,  left me with the reassuring words,  "well, it may be better once you catch on." When I catch on? I'm reasonably convinced that this isn't something that's going to eventually "soak in".

 To quote Will Farrell in the movie Zoolander, "I feel like I'm taking CRAZY PILLS!" (you'd have to have seen it). It seems as though I have been suddenly whisked into a bad futuristic remake of "The Emperor's New Clothes", the emperor being Adobe, and everybody can see that he's naked but nobody is saying anything! Instead, everybody keeps thinking that it must just be them, that they're "just not getting it", and that Flex MUST be easy to configure and use! After all, everybody else is doing it! I just have to keep squinting and eventually I'll see the light!  Not. I'm gonna say it: The EMPEROR IS NAKED! FLEX IS FAR TOO COMPLEX AND FRAGILE, AND JUST BECAUSE SOME PEOPLE ARE LUCKY ENOUGH TO HAVE JUST THE RIGHT CONFIGURATION FOR IT TO WORK THE FIRST TIME DOESN'T MAKE THIS PRODUCT READY FOR PRIME TIME! NOTHING should be this difficult, nothing. And you know what else I realize now that I've finally admitted that the emperor is naked? The flex interface isn't even all that good looking. In fact, it's kinda creepy and unnatural.

 Ah, okay, I feel better now that I've vented. I have, by the way, answered my initial questions of personal intelligence, and am utterly convinced that I'm a reasonably intelligent person with a decent track record of having picked up some pretty difficult technologies all on my own. Furthermore, in another month when I'm over how wronged and miffed I feel at this moment, I'm probably going to decide to dive in ONCE AGAIN and conquer this baby.

 Thanks for listening.

Doug out.

Posted by dougboude at 6:24 PM | PRINT THIS POST! | Link | 11 comments



22 July 2006
CF tags within CFSCRIPT Blocks

Some of us are fans of using CFSCRIPT for certain portions of our code. For myself, I’ll typically create my UDFs (User Defined Functions) in this manner…it just looks cleaner to my eye. There can be challenges to doing this, however, due to the fact that certain commonly used CF tags just do not have equivalent CFSCRIPT function calls, like CFQUERY or CFTHROW. It is, however, still possible to incorporate them.

I think a code sample is worth a thousand words, so consider the following sample:

 

<!--- first, we need to turn the CFQUERY tag into a coldfusion function --->
<cffunction name="cfquery" access="public" returntype="query">
 <cfargument name="dsn" type="string" required="true">
 <cfargument name="sqlstring" type="string" required="true">
 <cfargument name="password" type="string" required="false" default="">
 <cfargument name="username" type="string" required="false" default="">
 <cfif arguments.username IS NOT "" and arguments.password IS NOT "">
  <cfquery
   name="thisquery"
   datasource="#arguments.dsn#"
   username="#arguments.username#"
   password="#arguments.password#">
   #arguments.sqlstring#
  </cfquery>
 <cfelse>
  <cfquery name="thisquery" datasource="#arguments.dsn#">
   #preservesinglequotes(arguments.sqlstring)#
  </cfquery> 
 </cfif>
 <cfreturn thisquery>
</cffunction>

<!--- begin the actual UDFs --->
<CFSCRIPT>
 function getProdDescrip(productid){
  var thisSQL = "select shortdescrip from products where baseid ='" & productid & "'";
  descrip = cfquery(dsn="rrtradingpost",sqlstring=thisSQL);
  return descrip.shortdescrip;
 }
</CFSCRIPT>
<!--- end UDFs --->

<cfset thisDescrip = getProdDescrip('BCPLB')>

<cfoutput>#thisDescrip#</cfoutput>

Step 1 is to turn any needed CF tags into functions using the CFFUNCTION tag, defining the tag’s attributes as arguments to the CFFUNCTION.

Then, within our CFSCRIPT section we can refer to the newly created function by name, passing in the pertinent arguments. That’s it!

One thing to consider with this is that you can't build a sql string that includes the cfqueryparam tag and have it work, so you'll have to compromise on this and just pass in your where clause values in native sql format (single quotes, etc.).

Keep it beautiful.  Doug out.

Posted by dougboude at 12:27 PM | PRINT THIS POST! | Link | 3 comments
20 July 2006
Bullfrog
A Children's Story

The baby bullfrog sat very still, only his head protruding from the warm, dark water of the pond’s edge. His green skin glistened in the light of the late afternoon sun as he waited for a passing gnat or damselfly to get within range of his sticky white tongue.  If it weren’t for the almost undetectable ripples made by his rhythmic breathing, the boy probably wouldn’t have even known he was there.

Walking slowly along the pond’s edge, the boy went ahead, getting ever closer to the little frog. Before he got close enough to frighten it , however, the boy’s keen eyes discerned the amphibian, and so, as his father had taught him to do, he circled wide behind the creature and approached with the sun in front of him. By doing this he was able to get very close without his shadow scaring and sending the little creature swimming for cover in the pond weeds.  Finding himself within arm’s length of the frog, the boy slowly knelt, never taking his eyes from the green prize before him. He was very close now, and trying himself to keep as still as the frog. It was only because the frog was sure that he could not possibly be seen that his strong back legs did not immediately send him flying gracefully forward into deeper water. Instead, it sat motionless, using the camouflage that Nature had given it.

Slowly and with great care the boy stretched out his arm, keeping it low to the ground. When his cupped hand was only a few inches from the frog, the boy took a breath and then, as fast as a steel trap, the wet and wriggling creature was secure between his gentle fingers.

“Daddy! Daddy!” the boy called as he quickly ran across the field to where his father was playing catch with his little brother. “Look what I caught!” he said between breaths, holding his prize up towards his father’s admiring face. “Good job!” said his father as he knelt and drew his son’s closed hand toward him for a better look. The boy relaxed his grip and the little frog’s green head popped out between his fingers, blinking its golden eyes to keep them from drying out.

The little frog was quite frightened, and could only wonder at what would happen to him now. In that moment he wished again for the time some weeks past when he lived under the water as a tadpole. There were no birds to worry about, no raccoons, and especially no people. It wasn’t until he grew legs and crawled out of the pond to take his first breath of air that these things became his constant vigil. All he could do now, however, was hope to make his escape and leap his way back to the safety of the pond.

“Daddy, where do frogs come from?” asked the boy’s inquisitive younger brother. “Frogs are very special creatures,” the boys’ father said. “Listen….” In the distance, coming from the other side of the pond was a loud, low, rhythmic call that sounded very much like the moo of a cow. “Bwoowwww. Bwoowwww”, the call continued. From yet another part of the pond from a stand of tall cattails came the sound again, almost as if to answer the first. “That is the call of the bullfrog,” said their father, “and he is looking for a mate. Once a female finds him, they will lay eggs that look like jelly in the water’s edge. In just a few days, all of those eggs will turn into tadpoles and in just a few more days, every tadpole will grow legs and become a frog!”. Both boys looked at the little frog in wonder as they considered such amazing beginnings. The younger brother put out a finger and stroked the frog’s small green head, its eyes pulling inward at his touch. “Okay, looks like the little guy is getting kind of dry,” said the father. “Let’s take him back to his home now.”

Walking together, the three of them arrived at the pond’s edge. The eldest son knelt and, opening his outstretched hand, gave the little frog back his freedom. Letting out a single, high pitched squawk that would one day become the low call of its own father, the frog gave a long leap and dived into the shadowy waters of the pond, disappearing from the view of the smiling boys.

Posted by dougboude at 11:12 PM | PRINT THIS POST! | Link | 10 comments
18 July 2006
The Elusive Gnurd Bird
CFUNITED - ANOTHER PERSPECTIVE
This animal is a unique parallel species of homo sapien more properly classified as homo sapien3. Unlike any other species, this one rarely procreates amongst its own kind and is typically a genetic mutation resulting from a homo sapien union. As rare as the discovery of a mating pair of Gnurds is, it is even rarer that their own offspring possess the mutation that makes them a Gnurd. Though Gnurds are often not accepted or understood in mainstream homo sapien society and tend to sport unique eccentricities, it is this same rarity and uniqueness that make them special as well.

Habitat and Social Tendencies
Though usually alone, it is also what could be termed as "socialite by proxy", communicating profusely and consistently with its kind in one of several remote fashions, but rarely encountering one another physically. There are, however, certain times of the year when these typically solitary creatures stir from their dimly lit recesses and amass themselves in what would appear to be a ritualistic manner. Exactly what the purpose of these mass gatherings are remain for the most part a mystery. Some speculate that it is a re-establishment of the pecking order which cannot be accomplished by remote means; others have observed it to be more inline with a mating ritual, necessary because of the gross unbalance between the number of males of the species as compared to females. The fact that it is still a mystery is what moved me to pack my bags and go to Washington D.C. in order to observe and document one such gathering. What follows are my notes, observations, and hypothesii regarding the things I witnessed there.

The Gathering
The first day of the gathering found other gnurds still arriving. It was already apparent, though, that certain ones were being viewed in higher esteem than others, and I could see by the plumage being displayed that some of these creatures had been leading solitary lives FAR too long for their own good, boasting such outer markings as "CF_RELAX" and "What Would Ben Do?". There were what I am calling the "groomer" birds who would meet each gnurd as they arrived and adorn them all with similar vestments and a large grey gnurd bag. Soon the gathering place was a sea of Gnurds, constantly churning in every direction. As part of their acclimation to physical socializing, the gnurds at first milled about with very little interaction between them, though that was quickly beginning to shift. What just hours before could be called an 'awkward moment' when two gnurds accidentally made eye contact was now resulting in physical interaction and inquiry. The standard initial Gnurd meeting cry was something along the lines of, "so where do you work?", with the standard gnurd reply of "for so and so". In short order these rhetorical ice breakers were resulting in gnurds pairing off or congregating into small sub groups, typical conversations consisting of discussions of their more esteemed peers and latest gnurd controversies.

The second day of the gathering was when the formalities were casually imposed, with those gnurds higher in the pecking order taking turns addressing the hordes of other gnurds. There was obvious respect for these articulate birds, with the crowds growing silent and attentive as their knowledge was conveyed. The remaining days of this brief and rare gathering followed a similar style and pattern.

Gnurd Rivalry
Blatant rivalries among Gnurd birds during their gatherings is almost unheard of and rarely witnessed. Any kind of conflicts that may exist between these creatures is manifested at such a subtle level that only another Gnurd can even detect it. Only one time during the entire gathering was it ever obvious. The situation occurred between one of the beasts which was present at the gathering and another who had been unable to make the trek but was communicating via remote means. The first beast would squawk out some nearly uninteligable phrasology, challenging the other and ascerting its point on something that sounded to the human ear like "framework bad". The remote Gnurd would respond calmly and with utter confidence. After a few moments of the sqawking gnurd getting his own feathers ruffled, the spectator Gnurds suddenly lost interest, seeming to have sided with the remote Gnurd almost unanimously, and then disseminated into the rest of the flock.

Gnurd Mating Ritual
Very little is known about the details of the Gnurd's pre-coital rituals. Chance smiled upon me, however, as I was given the once-in-a-lifetime opportunity to witness the attempts of one male Gnurd. He was sitting and casually preening his feathers when a female Gnurd approached and sat within squawking distance. The male Gnurd immediately turned her way and began spouting a unique blend of casual conversation and techno babble. The female gave the male her attention for a few moments, and then suddenly put her wing up against her head, as if to cover her ears. The male took this as a sign of disinterest, and rather bullishly inquired as to whether or not she would prefer that he cease his noise. The female responded with a squawk that meant "no, it's just that my allergies are acting up and my ear is itching inside". The male then held out his pinky and replied (and I'm going to translate the Gnurd babble here), "You wanna use my finger to scratch it"? It became obvious to me at this point why the Gnurd population is so limited and unique, and why the male of the species has such difficulty procuring a mate.

In Conclusion
All told, the trip was well worth it. Gnurds are such awkward creatures that simply to have the opportunity to observe them in social settings provides a steady stream of unique, inexpensive entertainment. Oh, and if you REALLY want to be entertained, set a keg in their midst and see what a mild alteration of their perception of reality does to spice things up.
Posted by dougboude at 4:48 PM | PRINT THIS POST! | Link | 9 comments
12 July 2006
ByRef and ByVal in ColdFusion
Pop Quiz:
Using only your brain (stop laughing!), mentally execute the following code and figure out what values the returned structure will contain:


<cfset listvar = "1,2,3,4">
<cfset stCounter = structNew() >
<cfset stResults = structNew()>
<cfloop list="#listvar#" index="i">
    <cfset stCounter.item = i>
    <cfset stResults[i] = stCounter>
</cfloop>

Choices:
quiz choices
Early yesterday morning my choice would have been ‘B’. Late yesterday afternoon the answer was an obvious “D”. The reason is found in a little thing I like to call “ByRef” (Actually, the whole programming world calls it ByRef). ByRef stands for ‘By Reference’, and it is the polar opposite of ByVal (By Value).

Both of these terms refer to the way in which a value is passed along. You can equate it to the scenario of me giving you $100. If I hand you the cash, I have just given it to you “By Value”; you have it, it’s in your hand. If on the other hand I would have given you a check for $100, then I gave you the money “By Reference”; you don’t really have the money but you’re holding something that points to it.

ColdFusion by default passes structures by reference when you use them as a value. For instance, in the example of

<cfset thisVar = stResults>

(where stResults is a structure), my thisVar variable doesn’t actually have the stResults structure, but merely a pointer to the actual stResults. What this means is that if I modify stResults at some other place in my code and then go back to thisVar to get its value, thisVar’s value would also reflect the same changes. That’s really cool if you planned on things happening that way; not cool if you didn’t.

So how do we pass a structure by value and not by reference? Use the StructCopy function. Using the same example, if I set thisVar with

<cfset thisVar = StructCopy(stResults)>

then modifying the stResults structure afterwards will not reflect within thisVar’s value. StructCopy then is the equivalent of taking a snapshot of the structure, capturing it as it is at that point in time. Consider the following illustration:
byref byval example

If we want the pop quiz code at the beginning of this article to actually produce the answer ‘B’, then we need to make one small modification to it, like so:
<cfset listvar = "1,2,3,4">
<cfset stCounter = structNew() >
<cfset stResults = structNew()>
<cfloop list="#listvar#" index="i">
    <cfset stCounter.item = i>
    <cfset stResults[i] = StructCopy(stCounter)>
</cfloop>

So, boys and girls, that is the difference between ByRef and ByVal. Not typically something we have to ever specify in CF, but DEFINATELY something we have to be aware of since it affects our code (and causes us unnecessary amounts of troubleshooting time).
Posted by dougboude at 4:59 PM | PRINT THIS POST! | Link | 2 comments
10 July 2006
Family Constitution
Tips, Ideas, Food for Thought

Happiness of the family as a whole generally comes from strength in two main areas: Order and Stability. Each of these areas can be broken down into a few sub areas, all of them as important as the other, and all lending to the success of the whole and achievement of a truly happy family. Order comes by addressing self-discipline, having good and fair rules in place, and having consistency in enforcing those rules. Stability itself is composed of a stable predictable family routine, financial stability, and emotional stability. And most importantly, you as the leader of your household cannot neglect your own needs. You must be happy, you must be healthy, you must spend time with yourself reflecting and thinking.

 
The remainder of this document addresses all of these areas and lends suggestions as to how to work with them.

 YOU SPEND TIME WITH YOU

For yourself and by yourself, summarize the state of the family union every so often. Take a good look at where you are, how you got there, and where you want to be. Write down comments and suggestions for getting it where it needs to be, then prepare to talk to the family about it.

 

Get the family together, without distraction, and address them with your state of the union. Then, in a very ordered fashion, get their feedback…their perspectives, on each very specific area you covered. Keep the order, have a heavy hand if need be to keep people taking turns and waiting to be called on to talk, because the survival of what all of you love and need is at stake. Be firm, but gentle, but firm. As much as the world thinks it distasteful to say, the husband is the ruler of his house in many ways…that’s order, that’s the way it should be, and people are happier when everything is in order. The same way every successful company has a hierarchy of authority that makes it successful, so does a family: it requires leadership, and YOU my brutha are president for life.

 ORDER

THE PARENTS’ PART

KEY: husband and wife working together. Supporting each other and each other’s decisions. Being sure to both be doing things toward the common good and goals. The children will see if the union is strong or weak, and behave accordingly. You must agree on standards of discipline (what will and will not be tolerated), when to talk about a matter before setting out on your own to make a command decision, etc. Just lots of talking, and that means time specifically set aside for that.

 

LEAD BY EXAMPLE. Do as I say not as I do does not work. No hypocrites allowed.

 

Remember and remind each other of what is most important.

 

Do not talk about private matters in the presence of the children. Use good discretion in this area. Some things are none of their business and they should not be privy to the discussions that take place as you arrive at decisions. They may attempt to use such knowledge to undermine your rules for their own gain, or at the very least the hearing of such discussions could erode their morale.

 

THE KIDS’ PART

Their part is to follow the rules of the household, keep good attitudes (cause they’re catchy), and do their best to be good kids. Pretty easy stuff.

 

Some Rule Suggestions…

 

  • NO TV when there’s something else that needs to be done. It’s a life killer, for sure, and will WASTE your very precious time. That means no tv for anybody when there’s something else they should be doing.

 

  • NO WASTING ELECTRICITY. When you leave a room, you turn off the light and anything else that is on and doesn’t need to be. This includes hot water. If they don’t learn to turn the lights off QUICKLY, and take shorter showers, light bulbs will be removed and the hot water heater will be shut off at the panel except for certain hours. They’ll just have to use candles and take cold sponge baths. Period.

 

  • Install power saver bulbs.

 

  • Chores will be assigned. Not slave amounts of chores, but chores. Everybody has to pull their weight. That means animals taken care of, lawn mowing, rooms cleaned, laundry where it should be, dishes done, kitchen cleaned, trash taken out. Period. Anybody who doesn’t do their chores WHEN THEY ARE DUE loses privileges for a time, like after school activities, TV, and earlier bed times.

 

  • SET BEDTIMES. Based on age, and exceptions made on occasion when justified, heads will be on pillows and lights out by 11 on school nights. Period.

 

  • HOMEWORK WILL BE DONE BEFORE BEDTIME. PERIOD. So make sure you budget your time wisely, because except for VERY good reasons, no exceptions will be made to this rule.

 

 

It is VITAL that there be consequences for violation of the rules, including not doing chores when they are supposed to be done. Give a kid an inch, they’ll take a mile, and you’ll soon lose all control of the situation.  It is JUST AS VITAL that these consequences be doled out with judgement and compassion, bearing in mind that the goal isn’t to inflict pain as much as it is to help them learn self-discipline. But the order of the house as a whole depends on the order of the individuals. They must understand that their lack of self-discipline affects everybody, not just themselves.

 STABILITY

 FINANCIAL Stability

Read and execute Dave Ramsey’s book “Total Money Makeover”

SELF-DISCIPLINE

Self-Explanatory. Don’t spend if it violates the budget; Don’t waste gas on unnecessary trips; Plan outings with gas in mind. Don’t waste things at home (food, etc.).

 

INCOME

THE PARENT’S PART

Sign up for any and all services that you qualify for. WIC, Foodstamps, Unemployment, training programs, utility bill assistance…EVERYTHING. Typically this should be done by the wife (assuming she isn’t working outside of the home) since she has more time during work hours to do it. Small towns nearby have very short lines…it isn’t that much of an inconvenience. DO THIS IMMEDIATELY! Do it. Do it. DO IT.

 

Actively seek a job, every single day without fail. Read the paper, make calls, go register with temp agencies, register with the Unemployment office. DO YOUR PART. Some things are outside of your power to affect, others are totally within your power. Prove you are serious about wanting to provide for your family, and not proving it to anybody else except for yourself. You’ll sleep much better at night knowing in your own heart that you did all you could that day to address this area of financial responsibility.

 

Identify and FILL UP as many financial drains as possible. Some possible suggestions are:

  • Put the house on the market and sell the sucker. Right now, a mortgage and utility bills of that size are far beyond your means. If you don’t sell it, you will lose it and have nothing to show for it at all.
  • Work towards physically moving closer to those parts of town where you spend the most time to reduce travel distances.
  • If it’s best for the success of the family, dictate that they will all go to school locally. It’s a given this will generate rebellion and complaint, but necessity dictates. You yourself went to a different school every year of your life almost. You lived, you got educated, you didn’t cave in and cry about it. It isn’t like you would be sending them to some prison-like inner city school.
  • Implement strict electricity usage policies at home. Set a goal of reducing your monthly bill by $100 by doing nothing more than simply turning off what is not in use, including the heater/fan.
  • Shorten showers/hot water usage.
  • Turn off unneeded circuits at certain times.
  • Replace bulbs with money savers

 

 

THE KIDS’ PART

Their part is to comply with whatever decisions you come up with in this arena and to fulfill their obligations at home (chores) so you can concentrate on more important matters.

BUDGETING

THE PARENTS’ PART

 

Make a budget…a plan. I realize that there isn’t usually enough cash to go around where it’s needed, but at the VERY least make a list of who is owed how much and when, then nothing can go unnoticed. I also realize that sometimes it “seems” easier to deal with it if you just don’t think about it. But experience has taught that you ALWAYS feel better having faced it, even if only on paper, than totally avoiding it. Trust me on this. Make a list of bills.

 

After a budget, or a list of bills is made, make phone calls and see if arrangements are possible. When things are tight, the saying “robbing peter to pay paul” is reality. Reality also dictates that some things will not get paid; that’s life, just be sure to prioritize them, and make the ones absolutely essential first. My own personal order is this:

  • Food, water, and clothes;
  • Roof;
  • Utilities;
  • Transportation;
  • Everything else

Remember, you are surrounded by woods full of good things to eat if it comes down to it. Pigeons and doves taste good, squirrels taste good, rabbits taste good, turkeys taste good. Make a couple of throw lines for the river across the street and check them every afternoon. Fish tastes good too.

Say “NO” to the kids when the request is for something that isn’t needed and you cannot afford. JUST SAY NO. They won’t die, and you’ll still be a good father looking out for their best interest.

 

 

THE KIDS’ PART

It never hurts to ask for something, but do NOT complain and rebel if the answer is NO; there are good reasons for the judgements parents make when making a decision.

 

Follow the rules regarding conserving resources. DO turn off lights and other electrical items when not needed; DO take shorter showers to conserve hot water;

 

EMOTIONAL STABILITY

COMMUNICATION

You’re already very good about communicating with the family; very good. Just be sure to continue to weave in communication about family priorities, praise for doing well, and keeping your finger on the pulse of how the family’s morale is doing. They need to lean on you a lot at times for encouragement, and you are very good at encouraging people by your example. Just be mindful of how important the communication, reminders, and encouragement by example in word and deed is to everybody’s happiness. In 50 years when they all look back on their lives you want them to think of you and say “he was a damn good man and father”. But do also remember that you yourself don’t seem to have any issues in this area…NOBODY has a bigger heart than you, and nobody could ever deny that.

FAMILY TIME

Rather than it happen on a whim or the spur of the moment, pencil in planned family time once during the week, and on the weekend. And be sure that you do not allow the TV to be the central gathering point, except on few occasions…things have to stay balanced. Instead, do things like board games (scrabble, monopoly, risk), go for a walk down the road together, do a bbq outside for dinner, use that picnic table and nice yard while the weather permits, have a tailgate party, use your deck upstairs and just sit in lawn chairs and listen to music and talk. Shoot, start a new tradition, like family poker night or something…get creative, but make it time that everybody can participate in. Use that fireplace of yours…move the table, lay out blankets in front of it, and have a fireside chat.

ONE ON ONE TIME

It’s important to try and get one on one time with everybody here and there…ask them how they’re feeling, if they have any suggestions…let them participate and feel like a part of everybody’s success. Most especially, give the wife this one on one time. Re-institute date night, even if it is on a low budget at times, and don’t let it fall through the cracks. You could do things like take a walk around town, go to the city park, walk around the square. One on one, make them feel special, and work hard to keep it equal, even if one or two do tend to squeak more.

Posted by dougboude at 1:47 PM | PRINT THIS POST! | Link | 2 comments
08 July 2006
IF THE SOLUTION IS NOT BEAUTIFUL, THEN IT IS WRONG - STYLE, ELEGANCE, AND EFFICIENCY IN CODE
OUTPUTTING COMPLEX QUERY DATA

Preface to this Series

As with most coding challenges, there are always near infinite ways to overcome them. To say one approach is better than another is nearly always a matter of perspective and goals, but what I use as my personal measuring stick is the spirit of a quote by the late great Buckminster Fuller. It reads, “When I am working on a problem I never think about beauty. I only think about how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong.” I have adopted this quote as my personal and professional creed when it comes to problem solving. It also happens to be the motivation for this series, as I hope to inspire my peers to let their coding be a reflection of who they are as people. After all, we are artists and coding is the expression of our talents.

  

If the solution is not beautiful, it is wrong. With that in mind, let’s take a look at the first item of discussion that has led to a lot of “wrong” solutions out there. It’s one of the most basic of things, yet so often is done in such an ugly manner: outputting complex query data.

 

The Power of <CFOUTPUT>

For the most part, what I am about to share will not apply when talking about simply outputting a query, but rather comes heavily into play when we are given the complex task of outputting composite data from several sources that must be grouped and summarized. That, as many of you know, is where things can start to get really ugly and, without an understanding of one of our beloved CFOUTPUT’s lesser used attributes, there’s little hope of giving it any elegance at all.

  

The Scenario

 You are working on an application that manages projects for a large telecommunications company. Every project can be composed of several tasks, and each task can have multiple people assigned to it. Your challenge of the day is to produce a report showing all projects and their associated details. Here are the tables where your data is stored:

 

 

Here is the mockup you were given to duplicate for the report:

Report Sample

Now, time to build a solution. The more beautiful approach consists of two steps:

  1. Getting creative with our SQL statement,
  2. and nesting CFOUTPUT tags.

Creative SQL

The goal here is to retrieve EVERYTHING we need for our report in one query, the results of which will look like this:

working query

Here is the SQL statement for returning a query set like that previously shown:

 

 

SELECT Projects.projectName as A_ProjectName,  Tasks.taskName as B_TaskName, Roles.Rolename as C_RoleName, , Projects.CreatedDate AS projectCreationDate,
    Tasks.Description, Tasks.CreatedDate AS taskCreationDate,People.Firstname, People.Lastname, People.Title,
    People.Email
FROM ((((Projects INNER JOIN projectTasks ON Projects.projectID = projectTasks.ProjectID)
   INNER JOIN Tasks ON projectTasks.TaskID = Tasks.taskID)
   INNER JOIN taskAssignment ON Tasks.taskID = taskAssignment.TaskID)
   INNER JOIN People ON taskAssignment.PersonID = People.personID)
   INNER JOIN Roles ON taskAssignment.RoleID = Roles.roleID
ORDER BY A_ProjectName, B_TaskName, C_RoleName

 

Besides proper joins, the one thing about this SQL statement that is absolutely IMPERATIVE in order for us to be able to leverage our CFOUTPUT tag is the ORDER BY clause. The reason is this: Coldfusion will be processing our query sequentially, one row at a time starting at the top, and if everything isn’t in just the right order, we’ll get some unexpected and unpredictable results. If we DO have it in the right order, however, CFOUTPUT can do a lot of work in a few lines.

Nesting CFOUTPUT Tags

The second thing we’re going to do is something that many of you have seen CF complain about during your development: nest CFOUTPUT tags. Though usually it is true that you cannot nest CFOUTPUT tags, there is one situation where not only can they be nested, they should be: when utilizing the attribute GROUP.

 

Now that we have our data set, let’s resist that first impulse to use CFLOOP to output it and rather use CFOUTPUT, like this:

 

<h2>Projects</h2>

<ul>
 <cfoutput query="qrydataset" group="a_projectName">

  <l>

    #a_projectName#

  </li>

        </cfoutput>
</ul>

 

By telling CFOUTPUT to output the query “qrydataset”, we’re telling it to loop over that query and for each line output whatever information we have specified between the opening and closing CFOUTPUT tag. BY SPECIFYING THE GROUP attribute, however, we’re telling CFOUTPUT to loop through the query, but only perform an output for EACH UNIQUE VALUE of the field specified in GROUP.  The result then looks like this:

 

Projects

 

 

  • Baghdad Wireless Infrastructure Reconstruction Bid
  • Sensitivity Training for Executives
  • Verizon Acquisition

Even though in reality those project names occur multiple times in our query result, the GROUP attribute has limited output to only unique values. Cool, eh?

Real quick, let’s take a look at what can happen if our query had not been sorted on the ‘A_ProjectName’ field:

Projects

  • Baghdad Wireless Infrastructure Reconstruction Bid
  • Sensitivity Training for Executives
  • Verizon Acquisition
  • Sensitivity Training for Executives

Random values show up wherever they were within the query; not good.

 

Okay, so now we’ve got CFOUTPUT giving us a nice list of projects by name. Let’s add in the tasks for each project. This is where it gets really cool, as we nest a CFOUTPUT tag:

 

<ul>
 <CFOUTPUT QUERY="qrydataset" GROUP="a_projectName">
  <li>
   #a_projectName#
   <ul>
   <CFOUTPUT GROUP="b_taskName">
    <li>
     #b_taskname#
    </li>
   </CFOUTPUT>
   </ul>
  </li>
  </CFOUTPUT>
</ul>

(Notice that in the nested CFOUTPUT tag we did not have to re-specify the QUERY attribute)

It’s important to be able to visualize what’s happening here. The outer CFOUTPUT is the master and is looping over our entire query one row at a time starting with the first row. Using the GROUP attribute, we instructed the outer tag to only perform output upon encountering a unique value of ‘A_ProjectName’. Now, here is an important item to comprehend: Because the outer tag gives “scope”, or “limits” to any CFOUTPUT tags nested within it, our innermost CFOUTPUT tag is only going to cycle through those query rows that are in our current ‘A_ProjectName’ group. In other words, if our current unique value of ‘A_ProjectName’ is “Blah”, then our inner CFOUTPUT tag is only going to loop through those query rows whose ‘A_ProjectName’ is “Blah”. Once our ‘A_ProjectName’ value changes, let’s say to “Pooh”, our nested CFOUTPUT tag will once again be able to loop, but this time only over those query rows whose ‘A_ProjectName’ is “Pooh”. Here is what the results look like so far:

Projects

 

 

  • Baghdad Wireless Infrastructure Reconstruction Bid
    • Needs Analysis
    • Remote Worker Recruitment
  • Sensitivity Training for Executives
    • Assemble Curriculum Committee
    • Technical Writer Recruitment
    • Train Instructors
    • Course Marketing
    • Course Screening
  • Verizon Acquisition
    • Assess Value of Verizon
    • Assemble PR Committee
    • IT Analysis

We’re not finished yet, though. We need to output the people assigned to tasks and their roles, so let’s add another nested CFOUTPUT!

 

<ul>
      <CFOUTPUT QUERY="qrydataset" GROUP="a_projectName">
        <li>
            #a_projectName#
            <ul>
            <CFOUTPUT GROUP="b_taskName">
               <li>
                    #b_taskname#
                    <ul>
                    <CFOUTPUT GROUP="c_rolename">
                          <li>
                                #c_rolename#:
                          </li>
                    </CFOUTPUT>
                    </ul>
             </li>
           </CFOUTPUT>
           </ul>
        </li>
      </CFOUTPUT>
</ul>

As in the last iteration of our CFOUTPUT code, our most inner nest was instructed to only perform its output functionality upon encountering a unique value of ‘C_RoleName’. Because it is nested within the second level CFOUTPUT tag, it will restart its looping every time a unique value for the second level loop is encountered, limited by that second CFOUTPUT to only applicable query rows . Here are the results:

Project

  • Baghdad Wireless Infrastructure Reconstruction Bid
    • Needs Analysis
      • Business Analyst
    • Remote Worker Recruitment
      • HR Admin
  • Sensitivity Training for Executives
    • Assemble Curriculum Committee
      • Business Analyst
    • Technical Writer Recruitment
      • HR Admin
    • Train Instructors
      • Trainer
    • Course Marketing
      • Business Analyst
    • Course Screening
      • Trainer
  • Verizon Acquisition
    • Assess Value of Verizon
      • Business Analyst
    • Assemble PR Committee
      • Business Analyst
    • IT Analysis
      • Developer

Let’s add one more nested CFOUTPUT, this time without a GROUP attribute, in order to output the individuals assigned to specific task roles, but without regard to unique values:

 

<ul>
 <CFOUTPUT QUERY="qrydataset" GROUP="a_projectName">
  <li>
   #a_projectName#
   <ul>
   <CFOUTPUT GROUP="b_taskName">
    <li>
     #b_taskname#
     <ul>
     <CFOUTPUT GROUP="c_rolename">
      <li>
       #c_rolename#
       <ul>
       <CFOUTPUT>
        <li>
         #firstname# #lastname# (#email#)
        </li>
       </CFOUTPUT>
       </ul>
      </li>
     </CFOUTPUT>
     </ul>
    </li>
   </CFOUTPUT>
   </ul>
  </li>
  </CFOUTPUT>
</ul>

And here are our results now:

Projects

  • Baghdad Wireless Infrastructure Reconstruction Bid
    • Needs Analysis
      • Business Analyst
        • Shawna Easton (SE@bla.com)
        • Bjorn Jager (BJ@bla.com)
    • Remote Worker Recruitment
      • HR Admin
        • Maximus Minimus (MM@bla.com)
  • Sensitivity Training for Executives
    • Assemble Curriculum Committee
      • Business Analyst
        • Joan Goodbody (JGB@bla.com)
    • Technical Writer Recruitment
      • HR Admin
        • Shawna Easton (SE@bla.com)
        • Joan Goodbody (JGB@bla.com)
    • Train Instructors
      • Trainer
        • Joan Goodbody (JGB@bla.com)
    • Course Marketing
      • Business Analyst
        • Maximus Minimus (MM@bla.com)
        • Bjorn Jager (BJ@bla.com)
        • Simon Horwith (SH@bla.com)
    • Course Screening
      • Trainer
        • Shawna Easton (SE@bla.com)
  • Verizon Acquisition
    • Assess Value of Verizon
      • Business Analyst
        • Bjorn Jager (BJ@bla.com)
        • Maximus Minimus (MM@bla.com)
    • Assemble PR Committee
      • Business Analyst
        • Bjorn Jager (BJ@bla.com)
        • Debbie Reynolds (DR@bla.com)
      • HR Admin
        • Desislava Nikolava (DN@bla.com)
    • IT Analysis
      • Developer
        • Omar DuPuis (ODP@bla.com)
        • Doug Boude (dougboude@gmail.com)
        • Simon Horwith (SH@bla.com)

     

    Now, a few more items and some formatting, and we have the code to output the requested report:

     

    <h2>Projects</h2>
    <ul>
     <cfoutput query="qrydataset" group="a_projectName">
      <li>
       <font size="+1" color="red">#a_projectName#</font> <strong>Created</strong>: #ProjectCreationDate#
       <cfset TaskCounter=0>
       <ul>
       <cfoutput group="b_taskName">
        <cfset FTEcounter=0>
        <cfset TaskCounter = TaskCounter+1>
        <li>
         <font color="red">#b_taskname#</font> - #Description#
         <ul>
          <CFOUTPUT GROUP="c_rolename">
           <li>
            <strong>#c_rolename#</strong>
            <ul>
            <CFOUTPUT>
            <cfset FTEcounter=FTEcounter+1>
             <li>
              #firstname# #lastname# (#email#)
             </li>
            </CFOUTPUT>
            </ul>
           </li>
          </CFOUTPUT>
         </ul>
         #repeatString("nbsp;     #firstname# #lastname# (#email#)
             </li>
            </CFOUTPUT>
            </ul>
           </li>
          </CFOUTPUT>
         </ul>
         #repeatString("-",40)#<br>
        &am
             </li>
            </CFOUTPUT>
            </ul>
           </li>
          </CFOUTPUT>
         </ul>
         #repeatString("-",40)#<br>
         <strong>Total FTEs Assigned for #b_taskName#</strong>: #FTEcounter#<br>
         #repeatString("-",40)#
        </li>
       </cfoutput>
       </ul>
       <strong>Total Tasks for #a_projectName#</strong>: #TaskCounter#<br>
       #repeatString("-",40)#
      </li>
     </cfoutput>
    </ul>

    Notice that our report required counts at different levels. We took advantage of the fact that every time an outer CFOUTPUT tag changes unique values, the nested CFOUTPUT tag starts over. Notice the “<CFSET [bla]Counter = 0>” calls. At those points in the code we are resetting our counters. Then within the nested CFOUTPUT where the value we’re concerned about counting is being output, we increment those same counters, later outputting them wherever needed. Cool stuff, eh?

     

     

     

    And the final results:

    Projects

    • Baghdad Wireless Infrastructure Reconstruction Bid Created: 5/6/2005
      • Needs Analysis - Analyze the specifics of the GSA RFP
        • Business Analyst
          • Shawna Easton (SE@bla.com)
          • Bjorn Jager (BJ@bla.com)
        ----------------------------------------
        Total FTEs Assigned for Needs Analysis: 2
        ----------------------------------------
      • Remote Worker Recruitment - Recruit needed team members for remote assignment
        • HR Admin
          • Maximus Minimus (MM@bla.com)
        ----------------------------------------
        Total FTEs Assigned for Remote Worker Recruitment: 1
        ----------------------------------------
      Total Tasks for Baghdad Wireless Infrastructure Reconstruction Bid: 2
      ----------------------------------------
    • Remote Worker Recruitment - Recruit needed team members for remote assignment
      • HR Admin
        • Maximus Minimus (MM@bla.com)
      ----------------------------------------
      Total FTEs Assigned for Remote Worker Recruitment: 1
      ----------------------------------------
    Total Tasks for Baghdad Wireless Infrastructure Reconstruction Bid: 2
    ----------------------------------------
  • Sensitivity Training for Executives Created: 4/1/2006
    • Assemble Curriculum Committee - Assemble committee to draft curriculum for STE tra
      • Business Analyst
        • Joan Goodbody (JGB@bla.com)
      ----------------------------------------
      Total FTEs Assigned for Assemble Curriculum Committee: 1
      ----------------------------------------
    • Technical Writer Recruitment - Recruit technical writers to finalize curriculum
      • HR Admin
        • Shawna Easton (SE@bla.com)
        • Joan Goodbody (JGB@bla.com)
      ----------------------------------------
      Total FTEs Assigned for Technical Writer Recruitment: 2
      ----------------------------------------
    • Train Instructors - Train instructors on course curriculum
      • Trainer
        • Joan Goodbody (JGB@bla.com)
      ----------------------------------------
      Total FTEs Assigned for Train Instructors: 1
      ----------------------------------------
    • Course Marketing - Market course internally to management
      • Business Analyst
        • Maximus Minimus (MM@bla.com)
        • Bjorn Jager (BJ@bla.com)
        • Simon Horwith (SH@bla.com)
      ----------------------------------------
      Total FTEs Assigned for Course Marketing: 3
      ----------------------------------------
    • Course Screening - Assemble sampling of executives to screen the cour
      • Trainer
        • Shawna Easton (SE@bla.com)
      ----------------------------------------
      Total FTEs Assigned for Course Screening: 1
      ----------------------------------------
    Total Tasks for Sensitivity Training for Executives: 5
    ----------------------------------------
  • Verizon Acquisition Created: 4/3/2005
    • Assess Value of Verizon - Perform an in depth analysis of Verizon financials
      • Business Analyst
        • Bjorn Jager (BJ@bla.com)
        • Maximus Minimus (MM@bla.com)
      ----------------------------------------
      Total FTEs Assigned for Assess Value of Verizon: 2
      ----------------------------------------
    • Assemble PR Committee - Put together team of representatives to devise PR
      • Business Analyst
        • Bjorn Jager (BJ@bla.com)
        • Debbie Reynolds (DR@bla.com)
      • HR Admin
        • Desislava Nikolava (DN@bla.com)
      ----------------------------------------
      Total FTEs Assigned for Assemble PR Committee: 3
      ----------------------------------------
    • IT Analysis - Analyze existing Verizon IT capabilities
      • Developer
        • Omar DuPuis (ODP@bla.com)
        • Doug Boude (dougboude@gmail.com)
        • Simon Horwith (SH@bla.com)
      ----------------------------------------
      Total FTEs Assigned for IT Analysis: 3
      ----------------------------------------
    Total Tasks for Verizon Acquisition: 3
    ----------------------------------------

     

       

    I hope that you found this information useful, and may I encourage each and every one of you to consider using this approach the next time you see a template starting to get long, ugly, and IO heavy when outputting complex and nested data sets.

     

  • Posted by dougboude at 4:22 AM | PRINT THIS POST! | Link | 4 comments