Wednesday, January 11, 2012

Pair, Learn, Present?

Weekend Testing helped usher in a way for software testers to learn and practice their craft and build their technical skills. Now, a new initiative is underway and looks promising as the next step in bringing testing (and more testers) into the public eye.


Ajay Balamurugadas and Brian Osman are helping lead the next wave of software testing craftsmanship. This time, instead of addressing the workmanship and craft of testing (which Weekend Testing is well situated to help build and grow), Pair, Learn, Present is meant to help testers develop their skills as presenters (like, in public, with a full room of people, on testing and technical topics).

Are you interested yet?

Pair Learn Present (PLP) is being developed as a safe environment where testers can learn presentation skills by pairing with a partner, taking on a topic, and then presenting that topic to the world (through webinars or live presentations where appropriate). The idea and format is similar to Weekend Testing and espouses the idea of pairing testers to share knowledge and develop skills, however PLP will be focusing on developing presentation skills.

So if this sounds like an exciting idea to you (and it definitely sounds exciting to me :) ), then send an email message to PairLearnPresent [at] GMAIL [dot] com and tell them you want in. From there, they can help you with selecting topics and pairing with other testers.


You can also connect with PLP here:

On Twitter: @PLP_Learning
On Facebook: https://www.facebook.com/profile.php?id=100003306257247
On Skype: PairLearnPresent

Is 2012 the year you plan to break out of your shell and start presenting? If you've been hesitant or unsure, this may be a great way to get your feet wet. I've already told them my interest, so if you're looking for a partner to present with, hey, I'm available :).



Tuesday, January 10, 2012

Don't Quit!

This morning I shared a post that was about the inspiration my son gave to me by his actions. It reminded me of a darker time about 10 years ago. The title is of a poem I came across and have subsequently kept with me for many years. I first started paying attention to it in January of 2002. That was when I went through my first layoff, and I've certainly thought about it quite a bit over the subsequent few years that followed (between 2002 and 2005, I would be let go of three jobs in the space of three years). I remember well the feeling of frustration and near helplessness at that time. It was not a good time to be a software tester, at least not in my immediate area. It would have been easy to give in to defeatism and hopelessness, but carrying this with me helped me remember that there’s a bigger picture, a brighter horizon and, yes, even an eternal perspective.


In that kind of a world view, three lean years is not that great an amount of time, and it gave me a chance to reflect on what I really valued and what I really wanted to do. I discovered something of great worth in those lean years. Yes, my family and I had to cut back on many creature comforts we had enjoyed, but our overall level of happiness did not diminish. We bought less stuff than before, but our relationships with each other were what truly mattered. I'd certainly like to not go through that particular "Refiners Fire" again if I can otherwise avoid it, but it taught me that I had more to do with my ultimate outcome than any circumstances that might befall me.


Mostly, I realized that no one else was going to solve my problems but me. No government agency, no headhunter, no service, no networking group. They might have a peripheral boost, but if I wasn’t focused on doing something that I felt was valuable, important and of worth, it wouldn’t matter. Real change doesn’t happen when external forces push on you. That’s just adaptation. Real change will happen when we decide we want a change, and when that happens, nothing will stand in our way.

Don’t Quit

When things go wrong, as they sometimes will,
When the road you’re treading seems all uphill,
When the funds are low and the debts are high,
And you want to smile, but you have to sigh,
When care is pressing you down a bit,
Rest if you must- but do not quit.

Life is queer with its twists and turns,
As every one of us sometimes learns,
And many a failure turns about
When he might have won had he stuck it out;
Don’t give up, though the pace seems slow-
You might succeed with another blow.

Often the goal is nearer than it seems
To a faint and faltering man,
Often the struggler has given up
When he might have captured the victor’s cup.
And he learned too late, when the night slipped down,
How close he was to the golden crown.

Success is failure turned inside out-
The silver tint of the clouds of doubt-
And you never can tell how close you are,
It may be near when it seems afar;
So stick to the fight when you’re hardest hit-
It’s when things seem worst that you mustn’t quit.

--Author Unknown

Character Still Counts These Days

Some of you have already seen this on Facebook, so forgive the repeat, but it gives me a chance to go a little more in depth and apply it to my own testing journey.

For the past decade, I've been actively involved with my son in Scouting. From his first days as a Tiger Cub just coming out of Kindergarten, to his currently being an Eagle Scout and a Venturing Bronze Award recipient at 15, I've tried to show him that hard work and dedication to a goal will pay off. I've also frequently encouraged him (or perhaps cajoled is a better term at times) with "Come on, Nick, you are an Eagle Scout! If you can do that, you can do this!" for so many things (service projects, school work, etc.).

