My first blog post on Scriptogram
Hello! This is my first blog post, hosted by Scriptogram. Let's see how it goes!
:)
My first blog post on Scriptogram
Hello! This is my first blog post, hosted by Scriptogram. Let's see how it goes!
:)
Kanban Weekly Roundup - May 16, 2012
Updating a Dynamics CRM Customer Record via HTTP
My current project integrates with the Microsoft Dynamics CRM system for managing customer records. We already spiked out authenticating and our next step was attempting to update a record via its “REST Endpoint“.
On retrieving a record, you follow the OData style for finding something of relevant. Updating a record is interesting as we only want to send the fields that need to change remotely. Looking at their sample code, you need to:
- Create an authenticated POST request
- Set the X-HTTP-Method to MERGE
- Set the appropriate content type for the content you intend on sending. In our case, set the header Accept to application/json and the Content-Type to application/json; charset=utf-8
Our end point for a contact looked something like:
https://crm.thekua.com/xrmservices/2011/organizationdata.svc/ContactSet(guid'867dc3f2-909e-e111-9912-0050569c2d72')
.
Updating simple fields off a contact is easy. We post something like:
{
"EMailAddress1":"spike.jones4@gmail.com",
"MobilePhone":"33335"
}
We receive a HTTP 204 (No Content) on a success. Posting an invalid attribute (i.e. one that does not exist on the ContactSet such as “EMailAddreXXXs1″) results in a HTTP 400 (Bad request) and a nice description about what’s wrong. You will also get a HTTP 400 if you post the wrong datatype such as sending a string where they expect a number. If you pass invalid values (but of the correct datatype) for a field, your response is a HTTP 500 with a message like The value of 'gendercode' on record of type 'contact' is outside the valid range."
Updating Option Set Values
Updating simple datatypes is easy and obvious from a JSON point of view. You have a couple of complex datatypes, such as the standard GenderCode. When you query for a record, you get back something that looks like
{"GenderCode"=>{"__metadata"=>{"type"=>"Microsoft.Crm.Sdk.Data.Services.OptionSetValue"}, "Value"=>1}}
To update something like this, you need to send a nested JSON object. The example follows
{
"EMailAddress1":"spike.jones4@gmail.com",
"MobilePhone":"33335",
"GenderCode": {
"Value" : "1"
}
}
A HTTP 204 (No Content) response indicates a success. Viola!
On Nate’s Departure
As of Monday, May 14, Nate Kohari is no longer with the AgileZen team. Nate formally announced this news on Twitter earlier in the week:
This is really hard to swallow. My employment at Rally Software has been terminated, ending my involvement with AgileZen.
— Nate Kohari (@nkohari) May 15, 2012
As an original co-founder of AgileZen, Nate played the role of visionary and technologist from the beginning. In the recent past, he was instrumental in building the AgileZen team within the Rally organization. His departure came as a surprise to the entire team, and he will be greatly missed.
It is impossible to replace a person and leader like Nate. As a team, we will continue with the vision previously set out in order to deliver the best product we possibly can. We maintain our August release date and are excited to share our new, amazing product with you.
As always we are available to field any questions, comments, or concerns you may have. We will monitor the comments along with our Twitter feed. Alternatively, you can email me directly at alex@agilezen.com.
Design for Testability
Asked on the Agile-Testing mailing list:
Lesson 136: Testability is often a better investment than automation.
(I’m quoting “Lessons Learned in Software Testing” by Kaner/Bach/Pettichord)
If anyone has practical examples of improving testability, I’d be very interested to understand, and grateful.
I first encountered the issues of testability when working with integrated circuit design in the 1980s. The same issues apply to software systems.
- You want to be able to easily put the system into a known state. It’s best if you can get to the state you want for your test without going through a number of interactions or other states on the way.
- You want to be able to drive internal nodes of the system so that you can test parts in isolation. It’s much harder to test everything through the GUI, public API, IC pins, or whatever is the normal interface.
- You want to be able to sense internal nodes of the system so that you can test parts in isolation. Like being able to drive internal nodes, this reduces the combinatorial complexity.
- The special access you add for testability does add some complexity, can provide new failure modes, and might leave some paths untested. Be aware of this and consider what these issues are for your system.
Your work gets a bit easier if you consider this as part of building the system, rather than just as part of testing it. If you build your tests first, the tests will specify the state and access you need for testability. Running these tests while the system is built will result in testability appearing almost magically. Because of that, I’d say that testability trumps automation only when you’re already late in starting.
The Role of the Product Owner in Moving a Backlog Item to Done
Moving a Backlog Item to Done
Back to Basics: Daily Scrum
I Have No Impediments
People are Messy
It’s almost a cliche in the consulting field that all problems are people problems… sometimes though, I don’t think we really appreciate the depth of truth in that statement. Improving the systems in which we work, introducing some new processes, or bringing in a new approach or methodology or tool requires people to change what they are doing today and requires them to do something different tomorrow.
Change is hard… change is scary… change isn’t safe.
I’m guessing that most of us have read Kotter’s work on leading change… and while I do believe that managing change… or even leading change… is an essential part of bringing new ways of working into any organization… it feels to me that there is something deeper, more personal around change than putting gloves on a table, or posters up around an office. Resistance to change often runs deep for reasons that are not immediately obvious.
Let me tell you a little story about my wife and I growing up… while we both grew up in stable two-parent homes… our early childhood experiences were very different.
My family moved around a lot when I was a kid. By the time we settled down in Tampa, FL I had lived 4 different states, probably 6 or 7 different cities, and at least 6 different elementary schools. I was forced to get used to new environments and make new friends on a regular basis. While we had the basics, my family lived with a tremendous amount of financial insecurity.
My wife on the other hand grew up in one city her entire life. Her Dad was a mathemetician at Eglin Air Force Base, had one job, and she lived in one house until she went to college . Kimi grew up with a consistent set of friends and had all her family in the same general area. Her family was able to take a family vacation every year and didn’t have any of the financial instability I experienced as a kid.
While both families ended up just fine… my expectations about change very different from my wife’s expectations. My experience is that you do what you have to do, go where you have to go, and take chances and everything works out well. My wife’s experience is that you stay in one place, hold into what works, and don’t assume a bunch of risk and everything turns out well.
I could go on and on about other differences in our experiences growing up… relationships with parents and siblings… being the oldest or the youngest… the caliber of people we both chose to hang out with… our influences and our faith and the decisions we both made… but at this point I’ve already shared too much and don’t want to get into any more trouble than necessary to make my point
Needless to say people are complicated.
My point is this… as individuals, change isn’t really an intellectual process. It’s not really even just an emotional one… where if people could just see, or feel good about another way of doing things… they would get on board with the new approach. On many levels we are dealing with very personal deep seeded stuff… the stuff that anchors us as people and defines who we are in relation to the world.
I don’t know that I have any answers here… but I’ve been very intentional lately trying to understand more about the people I work with, who they are as people, their expectations about life and the world around them, and what makes them feel safe and secure in their experience with work. Sometimes you have direct access to that information, some times you have to infer it… but either way… it’s usually the truth behind the resistance.
Anyway… just something to think about. It’s an idea that’s been noodling around in my head for the past several months and this is my first attempt to put words around it. I’d be interested to hear what you have to share regarding this. I suspect it won’t be the last time this topic comes up.
Related Posts:- Safety to Change
- 2010 in Retrospective: Mike Cottmeyer Edition
- Catching Everyone Up…
- Change is the only constant…
- 2008 in Retrospective: Mike Cottmeyer Edition
Seek new assignments for things you have not done before & develop deep expertise in one area…
Haskell: Writing a custom equality operator
In the comments on my post about generating random numbers to test a function David Turner suggested that this was exactly the use case for which QuickCheck was intended for so I’ve been learning a bit more about that this week.
I started with a simple property to check that the brute force (bf) and divide and conquer (dc) versions of the algorithm returned the same result, assuming that there were enough values in the list to have a closest pair:
prop_closest_pairs xs = length xs >= 2 ==> dcClosest xs == (fromJust $ bfClosest xs)
I could then run that as follows:
> import QuickCheck.Test > quickCheck(prop_closest_pairs :: [(Double, Double)] -> Property)
It failed pretty quickly because the bf and dc versions of the algorithm sometimes return the pairs in a different order.
e.g. bf may say the closest pair is (2.0, 0.0), (2.1, 1.1) while dc says it’s (2.1, 1.1), (2.0, 0.0) which will lead to the quick check property failing because those values aren’t equal:
> ((2.0, 0.0), (2.1, 1.1)) == ((2.1, 1.1), (2.0, 0.0)) False
The best way I could think of to get around this problem was to create a type to represent a pair of points and then write a custom equality operator.
I initially ended up with the following:
type Point a = (a, a) data Pair a = P (Point a) (Point a)
instance Eq (Pair a) where P a b == P c d = a == c && b == d || a == d && b == c
Which didn’t actually compile:
qc_test.hs:41:58:
No instance for (Eq a)
arising from a use of `=='
In the second argument of `(&&)', namely `b == c'
In the second argument of `(||)', namely `a == d && b == c'
In the expression: a == c && b == d || a == d && b == c
The problem is that while we’ve made Pair an instance of the Equality type class there’s no guarantee that the value contained inside it is an instance of the Equality type class which means we might not be able to compare its values.
We need to add a class constraint to make sure that the value inside P is a part of Eq:
instance (Eq a) => Eq (Pair a) where P a b == P c d = a == c && b == d || a == d && b == c
Now we’re saying that we want to make Pair an instance of the Equality type class but only when the value that Pair contains is already an instance of the Equality type class.
In this case we’re just storing pairs of doubles inside the Pair so it will work fine.
Now if we compare the two points from above we’ll see that they’re equal:
> P (2.0, 0.0) (2.1, 1.1) == P (2.1, 1.1) (2.0, 0.0) True
I had to go and change the existing code to make use of this new but it didn’t take more than 5-10 minutes to do that.
LeanKit Announces Integration Partnership with Focused Objective
LeanKit Announced Partnership with Focused Objective
Lessons Learned: Lint and Javascript
Yesterday, I announced my new screencast series, Let's Code: Test-Driven Javascript. Today, I'm pleased to share an early screen test for the "Lessons Learned" channel. The goal for this channel is to provide a distilled look at a specific topic—to provide maximum information in minimum time. The series also includes "Live" and "Caffeinated" channels: a live recording of a real-world web application as it's developed, similar to my popular Let's Play TDD series. For details, check out the Kickstarter!
Lessons Learned: Lint & JavascriptIn this video, we take a concise look at what Lint is, how to use it, and how to incorporate it into your automated build. The example source code is available on GitHub and the transcript is below.
TranscriptHi, everyone. This is James Shore with my lessons learned about Lint and Javascript. We're going to look at what linting is, how to use it, and how to incorporate it into your automated build.
What is "Lint"? (00:10)Lint tools read your source code and look for common mistakes. In Javascript, this means things like missing semicolons or unsafe comparison operators. Javascript is full of "gotchas" that silently introduce bugs. A linter is invaluable for keeping your code defect-free.
The leading linter for Javascript is JSLint, by the famed Douglas Crockford. Now, Douglas Crockford can be a bit... curmudgeonly, and some people don't agree with some of the choices he's made with JSLint. They've forked JSLint to create JSHint. It provides more control over what's flagged as an error and what's not.
I chose to use JSHint for Let's Code: Test-Driven Javascript, but most of what I'm about to describe is equally applicable to JSLint.
Running JSHint Manually (00:50)The easiest way to run JSHint is to go to the website, paste in your code, and hit the "Lint" button. That's fine for one-off scripts, but not really suitable for professional web development.
Another option is to use the Node package manager to install a copy of JSHint. (You'll need to install Node first, if you haven't already.) If you use the -g option when you install JSHint, it will put a convenient command-line interface on your path.
Automating JSHint (01:13)Personally, I don't think the manual approach is a good idea. Javascript has so many gotchas that you really need to run Lint all the time, as part of your automated build. And if it's going to be in your automated build, you should install JSHint locally, not globally. That will ensure your build still works when other people check out your repository.
Once JSHint is installed, you can require() it in your build script. JSHint and JSLint both provide the same interface, and it's not a particularly friendly one. There's only one function exposed by the module: JSHINT. It takes the source code to check, a set of options, and an optional set of globals, and returns true or false depending on whether the lint succeeded or failed. It also populates an errors array on the JSHINT function with specific error messages.
Processing Files (02:00)The first parameter is the source code. You'll need to load your files from the file system. To load a file, use the readFileSync() function in Node's fs module. readFileSync() reads an entire file into memory. It takes a file encoding; if you're not sure what to use, utf8 is usually a safe bet. Once you have the file, you can pass it to JSHint.
Your automated build will likely have a list of files to check, so you'll need a function that calls Lint for each file and collates the overall "pass / fail" status as it goes.
Options (02:28)The second parameter is an object containing your JSHint options. These options control what Lint complains about and what it allows to pass. They're described in detail on the JSHint web site, so I won't repeat that here.
Globals (02:41)The third parameter is optional. It's an object containing your global variables. If you set the undef option to true, then JSLint will complain if you use any variables that haven't been explicitly declared. This third parameter allows you to make exceptions to the rule. For each global variable name you include, you set it to true if your code is allowed to change the variable, or false if it isn't.
Per-File Settings (03:02)You can also define options and globals by using a block comment at the top of a Javascript file or at the start of a function. This is useful for changing your global JSHint options on a case-by-case basis.
Interpreting JSHint's Results (03:13)When you run JSHint, it returns true or false according to whether or not your code passed. That's enough to cause your build to fail when you need it to, but you'll also want to print out the details of what Lint found.
To do that, you'll want to examine JSHint's errors array. Some elements of the array are blank--you can just skip those. The rest are objects with three properties: line, which is the line number; evidence, which is the source code containing the problem; and reason, which is Lint's error message. Sometimes line and evidence are left out, so you'll want to check for that.
Conclusion (03:46)So that's what I've learned so far about Lint and Javascript. To summarize, Lint is a tool for checking for problems in your source code. Given Javascript's "gotchas," I think it's an indispensable part of your automated build. You can use JSHint to include Lint in your build. Check out the source code for this episode for an example of how to do it. The link is available on your screen.
Thanks for watching, and I'll see you next time!
Back this project on Kickstarter! http://letscodejavascript.com
Product Backlog and Taskboard Evaluation – JIRA
JIRA is everywhere. Everyone talks about it, everybody wants it, but not everybody can have it – why is that? In my first article, I announced that a series of articles will follow in which Scrum tools will be reviewed. This blog entry is the first of many in which I will evaluate currently available Scrum tools that are able to represent a taskboard.
JIRA is a well-known issue tracking software developed and maintained by a company called Atlassian, that has a rich product portfolio in the field of software development, tracking and collaboration. Next to JIRA, Atlassian is also famous for its wiki software called Confluence. The following sections will focus on JIRA, especially on a plugin for JIRA called GreenHopper.
FunctionalityJIRA is an issue tracking software tool and that is its greatest power. It has countless features and it can be stated without hesitation, that JIRA might be THE issue tracking software tool currently available on the market. While issue tracking is certainly a must have, one aspect that makes JIRA interesting especially for Scrum and Kanban teams is its plugin architecture. Currently, 400+ plugins are available. The one that catches our attention (and the most popular plugin right now) is called GreenHopper, that adds an Agile layer on top of the JIRA architecture. With GreenHopper, Scrum and Kanban teams can migrate their product backlog, their taskboard, their burndown charts and other Scrum artifacts to JIRA and create their electronic counterparts. Until recently, the functionality of GreenHopper was comparable to that of many other Scrum tools.
Since version 5.8, GreenHopper goes beyond that by introducing what they call a rapid board. A rapid board is a new approach to guide Scrum and Kanban teams through their corresponding processes. Therefore, two standard presets are available and a third one, which is called DIY where teams can alter processes in a manner that suit them best. In my case, I have chosen the Scrum preset. Before you can start creating your backlog, you have to link your new rapid board to an existing JIRA project – not very intuitive but understandable since JIRA itself is not Agile. After having done so, GreenHopper will present you an empty product backlog (what they call the plan mode), that wants to get filled with user stories. Lets fire up our keyboard and add some stories! By the way, GreenHopper offers you a choice out of five types (blocker, critical, major, minor, trivial) which you can assign to your stories / tasks. I will explain later on why that might be handy.
Did you enter enough stories to keep your team busy for the next sprint? Great, call them in, because right now, the stories needs to get estimated by clicking on each story and filling in the story points. As soon as all story points are entered, the team can choose an amount of stories to commit by simply dragging a sprint marker until they think it is enough. The sprint marker will then automatically show the total amount of committed story points and we can start the sprint by just clicking on the “Start Sprint” button; GreenHopper will automatically redirect us to our well-loved taskboard.
The work view (the taskboard) gives us a basic taskboard design, featuring the obligatory set of „To Do – In Progress – Done“ columns. Interestingly, the stories dont get an own column. Instead, they are placed in the „To Do“ column, with their corresponding tasks just beneath them. Wait – did I say tasks before we actually created them? Yep, and the reason for this is linked to a positive and at the same time negative aspect of JIRA: its flexibility. JIRA is highly flexible, you can alter it in each possible way that suits you best. But that flexibility comes at a cost: the interface is often not very intuitive – I will cover that aspect in one of the following sections. Back to creating a task: We have to click on the generated ID of JIRA (EVAPRO-8 if you look at my provided screenshot), followed by a click on „More Actions“ and then you are finally able to choose „Create Sub-Task“. After finding that somewhat hidden button, the process of creating tasks is much better, mainly due to the ability to leave the create task window open – very time saving when entering multiple tasks. Even more time saving is the ability to perform nearly all the commands by using keyboard shortcuts – your team will love it!
Yet another powerful feature of JIRA is its very own (SQL like) querying language called JQL, with which you are able to perform any search request you can think of. But there is more than just that – team members can customize their dashboard by using JQL so that they see what they want to see. Your team will love you even more!
Back to the columns of the taskboard. You might already have guessed it; it is also flexible and can be altered according to your needs, e.g. by adding a committed column which means that the PO can test the functionality and move the story/task to complete when it satisfies him or her.
JIRA can be used for multi project setups. In fact, you can use multiple projects as input for one rapid board. Interestingly, JIRA does not offer any more hierarchies beyond epic level (and it is rumored that even epics are just relabeled tasks). A plugin called „structure“ helps to create infinite levels of hierarchies, but it is third party and not perfectly embedded within JIRA and GreenHopper.
Still, JIRA is a feature monster: interfaces to other tools? Check. Archival / export functionality? Check. User access control? Check. Event-based notification? Check. Time registration? Check. Support for adding bug stories/tasks? Check. Assign tasks to people? Check. Undo functionality? Uncheck – no undo available, due to use of AJAX (see below).
UsabilityWhen it comes to using JIRA with GreenHopper, the overall impression is twofold. On the one hand using JIRA without a mouse introduces a massive speed up of daily actions the team has to perform. On the other hand you get the feeling that GreenHopper, especially the rapid boards, did not leave beta status yet (which is clearly indicated by Atlassian. Rapid Boards are only available if you enable the „GreenHopper Labs“). Still, I would currently recommend enabling rapid boards, as they make the whole Scrum process more enjoyable.
Atlassian should also try to be more consistent when it comes to naming functionality. When you start the
normal planning board, GreenHopper will present you a „New Card“ button. For me as a user it is immediately clear that I can add new user stories by clicking on that button, as user stories are normally written on cards. When using a rapid board, this button is not available anymore. Instead, a much smaller and more hidden „Create issue“ link is presented. Even more confusing, in planning mode the „New Card“ *and* the „Create Issue“ links are available, both offering a completely different interface experience. Where „New Card“ is the much simpler, Scrum-related one, „Create issue“ is the JIRA standard interface, that is much more complex. In the end, it does not matter which interface I use to add a new story – but it is confusing.
Briefly touched in the previous section, it is also not very intuitive that one has to create a JIRA project before using GreenHopper. The same is true for adding a task to a story, which requires way too many clicks. Of course, you can change that interface to make the „Create Sub-Task“ link more visible, but that involves lots of unnecessary work for a feature that should be available by default.
PerformancePerformance-wise there is not much to say, JIRA performs quite well. Ok, to be more elaborate: JIRA works much smoother than other tools if the bandwidth available is low. In fact, I have tested JIRA and GreenHopper by setting up my smartphone as a hotspot and the experience is great. One of the reasons for that experience is, that especially GreenHopper (JIRA itself much less) make extensive use of AJAX functionality (where AJAX simplified means that the browser does not have to refresh the whole page when changing an option or clicking a button). As testing platform I have used Atlassians very own cloud service, and I never experienced any downtime nor hiccup. Does this mean that the cloud can be classified as highly-available? Of course not, but exploring that is outside the scope of this article.
ResourcesGreenHopper does not require a client software to be installed on each of the team‘s machines since it runs within a web browser, which is s
tandard nowadays. Atlassian claims that JIRA and GreenHopper work on each browser as long as you browser version is high enough. From my point of view, those versions are not cutting edge, so chances are high that it works within your company’s IT landscape. Screen wise, XGA resolution is required (1024 x 768 pixels) – any moderately modern screen should fulfill that. However, there is one barrier that might come at a cost. The current GreenHopper Version (5.9.X) requires atleast JIRA version 5.X – a JIRA version most of the companies will not have running right now. Although GreenHopper (til 5.8.X) does work with JIRA 4.4.X, the much praised rapid Boards were introduced in this very version – chances are high that those boards might be buggy when using GreenHopper 5.8.X.
Some aspects were already mentioned, nevertheless the interface is much better as one might expect after reading the usability section. First of all, the rapid entry of new stories and task is a big plus, thanks to the large amount of keyboard shortcuts and the possibility to leave the „New Task/Story“ window open after adding a task or a story. Another great aspect is the highly flexible and sophisticated user dashboard. Each team member can change the content he or she wants to see on his dashboard by arranging the available components or by adding a new component, using JQL.
One of these available components is the so-called Activity stream which offers a similar experience as Facebook‘s News-Feed. New Stories/Tasks but also changed states of issues are displayed, each of those items offer the possibility to leave a comment or to add it to the users watch list if he or she wants to track any upcoming changes. Next to its dashboard, the user can also configure the taskboard in such a way as it pleases him or her. For example, he or she can choose to show only recently updated tasks, tasks of high importance or self-assigned tasks. By doing so, GreenHopper allows the user to create an interface that suits his or her needs.
Again, the possibilities of GreenHopper do not stop here. A fullscreen mode is also supported, the same is true for high contrast figures (using the wallboard plugin). Drag & drop is of course also available for moving tasks or stories and last but not least, the website is designed in such a minimal way that its layout does not waste space horizontally or vertically. Although the design looks simple, it is created in a way that enables the use all that flexibility JIRA and its plugins provides.
MotivationMotivation is and was always the trump card of paper-based taskboards. Only they were able to provide a certain haptic feeling. A feeling, software is not able to give. Unsurprisingly, this is also true for JIRA with GreenHopper. However, Atlassian comes quite close by offering numerous high contrast figures, using the aforementioned wallboard plugin. Recently, a Minecraft Plugin has emerged which offers gamers an innovative new way of solving JIRA issues.
CostsJIRA and GreenHopper are available as download for installing it on your company‘s dedicated hardware and as on-demand, which basically means that Atlassian hosts JIRA including GreenHopper for you on their server farm. Which option you choose is of course up to you, although most of the companies will favor the first option due to security policies. The minimum fee is 10$ – either as a one time purchase when you want to deploy it on your own server (10 users, the money will be donated to charity(!)) or 10$ a month, if you want to run it on-demand (again 10 users). According to Forrester, JIRA is by far the cheapest option of the Top 10 vendors of Agile Software – twice as cheap than the second cheapest vendor and just 18 times cheaper than the most expensive vendor. That is quite a number. And if one compares the offered functionality with other vendors it becomes clear why JIRA rightfully claims being a rising star.
Advantages- Flexibility
- Costs
- Own query language
- Inconsistency
- Beta-feeling of rapid boards
- Flexibility
This was the first article that evaluates JIRA’s abilities to represent a taskboard. Next time I will evaluate ThoughtWorks Studios Mingle.
References
West, D., Hammond, J.S., The Forrester Wave: Agile Development Management Tools, Q2 2010, Forrester Research Inc.
Eliminate All Variables Except Those Under Test
We can't trust intermittent tests... so always identify the three sections on your tests, and make sure that the Setup section is sufficient to keep all the variables in a steady state except the ones under actual test.
The Greatest Love of All
“A world without love is a deadly place” – Helen Fisher
Player’s Log – Day 15 of my 30 Day ChallengeIt should come as no surprise when you live in a place like the UK and the weather lady candidly forecasts a second month of wind and rain. To be fair, the weather isn’t always dreary in the UK, but the seasonal weather seems to redefine itself year on year.
Nonetheless, as I make my way to work this morning, I’m acutely aware that the weather outside pretty much reflects how I’m feeling inside. They warned me this would happen but that hasn’t made it easier. Foretelling what has to come offers no consolation when you find yourself caught in the eye of the storm.
I’m referring to what the organisers of the 30 Day Challenge call the “midway slump”. It’s the precise moment when the euphoria of living your dream (Day 15 and counting…) collides with the tarmac of reality. The moment when hope gives way under a crescendo of self-doubt and criticism.
As part of the 30 Day Challenge, I’ve taken to sharing my project with others, telling certain people about the crazy challenge I’ve set myself as well as ask for help. I figured I might as well use the opportunity to develop my stoicism.
What would you say?There are usually 3 kinds of responses.
The first is one of support and encouragement. “Sure! I’ll review your book. It would be an honour to.” This is mostly followed by detailed feedback and input.
The second is one of silence from thin lips followed by a slight nod of the head which I take as a cue to change topics.
The third is one of destructive criticism and even outright condemnation. “I wouldn’t waste my time doing that if I were you,” such people would tell me knowingly.
Believe in “WE”So what is my takeaway from these responses?
That you have to share your dreams with others to find people who share your dreams. And when you find each other, support one another.
That it’s up to each and everyone one of us to discover what matters to us even when we’re surrounded by people who don’t care.
That if we’re in the business of nurturing people, why do so many of us choose to destroy dreams instead of help them flourish?
What words or acts of nurture will you choose to use today?
How To Make Decisions
I find that action builds momentum. The best kind of action is decisive action because then you are "all in." Dipping a toe in the water doesn’t make the same splash as diving into the pool.
When I'm under the gun, "satisficing" to make decisions serves me well. Gary Klein wrote a great book on how experts make rapid decisions under fire. (The book is Sources of Power.)
Some of the techniques I use include: criteria and weights, CARVER (Criticality, Accessibility, Return, Vulnerability, Effect, and Recognizability), and Six Thinking Hats. At Microsoft, I tend to use criteria and weight when I need to get agreement with others on what the priorities are. I also tend to use Six Thinking Hats when I need to rapidly have folks change perspective, and take a more holistic view. To make the most of Six Thinking Hats, I use questions at the whiteboard to focus the thinking and work our way through the hats.
At the end of the day, I've found that a lot of the decisions come down to who do you want to be and what experiences do you want to create. Basically, the more you can connect your decisions to your "Why" or to your values, the stickier they are.
In fact, the secret of changing habits is to first decide who you want to be and our identify helps us pattern match the best fits.

