Nomic Candyland

King Kandy - candy-land PhotoRecently I heard of an interesting game called Nomic. You don’t need any equipment — just some creative and indulgent friends. Today I got together with my creative brother-in-law and my creative oldest son to play Nomic Candyland.

You start with the regulation Candyland rules, but add that at the beginning of every turn the player may propose a new rule to the game. If the rule passes by majority vote it takes effect at the beginning of the next turn.

We ended up with a pretty fun game:

  1. Every player gets 10 hitpoints; if you lose all your hitpoints you’re out of the game.
  2. Players would hold a hand of three cards and would select cards to play from the hand.
  3. All the special candy cards (lollipop, ice cream cone, etc.)  are weapons that can hit players up to three tiles away. As the game proceeded some weapons acquired special abilities, for example, eating the gingerbread man to gain hitpoints; the candy cane being a machine gun with higher range; the peanut being a hand grenade with a range of four inches in any direction on the game board. Landing on another player dealt one hitpoint of damage.
  4. If you reach the castle at the end of the map, you don’t win; you “level up” and return to the start of the map. Eventually it was added that leveling up allowed you to move faster and deal more damage.
  5. imageAt the end of the Candyland board game is “Gloppy.” In order to pass him you have to defeat him in battle. The rules of battle assigned relative value to different colored cards. “Uh-oh, Gloppy drew a green card, that’s not looking good for me.”
  6. Additional special passageways were invented.
  7. A robber was added that wandered the board according to certain rules, hitting players and stealing their cards.

We had fun. The final turn went something like, “I’ll play a red card; since I’m at level two I’ll make it a double-red. That jumps me over the robber so he can’t hurt me, and I land on the red player, damaging them down from three hitpoints to two. Finally I’ll shooting the red player with my candy cane, finishing him off to win the game.”

Posted in Uncategorized | Leave a comment

I am in the woods and I have gone crazy.

After reading books from The David Birkenhead series I was looking for some similar sci fi and decided on some Heinlein books. The only one on the shelve at the library was Variable Star.

The main character is very smart. He’s talking to one of the most powerful businessmen in the solar system — or rather, he’s being spoken at by this person. As the protagonist half-listens, his mind wanders about how he and this formidable leader are in such different stations in life, and look at things from such different perspectives, that if he speaks his mind to this man, he won’t understand, he’ll just think it’s crazy.

It reminds the main character of a story (from some googling this story may be true). A man named Russell wrote a song called I’m Lost in the Woods. Since the melody sounded African he wanted a Zulu background chorus for it. But when he talked to translators about how to translate the title of his song, they all told him it wasn’t possible to translate: Zulu don’t get lost in the woods, and so they don’t have that concept. There was no common ground for Russell to relate to the Zulu what his song was about. He had to settle for a translation of, “I am in the woods and I have gone crazy.”

First, that’s awesome for the Zulu. There’s a macho-coolness in being a people for whom getting lost in the woods is such a non-possibility that they don’t even have a way to say it.

Second, sometimes communication can be that way between different cultures, or people with vastly different backgrounds and/or perspectives. You can try to communicate something important, but all the other person can ascertain is that you must be crazy, because what you’re saying doesn’t make any sense. From his perspective, at least.

Last, I suppose if you’re on the receiving end, and are tempted to label the speaker as crazy, it might be better to be patient to listen to more, to be creative with your listening, and to delay negative judgments (like, “that guy’s nuts”) for as long as you can.

Posted in Softer Skills | 1 Comment

Lessons From Some Indie Sci-Fi

A technical blog I follow recently posted a side-note about some indie sci-fi books he was enjoying. I started reading the David Birkenhead series and I found it so exciting that I finished the series as far is available so far. There were a few little sections in Midshipman that I wanted to reflect on further.

Privilege and Responsibility

In the protagonist’s early years he comes under the tutelage of a great instructor, and he reflects on one of the early lessons he learned:

What my tutor wanted me to learn from the experience was that the higher a person climbs in life and the more power they accrue, the greater their obligations towards others become and the less personal freedom of action they enjoy. Life cannot in fact be lived ay other way without become a mockery of itself.

If the individuals involved have any honor, that is. Or empathy.