This summer, he surprised me by saying he wanted to hang around after our Scout meetings and play Basketball at our church. Tuesday night is when a lot of our various meetings happen for many of our auxiliaries (Activities Days for girls between 8-12, Young Women's for girls ages 12-18, Cub Scouts for boys who are between 7-11, and Boy Scouts & Venturing for boys 11-18). Since we have the building that night, a lot of the guys in our Ward get together to play basketball after we finish with our meetings, and Nick decided to hang out and play ball with them.

Fast forward four months, and the High School team is holding basketball conditioning camp, which will be leading to tryouts three months later. I was somewhat surprised when my son said he wanted to participate in conditioning camp. I told him it was OK with it as long as his grades stayed above our agreed to threshold (any C's on a progress report means an automatic suspension of activity until it is resolved, however long it took to resolve it. I made sure the coaches knew that). We did actually have to call in on that a couple of times, but it was amazing how quickly he resolved those issues.

So we get to October and the team tryouts. I was hopeful but also apprehensive. Nick was enthusiastic, but he'd never played team ball with a league or in junior high, so he was starting from an inexperienced position to begin with. Still, he'd put a lot of work in, and I thought, well, maybe that will help him make the squad. Sadly, at the end of the first week tryouts, I picked him up from practice and he said "Well, I didn't make the team. I got cut in the first round."

I thought to myself "That's a bummer, but hey, he tried. I guess that's the end of that." He then surprised me and said "It's OK, the guys who were trying out are really good and have been doing this a long time." Wow, he's taking this well. "Besides, I asked the coach if I could be one of the team managers so I could keep working out with the team and learn some more, and get into better shape and learn the ropes, so I would be in a better position next year." Now that took me by complete surprise!

I asked him "So, you're willing to come each week and do the grunt work necessary to help the team? You're effectively going to be the 'water boy', you know that, right?" Please note, I didn't say that to belittle what he'd agreed to do, but I wanted to really see if he understood what being a team manager meant. It meant prepping the gym before and after games. It meant making sure water coolers were filled. It meant making sure that equipment was working, stats were being kept, uniforms were ordered and available. It meant running the scoreboard. It meant videotaping the practices and games. There wasn't going to be a lot of glamour in what he was going to be doing. He said he understood all that, and he was totally OK with it. Besides, some of his friends were helping with management duties, too, and his friends on the team were excited he'd be out there working with them.

For the past three months, my son has been getting up early on Saturdays and heading over after school to go and get the gym ready for practice, he's been doing full workouts with the team and acting as "crash test dummy" for drills, he's been hanging and removing nets from hoops, he's been tabulating team stats, he's been hauling water, he's been sweeping floors, and he's been traveling with the team to shoot video of the players, run the scoreboard and do all sorts of other things that the team needs. A lot of grunt work, almost none of it visible, but necessary and needed. He even went out and helped the team with fundraisers and special events so that they could raise money for a big Northern California basketball tournament that was being held 100 miles away in Patterson, CA (and which took up a good chunk of the week between Christmas and New Years). He did all of this, and more, while also keeping his grades up and doing all of the other things I've asked of him as a Dad. Not once did I hear him complain about any of it.

A couple of nights ago, my wife and I received a phone call. It was from the Junior Varsity team coach. He called us to commend Nick for all he'd done and for the commitment he'd made to the team, even in doing a lot of the unglamorous stuff necessary to help make the team perform well and stay on track with their training. That alone would have been nice, but there was more. He said he was so impressed with his work ethic and his desire to participate, that he asked if we would be OK with him being added to the J.V. team roster as a full player. Of course, were happy to say yes, but I told the coach of our own rules of eligibility regarding his grades. He laughed and said "Yes, I remember that, and of course, I will support you there. Still, if all that is in order, we'd like to offer him a full time spot on the team." To which we said "Certainly!"

As I asked Nick how he felt about all this, he played it cool (this is a common trait for a 15 year old, I realize ;) ), but he also showed a healthy dose of realism. "Dad, I'm on the team now, but I'm the low man on the J.V. squad. I'm probably not going to get much in the way of playing time, but hey, I now get the chance to play, and now I can practice and get better, so that maybe next year, I can start on the J.V team or maybe be eligible for the Varsity team" (he's a Sophomore right now, btw). I thought that was really cool, and a testament to level headed realism, but I could also see the faint smile on his face. He was excited, and he was happy at this turn of events, even if he wasn't going to outwardly admit it ;).

In the testing world, we are often faced with similar challenges. We often struggle with how we can break into a particular market, or we lament that there are no good jobs, or we say that there's no future in what we do, and nobody really cares, so what do we do? We go on and we do the bare minimum, or we just sigh and say "Ah well, such is life!" Well, I guess that's a way we could handle it... or we could do what my son did. He said "OK, so I can't be on the team right now in the capacity of a player... what can I do?!" Thomas Edison is famously quoted for saying "Opportunity is missed by most people because it is dressed in overalls and looks like work". Many times, we want to have the perks and the money and the prestige of doing something, but we are not willing to roll up our sleeves and do what is necessary. My son reminded me of just how valuable this process is. We can wait for something to happen to us, or we can go out and work to make it happen for us. There aren't any guarantees, of course, but "fortune favors the brave", and it favors those willing to do whatever it takes. To my son, thanks for the reminder, and thanks for proving you have the grit to do what is necessary, even if there's no prestige in doing it. You now have a shot at doing what you set out to do. Here's hoping you make the most of it, and thanks for reminding me of exactly what I need to do to make it on the big team in my own endeavors!

Monday, January 9, 2012

Book Review: The Tangled Web: A Guide to Securing Modern Web Applications

The web came together from many points of interest, and its open and free for all nature is both a blessing and a curse. It's a blessing in that the barrier to creating software to run on the web is very low (at least in its origin). A dizzying array of products, services, browsers, and other technologies has sprung up to make the experience more entertaining, engaging, and create one of the worlds most pervasive communications mediums. It's a curse in that with all of those varied (and competing) approaches, the ability to exploit and subvert the web is also relatively easy. We all agree that we want a more secure web. The big question is "how can we make that a reality?"


Michal Zalewski provides an answer in "The Tangled Web". As a software tester, this book is a well-spring. It shows the vulnerabilities that browsers have, and it gives an excellent walk through of potential exploits that testers can add to their plan of attack.

Michal starts out by giving us a tour and history of how we got where we are today, as well as a walk through of the basics of URL encoding, HTTP requests, cookies, HTML and CSS, Server and Browser Side Scripting (in all its various flavors). The variety of browser plug-ins that allow users to make their browsers more extensible and do things that go well beyond the traditional HTTP model of transactions is also covered (ActiveX, anyone?). This has not been a straight line of innovation, and it hasn't been done in the spirit of collegiality. In may ways, it's this lack of camaraderie that has led us to the situation we are in today; too much finger pointing and not enough mutual collaboration can be said to be the reason the web is much less secure than it potentially could be.


You could be forgiven if you think this section is just a rehash of basic Web Info 101, but you would be wrong. In each section, Michal shows some interesting inconsistencies, and ways that miscreant users can take advantage of them (Unicode manipulation to display completely logical looking URLs but be totally different due to using Cyrillic alphabet characters? I'll admit *I* never thought of that one; it's a phisher's dream!).


Part II focuses on Browser Security Features, i.e. those features in various browsers that are actually designed to help users (and developers) make sure that they are hindering the ability of rogue apps to cause mischief. Michal explores the vagaries of Content Isolation (the same origin policy being the most significant), Origin Inheritance (using URL's with data:, JavaScript: or about:), Frame Hijacking and Cross Domain Content Inclusion, following different security rules for Intranet vs. Internet usage, running services on non-standard ports, user generated content and files, and more explicit and aggressive forms of malicious use like Denial of Service attacks.


Part III focuses on some up and coming areas where web browser manufacturers are making feature distinctions with browser security as a legitimate selling point. Cross Origin Resource Sharing (CORS), Content Security Policy (CSP), HTTP Strict Transport Security (HSTS), in-Browser HTML Sanitization, and additional tweaks to modern browsers take center stage in this section. Many of these modifications are currently in play on some browsers but not others, and many are part of the HTML5 and CSS3 framework that is emerging. Michal makes the case that, while many of these schemes are somewhat effective, it would be wise to not let one's guard down and rely on these modifications on faith alone. Forewarned is forearmed. The section ends with a chapter dedicated to Common Web Vulnerabilities (and a good list of test areas for the aspiring penetration tester).


At the end of each chapter is a "Security Engineering" Cheat Sheet. Note that each of these suggestions can also be used as a "Security Deconstruction Cheat Sheet" as well. Any tester looking to expand on their penetration testing repertoire, or just expand their current Heuristic Testing models, would be well advised to look over each of these cheat sheets and see if, indeed, the sites and pages they are testing actually follow these directives, or if they don't.


Bottom Line:

This is not a book that you will be able to read in a single sitting and absorb everything that it contains, but it will make you sit up and think about aspects of web security you might never have considered before. This is in equal parts a wake-up call and a style reference. It sounds a much-needed alarm and shows us areas we take for granted way too often, and alerts us to issues we have likely never considered. If you’re a developer, tester, or infrastructure implementer, you would be wise to read and then re-read The Tangled Web. In our ever-changing world and with our web sites and services becoming more complex rather than less, the advice in this book may well prove to be both timely and timeless.

Exercise 42: Gothons Are Getting Classy: Learn Ruby the Hard Way: Practicum

All right, I need to pick up the pace here, or I'm not going to finish before the end of January as I planned. It's just that, as these projects get longer and more involved, it takes more time to do them and get them right. Here's another example of that.


In the last example, we saw that we could put functions inside of hashes. While that will work, there's another approach that serves the same purpose and really works better to encapsulate code that we want to duplicate for various purposes, and is actually at the heart of so called "object oriented programming". That heart is the structure called the "class".

Ruby utilizes classes to do a lot of things, specifically it allows us to make entirely new commands with their own methods that we can call on, and make copies of them that are unique and encapsulated within themselves (we could look at the idea of designing a car and have two separate cars with many similar components, but one's an SUV and the other is a Lamborghini. Similar in a lot of ways, different in key areas. we reuse the parts that are similar, and change or create components that are different for each instance. Zed makes the point that Classes are a huge area in programming, and to explore them completely goes way beyond the focus and point of this course and book.


We've actually been using classes quite a bit so far without realizing it. Examples are as follows:

stuff = ['Test', 'This', 'Out']
puts stuff.join(' ')

stuff is actually an Array class.
stuff.join(' ') has us using the Array class we called "stuff" and calling on the Array function (method) 'join', passing ' ' (an empty space). That's an example of using classes. Cool, huh?

Here's an example class. They are easier to make compared to hashes, but they have their own syntactic details to remember.






The @ symbol before the @number variable is part of that special syntax. This defines it as an "instance variable". This means that every instance of TheThing that we create will have its own value for @number. Instance variables are specific to the instance of the object that we create. We can't get at the name simply by typing a.number unless we explicitly make that data readable to the outside world.

We do that by including the attr_reader :number line.
If we wanted to make @number write-only, we could change the line to "attr_writer :number".
To make it read/write we could change the line to "attr_accessor :number".

This is all part of what is referred to as "encapsulating data" within an object-oriented context.

Next, there is an initialize method. This is how Ruby classes can be set up with internal variables (using the @ symbol). The variables can also be used  in the add_me_up() functions, where we add to the @number that we created.

The project for today is to recreate the game we made for Exercise 41, but in this case, we are going to make it as a class, and call the class to set up the game and run through the rooms. I took the liberty of modifying the program structure to use "here documents" just for fun. If you want to try it out using the program as Zed originally created it, check the LRTHW site and get that version and copy it out:








What You Should See




As you can see, the code output is almost identical to the last version. Two differences, we see two calls at the top to show that we are creating an instance of the class to start the game, and we are also seeing the effect of the Here Document usage: anything that appears between the opening and closing tag are treated as literal text, meaning the formatting spaces are preserved. That's why the text appears indented in the output. If I wanted to clean that up, I could move the text to the beginning of each line, but again, that kind of offends my sensibilities of formatted code. Still, if it was needed, I'd do it :).

TESTHEAD's TAKEAWAYS:

The key details we need to be aware of when we are looking at classes and how they are used are as follows:

- We made a class called Game and put functions inside it.
- Initialize is a special initialization method that sets up important variables.
- We can add functions to a class by nesting their definitions under the class keyword.
- We can nest the contents of the functions under their names.
- We can see how "@" is used with initialize, play, and death.
- We created a "Game" instance at the end and then told it to "play()". That's how everything got started.

Thursday, January 5, 2012

A Less Wayward Weekend Testing Americas




It's a new year, and one of my goals for this new year is that I want to see Weekend Testing Americas be a little more consistent. What do I mean by that? I mean that I want to be able to have the ability to regularly, with ease, tell people when a session will be. In 2010 and 2011, that was a bit challenging for me to do, as I often had to juggle other commitments to be available, and it also followed another reality. If a session were to happen, I had to be there.


Fortunately, that has been somewhat rectified by my partner in crime, Albert Gareev. Albert has agreed to be co-facilitator and my official second in command for WTA (he's been the de-facto co-facilitator and 2nd in command for a long time) so it's no longer tied to just my schedule specifically, but again, it requires now that Albert also be available.


The biggest frustration, though, was the fact that the sessions floated a lot, sometimes they were every other week, sometimes every three weeks, sometimes once a month. The net result was that it was hard to predict when sessions would be held. I couldn't commit to a twice-monthly schedule, but I felt that once a month was too little. I've since reconsidered that position.


Thus, for the year of 2012, there will be a dedicated Weekend Testing Americas time. Barring a reason to pre-empt it, we have decided to go with a calendared slot once a month, and that will always be the first Saturday of each month. In short, if the first Saturday of a month rolls around, and you haven't heard differently, you can expect to see a Weekend Testing Americas session take place.


There may well be "bonus" sessions in a given month (a guest presenter, a special topic or something timely that would make sense to do it at another time) and we are open to holding those sessions when they make sense.


The bigger questions, though, needs to come from those who actively participate in these sessions, and here's where I'm hoping to get some feedback:


  • If you come to Weekend Testing Americas sessions, why do you come out to them?
  • If you used to come out, but don't any longer, what is the reason you stopped coming?
  • If you have never participated before, but have had that tickle in the back of your mind to still want to try it, what has stopped you from coming out?
  • If you have had no intention at all to participate and still don't, why?


Additionally, regardless of where you fall on the "session attendee continuum", there is the never ending question of "what do you want Weekend Testing to be?". We who facilitate these sessions ask this a lot, and we try to anticipate what others might like to do and what might be interesting and helpful. Sometimes we hit home runs. Sometimes we strike out. Most of the time, we have good interactions and we all learn a lot, but after several dozen sessions, we'd like to have more input and feedback from those who are our customers and clients, i.e. our active test craftsman who come to our sessions to learn, grow and perfect their craft.


So, in the spirit of this post, I of course want to make sure everyone is aware that this Saturday is the first Saturday of the month. As such, we will be holding a Weekend Testing Americas Session.


Weekend Testing – Americas Chapter Session No. 23

Session Type: Game Play, Brainstorming, Bug Hunting

Date: Saturday, January 07, 2012

Time: 10:00 a.m. – 12:00 p.m. PST. Check to see session time in your time zone.

To join this session, please do the following:

1. Add “weekendtestersamericas” to your Skype contacts if you haven’t already.
 Request to have us add you as well.

2. Fifteen minutes prior to the start of the session, please message “weekendtestingamericas” and ask to be added to the chat session. Once we see you, we will add you to the session.

For more details, or to be added to our regular distribution, please contact WTAmericas ( at ) gmail (dot) com.

Hope to see you there :).

Wednesday, January 4, 2012

Book Review: The Creative Habit: Learn It and Use It for Life


It's been awhile since I did a book review, and I have a significant backlog, so I think it's only fair to finally review a title I've wanted to work with for awhile now.


Over the years, I've had numerous opportunities to get involved in a variety of projects and through them, I have become convinced of one thing. Not everyone has the temperament and constitution to be a "Artist" in the classical sense of the word, but everyone has the ability to be creative and create art. I'm using the idea of "art" in this sense the way Seth Godin describes it in his book "Linchpin".


We are rapidly developing away from a world where the mass produced and easily reproducible will offer anything in the way of lasting value and personal significance. The ability to create art, and to regularly nurture the ability to create, is going to be the true currency going forward. In short, we will be remembered for the art we create in our lives. Whether that be creative code, creative processes and, yes, even creative testing (and lets face it, testers are creative and make art every day :) ), then it would help to get somewhat in touch with ways to encourage our abilities to develop creativity or make it more of an every day occurrence.


Twyla Tharpe is well known as one of the great choreographers of the 20th century, and yes, much of this book is autobiographical and talks about her approach to dance, choreography and how she manages to develop her ideas. "The Creative Habit" is a discussion on how she goes about creating the art that is her life's work. If you think "well, I'm not a dancer, so this book is irrelevant to me", you are missing the point. This isn't a dance book. The ability to take her suggestions and ideas and apply them may require some reworking or tweaking to fit your own context. The truth is that, to be creative, you have to have a tolerance for the abstract, and understand that there really isn't any way to take something like "creativity" and break it down into a "paint by numbers" format. Having said that, Twyla does offer a number of areas to consider, and provides exercises to apply to your endeavor and see if it fits.


The second chapter, Rituals of Preparation, brings the reader through all of the doubts and nay-saying. She uses her own metaphors to show how she addresses the doubts that she has (people will laugh at me, I'm not any good at this, I don't have the talent to do this, I don't have any good ideas) and systematically dismembers each argument :). She also makes the point that part of the ability to create is the ability to put down other distractions and interference (she is not a fan of multi-tasking). To create, often the first step is giving up something else (typically temporarily, but hey, you may surprise yourself).


One of the exercises in Chapter 3 ("Your Creative DNA") is filling out your own Creative Autobiography. This is 33 questions that let you get in tune with areas you are comfortable with and areas you may have to stretch or, hey, develop from the ground up in some cases. I won't iterate all of the questions, but some key ones:



  • What is the best idea you've ever had? 
  • What made it great in your mind?
  • What are your habits? What patterns do you repeat?
  • When faced with impending success or the threat of failure, how do you respond?
  • At what moments do you feel your reach exceed your grasp?
  • What is your idea of mastery?


The key to the title is the word "Habit". Most of the ideas in this book are meant to help the reader make a commitment to develop their creativity, so that it becomes ingrained in them. In truth, I think that's an apt word, since Creativity is often sold to us as some rare gem that people either have or do not have. It's not true; everyone has varying levels of creativity in different areas. Whether you draw, write prose, create code, design web pages, sculpt, dance, or fill in the blank, the ability to create requires practice. It requires repeated effort.


Twyla uses the metaphor of a box, and that everything she creates has a box and a way to keep the details about what helps her create a dance stored in that labeled and well tended box. Jerry Weinberg talks of a similar method he calls "Fieldstoning". It's the same idea with different terms; the point is that we need to have a way to gather, categorize and process the inputs we get to make something, whatever it may be.


Once we have gathered our materials, it's time to start doing some arranging, or "scratching" as Twyla refers to it. She shows and exercise with a number of coins and the ability to arrange them in a number of different ways. the point of the exercise is that, with just a handful of coins, you can create a near infinite arrangement of the coins, and each will be different from the last one. Still, to make those unique arrangements, you as the person doing the exercise still have to move the coins.


Bottom Line: 

Creativity is not an ethereal spirit, but a craft, like plumbing, woodworking, construction, or automobile repair. It's a skill that can be developed, nurtured and learned, but to get good at it, it has to be practiced, in whatever area that you wish to have it work for you. My creativity may not be applicable to your creativity. Some exercises will be right on the money, and some will feel odd and disjointed, and that's OK. For those looking for a literal soup to nuts approach to turbocharge their creativity from the ground up, you may find this title lacking. If, however, you can appreciate the context in which you wish to apply your own creativity, and can tolerate some vague and possibly not totally applicable content, but can consider the ideas and morph them to your own endeavors, then there's a lot to like in The Creative Habit, and a lot that can be applied to whatever endeavor you aspire to.

Exercise 41: Gothons From Planet Percal #25: Learn Ruby the Hard Way: Practicum

Happy New Year everyone. Sorry for the delay between sections, but with it being New Years weekend, and activities with my kids, putting away Christmas decorations, and all of the other things related to turning a house upside down after a holiday season, I needed the holiday time. I'm back now, though, and on track to finish these modules out by the end of January if not sooner (good thing, as the end of January is my hard completion deadline for this project :) ).


So back in Exercise 40, we did some playing around with arrays and dictionaries/hashes. Alone with that, we had some additional items added into the mix that, to tell the truth I wasn't 100% sure what was going on. Fortunately, Zed and Rob tell us specifically what is happening here.

Here's the code block that they wanted me to focus on:

cities[:find] = method(:find_city)
puts cities[:find].call(cities, state)

variables can hold lots of values. They can also hold entire blocks of code. To do that, a "proc" (short for procedure) is made. to do that, a built in command called "method" is called (yes, functions and methods are interchangeable, but this is a specific method called "method" that actually does this... now you see why it's been a few days since I've posted ;) ).

The return from "method" is the full proc of "find_city" method (again, we need to pay attention here). That full proc is then stored in the hash called "cities", and uses a key called ":find".

The point here is that, with the "find_city" proc being included in a hash with the key of ":find", we can use that proc by calling on its key.

The 2nd line of code does the following:

Ruby reads the variable "cities" and determines it's a hash/dictionary.

[:find] looks at the "cities" hash/dictionary and evaluates the value of  ":find".

This is the proc "find_city" that we set up using "method". When it sees the method ".call", it calls the proc code.

Since the proc expects parameters, we pass it two parameters, in this case, "cities" and "state". find_city then tries to look up states inside cities.

If it finds a match, it returns it. If it doesn't it returns a message saying it couldn't find a match.

Finally, prints out the value returned by the ":find_city" proc using the puts method.

Did that seem confusing? Yeah, I agree. It's taken me a while to get my head around this, too, and I'm still not entirely sure that I'm 100% there. Zed offers the following trick to help us remember these things. Read the code backwards.

Try this:

* state and city are...
* passed as parameters to...
* a proc at...
* :find inside...
* the hash cities...
* and finally printed on the screen

Here's another way to read it, this time "inside-out".

* Find the center item of the expression, in this case [:find].
* Go counter-clock-wise and you have a hash cities, so this finds the element :find in cities.
* That gives us a proc. Keep going counter-clock-wise and you get to the parameters.
* The parameters are passed to the proc, and that returns a result. Go counter-clock-wise again.
* Finally, we are at the puts statement, and we have our end result.


I have to admit, it's these circular references that kind of drive me crazy (sort of like saying "to understand recursion, you have to first understand recursion"... please don't get me started!).

Zed suggests that reading code and not getting totally lost helps if you can do the three approaches he's described. When reading code, you should read it:

* Front to back.
* Back to front.
* Counter-clock-wise.

So here's the code for today's project. this spans multiple pages, so the screen shots are mostly carved up into their respective methods, give or take a couple. See below:








What You Should See

$ ruby ex41.rb

--------
The Gothons of Planet Percal #25 have invaded your ship and destroyed
your entire crew.  You are the last surviving member and your last
mission is to get the neutron destruct bomb from the Weapons Armory,
put it in the bridge, and blow the ship up after getting into an
escape pod.


You're running down the central corridor to the Weapons Armory when
a Gothon jumps out, red scaly skin, dark grimy teeth, and evil clown costume
flowing around his hate filled body.  He's blocking the door to the
Armory and about to pull a weapon to blast you.
> dodge!
Like a world class boxer you dodge, weave, slip and slide right
as the Gothon's blaster cranks a laser past your head.
In the middle of your artful dodge your foot slips and you
bang your head on the metal wall and pass out.
You wake up shortly after only to die as the Gothon stomps on
your head and eats you.

--------
Such a luser.

$ ruby ex41.rb

--------
The Gothons of Planet Percal #25 have invaded your ship and destroyed
your entire crew.  You are the last surviving member and your last
mission is to get the neutron destruct bomb from the Weapons Armory,
put it in the bridge, and blow the ship up after getting into an
escape pod.


You're running down the central corridor to the Weapons Armory when
a Gothon jumps out, red scaly skin, dark grimy teeth, and evil clown costume
flowing around his hate filled body.  He's blocking the door to the
Armory and about to pull a weapon to blast you.
> tell a joke
Lucky for you they made you learn Gothon insults in the academy.
You tell the one Gothon joke you know:
Lbhe zbgure vf fb sng, jura fur fvgf nebhaq gur ubhfr, fur fvgf nebhaq gur ubhfr.
The Gothon stops, tries not to laugh, then busts out laughing and can't move.
While he's laughing you run up and shoot him square in the head
putting him down, then jump through the Weapon Armory door.

--------
You do a dive roll into the Weapon Armory, crouch and scan the room
for more Gothons that might be hiding.  It's dead quiet, too quiet.
You stand up and run to the far side of the room and find the
neutron bomb in its container.  There's a keypad lock on the box
and you need the code to get the bomb out.  If you get the code
wrong 10 times then the lock closes forever and you can't
get the bomb.  The code is 3 digits.
[keypad]> 123
BZZZZEDDD!
[keypad]> 234
BZZZZEDDD!
[keypad]> 345
BZZZZEDDD!
[keypad]> 456
BZZZZEDDD!
[keypad]> 567
BZZZZEDDD!
[keypad]> 678
BZZZZEDDD!
[keypad]> 789
BZZZZEDDD!
[keypad]> 384
BZZZZEDDD!
[keypad]> 764
BZZZZEDDD!
[keypad]> 354
BZZZZEDDD!
[keypad]> 263
The lock buzzes one last time and then you hear a sickening
melting sound as the mechanism is fused together.
You decide to sit there, and finally the Gothons blow up the
ship from their ship and you die.

--------
You died.  You kinda suck at this.


Extra Credit

Explain how returning the next room works.


[We are effectively using hash keys, and those hash keys are calling on the actual functions as their return values. Each function is being stored as a proc in the ROOMS dictionary/hash table.]

Add cheat codes to the game so you can get past the more difficult rooms.

Instead of having each function print itself, learn about "here document" strings.

Write the room description as here document strings, and change the runner to use them.

[ Here document strings make it easy to put text together, and it's  nice to not have to repeat all of the puts statements. The only thing I don't like about them is that it kinda hurts my sensibility of properly indented code. Still, I guess I can live with it :) ].






