I wanted to talk about 2 things today.
- What we can learn from Polya’s How to Solve it and apply that to solve Powershell problems. This is not guidance, but a list of things that has worked for me in the past and some reflections thereof.
- What we can learn from Chess Grandmasters and be a better Powershell developer.
POINT-1:: Prof. Polya and How to Solve it.
Prof. George Polya in his seminal book How to solve it, wrote about these techniques for an aspiring mathematician. The book was also meant to be a guide for teachers of mathematics. I think some of these patterns can be used by Powershell developers or just developers in general.
- I am reproducing the text here from Wikipedia article and this Utah.Edu page.
- Polya’s text is in Italics.
- My annotations are in PS+.
- All emphasis are mine and underlined.
- I am just mentioning the relevant parts and skipping some of the other points mentioned by Polya.
Four principles (for becoming a Jedi Powershell master)
- Understand: First, you have to understand the problem.
- Plan: After understanding, then make a plan.
- Execute: Carry out the plan.
- Reflect and Learn: Look back on your work. How could it be better?
- What are you asked to find or show?
[PS+: Think output. Think PsObject. Think pipeline preservation. Think not killing a puppy.
Write-out the .EXAMPLE section of your Get-Help.
For.eg. Get-WorkingSet -computers, get-qadcomputer | Get-WorkingSet]
- Can you restate the problem in your own words?
- Can you think of a picture or a diagram that might help you understand the problem?
[PS+: David Agans in his debugging book also talks about writing a block-diagram or a flow-chart to flesh out the problem. Very helpful for tricky PS problems.
I wouldn't recommend a diagram if you are going to do a one-liner.]
- Is there enough information to enable you to find a solution?
[PS+: Do you need other module? Do you know what blog to read, or whose blog post to read? Do you know what to search for on MSDN, StackOverflow?
get-process | get-member -membertype Method]
- Do you understand all the words used in stating the problem?
[PS+: Talk to your friend]
- Do you need to ask a question to get the answer?
[PS+: Twitter, IRC, StackOverflow, and MS Forums. You should get to that after making an honest attempt at solving the problem.)
Strategy/Plan: (Hardest Step.)
**The skill at choosing an appropriate strategy is best learned by solving many problems. You will find choosing a strategy increasingly easy.**
Find the connection between the data and the unknown.
You may be obliged to consider auxiliary problems if an immediate connection cannot be found.
You should obtain eventually a plan of the solution.
- Have you seen it before?
[PS+: Codeplex, Poshcode, Github, StackOverflow, Script Center?]
- Or have you seen the same problem in a slightly different form?
[PS+: In a StackOverflow, blog or on #Powershell tag]
- Do you know a related problem?
- Look at the unknown! And try to think of a familiar problem having the same or a similar unknown.
[PS+: I have been trying out some P/Invoke stuff and I found this point particularly useful. P/Invoke is about converting Native Win32API functions and making them usable for managed code (C#) or Powershell. All P/Invoke stuff is written in C. My C is less than n00b level but after reading the blocks and blocks of solved C-code, I could sense how I will attack the problem. ]
- Here is a problem related to yours and solved before.
Could you use it? Could you use its result? Could you use its method?
[PS+: This again has been a really helpful tip. I usually end-up reading a lot of code on Poshcode and end-up modifying, extending some of the code. At times, I have ended-up using the functions but using it for a different purpose than what was originally intended.
You may need a Powershell buddy or a Powershell mentor to get you started thinking this way.]
- Should you introduce some auxiliary element in order to make its use possible?
[PS+: Use Modules. Check Poshcode. Check Gists, snippets. Code reusability using Powershell modules is not a catch-phrase. You would want to solve some problems and get it done with so that you don’t have to redo it from scratch later. Better still, someone may have done this for you already. You also need to maintain it depending on the use-cases where your modules have been used.
PsGet is an important step in that direction IMHO.
Ohloh Code Search
(Define Irony: Bing doesn’t support filetype:ps. But Bing supports filetype:pdf.]
- Could you restate the problem? Could you restate it still differently?
[PS+: Avoid thinking in terms of Cmdlets, Modules and .Net Classes at the outset. Try to be as generic and split the problem into its essential components - in English. This can be your SPEC document for your Powershell module.]
- If you cannot solve the proposed problem try to solve first some related problem. Could you imagine a more accessible related problem? A more general problem? A more special problem? An analogous problem?
[PS+: I usually work my way up from specific to general. I try to solve a specific problem with specific computername / PID and see if I can generalize it after solving it for 1 case.]
- Could you solve a part of the problem? Keep only a part of the condition, drop the other part?
[PS+: This should be easy. Don’t forget to understand the part you have not solved, and how it relates to the part you did solve.]
- Could you change the unknown or data, or both if necessary, so that the new unknown and the new data are nearer to each other?
- Did you use all the data? Did you use the whole condition? Have you taken into account all essential notions involved in the problem?
[PS+: Did you miss anything? Did you kill the puppy?]
Carry out the plan:
This step is usually easier than devising the plan. In general, all you need is care and patience, given that you have the necessary skills.
- Carrying out your plan of the solution, check each step. Can you see clearly that the step is correct?
[PS+: PowerGui and Powershell_ISE provides a step-into, step-out option in IDE. You can also create breakpoints and toggle between them.
You can check John Robbins's article on debugging]
- Persist with the plan that you have chosen.
- If it continues not to work discard it and choose another. Don’t be misled; this is how mathematics is done, even by professionals.
[PS+: Don’t get hung-over a function or a .Net Method if it doesn't work. XYZ person may say so, but you are the only one coding it - not them. Move on.]
Fourth principle: Review/extend
Polya mentions that much can be gained by taking the time to reflect and look back at what you have done, what worked and what didn’t. Doing this will enable you to predict what strategy to use to solve future problems, if these relate to the original problem.
[PS+: If there is one takeaway from Polya's book, it's this and this only.
Polya argues that after you have solved a problem, or in our case, a function or a script, much can be learned from reflecting on your solution and extending it to other class of problems.
Maybe you should group these scripts into a module? Maybe they are better apart since they don't have a single purpose. Maybe it's just a snippet for re-use later.
If you do not spend the time understanding the use-cases of your own script, you are losing a valuable learning opportunity.
I must admit that I rarely do this. The temptation to upload it on PoshCode and Tweet about it gets the best of me. But, if you do spend time reflecting on your own script and your own module, you will improve your own solution and extend it to other cases.]
POINT-2:: Annotating your and other’s code like Chess GM’s
What do chess grandmasters do, when they are not playing in competitions? They practice with other GM’s, try to beat Rybka (yes), and they review their own moves and annotate. They review games played by other masters, or their competitors and annotate.
I think annotating your code and reflecting on it is an important step in your personal development. You can also write really verbose in-line #comments and release it to the public. I’d go for annotating over verbose comments for one simple reason – when I annotate code, I use references which make sense only to me and in a particular context. All that verbiage may be useless if you don’t have the reference or the context.
Github provides an easy way to annotate code. (I don’t work for Github.)
Github has a free open-source plan, and also a paid private individual plan with 5 repos which starts at $7/mo.
I think that’s a better option, than building Mercurial on your own computer, administer and backup stuff only to get a 50% solution. Since you will be reusing your investment in knowledge and using the same tools (PoshGit), you can add that to your skill-set.
If you are starting out for the first-time, sooner or later you will end-up using code hosted on GitHub. It might be worthwhile investing some time learning about it.
I like Codeplex and PoshCode for cross-posting. But if I have to use a version control system which I will use day in day out and store my knowledge and annotations, I’d rather use Github.
Thanks for reading.
PS: I couldn’t incorporate these bullets above, so they made it to the PS section.
- Don’t forget going to user-group meetings.
- Don’t forget watching videos on TechEd, Channel9 and YouTube.
- Don’t forget to incorporate some form of unit-testing. I know Powershell doesn’t have a full-blow unit testing framework like nUnit, but you can review code-repos on Codeplex and see how they do it.