This realization by the hero is poignant because he is a freed slave in the process of making more and more of himself. As he does so, he finds himself obligated by a sense of duty and honor to take on more and more difficult tasks. He sense of commitment to the well-being of others less fortunate also drives him to a more difficult service than his former slavery. Furthermore, he sees both true and false dignitaries all around him, and he becomes aware of the great burden that the true dignitaries around him carry. Their sense of honor and their empathy for those less fortunate make their positions a real labor and heavy sense of responsibility, while false dignitaries only enjoy the privileges of their positions. On can see how this latter life makes a mockery of dignity and reveals a cold-hearted and false character.

Fairness

Later in the book the protagonist and this same instructor are discussing fairness. In his adolescence the hero gives the too-often-used whine, “It’s not fair!” The instructor suggests others who have life even worse than the protagonist, then adds this little discourse:

“And then we might consider the destitute, the ignorant, the endless legions of the crippled…” He shook his head and sighed [I especially enjoy the genuine sympathy the greats in this book frequently show]. “Life’s never fair, David, not can it be made fair. No matter how hard people try. If I could share only one lesson with you, this would be the one. Every single person there’s every been was a universe unto themselves, and their path through life a unique, individual voyage that can’t be meaningfully compared with that of another. Nothing’s ever the same twice and therefore no two lives, or two people, are comparable.” He sighed. “So fairness is an illusion, David, and yearning for it is a waste of precious time.”

Being a father of several children, the “It’s not fair!” complaint comes around. I suppose that if what their really saying is, “That’s not just!” then I ought to intervene and fix the circumstances. But if things are just, but not fair, then the primary thing to focus on is helping my son or daughter to grow up a bit more.

Of course, adults also can waste their time contemplating how life isn’t fair. As adults, we still need to mature — grow up — from time to time.

Honor and Recognition

I’m just realizing that all three marks I made in my copy of Midshipman are discourses of the protagonist’s instructor. Here’s the bit this time:

“One of the traits I’m expected to encourage in my charges is a true sense of nobility. An understanding that being a nobleman is more about obligations than privileges, and that true honor is the greatest burden that [a man] can ever bear.” He shook his head, then turned to face me. “The greater one’s abilities and power, the greater their obligations. Some people never come to understand that, David. They become monsters like the Emperor… devoting their entire lives to seeking the very highest titles and decorations. To them [recognition or a crown] is more precious than gold. They’ll do anything – even commit terrible crimes – to obtain what they seek, all the while never having a clue about the substance that necessarily lies behind the symbol. Others, however, live quietly and try to do what’s right even when it’s not easy. They don’t seek medals or crowns or glory – instead, all they’re interested in is satisfying the demands of their own personal sense of honor. Yet, though this sort of man doesn’t chase after honors, somehow the honors tend to find him.”

I find these lessons, and the protagonist’s discovery of them and experience with them, to be a rich way to internalize these myself.

Parent’s Note

I find the David Birkenhead books exciting and thought provoking to read. I find the protagonist to be a truly an inspiring hero. I find myself wanting to share these stories together with my kids in their pre-teen or teen years, but there is some content that gives me pause. I’ll share these with you:

  • Throughout the books there is war going on, and some of the effects of the violence are mentioned, including the blood and dismembered body parts. I felt the book treated these subjects with an appropriately broad brush: mentioning them, but not dwelling on them.
  • In Midshipman the protagonist draws a suggestive picture in order to distract an adversary; a couple details are given about the picture that would probably fall between a PG-13 and R rating.
  • In Lieutenant the protagonist sees evidence left on some clothing that one character is raping another. In my opinion the book treats this serious and sad issue situation with due gravity. I mention it because parents will generally want to control when and to what extent their children are exposed to this sad and sick reality of life.
  • In Captain the protagonist struggles with the fact that the spouse he was uniquely intended for is not in his life, particularly in the area of the natural urges of a young man. He sees a doctor on the matter, who advises him to stay very busy and take long, cold showers. It’s not a major theme of the book; the whole things is described and dealt with in just a few pages.
  • Commodore and Admiral haven’t been released as of the time of this writing.
Posted in Leadership, Softer Skills | Tagged | 3 Comments

Book: The Goal

I’ve never before had a business book that kept me turning pages like The Goal: A Process of Ongoing Improvement. Someone on one of the blogs I read suggested this so I requested it from the local library. When the 384-page paperback showed up I groaned – I do not usually get through nonfiction of this size. This is a business novel, which teaches its business principles through a story, so that helped a lot. I enjoyed both the story and was thrilled with the subject matter so much it really kept me moving till I got to the end.