TESTHEAD's TAKEAWAYS

Here documentation will take some getting used to, but I like the idea of being able to use a hash to keep the return values in check. It makes it easier to read once you see what it's actually doing, plus it makes it easier to maintain. Also, I need to pick up the pace and get back into a  daily groove where possible (it's amazing what you have to go back and review when you've been away for a few days!).

Tuesday, January 3, 2012

Situational Paralysis? Start Talking!


Now, I know I'm going to get some raised eyebrows for this one, but I'm secure enough to admit that I'm a bit odd at times (as if you all didn't already know that ;) ).


Seriously, though, have you ever found yourself staring at something that is just so hairy, gnarly and potentially time sucking that you keep putting it off forever? Avoidance may work for a time, but at some point, the issue has to be addressed. I have a built-in incentive that causes me to tackle this kind of situation every year. That is my end of year donation frenzy. I don't believe in resolutions, but I do believe in tax write-offs that I'm eligible to take, and one of the cleanest and easiest is donating things to charity. Of course, you have a finite time limit to maximize this potential, and for me, that finite time limit always ends on December 31st of each year.


So this often leaves me going through all sorts of things that need to be categorized, co-ordinated, grouped, sorted, sifted, and otherwise given some kind of order amid the chaos, and many times it's enough to drive someone to distraction (and a healthy dose of avoidance). Likewise, even outside of donating, having a closet/room/garage/house/project/presentation/talk/thesis/whatever that is in desperate need of corralling, it can be almost impossible to calm your thoughts and your nerves to address the problem objectively.