I recognized many of the principles it teaches being related to Lean manufacturing, but didn’t realize right away that this book was written a long time before Lean hit mainstream. For some reason that gives it more credibility in my mind.

The book is one man’s journey to debunk common manufacturing theory errors. He has the help of a “guru” type character. Of course every book where the protagonist has a guru, it’s important that the guru be scarce. You’ll find this frequently in fantasy books – the main character has a guide, but that guide suddenly disappears for long periods of time, leaving the protagonist to struggle and often experience failure. Consider Gandalf in any story he’s in, from The Hobbit through The Return of the King. That guy is disappearing (or dying, or having his staff broken) at the most inconvenient times! Leaving poor little hobbits and dwarves to fend for themselves, struggling (and learning and growing) in a cruel world.

Getting back to the book, here are some basic principles I found fun to ponder.

The success of a manufacturing plant can be improved by working on three values. In order of importance they are:

  1. Increasing throughput to sales.
  2. Decreasing inventory
  3. Decreasing operating expense.

To continually over time make changes in a manufacturing plant that move these numbers in these directions is to become more successful. In the book, the real value is in increasing throughput. The book purposely deemphasizes operating expenses.

  • Throughput is limited by the bottlenecks of the production system. The bottlenecks must be identified.
  • Trying to optimize anything besides the bottlenecks is a waste of time: it will not improve throughput.
  • Keep the bottleneck resources running! An hour lost for a bottleneck resource means an hour lost all the way up and down the system.

The book illustrates why throughput is limited by the bottlenecks by including a section about a boy scout troop hiking single-file for six miles.

    • The rate at which the last person of the troop travels the trail is throughput.
    • The amount of space between the first and last scouts is inventory.
    • The amount of effort each boy uses is operating expense.

One of the boys is a “bottleneck” because he’s a bit out of shape. When the bottleneck is in the middle of the single-file line, bad things happen. The faster folks up front get way ahead, representing high inventory. The folks behind him can’t go any faster than the bottleneck. Throughput of the entire system is constrained to the bottleneck, even when the other resources have excess capacity. Even the scouts up front, way ahead, aren’t helping matters because the product isn’t done until the last boy arrives at the camp. All they are doing is increasing inventory (waste) by always increasing the space between the first and last people.

The main character puts the bottleneck up front, and demands that everyone stay in line. Inventory at this point goes way down (good!) but throughput is still unchanged – they’re still moving along at the bottleneck’s pace. The boys complain about the slow-poke up front.

Then a very interesting thing happens. The protagonist gets everyone thinking about constructive ways to make the bottleneck faster. Before long they remove his backpack from him and share it among everyone who wants to go faster (they have excess capacity). Now the whole line speeds up:

    • Throughput it up! Everyone is moving faster.
    • Inventory is down! Everyone is still together.
    • Operating expense is down! The brisk yet steady pace is efficient for everyone.

The leadership team at the manufacturing plant applies these, and other principles, to their plant to great success. Here’s how they end up summarizing what they’ve done:

  1. Identify the system’s constraints (bottlenecks).
  2. Decide how to exploit the system’s constraints (focus everything on maximizing utilization on the constraint: minimize downtime, do a QA check on parts before they go through the bottleneck, etc.).
  3. Subordinate everything else to the above decision (don’t try to maximize non-bottleneck resources; make them work in a way that supports the bottleneck. The idea of a “cadence” in a production line is in line with this).
  4. Elevate the system’s constraints (try to improve the raw capacity of the bottlenecks, e.g., purchase more equipment or subcontract it out).
  5. Warning: if in this process a constraint is broken, go back to step 1, but do not allow inertia to cause a system’s constraint. (I actually don’t know what this means.)

The book concludes with a generalization of management. The hypothesis is that good management is properly figuring out (1) what to change, (2) what to change it to, and (3) how to change it. I think those might be clarifying steps to follow when one gets bogged down in a management situation.

Posted in Business, Lean | Leave a comment

Posting an AJAX JSON request with jQuery

After trying to Google this for the fifth time, and writing it from scratch for the seventh time, I’m sticking this snippet here. In AJAX apps, it’s always made sense to me to do JSON both ways, even though the jQuery default is form-data up and whatever down. Once ASP.NET MVC3 made JSON model binding turned on by default, something like the below is a natural next step.

(<span class="kwrd">function</span> ($) {
    $.postJSON = <span class="kwrd">function</span> (url, obj, callback) {
        $.ajax({
            url: url,
            type: <span class="str">'POST'</span>,
            dataType: <span class="str">'json'</span>,
            data: JSON.stringify(obj),
            contentType: <span class="str">'application/json; charset=utf-8'</span>,
            success: callback
        });
    };
} (jQuery));

Note: JSON.stringify is built in to modern browsers now, but for older browser just find json2.js (commonly available) and include it on your page.

Posted in CodeMinder, JavaScript, JSON, Programming, REST | 1 Comment

Script to turn on "Treat Warnings as Errors"

This PowerShell script recursively finds all .csproj files in a directory and sets “Treat warnings as errors” to “All” for every one of them that doesn’t already have it set. I definitely prefer this compilation option, but on larger systems getting those all flipped can be a tedious process.

get-childitem . -include *.csproj -recurse | %{
    [xml]$proj = get-content $_.FullName
    $modified = 0
    $proj.Project.PropertyGroup 
      | where-object { $_.Condition <span class="preproc">-match</span> <span class="str">'Configuration.*Platform.*(Debug|Release)'</span> }
      | %{
        <span class="kwrd">if</span> (-not $_.TreatWarningsAsErrors) {
            $node = $proj.CreateElement(<span class="str">'TreatWarningsAsErrors'</span>, $proj.Project.NamespaceURI)
            $node.InnerText = <span class="str">'true'</span>
            $node = $_.AppendChild($node)
            $modified = 1
        }
    }
    <span class="kwrd">if</span> ($modified <span class="preproc">-eq</span> 1) {
        $proj.Save($_.FullName)
    }
}
Posted in PowerShell, Programming | Leave a comment

ASP.NET Selective Validation Hack

Scenario: using classic ASP.NET Web Forms, we have a data entry page. On the bottom of the page are two buttons: “Save Draft” and “Submit.”

When a user Saves a Draft, we want to do some validation, but not all. We want to make sure only numbers are entered for numeric fields, yet we don’t need all required fields to be filled out. But when a user Submits the document, all validation should occur.

ASP.NET doesn’t support this very nice. Validation Groups get us close, but are meant to work on completely different sets of validators. In our case, one set of validators is a subset of the other. Things get especially dicey if you throw a ValidationSummary onto the page.

With one JavaScript hack that can go in your Master Page you can get the desired behavior. First, the ASP.NET markup:

<span class="kwrd">&lt;</span><span class="html">p</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">asp:ValidationSummary</span> <font style="background-color: #ffff00"><span class="attr">ValidationGroup</span><span class="kwrd">="*"</span></font> <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">p</span><span class="kwrd">&gt;</span>

<span class="kwrd">&lt;</span><span class="html">asp:TextBox</span> <span class="attr">ID</span><span class="kwrd">="SomeNumber"</span> <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;</span><span class="html">asp:RequiredFieldValidator</span> <font style="background-color: #ffff00"><span class="attr">ValidationGroup</span><span class="kwrd">="Submit"</span></font>
    <span class="attr">Text</span><span class="kwrd">="Required"</span> <span class="attr">ErrorMessage</span><span class="kwrd">="SomeNumber is required."</span>
    <span class="attr">ControlToValidate</span><span class="kwrd">="SomeNumber"</span> <span class="attr">Display</span><span class="kwrd">="Dynamic"</span>
    <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;</span><span class="html">asp:RangeValidator</span> <span class="attr">Type</span><span class="kwrd">="Integer"</span> <span class="attr">MinimumValue</span><span class="kwrd">="0"</span> <span class="attr">MaximumValue</span><span class="kwrd">="100"</span>
    <span class="attr">Text</span><span class="kwrd">="Number"</span> <span class="attr">ErrorMessage</span><span class="kwrd">="SomeNumber must be [0, 100]."</span>
    <span class="attr">ControlToValidate</span><span class="kwrd">="SomeNumber"</span> <span class="attr">Display</span><span class="kwrd">="Dynamic"</span>
    <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="kwrd">/&gt;</span>