What do I do in these situations? I start talking. Out loud. Seriously!


Why? Because the act of physically talking out what I have to do, as though I'm explaining it to someone else in the room, even if they are not there, forces me to actually address the root of the problem, which is "good grief, I don't know where to begin!" This analysis paralysis or situational paralysis is "the Lizard Brain" in full bloom, The Resistance in full battle formation, and you looking for any other thing to do than actually tackle the issue.


Here's a very recent example. There are so many things that I have in my office closet that make it virtually unusable. Projects from many areas of my life spread out, intermixed, in difficult to reach areas, all in various states of beginning, in progress, and nearing completion, but that's as close as many of them have gotten. The worst part is that more stuff keeps coming in, day after day, so that it looks like a small scale set of "hoarders" (no, I'm really not that bad, but since I seek that Zen space of "minimalist uncluttered bliss", it sure feels like it at times). Boxes of intermingled stuff, and of course, I've added to it by deliberately getting rid of the catch-all I've been using for years,  i.e. the computer hutch. With it gone, the closet is the last refuge for this stuff.

At this stage, I start a very openly verbal dialog (and yes, this is literally what I do, no hyperbole here):

"OK, give me a box. Good, what do we have here? It's the cable to my camcorder so it can be plugged into a television or secondary recording device. That is a video cable, and needs to go to the corner of the table."


"What's next? That is a bundle of USB connectors. Good, are there any more in this box? Excellent, let's gather them all together and classify them. What end do they have, and can I tell what they go to by sight? OK, this one goes to my digital camera. This one is an extension cord, these five are classic USB cables with the Type 1 end. These several are various ends with different styles of connectors... this one goes to my MP3 player, this one goes to the blue tooth headset, separate them all out."


"Excellent. Now let's get some plastic freezer bags and sort them all and get a sharpie and mark the bags to identify what they are."


"Oh look, here are a bunch of photographs. These go into the portable case that's labeled "Personal" and I'll review them later so that they can be sorted and scanned."


"Here's a bunch of papers that are out of date related to a testing tool I work with, and I have updated documents on my flash drive... let's go ahead and purge these."


And so on. I audibly talk my way through this conversation as though I'm explaining what I'm doing to someone in the room. It helps me to keep the avoidance at bay, and it also helps me to shout down the Lizard Brain and quiet The Resistance. It's entirely possible that you will be able to do something similar in the quiet of your own mind, but I find the process of actually putting words to the actions, and saying them aloud while I am doing them makes a huge difference. It also makes what seems like an endless process go so much faster.


So seriously, the next time you find yourself staring down an incredible challenge, one that is scary, difficult or just plain tedious, try talking your way through it. I'm willing to bet you'll be surprised at how effective you can be.

Monday, January 2, 2012

Finding New Knowledge in Current Places

One of the things I started doing during my Christmas/New Years break (still on it, today is the last day), I made a decision to go through my bookshelf and see what books I have never read. I was surprised to find that I had quite a few items that fit this list. This is not the "I agreed to review these titles and I am going to review them in the coming weeks" list, these are titles that I have had for years and have never opened.


Some of these were gifts. Some were titles I had to pick up for a class I took but never got to (and never really "needed" for the class anyway). Some were handed off to me by others who no longer needed them and I saw some potential future value in them. What they all have in common is this; I thought they would be worthwhile, but never cracked their potential. What these represent is a body of knowledge that is effectively a door stop, and nothing more. It's two cubic feet of processed tree product and a cup of ink. More than anything else, though, it's a displacement of space. That's harsh, but I think it's important to make this point... books do not do anything if you do not actually open them and read them.


I have lots of books that I've read a few chapters of, got the core value out of, and saw that there might be things I could use later on. I have a couple of Home Repair books that meet this criteria. Let's face it, I'm not going to be rewiring my bathroom tomorrow, but if I need to do it (and decide I have the ability and the equipment to make sure I can do a good and "to code" job), then I know where to go to reference that information. This book has value to me, because I know what's in it. This book is what I referred to as an "evergreen reference". It's an evergreen reference because I have read it and I know what the value points are. I have several cook books, though, that I've looked at the cover, seen the pictures, and done absolutely nothing with. I'm talking about years worth of nothing. Why do I keep them? Because I think that, maybe, I'll find some use from them, someday, but not right now. At what point do we say "this has exceeded its real shelf life, and I am really not going to ever use this"?


Often, we fall into a "sunk cost fallacy" when we buy a book or when we are given a book. We or someone else invested in this title on our behalf. We feel obligated to keep it. If we don't, we're throwing money away. The sunk cost fallacy is that the item has value just by its existing. It doesn't. The value is only unlocked if we actually use it. If it truly has no value to us, then "liberate" the title so someone else can get the value of it. The money has already been spent either way. The cost has already been realized. Only we can decide if those titles (or anything, really) is worth pursuing further or seeing if we can get more value out of it.


So what is my solution to this? It's simple. It's called my "15 Minutes a Day Reference Review Chain". I've added to my Goals List the goal of reviewing every single title in my bookshelf for a set period of time in a given day. Fifteen minutes, on a timer, and in that fifteen minutes, I go through a book, and I make a three point decision:

1. Do I have any use for this book today? If so, what can I apply here and now from this book?

2. Will I have a use for this book in the near term future (near term in my world view is 90 days) or can I realistically picture there being value in the title should there be a need for it in those 90 days (see example above regarding wiring of an electrical outlet)?

3. Do I see there being no chance of my using this information in any way, shape or form, for my self or any member of my family, in the long term (long term in my world view is 5 years or more)?

Each day, I do the same thing for a different book. Obviously, if I can answer yes for #1, it goes into "immediate rotation" which means it's no longer a dead reference, but a live active title to do something more with (read a chapter, work on a problem, make a model based on the information, etc.). If it's a number 2 "yes", then it goes to the bottom of the pile, and I see if I actually hit it in the time period (just cause I'm geeky that way and want to see if I really will). If I get through #3, and I've answered "no" across the board, it goes into a box in the garage (and I make a list of what goes in there and keep the list in an easy to find place). I give myself a "mea culpa" buffer of 90 days once a title hits the box. If in those 90 days I have not re-considered, then my local library gets a new title for their shelves. Now, someone else can take advantage of knowledge that I have actively decided I do not need.


Note, this approach requires active review of each title. I have to physically read through each book, at least in a skimmed manner,  and I have to make a decision. This way, I really evaluate every title I own on a regular interval, and in the process, I may find that I cover a lot of ground, learn a lot of things from sources I otherwise might never have considered, and I make a true and objective evaluation of the value of the titles I actually have. What I've already discovered from this process is that I have a ton of hidden knowledge already in my hands that is just sitting there, waiting to be discovered.


How about you? What do you have waiting in your bookshelf that can help you right here and right now? It could be cooking better, it could be a book on wilderness survival, but somewhere you may be able to find something to relate to your current needs and skill set in things you already have. Do some digging, and give yourself fifteen minutes a day in what you already have. I'll keep you updated on what I discover in the two cubic feet of paper that is now next to my door (there so I literally trip over it whenever I walk into my office :) ).