<span class="kwrd">&lt;</span><span class="html">p</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">asp:Button</span> <span class="attr">Text</span><span class="kwrd">="Save Draft"</span> <span class="attr">onclick</span><span class="kwrd">="OnSaveDraft"</span> <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">asp:Button</span> <span class="attr">Text</span><span class="kwrd">="Submit"</span> <span class="attr">onclick</span><span class="kwrd">="OnSubmit"</span> <font style="background-color: #ffff00"><span class="attr">ValidationGroup</span><span class="kwrd">="Submit"</span></font> <span class="attr">runat</span><span class="kwrd">="server"</span> <span class="kwrd">/&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">p</span><span class="kwrd">&gt;</span>

Then drop this near the bottom of your Page or Master Page:

&lt;script type=<span class="str">"text/javascript"</span>&gt;
<span class="rem">// Override this part of ASP.NET validation in order to make validation</span>
<span class="rem">// groups work as subsets of each other rather than completely independently.</span>
<span class="kwrd">function</span> IsValidationGroupMatch(control, validationGroup) {
    <span class="kwrd">if</span> ((<span class="kwrd">typeof</span> (validationGroup) == <span class="str">"undefined"</span>) || (validationGroup == <span class="kwrd">null</span>)) {
        <span class="kwrd">return</span> <span class="kwrd">true</span>;
    }
    <span class="kwrd">var</span> controlGroup = <span class="str">""</span>;
    <span class="kwrd">if</span> (<span class="kwrd">typeof</span> (control.validationGroup) == <span class="str">"string"</span>) {
        controlGroup = control.validationGroup;
    }
    <span class="kwrd">return</span> (controlGroup == validationGroup<font style="background-color: #ffff00"><strong> || controlGroup == <span class="str">'*'</span> || validationGroup.length &gt; 0</strong></font>);
}    
&lt;/script&gt;

The method IsValidationGroupMatch() is supplied by ASP.NET client-side validation. We override that method and add the highlighted bit to it.

Caveat 1: This won’t affect server-side validation, so to be thorough the OnSubmit in the code behind should have at the top, Validate(“”); if(!Page.IsValid) return;

Caveat 2: This will probably cause problems if you want to use Validation Groups in the way they were originally intended, as completely isolated sets of validators.

Posted in Programming | Leave a comment

The Speed of Trust: Integrity

A quick check of where we’re at in this large book. The main structure starts inward-most and works out:

  1. Self trust (credibility).
    1. Integrity. ← You are here.
    2. Intent.
    3. Capabilities.
    4. Results.
  2. Relationship trust.
  3. Organizational trust.
  4. Market trust.
  5. Societal trust.

Integrity vs. other aspects of credibility.

To see Integrity’s importance in overall credibility, imagine you have a coworker like this:

  • Full of good intentions; he wants to see himself and his company succeed (Intent).
  • Very talented, smart and driven; an excellent communicator and persuasive negotiator (Capable).
  • He brings in sales, beats competitors, and closes deals (Results).

Quite a force to be reckoned with! But though he has all this, if he has almost no Integrity, it casts a dark, even frightening shadow over this character. He is “credible” in important ways, but such a manipulative, deceitful person would likely engage in fraud, extortion and scandal to accomplish his goals.

Now let’s flip the coin a bit: imagine a man who is a practical angel in terms of Integrity; would never lie or cheat. Yet he is aimless in his direction (Intent), he can hardly do anything on his own (Capabilities), and has no track record of getting things completed (Results). We have a nice, honest man, who is irrelevant.

Integrity vs. compliance.

Another aspect of the Integrity discussion points out that if, for an individual within an organization, “ethics” is seen merely as compliance with the rules, you have a major problem. A simple “follow the rules” mentality is insufficient to produce integrity. In my (Jason’s) opinion, this will lead to textbook legalism’s duplicitousness. I particularly like this quote:

Rules cannot take the place of character. -Alan Greenspan

Instead of legislating ethics by a code of rules one must comply with, an organization should clarify its values, emphasize them constantly, and foster integrity to those values. I’m going to pull in a bit I’ve learned about company values here from Dave Ramsey’s EntreLeadership podcast. A company’s values are not a list of 12 adjectives that are framed on a wall somewhere. They are two or three core things that an organization lives and dies by.

The story was told of an airline company that has “humor” as one of its core values. They received a complaint from a customer who was bothered by the use of humor during the safety instructions. The CEO of this airline responded personally in a way that remained steadfastly integrated with the core value. The entire response:

We’ll miss you. -CEO

The core values were not negotiable. They weren’t to be sacrificed or compromised, even if staying true to them would be costly. That, in a nutshell, is integrity: holding firm to one’s values even when it’s costly.

Improving your integrity.

I’ll lastly mention the book’s three suggestions for improving your integrity; the book elaborates on these suggestions; I’ll just bullet them here:

  • Make and keep commitments to yourself.
  • Stand for something.
  • Be open.
Posted in Leadership, Softer Skills | Tagged | 1 Comment

Global JavaScript Events with jQuery

When building web applications with sophisticated client-side behavior (i.e., you have a lot of JavaScript) I work hard to define loosely-coupled JavaScript modules. Intentional developers strive for structured and modular server-side code, but because of JavaScript’s history we tend not to take the same care with it. We then repeat the sins of the past when we find ourselves with hundreds or thousands of lines of JavaScript that aren’t encapsulated and decoupled.

Key Point: Write loosely-coupled JavaScript modules within your application.

Of course, you do need some coupling between modules. To realize the interactions that must occur between JavaScript modules, consider using a global event technique. Modules publish information to the world when something interesting happens; other modules subscribe to information they need to react to.

Key Point: Publishers shouldn’t need to know anything about their subscribers.

Here are a few ways to set up a global publish/subscribe mechanism your JavaScript modules to use:

Roll Your Own

We don’t want to succumb to the “Not Invented Here” problem, but these few lines create a simple but useful window.Bus object that supports global events.

(<span class="kwrd">function</span>() {

    var subscriptions = null;

    window.Bus = {

        reset: <span class="kwrd">function</span>() {
             subscriptions = {};
        },

        subscribe: <span class="kwrd">function</span>(messageType, callback) {
            <span class="kwrd">if</span> (<span class="kwrd">typeof</span> subscriptions[messageType] === <span class="rem">'undefined') {</span>
                subscriptions[messageType] = [];
            }
            subscriptions[messageType].push(callback);
        },

        publish: <span class="kwrd">function</span>(messageType, args) {
            <span class="kwrd">if</span> (<span class="kwrd">typeof</span> subscriptions[messageType] === <span class="rem">'undefined') return;</span>
            var subscribers = subscriptions[messageType];
            <span class="kwrd">for</span> (var i=0; i&lt;subscribers.length; i++) {
                subscribers[i](args);
            }
        }

    };

    window.Bus.reset();

}());

// Subscriber usage:
window.Bus.subscribe(<span class="rem">'UserCreated', function(user) {</span>
    alert(<span class="rem">'User ' + user.Name + ' created!');</span>
});

// Publisher usage:
var newUser = { Name: <span class="str">"The Hulk"</span> };
window.Bus.publish(<span class="rem">'UserCreated', newUser);</span>

jQuery

One quick way to get there without adding any more dependencies than you probably already have is it just use features jQuery’s eventing system. Here’s code that demonstrates how to use jQuery as a global pub/sub framework. In this example, there are two modules, a publisher and a subscriber, each with a bit of HTML and a bit of JavaScript. The JavaScript comments explain the main points.

<span class="kwrd">&lt;</span><span class="html">html</span><span class="kwrd">&gt;</span>
<span class="kwrd">&lt;</span><span class="html">head</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">title</span><span class="kwrd">&gt;</span>Client-side Pub/Sub with jQuery<span class="kwrd">&lt;/</span><span class="html">title</span><span class="kwrd">&gt;</span>
    <span class="rem">&lt;!-- add reference to jQuery --&gt;</span>
<span class="kwrd">&lt;/</span><span class="html">head</span><span class="kwrd">&gt;</span>

<span class="kwrd">&lt;</span><span class="html">body</span><span class="kwrd">&gt;</span>

    <span class="kwrd">&lt;</span><span class="html">div</span><span class="kwrd">&gt;</span>
        <span class="kwrd">&lt;</span><span class="html">input</span> <span class="attr">id</span><span class="kwrd">='PublishButton'</span> <span class="attr">type</span><span class="kwrd">='button'</span> <span class="attr">value</span><span class="kwrd">='Publish'</span> <span class="kwrd">/&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">div</span><span class="kwrd">&gt;</span>

    <span class="kwrd">&lt;</span><span class="html">b</span><span class="kwrd">&gt;</span>Events:<span class="kwrd">&lt;/</span><span class="html">b</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;</span><span class="html">div</span> <span class="attr">id</span><span class="kwrd">='Subscriber1'</span><span class="kwrd">&gt;</span>
    <span class="kwrd">&lt;/</span><span class="html">div</span><span class="kwrd">&gt;</span>

<span class="kwrd">&lt;/</span><span class="html">body</span><span class="kwrd">&gt;</span>

<span class="kwrd">&lt;</span><span class="html">script</span> <span class="attr">type</span><span class="kwrd">='text/javascript'</span><span class="kwrd">&gt;</span>
<span class="rem">// This function block correlates with the publisher's scope.</span>
$(<span class="kwrd">function</span>() {

    <span class="rem">// Represents a secret value only the publisher knows about directly,</span>
    <span class="rem">// but will include in its event args.</span>
    <span class="kwrd">var</span> someNumber = 7;

    <span class="rem">// When the button is clicked we publish an event.</span>
    $(<span class="str">"#PublishButton"</span>).click(<span class="kwrd">function</span>() {
        <span class="kwrd">var</span> dt = <span class="kwrd">new</span> Date();
        <span class="rem">//</span>
        <span class="rem">// The next line is the important one; notice how the event args</span>
        <span class="rem">// are passed as an array.</span>
        <span class="rem">//</span>
        $.<span class="kwrd">event</span>.trigger(<span class="str">'CustomEventName'</span>, [someNumber, dt]);
        someNumber++;
    });

});

<span class="rem">// This function block correlates with the subscriber's scope.</span>
$(<span class="kwrd">function</span>() {
    <span class="rem">//</span>
    <span class="rem">// Notice how we're not calling bind() on the subscriber like a typical</span>
    <span class="rem">// jQuery event, but calling it on our own UI component.</span>
    <span class="rem">// Also notice how the event args, which were published as an array,</span>
    <span class="rem">// are flattened into individual parameters.</span>
    <span class="rem">//</span>
    $(<span class="str">"#Subscriber1"</span>).bind(<span class="str">'CustomEventName'</span>, <span class="kwrd">function</span>(<span class="kwrd">event</span>, number, date) {
        $(<span class="str">"&lt;div&gt;"</span>).text(<span class="str">"Event published: "</span> + number + <span class="str">" @ "</span> + date).appendTo($(<span class="kwrd">this</span>));
    });
});
<span class="kwrd">&lt;/</span><span class="html">script</span><span class="kwrd">&gt;</span>

<span class="kwrd">&lt;/</span><span class="html">html</span><span class="kwrd">&gt;</span>
<!--
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
-->

Use a Global Event Library

The following JavaScript libraries are a few that provide a global pub/sub infrastructure:

Posted in JavaScript | 2 Comments

SQL Snapshot Notes

Sometimes when testing you need to repetitively restore a database back to a certain point in time. For very large databases the regular SQL restore can take quite a while. It seemed to me that using snapshots instead of regular backups cut this restore down quite a bit.

To Create the Snapshot

<span class="kwrd">create</span> <span class="kwrd">database</span> [NewDatabaseName] <span class="kwrd">on</span> (
    name = [SourceDatabaseLogicalName],
    filename = <span class="str">'\file\to\create\snapshot.ss'</span>
) <span class="kwrd">as</span> snapshot <span class="kwrd">of</span> [SourceDatabase]

To Restore the Snapshot

<span class="rem">-- force <strike>choke</strike> close any connections</span>
<span class="kwrd">alter</span> <span class="kwrd">database</span> [SourceDatabase]
    <span class="kwrd">set</span> single_user
    <span class="kwrd">with</span> <span class="kwrd">rollback</span> <span class="kwrd">immediate</span>

<span class="kwrd">go</span>

<span class="rem">-- restore from snapshot</span>
<span class="kwrd">restore</span> <span class="kwrd">database</span> [SourceDatabase]
     <span class="kwrd">from</span> database_snapshot = <span class="str">'NewDatabaseName'</span>&nbsp;

Notes

  • NewDatabaseName: The name of a database that doesn’t exist yet, but will be created and store the snapshot information.
  • SourceDatabase: The name of the database you want to create a snapshot of.
  • SourceDatabaseLogicalName: The “logical name” of the main MDF file for the database you want to create a snapshot of. In SQL Management Studio, do right-click/Properties for the database, and look here:

image

Posted in CodeMinder, SQL | Leave a comment